Skip to content
Coritan Docs

Receive organization webhooks

Send your organization's events to an endpoint on your own server, and learn how deliveries, retries and signatures work.

View as Markdown

A webhook tells your own systems when something happens in your organization: a customer signs up, a customer orders a service, an invoice is paid. For each event you subscribe to, we send an HTTPS POST with a JSON body to the endpoint you choose.

  • You need the owner or admin role in the organization.
  • Set up an HTTPS endpoint that answers with a 2xx status within 10 seconds.
  • We cannot give you the signing secret yet (see Signatures), so put a long random token in the endpoint's URL and refuse requests that do not carry it.
  1. Go to Organizations, open your organization and choose Webhooks.
  2. Choose New webhook….
  3. Enter the Endpoint URL. It must start with https://.
  4. Tick the Events to send. To subscribe to an event the list does not offer, such as service.ordered, type its name in Other events; separate several names with commas.
  5. Choose Create webhook.

To change a webhook, choose Edit webhook on its row. Untick Enabled to stop deliveries and keep the settings, or use the switch in the Enabled column. To delete one, choose Delete webhook and type the endpoint's host name to confirm. Deliveries stop at once.

The webhook appears in the table with its events. Select a row to see when we last delivered to it and how many deliveries have failed in a row. We do not keep a log of each delivery.

The event name arrives in the X-Webhook-Event header. These are the events we send today:

Event When Body fields
customer.created A customer registers or signs in with a social account for the first time, or you add one. customer_id, email
service.ordered A member orders a service for a customer from the dashboard or the API. service_id, customer_id, product_id
order.created A customer orders from your storefront. service_id, customer_id, product_id, invoice_id
service.suspended A member suspends a customer service. service_id, customer_id
service.unsuspended A member lifts a suspension. service_id, customer_id
invoice.created Our daily billing run creates invoices for your customers. Sent in the platform_mor and hybrid billing modes. count, generated_at
invoice.paid An invoice is paid in full. invoice_id, invoice_number, amount, customer_id, gateway
payout.created We create a payout for your organization. payout_id, period_start, period_end

Subscribe to * to receive every event. The Commerce API sends its own events with names that start with commerce., such as commerce.order.placed; Sell with the Commerce API lists them.

The dashboard's list also offers Customer updated, Service created, Service cancelled, Invoice overdue and Payout completed. We do not send those events yet, so a webhook subscribed only to them receives nothing.

We count a delivery as done when your endpoint answers with a 2xx status. Any other answer, a timeout after 10 seconds or a connection error is a failure, and we try again 1, 5, 30 and 120 minutes after each failure: five attempts in all. When the fifth attempt fails and the webhook has failed 10 times in a row, we turn it off. Fix the endpoint, then turn the webhook back on.

The same event can arrive more than once, so make your handler safe to run twice.

Each delivery carries an X-Webhook-Signature header in the form t=<unix time>,v1=<hex HMAC-SHA256>. We create a signing secret for each webhook, but no API or page shows it yet, so you cannot check the signature. Until you can, treat the endpoint URL as the credential: keep it private, and change it if it leaks.

The webhook turned itself off
It failed 10 times in a row. Check that the endpoint answers 2xx within 10 seconds, then turn the webhook back on.
Nothing arrives for an event you ticked
Check that the event is in the table under Events. The dashboard offers some events we do not send yet.
404 Webhook not found
The webhook ID belongs to another organization or the webhook was deleted.

Every route needs an owner's or admin's access token, sent as Authorization: Bearer $CORITAN_TOKEN.

Shell
curl -X POST "https://api.coritan.com/api/v1/orgs/acme/webhooks" \
  -H "Authorization: Bearer $CORITAN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"url": "https://example.com/hooks/coritan/7Hq2xV9pLk", "events": ["invoice.paid", "service.ordered"]}'
Route What it does
GET /api/v1/orgs/{org_slug}/webhooks Lists the webhooks.
POST /api/v1/orgs/{org_slug}/webhooks Creates one from url and events, and answers 201.
PATCH /api/v1/orgs/{org_slug}/webhooks/{webhook_id} Changes any of url, events and is_active.
DELETE /api/v1/orgs/{org_slug}/webhooks/{webhook_id} Deletes the webhook.

Each webhook in an answer has id, url, events, is_active, failure_count (failures in a row), last_triggered_at (the last successful delivery) and created_at.

API operations on this page