Early access. Webhooks are rolling out. The subscription API is self-serve — you authenticate with the same
AccessToken you already use for the rest of the API, with no special provisioning or per-partner setup. If the public endpoint isn’t live for you yet, or you’d like to be part of the early rollout, reach out to api-support@coverwhale.com. Until you’ve confirmed events are flowing, keep polling as you do today.Overview
Webhooks let Cover Whale push you a notification the instant a submission you care about changes state — a bind completes, a policy enters or exits pending cancellation, a policy is canceled or reinstated. Instead of pollingGET /v1/submission/{displayId} on a timer, you register an HTTPS endpoint once and receive a signed POST when something actually happens.
Webhooks are the recommended integration pattern. Polling still works, but it is slower to react, wastes both sides’ capacity, and is rate-limited. If you poll only to detect status changes, move to webhooks.
- You create a subscription — an HTTPS endpoint URL plus the event types you want — via the subscription API. Cover Whale returns a signing secret once.
- When a matching event fires for a submission owned by your account, Cover Whale sends a
POSTto your endpoint with a JSON body signed with your secret. - Your endpoint verifies the signature, responds
2xx, and (if it needs the full record) fetches submission detail on demand.
display_id and carries no documents — you fetch the full submission only when you actually need it, only for the one submission that changed.
Event types
You subscribe to one or more of these event types:bind_completed fires only for new-business binds; endorsement and renewal binds are their own events (endorsement_bound, renewed) so a busy policy doesn’t flood you with “bind” events. Subscribe to whichever you need.submission.public_reply is in early access alongside the status events. It fires on public, broker-visible messages — staff replies and automated broker notifications (payment confirmations, filing notices, quote messages). Internal, staff-only notes never fire it. Because a reply isn’t a status change, the payload is status-less: it carries a note_id reference instead of previous_status / new_status, and never embeds the message content — you fetch the reply body on demand (see below). Want it switched on for your account? Reach out to api-support@coverwhale.com.Expect roughly 1,200–1,500 public replies per day at weekday peak across an active book — subscribe deliberately.The event payload
Every delivery has the same envelope. It carries status metadata only — never documents, COIs, policy PDFs, or download URLs.
Status codes:
1 = Bound, 2 = Requested Bind, 5 = Pending Cancellation, 6 = Canceled, 10 = Not Taken Up.
The submission.public_reply payload
submission.public_reply uses the same envelope but is status-less — no previous_status / new_status. It carries a note_id reference and never embeds the message body:
Fetch the reply content
The webhook is content-free by design. Retrieve the reply body on demand — only for the one note that fired — with your existingAccessToken:
Privacy is enforced hard: the endpoint returns the note only if it is a public reply on a submission your account owns. Internal notes, notes on another company’s submission, and missing ids all return an identical
404 — it never reveals whether a non-public note exists.previous_status is the last partner-visible state, not necessarily the immediately-prior internal status (the transition may pass through internal sub-states you never see). Treat the event_type as authoritative for what happened, and use previous_status/new_status to reconcile — not as an exact audit of the prior status.Register a webhook
Manage your subscriptions with the subscription API. It uses the sameAccessToken you already use for the rest of the Cover Whale API (see Authentication) — no separate credential.
Base path: https://api.coverwhale.dev/v1/webhook-subscriptions (test) · https://api.coverwhale.com/v1/webhook-subscriptions (production).
Create a subscription
endpoint_urlmust be HTTPS.event_typesmust be a non-empty subset of the event types above.
Manage subscriptions
All operations are automatically scoped to your account — you can only see and modify your own subscriptions. Prefer
active: false (via PUT) over DELETE when you just want to pause deliveries and keep the subscription listed.
Verify the signature
Always verify every delivery before trusting it. Your endpoint is public; the signature is what proves a request actually came from Cover Whale. Each delivery carries these headers:
To verify: compute
HMAC-SHA256 over the exact raw bytes of the request body (not a re-serialized copy) using your secret, and compare to X-CW-Signature with a constant-time comparison.
Rotating your secret
CallPOST /webhook-subscriptions/{id}/rotate-secret to issue a new secret (returned once). For a grace window after rotation, Cover Whale signs every delivery with both secrets: X-CW-Signature uses the new secret and X-CW-Signature-Previous uses the old one. Accept a delivery whose signature matches either. This lets you roll your receiver over to the new secret without dropping in-flight events. Once the window elapses, only the new secret is sent.
Delivery, retries, and idempotency
- Asynchronous. Delivery never blocks the underlying bind/cancel/reinstate — an event may arrive a moment after the change.
- Respond
2xxwithin 10 seconds. Any2xxmeans “received.” We wait up to 10 seconds for your response, so acknowledge first and process asynchronously; don’t do slow work before responding, or you’ll time out and trigger a retry. - Retries with backoff. On a timeout, connection error, or
5xx, Cover Whale retries with exponential backoff — up to 8 attempts over roughly 24 hours, with the gap between attempts growing1m → 5m → 15m → 1h → 3h → 6h → 12h. 4xxis permanent. A4xxtells us the request itself is unacceptable — we do not retry; the event is dead-lettered immediately. Return4xxonly when you truly cannot accept the event, not for transient problems.- Dead-letter + replay. After retries are exhausted, an event is dead-lettered. Once your endpoint is healthy again, contact support with the affected
display_id(s) or time window and we can replay from our ledger. - Idempotency. Retries reuse the same
event_id(X-CW-Event-Id). Deduplicate on it — you may receive the same event more than once, but it is the same logical event. - No ordering guarantee. Under retry, events for the same
display_idcan arrive out of order. Reconcile withprevious_status/new_status/occurred_at, not arrival order.
Best practices
1
Verify every request
Reject any delivery whose signature doesn’t validate. An unverified webhook endpoint is an open door.
2
Acknowledge fast, process later
Return
2xx immediately, enqueue the event, and do the real work off the request path. Slow handlers cause timeouts and unnecessary retries.3
Be idempotent
Key your processing on
event_id so a redelivered event is a no-op.4
Guard against replay
Anchor replay protection on the signed
event_id (dedup) and occurred_at (reject events far in the past) — both are inside the signed body. X-CW-Timestamp is a convenience header only and is not covered by the signature.5
Fetch on demand
The payload is intentionally lean. When you need the full record, fetch
GET /v1/submission/{display_id} — only for the submission that changed.6
Monitor and log
Log
event_id, event_type, and display_id for every delivery so you can reconcile and request replays if you have an outage.Troubleshooting
Need help? Reach us at api-support@coverwhale.com.