Sample webhook payloads for Google Cloud Marketplace private offer lifecycle
events
GCP private offer webhooks notify your endpoint when a Google Cloud Marketplace
private offer changes lifecycle state in Tackle. Use these notifications to
update CRM records, trigger buyer follow-up, or sync offer status into your
systems.
GCP Only — These event types are for Google Cloud Marketplace private
offers only. AWS and Azure private offer webhooks are unchanged.Preview — These webhooks are in preview and are not Generally Available
(GA). Event types, payload fields, and delivery behavior may change before GA.
Subscribing to GCP Private Offer Webhooks
Webhooks are delivered to the endpoint configured for your vendor account (or a
product-level endpoint if one is set). See Create or Update Webhook to configure
your endpoint.
Your endpoint must:
- Accept
POSTrequests withContent-Type: application/json - Return a
2xxHTTP status code (for example200 OK) to acknowledge receipt - Respond within 10 seconds — offload long-running work to an async process
Delivery also depends on your vendor being rolled onto the Offers GCP API. Until
then you may still receive the legacy unprefixed private_offer_* events for
GCP (see
Migration from unprefixed GCP event types).
Event Types
| Event Type | Description |
|---|---|
gcp_private_offer_created | A new private offer was created in Tackle. |
gcp_private_offer_created_in_marketplace | The offer was first published or went live in Google Cloud Marketplace. |
gcp_private_offer_failed_to_create_in_marketplace | Marketplace create failed while the offer was still unpublished. |
gcp_private_offer_cancelled_in_marketplace | The offer was first cancelled in the marketplace. |
gcp_private_offer_failed_to_cancel_in_marketplace | Marketplace cancel failed on a published offer. |
gcp_private_offer_purchase_instructions_sent | Purchase-instructions email was first sent to the buyer. |
gcp_private_offer_invitation_opened | The buyer opened the purchase-instructions email. |
gcp_private_offer_viewed | The buyer viewed the offer through the Tackle marketplace redirect. |
gcp_private_offer_accepted | The offer was first accepted. |
Tackle sends each lifecycle event on the first transition (for example first
publish), not on every later field update. Retries may deliver the same event
more than once — deduplicate with po_id, event_type, and timestamps in
private_offer_metadata if needed.
Correlating Offers With Your Systems
Every payload carries Tackle identifiers plus optional marketplace context:
po_id— the Tackle private offer id. Use this for Tackle API calls such as
GET https://gcp.offers.tackle.io/api/private-offers/{po_id}.offerid— the Google Cloud Marketplace private offer id (cloudId). Empty
string until the offer exists in GCP.private_offer_metadata.offer_metadata— Additional Fields configured on the
private offer, forwarded as stored.cloud_data— the marketplace
PrivateOffer
resource when Tackle has stored marketplace data. Nested keys match the
Commerce Producer API (camelCase). Omitted when empty.
offeridis notpo_id.po_idis the Tackle private offer id.offeridis
the Google Cloud Marketplace private offer id. They identify different objects
in different systems.
Optional fields are omitted when empty (unlike some AWS agreement fields
that always appear as '' / {}). Code for missing keys as well as present
values.
Common Fields
All GCP private offer webhooks share this base shape.
| Field | Type | Description |
|---|---|---|
event_type | String | One of the gcp_private_offer_* values above. |
marketplace | String | Always gcp. |
destination | String | Always callback. |
po_id | String | Tackle private offer id. |
offerid | String | Google Cloud Marketplace private offer id. Empty string until the offer exists in GCP. |
vendorid | String | Tackle vendor id. |
offer_type | String | Offer type (for example direct or partner_resale). |
created_at | String | Offer created timestamp in ISO 8601 format. |
productid | String | Commerce Producer service / product id when known. Omitted when unknown. |
buyer_company_name | String | Buyer company name when known. |
seller_company_name | String | Seller (vendor) display name when known. Omitted when unknown. |
created_in_marketplace_at | String | Timestamp when the offer was first published in the marketplace. Omitted until publish. |
buyer_billing_account_ref | String | Billing account id without the billingAccounts/ prefix when known. Omitted when unknown. |
actor | Object | Actor who triggered the change when known (user_id, name, email). May be {}. |
extra_data.users[] | Array | Buyer emails as { "email": "..." } objects. |
errors[] | Array | Marketplace errors (code, message) when present. Omitted when there are none. |
private_offer_metadata | Object | Tackle adjuncts (timestamps, buyers, Additional Fields). See below. |
cloud_data | Object | Marketplace PrivateOffer payload when present. Same shape as REST cloudData. Omitted when empty. |
private_offer_metadata
private_offer_metadata| Field | Type | Description |
|---|---|---|
last_modified_at | String | Last modified timestamp in ISO 8601 format. |
buyers[] | Array | Buyer objects with email_address and optional full_name / title. |
accepted_at | String | Present after acceptance. |
cancelled_at | String | Present after cancel. |
sent_at | String | Present after purchase instructions are sent. |
viewed_offer_at | String | Present after the buyer views the offer via redirect. |
opened_instructions_at | String | Present after the buyer opens the purchase-instructions email. |
archived_at | String | Present when the offer is archived. |
offer_metadata | Object | Additional Fields from the private offer, as key/value pairs. Keys are exactly as entered in Tackle. |
pre_registration_details | Object | Pre-registration details when present. |
Private Offer Created
Sent when a new private offer is created in Tackle (before or without
marketplace publish).
Example Payload
{
"actor": {
"user_id": "auth0|example",
"name": "Ada Lovelace",
"email": "[email protected]"
},
"marketplace": "gcp",
"created_at": "2026-08-01T00:00:00Z",
"destination": "callback",
"event_type": "gcp_private_offer_created",
"extra_data": {
"users": [{ "email": "[email protected]" }]
},
"offerid": "",
"po_id": "01HZXEXAMPLEPOID00000000",
"vendorid": "ACMEVENDOR",
"offer_type": "direct",
"buyer_company_name": "Buyer Co",
"seller_company_name": "Seller Inc",
"productid": "example-service-id",
"private_offer_metadata": {
"last_modified_at": "2026-08-01T00:00:00Z",
"buyers": [
{
"email_address": "[email protected]",
"full_name": "Buyer"
}
],
"offer_metadata": {
"Salesforce Opportunity ID": "0069000000ABcDeFGH"
}
}
}Private Offer Created in Marketplace
Sent when the offer is first published or goes live in Google Cloud Marketplace.
Example Payload
{
"actor": {
"user_id": "auth0|example",
"name": "Ada Lovelace",
"email": "[email protected]"
},
"marketplace": "gcp",
"created_at": "2026-08-01T00:00:00Z",
"destination": "callback",
"event_type": "gcp_private_offer_created_in_marketplace",
"extra_data": {
"users": [{ "email": "[email protected]" }]
},
"offerid": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"po_id": "01HZXEXAMPLEPOID00000000",
"vendorid": "ACMEVENDOR",
"offer_type": "direct",
"buyer_company_name": "Buyer Co",
"seller_company_name": "Seller Inc",
"created_in_marketplace_at": "2026-08-20T12:00:00Z",
"buyer_billing_account_ref": "011542-B6FA9A-2EE376",
"productid": "example-service-id",
"private_offer_metadata": {
"last_modified_at": "2026-08-20T12:00:00Z",
"buyers": [
{
"email_address": "[email protected]",
"full_name": "Buyer"
}
]
},
"cloud_data": {
"name": "projects/example/locations/global/privateOffers/a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"state": "PUBLISHED",
"customer": {
"entityTitle": "Buyer Co",
"email": "[email protected]"
}
}
}Private Offer Failed to Create in Marketplace
Sent when marketplace create fails while the offer is still unpublished.
offerid may still be empty; errors carries marketplace failure details.
Example Payload
{
"actor": {
"user_id": "auth0|example",
"name": "Ada Lovelace",
"email": "[email protected]"
},
"marketplace": "gcp",
"created_at": "2026-08-01T00:00:00Z",
"destination": "callback",
"event_type": "gcp_private_offer_failed_to_create_in_marketplace",
"extra_data": {
"users": [{ "email": "[email protected]" }]
},
"offerid": "",
"po_id": "01HZXEXAMPLEPOID00000000",
"vendorid": "ACMEVENDOR",
"offer_type": "direct",
"buyer_company_name": "Buyer Co",
"seller_company_name": "Seller Inc",
"errors": [
{
"code": "PRIVATE_OFFER_BILLING_ACCOUNT_NOT_FOUND",
"message": "Billing account not found"
}
],
"private_offer_metadata": {
"last_modified_at": "2026-08-20T12:05:00Z",
"buyers": [
{
"email_address": "[email protected]"
}
]
}
}Private Offer Purchase Instructions Sent
Sent when purchase-instructions email is first sent.
private_offer_metadata.sent_at is set. For this event, actor is the user who
sent the instructions when known.
Example Payload
{
"actor": {
"user_id": "auth0|example",
"name": "Ada Lovelace",
"email": "[email protected]"
},
"marketplace": "gcp",
"created_at": "2026-08-01T00:00:00Z",
"destination": "callback",
"event_type": "gcp_private_offer_purchase_instructions_sent",
"extra_data": {
"users": [{ "email": "[email protected]" }]
},
"offerid": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"po_id": "01HZXEXAMPLEPOID00000000",
"vendorid": "ACMEVENDOR",
"offer_type": "direct",
"buyer_company_name": "Buyer Co",
"seller_company_name": "Seller Inc",
"created_in_marketplace_at": "2026-08-20T12:00:00Z",
"productid": "example-service-id",
"private_offer_metadata": {
"last_modified_at": "2026-08-21T09:00:00Z",
"sent_at": "2026-08-21T09:00:00Z",
"buyers": [
{
"email_address": "[email protected]",
"full_name": "Buyer"
}
]
},
"cloud_data": {
"name": "projects/example/locations/global/privateOffers/a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"state": "PUBLISHED"
}
}Private Offer Accepted
Sent when the offer is first accepted.
Example Payload
{
"actor": {},
"marketplace": "gcp",
"created_at": "2026-08-01T00:00:00Z",
"destination": "callback",
"event_type": "gcp_private_offer_accepted",
"extra_data": {
"users": [{ "email": "[email protected]" }]
},
"offerid": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"po_id": "01HZXEXAMPLEPOID00000000",
"vendorid": "ACMEVENDOR",
"offer_type": "direct",
"buyer_company_name": "Buyer Co",
"seller_company_name": "Seller Inc",
"created_in_marketplace_at": "2026-08-20T12:00:00Z",
"productid": "example-service-id",
"private_offer_metadata": {
"last_modified_at": "2026-09-01T10:00:00Z",
"accepted_at": "2026-09-01T10:00:00Z",
"buyers": [
{
"email_address": "[email protected]",
"full_name": "Buyer"
}
]
},
"cloud_data": {
"name": "projects/example/locations/global/privateOffers/a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"state": "ACCEPTED",
"customer": {
"entityTitle": "Buyer Co",
"email": "[email protected]"
}
}
}Other Lifecycle Events
These use the same common fields. Differentiate them with event_type and the
matching timestamp in private_offer_metadata:
| Event Type | Typical signal in private_offer_metadata |
|---|---|
gcp_private_offer_cancelled_in_marketplace | cancelled_at |
gcp_private_offer_failed_to_cancel_in_marketplace | errors[] present; offer remains published |
gcp_private_offer_invitation_opened | opened_instructions_at |
gcp_private_offer_viewed | viewed_offer_at |
Migration from Unprefixed GCP Event Types
When your account uses the Offers GCP API for Google Cloud private offers,
handle gcp_private_offer_* instead of unprefixed private_offer_* for GCP
only. AWS and Azure unprefixed webhooks are unchanged.
Legacy event_type (deprecated for GCP) | Replacement |
|---|---|
private_offer_created | gcp_private_offer_created |
private_offer_created_in_marketplace | gcp_private_offer_created_in_marketplace |
private_offer_failed_to_create_in_marketplace | gcp_private_offer_failed_to_create_in_marketplace |
private_offer_cancelled_in_marketplace | gcp_private_offer_cancelled_in_marketplace |
private_offer_failed_to_cancel_in_marketplace | gcp_private_offer_failed_to_cancel_in_marketplace |
private_offer_purchase_instructions_sent | gcp_private_offer_purchase_instructions_sent |
private_offer_invitation_opened | gcp_private_offer_invitation_opened |
private_offer_viewed | gcp_private_offer_viewed |
private_offer_accepted | gcp_private_offer_accepted |
During migration, some vendors may briefly receive both the new
gcp_private_offer_* event and the legacy unprefixed event for the same
transition. Prefer gcp_private_offer_* for new integrations.
