Zernio
APIFor you
Zernio
APIFor you
Overview

Webhooks

OverviewPost webhooksInbox webhooksEmail, calendar and files webhooksAutomation webhooksSupport Assistant webhooksAccount webhooksAnalytics webhooksCreator campaign webhooksAds webhooksCall webhooksWhatsApp webhooksPhone number webhooksSMS registration webhooksBranded calling webhooks
Dashboard
OverviewPlatformsAPI ReferenceResources
Webhooks

Creator campaign webhooks

Receive an event when a creator joins, submits a post, gets approved or rejected, becomes payable or gets paid.


Creator campaign events follow a campaign from the first creator joining to the last payout.

Subscribe with POST /v1/webhooks/settings and the event names below (first event).

Delivery, retries and signatures are the same for every event (how webhooks behave).

Events

EventDescription
campaign_submission.receivedA creator submitted a post and its tracking window opened.
campaign_submission.flaggedA submission gained a fraud flag it did not carry before.
campaign_submission.pending_reviewA submission is ready for your review.
campaign_submission.approvedYou approved a submission.
campaign_submission.rejectedYou rejected a submission.
creator_campaign.budget_exhaustedEarnings reached the campaign budget.
creator_campaign.closedA campaign closed.
campaign_payout.payableHeld earnings became payable.
campaign_payout.settledA payout was recorded.
campaign_payout.failedA treasury payout did not reach the creator.
campaign_participant.joinedA creator joined a campaign.
campaign_participant.suspendedYou suspended a participant.
campaign_participant.removedYou removed a participant.

How it behaves

  • Every event is sent on the campaign's profile. A webhook or API key scoped to that profile receives them.
  • The payloads carry no connected account id. campaign.id, participant.id and creator.id identify what changed.
  • Every event belongs to the creator_campaigns resource group. A restricted API key needs that group to subscribe.
  • Amounts are USD cents. A payout event's payableCents is the balance after the event, not a delta.
  • Retries and redeliveries keep the event id. Dedupe on it before you pay anyone.

campaign_submission.received

A creator submitted a post to a campaign. Zernio resolved it, opened its tracking window and took the first view sample.


Request Body

application/json

TypeScript Definitions

Use the request body type in TypeScript.

Webhook payload for campaign_submission.received, campaign_submission.flagged, campaign_submission.pending_review, campaign_submission.approved and campaign_submission.rejected. received fires for every accepted submission; flagged fires when a submission gains a flag it did not carry before (at submission or on a later sync), and submission.flags lists every flag it carries; pending_review fires when the submission becomes ready for the operator's review; approved and rejected fire on the operator's decision.

Response Body

Example Requests

Webhook payload for campaign_submission.received, campaign_submission.flagged, campaign_submission.pending_review, campaign_submission.approved and campaign_submission.rejected. received fires for every accepted submission; flagged fires when a submission gains a flag it did not carry before (at submission or on a later sync), and submission.flags lists every flag it carries; pending_review fires when the submission becomes ready for the operator's review; approved and rejected fire on the operator's decision.

POST/campaign_submission.received


campaign_submission.flagged

A submission gained a new flag, such as duplicate_post, view_spike or low_authenticity. submission.flags lists every flag it carries. Zernio never rejects on its own; the decision is yours.


Request Body

application/json

TypeScript Definitions

Use the request body type in TypeScript.

Webhook payload for campaign_submission.received, campaign_submission.flagged, campaign_submission.pending_review, campaign_submission.approved and campaign_submission.rejected. received fires for every accepted submission; flagged fires when a submission gains a flag it did not carry before (at submission or on a later sync), and submission.flags lists every flag it carries; pending_review fires when the submission becomes ready for the operator's review; approved and rejected fire on the operator's decision.

Response Body

Example Requests

Webhook payload for campaign_submission.received, campaign_submission.flagged, campaign_submission.pending_review, campaign_submission.approved and campaign_submission.rejected. received fires for every accepted submission; flagged fires when a submission gains a flag it did not carry before (at submission or on a later sync), and submission.flags lists every flag it carries; pending_review fires when the submission becomes ready for the operator's review; approved and rejected fire on the operator's decision.

