Webhook events

delivery.status_changed

A campaign, ad set or ad changed delivery status.

Event type: delivery.status_changed.

When it fires

A campaign, ad set or ad changed delivery status. Checked every 15 minutes.

Envelope

Every event shares these top-level fields. The event-specific fields are under data.

FieldTypeRequiredDescription
idstringYesUnique event id. Deliveries are at-least-once, so dedupe on it.
type"delivery.status_changed"Yes
createdAtstring (date-time)Yes
apiVersion"v1"Yes
organizationIdintegerYes
brandIdinteger | nullYes
accountIdstring | nullYesThe ad account the event concerns.
providerstring | nullYesThe ad platform the event happened on. One of meta, whop.

Data

FieldTypeRequiredDescription
data.levelstringYesOne of campaign, adset, ad.
data.entityobjectYes
data.entity.providerIdstringYes
data.entity.koastIdstring | nullYes
data.entity.namestring | nullYes
data.entity.campaignLaunchIdstring | nullYes
data.fromstring | nullYesThe status Koast last recorded. Null when none was recorded yet. One of LIVE, OFF, UNDER_REVIEW, REJECTED, SCHEDULED, PROCESSING, NOT_DELIVERING, DRAFT.
data.tostringYesDelivery status as Koast displays it. One of LIVE, OFF, UNDER_REVIEW, REJECTED, SCHEDULED, PROCESSING, NOT_DELIVERING, DRAFT.
data.providerStatusstring | nullYesThe ad platform's own status string, unmapped.
data.changedAtstring (date-time)Yes

Example payload

{
  "id": "evt_2xKq7Vb9mN4pR8sT",
  "type": "delivery.status_changed",
  "createdAt": "2026-09-19T14:30:00Z",
  "apiVersion": "v1",
  "organizationId": 1,
  "brandId": 1,
  "accountId": "string",
  "provider": "meta",
  "data": {
    "level": "campaign",
    "entity": {
      "providerId": "string",
      "koastId": "string",
      "name": "string",
      "campaignLaunchId": "string"
    },
    "from": "LIVE",
    "to": "LIVE",
    "providerStatus": "string",
    "changedAt": "2026-09-19T14:30:00Z"
  }
}

Delivery headers

HeaderRequiredDescription
webhook-idYesThe delivery id; identical across retries of the same event. Dedupe on the envelope id.
webhook-timestampYesUnix seconds at signing time. Reject deliveries older than 5 minutes.
webhook-signatureYesSpace-separated v1,<base64 HMAC-SHA256> signatures (Standard Webhooks). Two are sent while a rotated secret overlaps.

Acknowledge

Your responseMeaning
2XXReturn any 2xx status to acknowledge the delivery.

Signing, retries and endpoint setup are in the Webhooks guide.

On this page