📨 Webhooks

Webhooks overview

  • Webhooks notify organizations in near real time about changes to related entities (orders, contacts, merchants, invitations).
  • You can configure multiple endpoints per organization; all active endpoints receive all events.
  • Event status can be inspected via the API.

Getting started

  1. Create an endpoint with a URL and a secret.
  2. Store your secret securely; it’s used to sign each webhook.
  3. Verify signatures on every request (see Security below).
  4. Use Ping to test your integration before going live.

Managing endpoints (Org‑scoped)

  • Create: POST /organizations/:organizationId/webhooks
  • List/get: GET /organizations/:organizationId/webhooks[/ :webhookId]
  • Rotate secret: POST /organizations/:organizationId/webhooks/:webhookId/rotate-secret
  • Pause/resume: POST /organizations/:organizationId/webhooks/:webhookId/(pause|resume)
  • Delete: DELETE /organizations/:organizationId/webhooks/:webhookId (soft delete)
  • Ping: POST /organizations/:organizationId/webhooks/:webhookId/ping

Secrets are write‑only and never returned after creation/rotation.

Events (read APIs)

  • List: GET /organizations/:organizationId/webhook-events
    • Filters: type, from, to, merchantId, resourceType, resourceId, page, limit
  • Get: GET /organizations/:organizationId/webhook-events/:eventId
  • Deliveries (lean status): GET /organizations/:organizationId/webhook-events/:eventId/deliveries
    • Returns per-endpoint deliveries with deliveryStatus, retryCount, lastRetryAt, lastStatusCode, lastRespondedAt

Replay (Org-scoped, internal use by ops or via permissions):

  • Replay an event: POST /organizations/:organizationId/webhook-events/:eventId/replay
    • Re-enqueues to all active endpoints (or a single endpoint internally)

Event types (initial set)

  • Orders: order.created, order.pending, order.processing, order.paid, order.failed, order.cancelled, order.completed, order.expired
  • Contacts: contact.created, contact.updated, contact.deleted
  • Merchants: merchant.created, merchant.updated, merchant.deleted
  • Invitations: invitation.created, invitation.accepted, invitation.expired, invitation.revoked

Subject to expansion; breaking changes roll out via the version field.

Payload and headers

  • Content type: application/json
  • Body skeleton
1{
2 "id": "evt_...",
3 "type": "order.paid",
4 "version": "v1",
5 "occurred_at": "2025-08-16T21:52:14.292Z",
6 "source": "koywe.api",
7 "environment": "production",
8 "organization_id": "org_...",
9 "merchant_id": "mrc_...",
10 "data": { /* type-specific */ },
11 "relationships": { "self": { "type": "order", "id": "ord_..." } }
12}
  • Headers (set by Koywe):
    • Koywe-Event-Id, Koywe-Event-Type, Koywe-Event-Version
    • Koywe-Organization-Id, Koywe-Merchant-Id (if applicable)
    • Koywe-Environment
    • Koywe-Webhook-Id
    • Koywe-Signature: HMAC-SHA256 (hex) over the raw request body using your endpoint secret
    • Koywe-Integrity-Signature: added by the delivery service to protect in-flight integrity

Environment is one of: local | qa | sandbox | production.

Security (signature verification)

  • Compute HMAC-SHA256 of the exact request body using your saved endpoint secret.
  • Compare your digest (hex) with Koywe-Signature. If they don’t match, reject the webhook.
  • Replay-safe: use idempotency by event id (id is stable across replays).

Minimal pseudo-verification:

expected = hex(hmac_sha256(secret, raw_body))
if header["Koywe-Signature"] != expected: reject

Delivery behavior and retries

  • On event creation, Koywe persists the event and enqueues a delivery per active endpoint.
  • Each delivery receives a unique task id; you can fetch lean status via the deliveries endpoint.
  • If an endpoint fails, other endpoints still receive their deliveries.
  • You can request a replay to resend an event.

Best practices

  • Respond 2xx quickly (< 5s); process asynchronously on your side.
  • Validate Koywe-Signature on every request.
  • Treat webhooks as at-least-once delivery; deduplicate using event id.
  • Use the ping endpoint to verify connectivity after configuration or secret rotation.

Permissions (org-scoped)

  • organization_webhooks.manage: create/update/pause/resume/delete/rotate
  • organization_webhooks.view: list/get endpoints
  • organization_webhook_events.view: list/get events, view deliveries
  • organization_webhook_events.replay: replay events

This summary complements the OpenAPI docs with usage guidance, security expectations, and event taxonomy.