Webhooks

Receive real-time notifications for campaign lifecycle events.

Webhooks

Webhooks let you receive real-time HTTP notifications when campaign events occur, instead of polling the API.

Event Types

Event TypeDescriptionStatus
campaign.createdFires when a campaign is submitted via POST /campaignsActive
campaign.updatedFires when a campaign is modified (budget, end date, or pause state)Active
campaign.processingFires when the ad platform is processing the campaignDefined (not yet wired)
campaign.completedFires when a campaign finishes its runDefined (not yet wired)
campaign.failedFires when the ad platform rejects the campaignDefined (not yet wired)

Note: campaign.processing, campaign.completed, and campaign.failed are defined in the API and available for webhook registration, but notifications for these lifecycle events are still being connected to the campaign creation pipeline. You can register webhooks for them now so they'll fire automatically once wired.

Payload Format

Every webhook delivery is an HTTP POST to your registered URL with this body:

{
  "eventType": "campaign.created",
  "data": {
    "id": 98765,
    "name": "Summer Release Promo",
    "platform": "meta",
    "status": "TO_REVIEW",
    "startDate": "2026-04-01T00:00:00.000Z",
    "endDate": "2026-04-14T00:00:00.000Z",
    "budget": 300
  },
  "timestamp": "2026-04-01T00:01:23.456Z"
}
FieldTypeDescription
eventTypestringOne of the event types listed above
dataCampaignDataThe campaign data at the time of the event
timestampstring (ISO 8601)When the event occurred

Delivery Headers

Each webhook request includes these headers:

Content-Type: application/json
X-Symphony-Event: campaign.created

Use the X-Symphony-Event header to route events in your handler without parsing the body.

Webhook Status Lifecycle

Each registered webhook has a status that tracks its delivery health:

StatusMeaning
pendingWebhook is registered and ready to receive events
processingEvent was delivered successfully (last delivery succeeded)
failedLast delivery attempt failed (e.g., your server returned an error or was unreachable)
finishedWebhook has been fully processed

When you update a webhook's URL, its status resets to pending.

Managing Webhooks

List all webhooks

curl https://api.symphonyos.co/api/sym/v2/webhooks \
  -H "x-api-key: YOUR_API_KEY"

Response:

{
  "success": true,
  "data": [
    {
      "id": 1,
      "url": "https://your-app.com/webhooks/symphony",
      "status": "pending",
      "eventType": "campaign.created",
      "createdAt": "2026-03-15T10:30:00.000Z",
      "updatedAt": "2026-03-15T10:30:00.000Z"
    },
    {
      "id": 2,
      "url": "https://your-app.com/webhooks/symphony",
      "status": "processing",
      "eventType": "campaign.updated",
      "createdAt": "2026-03-15T10:31:00.000Z",
      "updatedAt": "2026-03-20T14:00:00.000Z"
    }
  ]
}

Create a webhook

curl -X POST https://api.symphonyos.co/api/sym/v2/webhooks \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://your-app.com/webhooks/symphony",
    "eventType": "campaign.created"
  }'

Response (201):

{
  "success": true,
  "data": {
    "id": 3,
    "url": "https://your-app.com/webhooks/symphony",
    "status": "pending",
    "eventType": "campaign.created",
    "createdAt": "2026-03-25T09:00:00.000Z",
    "updatedAt": "2026-03-25T09:00:00.000Z"
  }
}

Update a webhook

Change the URL for an existing webhook. Status resets to pending.

curl -X PUT https://api.symphonyos.co/api/sym/v2/webhooks/3 \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://your-app.com/webhooks/v2/symphony"
  }'

Response:

{
  "success": true,
  "data": {
    "id": 3,
    "url": "https://your-app.com/webhooks/v2/symphony",
    "status": "pending",
    "eventType": "campaign.created",
    "createdAt": "2026-03-25T09:00:00.000Z",
    "updatedAt": "2026-03-25T12:00:00.000Z"
  }
}

Delete a webhook

curl -X DELETE https://api.symphonyos.co/api/sym/v2/webhooks/3 \
  -H "x-api-key: YOUR_API_KEY"

Response:

{
  "success": true,
  "message": "Webhook 3 deleted successfully"
}

Best Practices

  1. Respond quickly — return a 200 status within 5 seconds. Process the event asynchronously if needed.
  2. Handle duplicates — in rare cases, the same event may be delivered more than once. Use the timestamp and campaign id to deduplicate.
  3. Register for specific events — create separate webhooks for each event type you care about, rather than trying to catch everything with one.
  4. Monitor webhook status — periodically check GET /webhooks to ensure none have failed status. Update the URL if your endpoint has moved.
  5. Use HTTPS — always register https:// URLs to protect webhook payloads in transit.

Did this page help you?