Docs/API Reference/Webhooks

Webhooks

The Webhooks API lets you register HTTP endpoints to receive real-time event notifications. Ptolemy delivers a signed POST request to your endpoint whenever a subscribed event occurs in your workspace.

/v1/workspaces/{workspaceId}
Webhook EndpointsEvent SubscriptionsSignature VerificationRetry Behaviour

Webhook Endpoints

A webhook endpoint is a URL registered in your workspace to receive event deliveries. Each endpoint has an active/inactive state and a secret used to sign payloads.

GET/webhooksList webhooksViewer+
POST/webhooksCreate a webhookAdmin

Creates a webhook endpoint. A signing secret is automatically generated and returned once — store it securely.

Request body
{ "url": "https://your-app.example.com/webhooks/ptolemy", "label": "production-ingest", "active": true }
Response — 201 Created
{ "id": "uuid", "url": "https://your-app.example.com/webhooks/ptolemy", "label": "production-ingest", "active": true, "secret": "whsec_a3f9b2c1d4e5f6a7b8c9d0e1...", "created_at": "2026-04-15T09:00:00Z" }
The secret is returned once at creation time and cannot be retrieved again. Use it to verify incoming payloads with HMAC-SHA256.
GET/webhooks/{id}Get a webhookViewer+
PATCH/webhooks/{id}Update a webhookAdmin
DELETE/webhooks/{id}Delete a webhookAdmin
POST/webhooks/{id}/rotate-secretRotate signing secretAdmin
POST/webhooks/filterFilter webhooksViewer+

Event Subscriptions

Each webhook can subscribe to one or more event types. Only subscribed event types will trigger deliveries to that endpoint. By default, a newly created webhook has no subscriptions — add at least one to start receiving events.

GET/webhooks/{id}/subscriptionsList subscriptionsViewer+
POST/webhooks/{id}/subscriptionsAdd a subscriptionAdmin
DELETE/webhooks/{id}/subscriptions/{subscriptionId}Remove a subscriptionAdmin
PUT/webhooks/{id}/subscriptionsBulk replace subscriptionsAdmin

Signature Verification

Every webhook delivery includes a Ptolemy-Signature header. Verify this header on every request to ensure the payload came from Ptolemy and hasn’t been tampered with.

Ptolemy-Signature header format
Ptolemy-Signature: t=1713168305,v1=a3f9b2c1d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1

Verification steps:

1. Extract timestamp and signature
Split the header on ,. The t= value is a Unix timestamp; the v1= value is the HMAC-SHA256 signature.
2. Construct the signed string
Concatenate the timestamp, a . character, and the raw request body: {t}.{body}.
3. Compute expected signature
HMAC-SHA256 the signed string using your whsec_ secret (hex-encoded output).
4. Compare & check timestamp
Compare the computed signature with v1= using a constant-time comparison. Reject if the timestamp is more than 5 minutes old.
import hashlib, hmac, time def verify_signature(payload: bytes, header: str, secret: str) -> bool: parts = dict(p.split('=', 1) for p in header.split(',')) t, sig = parts['t'], parts['v1'] if abs(time.time() - int(t)) > 300: return False signed = f'{t}.{payload.decode()}' expected = hmac.new(secret.encode(), signed.encode(), hashlib.sha256).hexdigest() return hmac.compare_digest(expected, sig)

Retry Behaviour

If your endpoint returns a non-2xx status code or doesn’t respond within 10 seconds, Ptolemy will retry delivery with exponential backoff.

AttemptDelay after previous attempt
1 (initial)
230 seconds
35 minutes
430 minutes
52 hours

After 5 failed attempts, the delivery is marked as failed and no further retries are made. You can manually trigger a redelivery at any time using POST /webhook-deliveries/{id}/redeliver.

If more than 20% of deliveries to a webhook fail over a 24-hour window, Ptolemy will automatically deactivate the endpoint and send an email notification to workspace Admins. Re-activate the webhook via PATCH /webhooks/{id} once your endpoint is fixed.
PrivacyTermsStatus© 2025 Ptolemy Pty Ltd