POST requests with a versioned Cevoid payload. It does not support custom methods, customer-defined authorization headers, payload scripting, inbound webhooks, or developer topic subscriptions.
Prerequisites
- You can access Settings and Flows in your Cevoid workspace.
- You have a public HTTPS receiver that accepts
POSTrequests, preserves the exact raw request body for signature verification, does not redirect, and returns a2xxresponse after accepting an event.
Set up a webhook
- Go to Settings → Integrations → Cevoid API.
- Create a webhook destination, or reuse an active destination.
- Copy the signing secret when Cevoid shows it. The secret is shown once.
- Go to Settings → Flows and create a Flow.
- Choose
order.fulfilled,order.delivered, orreview.submittedas the trigger. - Add a webhook action, choose the destination, then publish the Flow.
Request contract
Cevoid sends an HTTPSPOST with content-type: application/json and these Standard Webhooks headers:
webhook-id: stable public event ID; retries keep the same valuewebhook-timestamp: Unix seconds for this attemptwebhook-signature: one or morev1,<base64>signatures
type: "cevoid.test". They do not create fake Flow, run, or version records.
Verify the exact raw body
Verify the signature before parsing JSON. Build the signed content as:whsec_, calculate HMAC-SHA256, encode the digest as base64, and compare it in constant time with any v1 signature in webhook-signature. Reject stale timestamps according to your replay-risk policy. During secret rotation, accept a match from either current secret while both signatures are present.
Node.js
rawBody directly from your framework’s raw-body middleware. Do not use JSON.stringify(req.body).
Python
HMAC test vector
This fixture is derived from the automated signing contract:Respond and deduplicate
Return any2xx response after you durably accept the event. Cevoid does not follow redirects.
Delivery is at least once. Store webhook-id and ignore an ID you have already processed. A timeout or lost response can mean your service accepted an event that Cevoid retries.
Cevoid automatically retries HTTP 408, 425, 429, and 5xx responses after approximately 1 minute, 5 minutes, 30 minutes, 2 hours, 6 hours, and 12 hours, with jitter. HTTP 2xx is accepted. Redirects, other 3xx, and most 4xx responses are terminal. 401 and 403 are terminal but can be retried manually after you fix the receiver.
Limits are 10 requests per second per destination and 50 requests per second per workspace. Requests have bounded timeouts and response capture. URLs must use HTTPS in production, cannot contain credentials, fragments, or query strings, and must resolve only to allowed public network addresses. DNS and URL safety are checked again for every attempt.
Test, retry, and replay
- Send test queues a real signed
cevoid.testrequest and opens its delivery record. - Retry sends the same logical event again. It keeps the same Outbox item,
webhook-id, URL snapshot, and byte-identical body. Only the attempt timestamp and signature change. - Replay creates a new logical delivery and
webhook-id. It clones the original versioned event data but uses the destination’s current active revision and URL.
Troubleshooting
- No request arrives: confirm the destination and Flow are active, then inspect the delivery and attempt status.
- Signature mismatch: verify against the exact raw bytes, not parsed JSON, and remove
whsec_before base64 decoding. - Repeated events: deduplicate using
webhook-id. - Redirect or private-network error: use the final public HTTPS URL directly. Redirects and non-public targets are blocked.
- Delivery remains incomplete: fix the terminal reason, enable the destination, then choose retry or replay deliberately.
- Secret was lost: rotate it. Accept both signatures during the overlap, deploy the new secret, then finish rotation.