Skip to main content
PanoQore posts events to your HTTPS endpoints as they happen. Managing endpoints needs webhooks:manage.

Add an endpoint

A signed test event is sent first, and the endpoint is saved only if it answers 2xx. Otherwise you get WEBHOOK_TEST_FAILED. The answer’s secret, starting whsec_, is what you verify with. POST /v1/webhook-endpoints/{id}/secret shows it again, and each reveal goes on the audit log. An endpoint receives what happens from then on, not earlier events. The URL must be https, and private and loopback addresses are refused. Redirects are not followed. A tenant can have 20 endpoints, each with up to 20 topics.

Topics

A topic is an event type, a group such as entry.*, or *. The groups are account, entry, hold, named_account, inbound_credit, approval, fx_rate, fx_quote and break. An inbound credit arrives as entry.posted, with kind: TRANSFER_IN. * also delivers other public events, such as statement.ingested. Sign-ins, team changes, API key changes and webhook changes are never sent.

The delivery

Each delivery is a CloudEvents 1.0 JSON document, with Content-Type: application/cloudevents+json.
data is snake_case, unlike API responses. The type has a panoqore. prefix, and the Qore-Event-Type header and topics do not.
A test event has type: panoqore.webhook.test, and its id is not an evt_ id.

Verify the signature

Qore-Signature is t=<unix seconds>,v1=<hex>, where the hex is HMAC-SHA256 of <t>.<body>, keyed with the whole secret including whsec_. Use the raw bytes of the body, before any JSON parsing. Refuse a timestamp more than five minutes from now, so a captured delivery cannot be replayed.

Answering

Answer 2xx within 10 seconds. Do slow work after answering. Anything else is retried: eight tries over about 24 hours, after 1 minute, 4 minutes, 25 minutes, 90 minutes, 4 hours, 6 hours and 12 hours. Then the delivery waits for a replay. Delivery is at least once, so drop duplicates by the event id.

Replay

GET /v1/events?publicOnly=true lists the event stream. It holds the same events, and each has a seq, its gap-free number on the tenant.