Skip to main content
All routes require:
The key must include the scope below and access to that store. The dashboard permission ceiling is manageSettings. These endpoints manage outgoing Join Markt events. They are separate from payment-provider IPN.
{webhookId} is the webhook record id, or the public id WHK- plus five groups of four characters from 23456789ABCDEFGHJKMNPQRSTUVWXYZ. Letter case does not matter for the public id. A public id that is not in this store is handled as a missing webhook (404). A store can have 20 webhooks. The 21st create returns 400 with error Maximum of 20 webhooks per shop.

Webhook object

List, get, update, create, and rotate return this object. Create and rotate add secret. List and get do not.
string
Webhook record id.
string
Public id shaped WHK-XXXX-XXXX-XXXX-XXXX-XXXX.
string
Store record id.
string
Label, 1–120 characters.
string
Endpoint URL.
string
Last four characters of the signing secret.
string[]
Subscribed events. Each value is order.created, order.completed, order.refunded, or product.updated.
boolean
Event delivery selects rows with enabled true, disabledAt null, and the event name in events. POST .../test checks enabled only. A 2xx delivery sets failureCount to 0, sets lastDeliveredAt, and clears disabledAt. After 10 failed deliveries the row is saved with enabled false and disabledAt set. JOIN_MARKT_WEBHOOK_AUTO_DISABLE overrides 10 when it is a positive number.
number
Consecutive delivery failures. A 2xx delivery sets this to 0.
string | null
ISO time when the endpoint was disabled, or null.
string | null
ISO time of the last 2xx delivery, or null.
string
ISO create time.
string
ISO update time.
string
Full signing secret. Present on create (201) and rotate only. It starts with whsec_.

URL rules

Create and update run the same URL check when url is set.
  • The value must be an absolute URL, max 2048 characters, with no username or password.
  • The protocol is https.
  • Loopback, unspecified, link-local, and cloud-metadata hosts are rejected.
  • Private addresses and internal hostnames are rejected.
400 messages: Invalid webhook URL, Webhook URL must not include credentials, Webhook URL must use HTTPS, Webhook URL host is not allowed.

List webhooks

Scope: webhook:read. No query parameters.
string
required
Store record id.
webhooks is an array of webhook objects without secret.

Create webhook

Scope: webhook:write. Status 201. JSON object. Fields other than the ones below are ignored. Invalid JSON returns 400 with error Invalid JSON.
string
required
Store record id.
string
required
Trimmed label, 1–120 characters.
string
required
Endpoint URL. See URL rules.
string[]
required
At least one of order.created, order.completed, order.refunded, product.updated.
boolean
Defaults to true. false creates a disabled endpoint. Create does not set disabledAt.
The 201 body is the webhook object plus secret.

Get webhook

Scope: webhook:read.
string
required
Store record id.
string
required
Record id or WHK- public id.
Returns the webhook object without secret. 404 with error Webhook not found when the id is not in this store.

Update webhook

Scope: webhook:write. JSON object. At least one of name, url, events, or enabled is required. Other properties are ignored. Invalid JSON returns 400 with error Invalid JSON. An empty update returns 400 with error Provide at least one field to update.
string
required
Store record id.
string
required
Record id or WHK- public id.
string
Trimmed label, 1–120 characters.
string
Endpoint URL. See URL rules.
string[]
At least one event id when this field is sent. Same enum as create.
boolean
false sets disabledAt to the current time. true clears disabledAt and sets failureCount to 0.
Returns the webhook object without secret.

Delete webhook

Scope: webhook:delete. No body is read.
string
required
Store record id.
string
required
Record id or WHK- public id.

Rotate secret

Scope: webhook:write. No body is read. Returns the webhook object plus a new secret. secretPrefix becomes the last four characters of that secret. Later deliveries are signed with the new secret.
string
required
Store record id.
string
required
Record id or WHK- public id.

Send test

Scope: webhook:write. No body is read. Sends one webhook.test delivery and waits for that attempt (the outbound request aborts after 10 seconds). A disabled endpoint returns 400 with error Webhook is disabled. A missing stored secret returns 400 with error Webhook secret is missing; rotate the endpoint.
string
required
Store record id.
string
required
Record id or WHK- public id.
boolean
true when the endpoint returned a status from 200 through 299.
string
Delivery row id.
number | null
HTTP status from the endpoint, or null when there was no HTTP response.
boolean
Present when ok is false. true when this failure reached the auto-disable threshold.
The posted JSON is the event envelope with type webhook.test and data { "ok": true }.

List deliveries

Scope: webhook:read. No query parameters. Returns the newest 50 delivery rows.
string
required
Store record id.
string
required
Record id or WHK- public id.
object[]
Newest first.

Event envelope

Deliveries POST JSON with Content-Type: application/json and User-Agent: JoinMarkt-Webhooks/1.0. v1 is HMAC-SHA256 of the signing secret over the string <unix seconds>.<raw body>, hex-encoded. The raw body is the exact JSON bytes. Verification rejects a timestamp more than 5 minutes from the current time.
id starts with evt_. created is unix seconds. type is the event name. data is the event payload. For webhook.test, data is { "ok": true }.

Errors

Failed responses use { "success": false, "error": "...", "code": "..." }. A 500 also includes errorId. Zod field errors are the issue messages joined with ; .