POST/campaign_submission.flagged


campaign_submission.pending_review

A submission is ready for review. A CPM submission reached minViewsToEarn, a pool submission reached minViewsToQualify, and per post submissions arrive here after their first accrual.


Request Body

application/json

TypeScript Definitions

Use the request body type in TypeScript.

Webhook payload for campaign_submission.received, campaign_submission.flagged, campaign_submission.pending_review, campaign_submission.approved and campaign_submission.rejected. received fires for every accepted submission; flagged fires when a submission gains a flag it did not carry before (at submission or on a later sync), and submission.flags lists every flag it carries; pending_review fires when the submission becomes ready for the operator's review; approved and rejected fire on the operator's decision.

Response Body

Example Requests

Webhook payload for campaign_submission.received, campaign_submission.flagged, campaign_submission.pending_review, campaign_submission.approved and campaign_submission.rejected. received fires for every accepted submission; flagged fires when a submission gains a flag it did not carry before (at submission or on a later sync), and submission.flags lists every flag it carries; pending_review fires when the submission becomes ready for the operator's review; approved and rejected fire on the operator's decision.

POST/campaign_submission.pending_review


campaign_submission.approved

You approved a submission. What it earned so far moves to owed with the campaign hold. Later earnings post straight to owed.


Request Body

application/json

TypeScript Definitions

Use the request body type in TypeScript.

Webhook payload for campaign_submission.received, campaign_submission.flagged, campaign_submission.pending_review, campaign_submission.approved and campaign_submission.rejected. received fires for every accepted submission; flagged fires when a submission gains a flag it did not carry before (at submission or on a later sync), and submission.flags lists every flag it carries; pending_review fires when the submission becomes ready for the operator's review; approved and rejected fire on the operator's decision.

Response Body

Example Requests

Webhook payload for campaign_submission.received, campaign_submission.flagged, campaign_submission.pending_review, campaign_submission.approved and campaign_submission.rejected. received fires for every accepted submission; flagged fires when a submission gains a flag it did not carry before (at submission or on a later sync), and submission.flags lists every flag it carries; pending_review fires when the submission becomes ready for the operator's review; approved and rejected fire on the operator's decision.

POST/campaign_submission.approved


campaign_submission.rejected

You rejected a submission. Its tracking window is cancelled and its unsettled earnings go back to the campaign budget.


Request Body

application/json

TypeScript Definitions

Use the request body type in TypeScript.

Webhook payload for campaign_submission.received, campaign_submission.flagged, campaign_submission.pending_review, campaign_submission.approved and campaign_submission.rejected. received fires for every accepted submission; flagged fires when a submission gains a flag it did not carry before (at submission or on a later sync), and submission.flags lists every flag it carries; pending_review fires when the submission becomes ready for the operator's review; approved and rejected fire on the operator's decision.

Response Body

Example Requests

Webhook payload for campaign_submission.received, campaign_submission.flagged, campaign_submission.pending_review, campaign_submission.approved and campaign_submission.rejected. received fires for every accepted submission; flagged fires when a submission gains a flag it did not carry before (at submission or on a later sync), and submission.flags lists every flag it carries; pending_review fires when the submission becomes ready for the operator's review; approved and rejected fire on the operator's decision.

POST/campaign_submission.rejected


creator_campaign.budget_exhausted

The campaign earnings reached its budget. Nothing more accrues until budget is freed. It fires once per campaign.


Request Body

application/json

TypeScript Definitions

Use the request body type in TypeScript.

Webhook payload for creator_campaign.budget_exhausted and creator_campaign.closed. budget_exhausted fires once, when the campaign's earnings first reach campaign.budgetCents, and carries campaign.budgetExhaustedAt. closed fires once, when the campaign closes, and carries campaign.closedAt.

Response Body

Example Requests

