Sellvik / developers
Admin API

Webhooks management

Register, list, and revoke webhook subscriptions programmatically.

The actual webhook contract — events, signing, retries — is documented under Webhooks. This page covers the management API: creating, updating, and deleting subscriptions.

You can also manage webhooks from the panel (Settings → Webhooks). The API exists for repeatable infra-as-code setups.

Webhook object

{
  "id": "wh_a1b2c3...",
  "name": "Shipping integration",
  "url": "https://erp.example.com/sellvik-events",
  "events": ["order.created", "order.fulfilled", "order.cancelled"],
  "enabled": true,
  "failureCount": 0,
  "lastDeliveryAt": "2026-05-27T13:45:00.000Z",
  "createdAt": "2026-05-20T10:00:00.000Z"
}

The secret field is only ever returned at creation time. It is not queryable afterward. Lose it ⇒ delete and recreate the webhook.


List webhooks

GET /api/v1/admin/webhooks

Scope: webhooks:read

Query parameters

NameTypeNotes
limitinteger (1–100)Default 50.
cursorstringOpaque.

Response

{
  "items": [/* … Webhook objects without `secret` … */],
  "nextCursor": null
}

Create a webhook

POST /api/v1/admin/webhooks

Scope: webhooks:write

Request body

{
  "name": "Shipping integration",
  "url": "https://erp.example.com/sellvik-events",
  "events": ["order.created", "order.fulfilled", "order.cancelled"]
}
FieldRequiredNotes
namenoHuman-readable label. Default null.
urlyesHTTPS only. http:// is rejected outside dev shops.
eventsyesNon-empty array of event names. See Events.

Response

HTTP/1.1 201 Created

{
  "id": "wh_a1b2c3...",
  "name": "Shipping integration",
  "url": "https://erp.example.com/sellvik-events",
  "events": ["order.created", "order.fulfilled", "order.cancelled"],
  "enabled": true,
  "secret": "whsec_a1b2c3d4e5f6...",
  "createdAt": "2026-05-27T14:00:00.000Z"
}

Store secret immediately. It's needed to verify incoming webhook signatures. The same value never appears in any other response.

Errors

StatusCodeWhen
400invalid_bodyMissing fields, invalid URL, unknown event name.
400http_url_rejectedTrying to set an http:// URL on a non-dev shop.
409duplicate_endpointSame URL already subscribed (for any event set).

Get a webhook

GET /api/v1/admin/webhooks/{id}

Scope: webhooks:read


Update a webhook

PATCH /api/v1/admin/webhooks/{id}

Scope: webhooks:write

Any subset of:

{
  "enabled": false,
  "url": "https://new.example.com/sellvik-events",
  "events": ["order.created"],
  "name": "Shipping integration (paused)"
}

Disabling stops new deliveries but does not invalidate the secret — re-enable to resume. Use this for incident response without losing the secret.


Delete a webhook

DELETE /api/v1/admin/webhooks/{id}

Scope: webhooks:write

204 No Content. Pending deliveries continue draining for ~5 minutes after deletion, then stop.


List webhook deliveries

GET /api/v1/admin/webhooks/{id}/deliveries

Scope: webhooks:read

Returns delivery attempts for a webhook, newest first. Useful for debugging 4xx/5xx responses from your endpoint.

Query parameters

NameTypeNotes
limitinteger (1–100)Default 50.
cursorstringOpaque.
statusenumpending, succeeded, failed, dropped.

Response

{
  "items": [
    {
      "id": "del_a1b2c3...",
      "event": "order.created",
      "status": "succeeded",
      "attempts": 1,
      "lastAttemptAt": "2026-05-27T13:45:01.000Z",
      "lastResponseCode": 200,
      "lastResponseBody": "{\"received\":true}",
      "deliveredAt": "2026-05-27T13:45:01.000Z"
    },
    {
      "id": "del_xyz...",
      "event": "order.fulfilled",
      "status": "failed",
      "attempts": 5,
      "lastAttemptAt": "2026-05-27T13:50:30.000Z",
      "lastResponseCode": 502,
      "lastResponseBody": "Bad Gateway",
      "deliveredAt": null
    }
  ],
  "nextCursor": null
}

Deliveries are retained for 30 days.

On this page