Webhooks
Subscribe a URL to an event type and the Directory will POST to it when that event fires. All three routes require webhooks.manage; subscriptions are scoped to the API key that created them.
/v1/webhooksCreate a subscription. Body: `{ "event_type": "rfq.quote_submitted", "target_url": "https://…" }`. Both fields required (400 otherwise). Returns 201.
The signing secret is returned only in the creation response. Store it immediately — it is never shown again. To rotate, delete the subscription and create a new one.
{
"data": {
"id": "1c9d…",
"event_type": "rfq.quote_submitted",
"target_url": "https://sourcing.example.com/hooks/directory",
"is_active": true,
"created_at": "2026-09-02T02:39:00Z",
"secret": "a3f1…64 hex chars…"
}
}/v1/webhooksList your key's subscriptions. Secrets are not included.
/v1/webhooks/:idDelete a subscription owned by your key. Returns `{ "success": true }`.
Complete event list
The API fires exactly these eight events. One subscription listens to one event_type; create several to cover several events.
| Event | Fires when | Payload `data` |
|---|---|---|
business.created | A business is created via the API | business_id, name, slug |
business.updated | A business is updated via the API | business_id, name, updated_fields |
product.created | A product is created via the API | product_id, business_id, name |
product.updated | A product is updated via the API | product_id, business_id, updated_fields |
supplier.performance_updated | Supplier performance is upserted | business_id |
rfq.created | An RFQ is created via /v1/rfq/inbound | rfq_id, external_rfq_id, rfq_number |
rfq.status_changed | An RFQ update includes a new status | rfq_id, status, external_rfq_id |
rfq.quote_submitted | A supplier quote is recorded | rfq_id, external_rfq_id, supplier_id, quoted_price |
Delivery format
{
"event": "rfq.quote_submitted",
"timestamp": "2026-09-02T02:40:12.483Z",
"data": {
"rfq_id": "9f31…",
"external_rfq_id": "PROC-2026-0042",
"supplier_id": "c3a1…",
"quoted_price": 56000000
}
}- Delivery is fire-and-forget: a failed POST does not fail or retry the originating API call.
quoted_pricein the payload is a bare number — read the authoritative amount and currency fromGET /v1/rfq/:id/quotes.- Treat the webhook as a nudge, not as the source of truth. Fetch the resource after receiving it.
- Respond quickly with 2xx and process asynchronously.