Webhook payload for creator_campaign.budget_exhausted and creator_campaign.closed. budget_exhausted fires once, when the campaign's earnings first reach campaign.budgetCents, and carries campaign.budgetExhaustedAt. closed fires once, when the campaign closes, and carries campaign.closedAt.

POST/creator_campaign.budget_exhausted


creator_campaign.closed

A campaign closed, because you closed it or because endsAt passed and every tracking window had its final read. A pool campaign is split among participants at this moment.


Request Body

application/json

TypeScript Definitions

Use the request body type in TypeScript.

Webhook payload for creator_campaign.budget_exhausted and creator_campaign.closed. budget_exhausted fires once, when the campaign's earnings first reach campaign.budgetCents, and carries campaign.budgetExhaustedAt. closed fires once, when the campaign closes, and carries campaign.closedAt.

Response Body

Example Requests

Webhook payload for creator_campaign.budget_exhausted and creator_campaign.closed. budget_exhausted fires once, when the campaign's earnings first reach campaign.budgetCents, and carries campaign.budgetExhaustedAt. closed fires once, when the campaign closes, and carries campaign.closedAt.

POST/creator_campaign.closed


campaign_payout.payable

A participant's held earnings matured. payout.payableCents is the participant's whole payable balance, the amount to pay when you pay from your own rails.


Request Body

application/json

TypeScript Definitions

Use the request body type in TypeScript.

Webhook payload for campaign_payout.payable and campaign_payout.settled. payable fires when a participant's held earnings mature; payout.payableCents is the participant's whole payable balance, so a partner paying from its own rails pays that amount and records it with POST /v1/creator-campaigns/{campaignId}/participants/{participantId}/settle. settled fires when a settlement is recorded and carries payout.settlement. failed fires when a treasury payout is refused, unconfirmed or reversed; the amount returns to payable (minus anything a rejection claws back) and payout.failure says why.

Response Body

Example Requests

Webhook payload for campaign_payout.payable and campaign_payout.settled. payable fires when a participant's held earnings mature; payout.payableCents is the participant's whole payable balance, so a partner paying from its own rails pays that amount and records it with POST /v1/creator-campaigns/{campaignId}/participants/{participantId}/settle. settled fires when a settlement is recorded and carries payout.settlement. failed fires when a treasury payout is refused, unconfirmed or reversed; the amount returns to payable (minus anything a rejection claws back) and payout.failure says why.

POST/campaign_payout.payable


campaign_payout.settled

A payout to a participant was recorded. payout.settlement holds the amount and the reference. recorded is true when the money moved outside Zernio.


Request Body

application/json

TypeScript Definitions

Use the request body type in TypeScript.

Webhook payload for campaign_payout.payable and campaign_payout.settled. payable fires when a participant's held earnings mature; payout.payableCents is the participant's whole payable balance, so a partner paying from its own rails pays that amount and records it with POST /v1/creator-campaigns/{campaignId}/participants/{participantId}/settle. settled fires when a settlement is recorded and carries payout.settlement. failed fires when a treasury payout is refused, unconfirmed or reversed; the amount returns to payable (minus anything a rejection claws back) and payout.failure says why.

Response Body

Example Requests

Webhook payload for campaign_payout.payable and campaign_payout.settled. payable fires when a participant's held earnings mature; payout.payableCents is the participant's whole payable balance, so a partner paying from its own rails pays that amount and records it with POST /v1/creator-campaigns/{campaignId}/participants/{participantId}/settle. settled fires when a settlement is recorded and carries payout.settlement. failed fires when a treasury payout is refused, unconfirmed or reversed; the amount returns to payable (minus anything a rejection claws back) and payout.failure says why.

POST/campaign_payout.settled


campaign_payout.failed

A payout through your Zernio balance did not reach the creator. Stripe refused it, it stayed unconfirmed for 24 hours, or it was reversed. The amount is payable again.


Request Body

application/json

TypeScript Definitions

Use the request body type in TypeScript.

