Webhooks API

Apex has three webhook surfaces. They are not interchangeable.

SurfacePathWhat it is
Inbound source/api/webhooksRegister a named source so an outside system can POST signed events into Apex
Operator alerts/api/notificationsApex calls your URL (or Slack) when an experiment starts or finishes
Journey destination/api/webhook-destinationsAn HTTPS endpoint a journey Webhook step can call

All management endpoints need a session or an apex_sk_ key. Incoming POSTs to a source use that source's signing secret, not your API key.

Inbound sources

Register a source, then give the other system this URL:

https://app.apex.inc/api/webhooks/<source>

Apex maps fields from the payload into analytics rows. This path does not write revenue events today.

GET/api/webhooks

List inbound sources for the workspace.

curl https://app.apex.inc/api/webhooks \ -H "x-api-key: apex_sk_..."
POST/api/webhooks

Register an inbound source.

ParameterTypeDescription
sourcerequiredstringLowercase identifier. Letters, numbers, dashes, underscores. Becomes the URL path.
fieldMappingobjectMap payload fields to Apex metric fields. Dot-paths allowed (e.g. data.email → email).
curl -X POST https://app.apex.inc/api/webhooks \ -H "Content-Type: application/json" \ -H "x-api-key: apex_sk_..." \ -d '{ "source": "billing", "fieldMapping": { "customer.email": "email", "amount": "value" } }'

The response includes secret (prefix whsec_). Store it. Apex only returns it at create time. The other system must sign the raw body with HMAC-SHA256 and send one of:

  • x-webhook-signature
  • x-hub-signature-256
  • stripe-signature

Unsigned or badly signed POSTs are rejected.

DELETE/api/webhooks

Remove an inbound source.

ParameterTypeDescription
sourcerequiredstringSource identifier (query string, not a body id).
curl -X DELETE "https://app.apex.inc/api/webhooks?source=billing" \ -H "x-api-key: apex_sk_..."
POST/api/webhooks/:source

Receive a signed payload from the other system.

The other system POSTs JSON to this URL. Apex verifies the signature against the stored secret, maps fields, and records the event.

There is no HubSpot- or Stripe-shaped shortcut at /api/webhooks/hubspot. Those products have their own integration methods. Use this route for a custom source you registered.

Operator alerts (Apex → you)

To hear when an experiment starts or finishes, create a notification config. This is not /api/webhooks.

POST/api/notifications

Create a webhook or Slack alert. Workspace admin only.

ParameterTypeDescription
typerequiredstring`webhook` or `slack`.
urlstringRequired when type is webhook. HTTPS URL Apex will POST to.
webhookUrlstringRequired when type is slack. Incoming Slack webhook URL.
channelstringSlack channel label. Defaults to #general.
triggersarrayEvents to subscribe to. Unknown values are dropped.
headersobjectExtra headers on webhook deliveries.

Triggers the create endpoint accepts:

TriggerFired when
experiment.startedAn experiment starts running
experiment.completedAn experiment finishes
task.createdA workspace task is created
budget.recommendationA budget recommendation is ready
model.driftScoring drift is detected
scoring.changedScoring weights change

There is no goal.reached, lead.created, or connector.synced trigger.

curl -X POST https://app.apex.inc/api/notifications \ -H "Content-Type: application/json" \ -H "x-api-key: apex_sk_..." \ -d '{ "type": "webhook", "url": "https://example.com/hooks/apex", "triggers": ["experiment.started", "experiment.completed"] }'
GET/api/notifications

List alert configs. Add ?logs=true to include recent delivery attempts.

DELETE/api/notifications

Remove an alert. Pass ?id=notif_… . Workspace admin only.

Journey destinations (Apex → your stack)

A journey Webhook step does not take a raw URL. Register the destination first at Set up Apex (webhook destinations), then pick it on the step.

GET/api/webhook-destinations

List destinations. Signing keys are redacted.

POST/api/webhook-destinations

Register an HTTPS destination. Workspace admin only.

ParameterTypeDescription
namerequiredstringLabel on the journey canvas.
baseUrlrequiredstringHTTPS URL. Private IPs and metadata hosts are rejected.
descriptionstringShown in the picker.
idstringStable id. Letters, numbers, dash, underscore. Apex mints one if omitted.

Each destination gets its own HMAC signing key. Rotate it at POST /api/webhook-destinations/:id/rotate. Send a test ping at POST /api/webhook-destinations/:id/ping.