Skip to main content
Webhooks let you receive real-time HTTP notifications when events happen in your account. Instead of polling the API for changes, you register a URL and we’ll send a POST request to it whenever a relevant event is triggered.

Setting up a webhook

To get started, use the Create webhook endpoint to register a webhook URL (must be HTTPS and not an IP).
curl -X POST https://api.engine.usesophic.com/webhooks \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://your-app.com/webhooks/sophic"
  }'

Webhook headers

Every webhook delivery includes the following HTTP headers:
HeaderDescription
Content-TypeAlways application/json.
Webhook-IdThe unique ID of this delivery (e.g. whd_abc123). Use this to deduplicate retried deliveries.
Webhook-TimestampUnix timestamp (seconds) of when the delivery was dispatched. Use this to reject stale messages.
Webhook-SignatureHMAC-SHA256 signature(s) of the payload. Multiple signatures may be present during secret rotation.
Webhook-Attempt1-indexed attempt number for this delivery. 1 on the first try, incremented on each retry.
Event-IdThe ID of the originating event (e.g. evt_abc123). Not present on test deliveries.

Receiving webhooks

When an event occurs, we send a POST request to your registered URL. The webhook payload follows the same schema as the Event resource:
{
  "id": "evt_abc123",
  "name": "order.filled",
  "resource": {
    "id": "ord_xyz789",
    "resource_type": "order"
  },
  "data": {
    // ... event-specific data
  },
  "created_at": "2026-01-15T10:30:00Z"
}
Your endpoint should return a 2xx status code within 15 seconds to acknowledge receipt. Any other status code, timeout, or connection error is treated as a failed delivery and will be retried. The maximum time we’ll wait for a response is 25 seconds (5s connect + 15s read + 5s write).

CSRF protection

If you use Rails, Django, or another web framework, your site might automatically check that every POST request contains a CSRF token. This is an important security feature, but it can also prevent your site from processing legitimate webhook events. If so, you may need to exempt your webhook route from CSRF protection.
from django.views.decorators.csrf import csrf_exempt
from django.views.decorators.http import require_POST

@require_POST
@csrf_exempt
def webhook(request):
    # Process webhook payload
    ...

Testing

You can use the Test webhook endpoint to send a test delivery to your URL during development. You specify the event name and data in the request body, and we’ll dispatch a delivery to your webhook endpoint. Test deliveries don’t include the Event-Id header since no real event is created.