Webhook payload for campaign_payout.payable and campaign_payout.settled. payable fires when a participant's held earnings mature; payout.payableCents is the participant's whole payable balance, so a partner paying from its own rails pays that amount and records it with POST /v1/creator-campaigns/{campaignId}/participants/{participantId}/settle. settled fires when a settlement is recorded and carries payout.settlement. failed fires when a treasury payout is refused, unconfirmed or reversed; the amount returns to payable (minus anything a rejection claws back) and payout.failure says why.

Response Body

Example Requests

Webhook payload for campaign_payout.payable and campaign_payout.settled. payable fires when a participant's held earnings mature; payout.payableCents is the participant's whole payable balance, so a partner paying from its own rails pays that amount and records it with POST /v1/creator-campaigns/{campaignId}/participants/{participantId}/settle. settled fires when a settlement is recorded and carries payout.settlement. failed fires when a treasury payout is refused, unconfirmed or reversed; the amount returns to payable (minus anything a rejection claws back) and payout.failure says why.

POST/campaign_payout.failed


campaign_participant.joined

A creator joined, by opening their invite link or by joining from the open link. It fires once per participant, and participant.joinedAt says when.


Request Body

application/json

TypeScript Definitions

Use the request body type in TypeScript.

Webhook payload for campaign_participant.joined, campaign_participant.suspended and campaign_participant.removed. participant.status is the status after the change. participant.joinedAt is null for a participant removed before they ever joined.

Response Body

Example Requests

Webhook payload for campaign_participant.joined, campaign_participant.suspended and campaign_participant.removed. participant.status is the status after the change. participant.joinedAt is null for a participant removed before they ever joined.

POST/campaign_participant.joined


campaign_participant.suspended

You suspended a participant. They can no longer connect accounts or submit posts to this campaign. Posts they already submitted keep earning until you reject them.


Request Body

application/json

TypeScript Definitions

Use the request body type in TypeScript.

Webhook payload for campaign_participant.joined, campaign_participant.suspended and campaign_participant.removed. participant.status is the status after the change. participant.joinedAt is null for a participant removed before they ever joined.

Response Body

Example Requests

Webhook payload for campaign_participant.joined, campaign_participant.suspended and campaign_participant.removed. participant.status is the status after the change. participant.joinedAt is null for a participant removed before they ever joined.

POST/campaign_participant.suspended


campaign_participant.removed

You removed a participant from the campaign. Removing a participant twice fires the event once.


Request Body

application/json

TypeScript Definitions

Use the request body type in TypeScript.

Webhook payload for campaign_participant.joined, campaign_participant.suspended and campaign_participant.removed. participant.status is the status after the change. participant.joinedAt is null for a participant removed before they ever joined.

Response Body

Example Requests

Webhook payload for campaign_participant.joined, campaign_participant.suspended and campaign_participant.removed. participant.status is the status after the change. participant.joinedAt is null for a participant removed before they ever joined.

POST/campaign_participant.removed

Related

  • Creator campaigns guide
  • Creator payouts pricing
  • How webhooks behave
Was this page helpful?

Analytics webhooks

Receive a cursor each time an account's analytics sync completes, then read every changed post in one call to the delta feed.

Ads webhooks

Events for an ads account's first sync and stalls, Meta Lead Gen leads, ad reviews and delivery issues, exhausted budgets, triggered ad rules, and ad account and ad status changes.

On this page

EventsHow it behavescampaign_submission.receivedcampaign_submission.flaggedcampaign_submission.pending_reviewcampaign_submission.approvedcampaign_submission.rejectedcreator_campaign.budget_exhaustedcreator_campaign.closedcampaign_payout.payablecampaign_payout.settledcampaign_payout.failedcampaign_participant.joinedcampaign_participant.suspendedcampaign_participant.removedRelated
id*string

Stable webhook event ID: the dedupe key, also sent as the X-Zernio-Event-Id header and identical on every retry and redelivery. It identifies the event only, never an account or other resource.

profiles?array<>

The profiles this event belongs to, each with the externalId you set on it (null when none is set). Present on every event tied to a profile and absent on events that belong to none. Events spanning several profiles (a post published to accounts of different profiles) list each once. Use it to route the event to your tenant without storing Zernio profile ids.

