> ## Documentation Index
> Fetch the complete documentation index at: https://docs.joinmarkt.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Merchant webhooks

> Create and manage outgoing shop webhooks with a Bearer API key.

All routes require:

```txt theme={null}
Authorization: Bearer mk_live_<your_key>
```

Paths are store-scoped. The key must include `webhook:read`, `webhook:write`, or `webhook:delete` **and** access to that shop. Dashboard permission ceilings still apply (`manageSettings`).

These endpoints manage **outgoing MARKT events**. They are not payment-provider IPN.

## List

```http theme={null}
GET /api/merchant/v1/stores/{storeId}/webhooks
```

Scope: `webhook:read`

```json theme={null}
{
  "webhooks": [
    {
      "id": "clxyz...",
      "storeId": "cm...",
      "name": "Orders to backend",
      "url": "https://example.com/webhooks/markt",
      "secretPrefix": "a1b2",
      "events": ["order.completed"],
      "enabled": true,
      "failureCount": 0,
      "disabledAt": null,
      "lastDeliveredAt": "2026-09-21T12:00:00.000Z",
      "createdAt": "2026-09-21T11:00:00.000Z",
      "updatedAt": "2026-09-21T12:00:00.000Z"
    }
  ]
}
```

The signing secret is never returned on list or get.

## Create

```http theme={null}
POST /api/merchant/v1/stores/{storeId}/webhooks
```

Scope: `webhook:write`

```json theme={null}
{
  "name": "Orders to backend",
  "url": "https://example.com/webhooks/markt",
  "events": ["order.created", "order.completed", "order.refunded", "product.updated"]
}
```

`201` includes `secret` (`whsec_…`) **once**. HTTPS is required in production. Local `http://127.0.0.1` is allowed only outside production.

## Get / update / delete

```http theme={null}
GET    /api/merchant/v1/stores/{storeId}/webhooks/{webhookId}
PATCH  /api/merchant/v1/stores/{storeId}/webhooks/{webhookId}
DELETE /api/merchant/v1/stores/{storeId}/webhooks/{webhookId}
```

Scopes: `webhook:read` / `webhook:write` / `webhook:delete`

PATCH body (any subset):

```json theme={null}
{
  "name": "Renamed",
  "url": "https://example.com/webhooks/markt",
  "events": ["order.completed"],
  "enabled": false
}
```

## Rotate secret

```http theme={null}
POST /api/merchant/v1/stores/{storeId}/webhooks/{webhookId}/rotate
```

Scope: `webhook:write`

Returns a new `secret` once. Previous signatures stop verifying.

## Test ping

```http theme={null}
POST /api/merchant/v1/stores/{storeId}/webhooks/{webhookId}/test
```

Scope: `webhook:write`

Sends `webhook.test` immediately. Disabled endpoints return `400`.

## Delivery log

```http theme={null}
GET /api/merchant/v1/stores/{storeId}/webhooks/{webhookId}/deliveries
```

Scope: `webhook:read`

```json theme={null}
{
  "deliveries": [
    {
      "id": "cldel...",
      "webhookId": "clxyz...",
      "eventId": "evt_…",
      "event": "order.completed",
      "attempt": 1,
      "status": "success",
      "responseCode": 200,
      "responseBodyPreview": "ok",
      "errorMessage": null,
      "durationMs": 84,
      "createdAt": "2026-09-21T12:00:00.000Z"
    }
  ]
}
```

Statuses: `pending`, `success`, `failed`, `queued`, `skipped`.

## Signature (receiver)

```bash theme={null}
# raw body must be the exact JSON bytes
# header: X-Markt-Signature: t=<unix>,v1=<hex>
# HMAC-SHA256(secret, `${t}.${rawBody}`)
```

See [Outgoing webhooks](/developers/outgoing-webhooks) for Node verification.

## Errors

| Status | Meaning |
| - | - |
| 400 | Invalid URL, events, JSON, or disabled test |
| 401 | Missing, invalid, expired, or revoked token |
| 403 | Scope, shop, or `manageSettings` ceiling |
| 404 | Webhook not in this store |
| 429 | Rate limit exceeded |

## Related

* [Outgoing webhooks](/developers/outgoing-webhooks)
* [API keys](/developers/api-keys)
* [Merchant orders](/api/merchant-orders)
* [Payment-provider IPN](/developers/webhooks)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.