Skip to content

Webhooks

4 operations

GET/webhooks#

Read this install's webhook subscription

Scope not declared in the specification

The signing secret is never returned; it can only be rotated.

Parameters

No parameters.

Responses

200

The active subscription, or null when none is configured

NameTypeDescription
dataRequirednullableWebhookSubscription

One subscription per install; PUT is a full replace.

  • 401

    Missing, invalid, expired, or revoked token

  • 429

    Token budget exhausted (180 requests/minute, 60 writes/minute per install)

Request
curl -X GET "https://dukkan.one/platform-api/v1/webhooks" \
  -H "Authorization: Bearer $DUKKAN_ACCESS_TOKEN"
Response
{
  "data": {
    "id": "6f1d2c3b-4a59-4e8f-9b70-2d1c3e4f5a6b",
    "endpoint_url": "string",
    "topics": [
      "order.created"
    ],
    "status": "active",
    "consecutive_failures": 1,
    "activated_at": "2026-08-18T16:00:00Z",
    "disabled_at": "2026-08-18T16:00:00Z",
    "secret": "string"
  }
}

PUT/webhooks#

Create or replace this install's webhook subscription

Scope not declared in the specification

One endpoint per install; a PUT fully replaces the topic list. The signing secret is returned EXACTLY ONCE — on creation, or when rotate_secret is true — and can never be read back afterwards. Topics are scope-gated: subscribing to a topic requires the read scope that governs its payload. endpoint_url must be a public HTTPS URL.

Parameters

No parameters.

Request body Required

Create or replace the install's single subscription.

NameTypeDescription
endpoint_urlRequiredstring

Public HTTPS URL. Private, loopback and IP-literal hosts are refused.

topicsRequiredWebhookTopic[]
rotate_secretboolean

Mint a new signing secret and return it once in the response.

Responses

200

Subscription created or replaced; secret present only when minted

NameTypeDescription
dataRequiredWebhookSubscription

One subscription per install; PUT is a full replace.

  • 400

    Invalid request

  • 401

    Missing, invalid, expired, or revoked token

  • 403

    Required live scope is missing

  • 404

    Resource not found in the token-bound store

  • 429

    Token budget exhausted (180 requests/minute, 60 writes/minute per install)

Request
curl -X PUT "https://dukkan.one/platform-api/v1/webhooks" \
  -H "Authorization: Bearer $DUKKAN_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "endpoint_url": "https://app.example.com/webhooks/dukkan",
  "topics": [
    "order.created"
  ],
  "rotate_secret": false
}'
Response
{
  "data": {
    "id": "6f1d2c3b-4a59-4e8f-9b70-2d1c3e4f5a6b",
    "endpoint_url": "string",
    "topics": [
      "order.created"
    ],
    "status": "active",
    "consecutive_failures": 1,
    "activated_at": "2026-08-18T16:00:00Z",
    "disabled_at": "2026-08-18T16:00:00Z",
    "secret": "string"
  }
}

DELETE/webhooks#

Stop delivery for this install

Scope not declared in the specification

Parameters

No parameters.

Responses

204

Subscription revoked

No response body.

  • 401

    Missing, invalid, expired, or revoked token

  • 429

    Token budget exhausted (180 requests/minute, 60 writes/minute per install)

Request
curl -X DELETE "https://dukkan.one/platform-api/v1/webhooks" \
  -H "Authorization: Bearer $DUKKAN_ACCESS_TOKEN"
Response
{
  "error": {
    "code": "invalid_request",
    "message": "A human-readable explanation",
    "request_id": "req_01J8Z1K5X9",
    "details": {}
  }
}

POST/webhooks/test#

Fire one signed test delivery (sandbox stores only)

Scope not declared in the specification

Writes a real outbox event for the topic, built from the sandbox store's own records (overridable through data), fans it out to this install's subscription and lets the delivery worker sign and send it with the same secret and SSRF checks as production traffic. The envelope carries test: true. Requires an active subscription that includes the topic and the scope that governs it. Budget: 30 per ten minutes per install. Answers 403 sandbox_required on real stores, 409 webhook_not_subscribed / webhook_topic_not_subscribed / sample_unavailable when the rehearsal cannot be built.

Parameters

No parameters.

Request body Required

Fire one signed test delivery (sandbox stores only).

NameTypeDescription
topicRequiredWebhookTopic

Webhook topic. Subscribing needs the read scope that governs the payload; app.uninstalled needs none and still delivers after revocation.

Values:order.createdorder.status_changedorder.paidproduct.createdproduct.updatedproduct.deletedinventory.movement_createdfulfillment.requestedfulfillment.createdfulfillment.updatedrefund.createdapp.uninstalled
dataobject

Optional overrides merged over the platform-built sample payload for the topic (at most 16 KB).

Responses

202

Event written and fanned out; the worker sends within about a minute

NameTypeDescription
dataRequiredWebhookTestEvent

The accepted test event and its queued deliveries.

  • 400

    Invalid request

  • 401

    Missing, invalid, expired, or revoked token

  • 403

    Required live scope is missing

  • 409

    State transition, inventory, refund, or idempotency conflict

  • 413

    Override data exceeds 16 KB

  • 429

    Token budget exhausted (180 requests/minute, 60 writes/minute per install)

Request
curl -X POST "https://dukkan.one/platform-api/v1/webhooks/test" \
  -H "Authorization: Bearer $DUKKAN_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "topic": "order.created",
  "data": {}
}'
Response
{
  "data": {
    "event_id": "6f1d2c3b-4a59-4e8f-9b70-2d1c3e4f5a6b",
    "topic": "order.created",
    "sequence": 1661,
    "occurred_at": "2026-08-18T16:00:00Z",
    "test": true,
    "data": {},
    "deliveries": [
      {
        "id": "6f1d2c3b-4a59-4e8f-9b70-2d1c3e4f5a6b",
        "status": "pending",
        "endpoint_url": "string"
      }
    ]
  }
}