test?boolean

Always true when present: only a sample sent by POST /v1/webhooks/test with an event carries it. Real deliveries never do.

event*string

Value in

  • "campaign_submission.received"
  • "campaign_submission.flagged"
  • "campaign_submission.pending_review"
  • "campaign_submission.approved"
  • "campaign_submission.rejected"
campaign*
participant*
creator*
submission*
timestamp*string

UTC time at which Zernio generated this event (set once when the event payload is built, before delivery is queued). Retries and redeliveries keep the original value, so it reflects the event, not the delivery attempt.

Formatdate-time
id*string

Stable webhook event ID: the dedupe key, also sent as the X-Zernio-Event-Id header and identical on every retry and redelivery. It identifies the event only, never an account or other resource.

profiles?array<>

The profiles this event belongs to, each with the externalId you set on it (null when none is set). Present on every event tied to a profile and absent on events that belong to none. Events spanning several profiles (a post published to accounts of different profiles) list each once. Use it to route the event to your tenant without storing Zernio profile ids.

test?boolean

Always true when present: only a sample sent by POST /v1/webhooks/test with an event carries it. Real deliveries never do.

event*string

Value in

  • "campaign_submission.received"
  • "campaign_submission.flagged"
  • "campaign_submission.pending_review"
  • "campaign_submission.approved"
  • "campaign_submission.rejected"
campaign*
participant*
creator*
submission*
timestamp*string

UTC time at which Zernio generated this event (set once when the event payload is built, before delivery is queued). Retries and redeliveries keep the original value, so it reflects the event, not the delivery attempt.

Formatdate-time
id*string

Stable webhook event ID: the dedupe key, also sent as the X-Zernio-Event-Id header and identical on every retry and redelivery. It identifies the event only, never an account or other resource.

profiles?array<>

The profiles this event belongs to, each with the externalId you set on it (null when none is set). Present on every event tied to a profile and absent on events that belong to none. Events spanning several profiles (a post published to accounts of different profiles) list each once. Use it to route the event to your tenant without storing Zernio profile ids.

test?boolean

Always true when present: only a sample sent by POST /v1/webhooks/test with an event carries it. Real deliveries never do.

event*string

Value in

  • "campaign_submission.received"
  • "campaign_submission.flagged"
  • "campaign_submission.pending_review"
  • "campaign_submission.approved"
  • "campaign_submission.rejected"
campaign*
participant*
creator*
submission*
timestamp*string

UTC time at which Zernio generated this event (set once when the event payload is built, before delivery is queued). Retries and redeliveries keep the original value, so it reflects the event, not the delivery attempt.

Formatdate-time
id*string

Stable webhook event ID: the dedupe key, also sent as the X-Zernio-Event-Id header and identical on every retry and redelivery. It identifies the event only, never an account or other resource.

profiles?array<>

The profiles this event belongs to, each with the externalId you set on it (null when none is set). Present on every event tied to a profile and absent on events that belong to none. Events spanning several profiles (a post published to accounts of different profiles) list each once. Use it to route the event to your tenant without storing Zernio profile ids.

test?boolean

Always true when present: only a sample sent by POST /v1/webhooks/test with an event carries it. Real deliveries never do.

event*string

Value in

  • "campaign_submission.received"
  • "campaign_submission.flagged"
  • "campaign_submission.pending_review"
  • "campaign_submission.approved"
  • "campaign_submission.rejected"
campaign*
participant*
creator*
submission*
timestamp*string

UTC time at which Zernio generated this event (set once when the event payload is built, before delivery is queued). Retries and redeliveries keep the original value, so it reflects the event, not the delivery attempt.

Formatdate-time
id*string

Stable webhook event ID: the dedupe key, also sent as the X-Zernio-Event-Id header and identical on every retry and redelivery. It identifies the event only, never an account or other resource.

profiles?array<>

The profiles this event belongs to, each with the externalId you set on it (null when none is set). Present on every event tied to a profile and absent on events that belong to none. Events spanning several profiles (a post published to accounts of different profiles) list each once. Use it to route the event to your tenant without storing Zernio profile ids.

