CompuDime API docs

Reference / Webhook receivers

POST /v1/webhooks

Register a webhook receiver

Registers an HTTPS receiver for the order events of your integration and answers 201 with it and its signing secret. This signing secret is shown once, in this answer, and never again: store it now, like a password. If you lose it, rotate it (POST /v1/webhooks/{webhookId}/rotate-secret). url must start with https://, reach a public address (private, loopback, link-local and other reserved addresses are refused as typed, and again when CompuDime connects), carry no user name or password, and be at most 2048 characters long. events names at least one order event (see the top-level webhooks); webhook.test is not one, every receiver gets the test events you send it. Your integration may keep at most 5 receivers per key mode (409 webhook_limit_reached), and a URL it already has is 409 webhook_exists naming that receiver, so retrying after a lost answer never registers twice. Needs a key with the order-intake capability. Free. Receivers belong to the calling key's integration and mode. A live key's receivers get the order events they subscribe to; a test key's receivers get only the test events you send them, because a test key's orders are simulated and never send a webhook. A test key never sees a live receiver and a live key never sees a test one. Receivers CompuDime staff registered for your integration are live receivers.

KeyRequired. See Authentication.
Capabilityorder-intake
Scopeorders.webhooks
Pricefree. How pricing works.

Example

curl -s -X POST "https://api.compudime.com/v1/webhooks" \
  -H "Authorization: Bearer $PUBLIC_API_KEY" \
  -H "Content-Type: application/json" \
  -d @body.json

With this body.json:

{
  "url": "https://hooks.example.com/compudime/orders",
  "events": [
    "order.dispatched",
    "order.parked"
  ]
}

The answer looks like this:

{
  "requestId": "req_0123456789abcdef",
  "webhook": {
    "id": "7b0c9a1e-3f52-4c1d-9a7e-2d4f6b8c0e13",
    "url": "https://hooks.example.com/compudime/orders",
    "events": [
      "order.dispatched",
      "order.parked"
    ],
    "active": true,
    "mode": "live",
    "secretPrefix": "whsec_3f9a1c",
    "createdAt": "2026-10-13T15:00:00Z",
    "updatedAt": "2026-10-13T15:00:00Z"
  },
  "secret": "whsec_3f9a1c\u003c58 more hex digits\u003e",
  "secretNote": "This signing secret is shown once, in this answer, and never again: store it now, like a password. If you lose it, rotate it (POST /v1/webhooks/{webhookId}/rotate-secret)."
}

Request body

JSON: WebhookCreateRequest (required).

NameTypeDescription
events requiredarray of stringThe order events to send to it. Repeats are ignored; the receiver gets each event at most once per order. At least 1 item.
url requiredstringurl must start with https://, reach a public address (private, loopback, link-local and other reserved addresses are refused as typed, and again when CompuDime connects), carry no user name or password, and be at most 2048 characters long. At most 2048 characters.

Responses

StatusDescriptionBody
201The receiver is registered; secret is shown in this answer only.WebhookSecretResponse
400The body is not a JSON object with url and events, the url breaks a rule (url must start with https://, reach a public address (private, loopback, link-local and other reserved addresses are refused as typed, and again when CompuDime connects), carry no user name or password, and be at most 2048 characters long.), or events is empty or names an event that does not exist (code bad_request).Problem
401Public API key is missing, invalid, or revoked.Problem
403The API key does not carry the order-intake capability, or the store has not turned it on (code capability_not_enabled).Problem
405The requested method is not allowed for this endpoint.Problem
409webhook_exists: your key already has a receiver with this url; the detail names it. webhook_limit_reached: your integration already keeps 5 receivers for this key mode.Problem
429Too many requests from this API key (code rate_limited). Each key has its own request budget at the API edge, refilled continuously; it covers every authenticated endpoint, including the free ones, and is checked before anything is billed or sent to the store. Wait at least Retry-After seconds before the next request with this key, then resume; if 429 answers again, back off exponentially (double the wait each time, up to a minute or so) and add random jitter so parallel workers do not retry in step. A 429 is never charged and reserves nothing.
Header Retry-After: Whole seconds to wait before retrying with this key: the time until the key's next request token at the edge (never less than 1), or 60 when the store plan's per-minute ceiling refused the call.
Problem
500The API edge encountered an internal error.Problem
503A required Public API dependency is temporarily unavailable. Also answered, with code endpoint_disabled, while CompuDime has temporarily switched the endpoint off: the whole API, the endpoint's family (x-compudime-family) or this endpoint alone; the detail says which and why. It is checked before anything is validated, reserved or sent to the store, so it is never charged; it is retryable and carries Retry-After.
Header Retry-After: Sent with code endpoint_disabled: whole seconds to wait before asking again. A switch has no scheduled end, so this is a polling interval (60), not a promise.
Problem

Error bodies are problem JSON; every code is listed there.

Access level

What your integration's access level changes here.

LevelScopeEffect
ownorders.webhooksThe level does not change this operation: own and all return the same data.
allorders.webhooksThe level does not change this operation: own and all return the same data.