test?boolean

Always true when present: only a sample sent by POST /v1/webhooks/test with an event carries it. Real deliveries never do.

event*string

Value in

  • "campaign_submission.received"
  • "campaign_submission.flagged"
  • "campaign_submission.pending_review"
  • "campaign_submission.approved"
  • "campaign_submission.rejected"
campaign*
participant*
creator*
submission*
timestamp*string

UTC time at which Zernio generated this event (set once when the event payload is built, before delivery is queued). Retries and redeliveries keep the original value, so it reflects the event, not the delivery attempt.

Formatdate-time
id*string

Stable webhook event ID: the dedupe key, also sent as the X-Zernio-Event-Id header and identical on every retry and redelivery. It identifies the event only, never an account or other resource.

profiles?array<>

The profiles this event belongs to, each with the externalId you set on it (null when none is set). Present on every event tied to a profile and absent on events that belong to none. Events spanning several profiles (a post published to accounts of different profiles) list each once. Use it to route the event to your tenant without storing Zernio profile ids.

test?boolean

Always true when present: only a sample sent by POST /v1/webhooks/test with an event carries it. Real deliveries never do.

event*string

Value in

  • "creator_campaign.budget_exhausted"
  • "creator_campaign.closed"
campaign*
timestamp*string

UTC time at which Zernio generated this event (set once when the event payload is built, before delivery is queued). Retries and redeliveries keep the original value, so it reflects the event, not the delivery attempt.

Formatdate-time
id*string

Stable webhook event ID: the dedupe key, also sent as the X-Zernio-Event-Id header and identical on every retry and redelivery. It identifies the event only, never an account or other resource.

profiles?array<>

The profiles this event belongs to, each with the externalId you set on it (null when none is set). Present on every event tied to a profile and absent on events that belong to none. Events spanning several profiles (a post published to accounts of different profiles) list each once. Use it to route the event to your tenant without storing Zernio profile ids.

test?boolean

Always true when present: only a sample sent by POST /v1/webhooks/test with an event carries it. Real deliveries never do.

event*string

Value in

  • "creator_campaign.budget_exhausted"
  • "creator_campaign.closed"
campaign*
timestamp*string

UTC time at which Zernio generated this event (set once when the event payload is built, before delivery is queued). Retries and redeliveries keep the original value, so it reflects the event, not the delivery attempt.

Formatdate-time
id*string

Stable webhook event ID: the dedupe key, also sent as the X-Zernio-Event-Id header and identical on every retry and redelivery. It identifies the event only, never an account or other resource.

profiles?array<>

The profiles this event belongs to, each with the externalId you set on it (null when none is set). Present on every event tied to a profile and absent on events that belong to none. Events spanning several profiles (a post published to accounts of different profiles) list each once. Use it to route the event to your tenant without storing Zernio profile ids.

test?boolean

Always true when present: only a sample sent by POST /v1/webhooks/test with an event carries it. Real deliveries never do.

event*string

Value in

  • "campaign_payout.payable"
  • "campaign_payout.settled"
  • "campaign_payout.failed"
campaign*
participant*
creator*
payout*
timestamp*string

UTC time at which Zernio generated this event (set once when the event payload is built, before delivery is queued). Retries and redeliveries keep the original value, so it reflects the event, not the delivery attempt.

Formatdate-time
id*string

Stable webhook event ID: the dedupe key, also sent as the X-Zernio-Event-Id header and identical on every retry and redelivery. It identifies the event only, never an account or other resource.

profiles?array<>

The profiles this event belongs to, each with the externalId you set on it (null when none is set). Present on every event tied to a profile and absent on events that belong to none. Events spanning several profiles (a post published to accounts of different profiles) list each once. Use it to route the event to your tenant without storing Zernio profile ids.

test?boolean

Always true when present: only a sample sent by POST /v1/webhooks/test with an event carries it. Real deliveries never do.

event*string

Value in

  • "campaign_payout.payable"
  • "campaign_payout.settled"
  • "campaign_payout.failed"
campaign*
participant*
creator*
payout*
timestamp*string

UTC time at which Zernio generated this event (set once when the event payload is built, before delivery is queued). Retries and redeliveries keep the original value, so it reflects the event, not the delivery attempt.

Formatdate-time
id*string

Stable webhook event ID: the dedupe key, also sent as the X-Zernio-Event-Id header and identical on every retry and redelivery. It identifies the event only, never an account or other resource.

profiles?array<>

The profiles this event belongs to, each with the externalId you set on it (null when none is set). Present on every event tied to a profile and absent on events that belong to none. Events spanning several profiles (a post published to accounts of different profiles) list each once. Use it to route the event to your tenant without storing Zernio profile ids.

test?boolean

Always true when present: only a sample sent by POST /v1/webhooks/test with an event carries it. Real deliveries never do.

event*string

Value in

  • "campaign_payout.payable"
  • "campaign_payout.settled"
  • "campaign_payout.failed"
campaign*
participant*
creator*
payout*
timestamp*string

UTC time at which Zernio generated this event (set once when the event payload is built, before delivery is queued). Retries and redeliveries keep the original value, so it reflects the event, not the delivery attempt.

Formatdate-time
id*string

Stable webhook event ID: the dedupe key, also sent as the X-Zernio-Event-Id header and identical on every retry and redelivery. It identifies the event only, never an account or other resource.

profiles?array<>

The profiles this event belongs to, each with the externalId you set on it (null when none is set). Present on every event tied to a profile and absent on events that belong to none. Events spanning several profiles (a post published to accounts of different profiles) list each once. Use it to route the event to your tenant without storing Zernio profile ids.

test?boolean

Always true when present: only a sample sent by POST /v1/webhooks/test with an event carries it. Real deliveries never do.

event*string

Value in

  • "campaign_participant.joined"
  • "campaign_participant.suspended"
  • "campaign_participant.removed"
campaign*
participant*
creator*
timestamp*string

UTC time at which Zernio generated this event (set once when the event payload is built, before delivery is queued). Retries and redeliveries keep the original value, so it reflects the event, not the delivery attempt.

Formatdate-time
id*string

Stable webhook event ID: the dedupe key, also sent as the X-Zernio-Event-Id header and identical on every retry and redelivery. It identifies the event only, never an account or other resource.

profiles?array<>

The profiles this event belongs to, each with the externalId you set on it (null when none is set). Present on every event tied to a profile and absent on events that belong to none. Events spanning several profiles (a post published to accounts of different profiles) list each once. Use it to route the event to your tenant without storing Zernio profile ids.

test?boolean

Always true when present: only a sample sent by POST /v1/webhooks/test with an event carries it. Real deliveries never do.

event*string

Value in

  • "campaign_participant.joined"
  • "campaign_participant.suspended"
  • "campaign_participant.removed"
campaign*
participant*
creator*
timestamp*string

UTC time at which Zernio generated this event (set once when the event payload is built, before delivery is queued). Retries and redeliveries keep the original value, so it reflects the event, not the delivery attempt.

Formatdate-time
id*string

Stable webhook event ID: the dedupe key, also sent as the X-Zernio-Event-Id header and identical on every retry and redelivery. It identifies the event only, never an account or other resource.

profiles?array<>

The profiles this event belongs to, each with the externalId you set on it (null when none is set). Present on every event tied to a profile and absent on events that belong to none. Events spanning several profiles (a post published to accounts of different profiles) list each once. Use it to route the event to your tenant without storing Zernio profile ids.

test?boolean

Always true when present: only a sample sent by POST /v1/webhooks/test with an event carries it. Real deliveries never do.

event*string

Value in

  • "campaign_participant.joined"
  • "campaign_participant.suspended"
  • "campaign_participant.removed"
campaign*
participant*
creator*
timestamp*string

UTC time at which Zernio generated this event (set once when the event payload is built, before delivery is queued). Retries and redeliveries keep the original value, so it reflects the event, not the delivery attempt.

Formatdate-time