API Keys & Webhooks API

Mint and revoke API keys, register webhook endpoints, rotate signing secrets, send test deliveries and read the delivery log.

10 endpoints. Every request needs an API key or a session token — see Authentication. To send one of these calls from the browser, use the interactive reference.

GEThttps://api.spirestock.com/api/v1/developer/api-keys

List the API keys issued for your workspace. The secret itself is never returned — only the prefix, so you can identify a key you already saved. Workspace administrators only.

Example request

curl https://api.spirestock.com/api/v1/developer/api-keys \
  -H "Authorization: Bearer YOUR_TOKEN"

Example response

{
  "response_code": 200,
  "data": [
    {
      "id": 3,
      "name": "Warehouse sync",
      "key_prefix": "df_9f3a1c",
      "scopes": "read",
      "status": 1,
      "last_used_at": "2026-08-08T11:02:41.000Z",
      "expires_at": null,
      "created_at": "2026-07-30T09:15:00.000Z"
    }
  ]
}
POSThttps://api.spirestock.com/api/v1/developer/api-keys

Issue a new API key. The plaintext key is returned once, in this response only — it is stored as a SHA-256 hash and cannot be retrieved again. Send it as X-API-Key on subsequent requests. Workspace administrators only; requires a session token, not an API key.

Request body

  • name (string)requiredLabel to identify the key later
  • scopes (string)Comma-separated. Actions: read (GET/HEAD), write (all methods, implies read). Optional resource scopes confine the key to those route groups, e.g. 'read,orders'. Use '*' for full access.
  • expires_in_days (integer)1-3650. Omit for a key that never expires

Example request

curl -X POST https://api.spirestock.com/api/v1/developer/api-keys \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Warehouse sync",
    "scopes": "read,orders",
    "expires_in_days": 90
  }'

Example response

{
  "response_code": 201,
  "message": "API key created. Save this key — it won't be shown again.",
  "data": {
    "id": 3,
    "key": "df_9f3a1c7e2b...",
    "name": "Warehouse sync",
    "key_prefix": "df_9f3a1c",
    "scopes": "read,orders",
    "expires_at": "2026-11-08T00:00:00.000Z"
  }
}
DELETEhttps://api.spirestock.com/api/v1/developer/api-keys/{id}

Revoke an API key. The record is kept for audit purposes and its status is set to 0. Workspace administrators only.

Parameters

  • id (integer)requiredAPI key ID

Example request

curl -X DELETE https://api.spirestock.com/api/v1/developer/api-keys/3 \
  -H "Authorization: Bearer YOUR_TOKEN"

Example response

{
  "response_code": 200,
  "message": "API key revoked"
}
GEThttps://api.spirestock.com/api/v1/developer/webhooks

List the webhook endpoints registered for your workspace, including delivery health via last_triggered_at and failure_count. Signing secrets are never included — rotate if you lost one. The response also carries supported_events.

Example request

curl https://api.spirestock.com/api/v1/developer/webhooks \
  -H "Authorization: Bearer YOUR_TOKEN"

Example response

{
  "response_code": 200,
  "data": [
    {
      "id": 1,
      "organization_id": 5,
      "name": "Order events",
      "url": "https://example.com/hooks/spirestock",
      "events": "order.created,order.delivered",
      "status": 1,
      "last_triggered_at": "2026-08-09T18:40:12.000Z",
      "failure_count": 0
    }
  ],
  "supported_events": ["order.created", "order.delivered", "user.created"]
}
POSThttps://api.spirestock.com/api/v1/developer/webhooks

Register a webhook endpoint. A signing secret is generated and returned in this response only — store it and use it to verify deliveries. The URL must be HTTPS and resolve to a public address; private, loopback and link-local targets are rejected. Workspace administrators only.

Request body

  • name (string)requiredLabel to identify the endpoint
  • url (string)requiredHTTPS URL that will receive the POST. Must resolve to a public address
  • events (string[] | string)Any of order.created, order.delivered, user.created — as an array or comma-separated string. Unknown events are rejected

Example request

curl -X POST https://api.spirestock.com/api/v1/developer/webhooks \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Order events",
    "url": "https://example.com/hooks/spirestock",
    "events": ["order.created", "order.delivered"]
  }'

Example response

{
  "response_code": 201,
  "message": "Webhook created. Save the signing secret — it won't be shown again.",
  "data": {
    "id": 1,
    "organization_id": 5,
    "name": "Order events",
    "url": "https://example.com/hooks/spirestock",
    "secret": "6f1c0e0b8a9d...",
    "events": "order.created,order.delivered",
    "status": 1,
    "failure_count": 0
  }
}
PUThttps://api.spirestock.com/api/v1/developer/webhooks/{id}

Update a webhook endpoint. Omitted fields are left unchanged. Send status 0 to pause deliveries without deleting the endpoint or rotating its secret — pausing also cancels deliveries already queued for it. Workspace administrators only.

Parameters

  • id (integer)requiredWebhook ID

Request body

  • name (string)Label to identify the endpoint
  • url (string)HTTPS URL that will receive the POST
  • events (string[] | string)Events to subscribe to, as an array or comma-separated string
  • status (integer)1 to deliver, 0 to pause

Example request

curl -X PUT https://api.spirestock.com/api/v1/developer/webhooks/1 \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "events": ["order.created", "order.delivered", "user.created"],
    "status": 1
  }'

Example response

{
  "response_code": 200,
  "message": "Webhook updated",
  "data": {
    "id": 1,
    "name": "Order events",
    "url": "https://example.com/hooks/spirestock",
    "events": "order.created,order.delivered,user.created",
    "status": 1
  }
}
DELETEhttps://api.spirestock.com/api/v1/developer/webhooks/{id}

Delete a webhook endpoint permanently. Deliveries stop immediately, any queued deliveries are cancelled, and the signing secret is discarded. Workspace administrators only.

Parameters

  • id (integer)requiredWebhook ID

Example request

curl -X DELETE https://api.spirestock.com/api/v1/developer/webhooks/1 \
  -H "Authorization: Bearer YOUR_TOKEN"

Example response

{
  "response_code": 200,
  "message": "Webhook deleted"
}
POSThttps://api.spirestock.com/api/v1/developer/webhooks/{id}/rotate-secret

Issue a new signing secret for an endpoint. The only way to recover a secret lost after creation, and the correct response to one that leaked. Deliveries are signed with the new secret immediately, with no grace period — deploy it to your endpoint first. Workspace administrators only.

Parameters

  • id (integer)requiredWebhook ID

Example request

curl -X POST https://api.spirestock.com/api/v1/developer/webhooks/1/rotate-secret \
  -H "Authorization: Bearer YOUR_TOKEN"

Example response

{
  "response_code": 200,
  "message": "Signing secret rotated. Deliveries are signed with the new secret from now on — update your endpoint.",
  "data": {
    "id": 1,
    "secret": "4b8e2c0a6f1d9e3b7a5c1f0d8e2b6a4c9f3e1d7b5a0c2e8f4d6b0a2c8e4f6d0b"
  }
}
POSThttps://api.spirestock.com/api/v1/developer/webhooks/{id}/test

Send a webhook.test payload, signed exactly like a real event, so you can confirm your endpoint is reachable and your signature check works before real events fire. Never retried. A delivery failure is reported in the body rather than as an error status — you asked whether the endpoint is reachable, and the answer 'no' is still a successful answer.

Parameters

  • id (integer)requiredWebhook ID

Example request

curl -X POST https://api.spirestock.com/api/v1/developer/webhooks/1/test \
  -H "Authorization: Bearer YOUR_TOKEN"

Example response

{
  "response_code": 200,
  "message": "Webhook test delivered — endpoint returned 200",
  "data": {
    "delivered": true,
    "event_id": "evt_9f3a1c7e2b8d4a6f0c5e1b7a3d9f2e4c",
    "response_status": 200,
    "duration_ms": 218
  }
}
GEThttps://api.spirestock.com/api/v1/developer/webhook-deliveries

Recent delivery attempts, newest first — what was sent, what your endpoint returned, and what is still queued for retry. The first place to look when an endpoint is not receiving what you expect.

Parameters

  • webhook_id (integer)Limit to a single endpoint
  • status (string)One of pending, sending, sent, dead
  • limit (integer)1-200

Example request

curl "https://api.spirestock.com/api/v1/developer/webhook-deliveries?webhook_id=1&status=dead" \
  -H "Authorization: Bearer YOUR_TOKEN"

Example response

{
  "response_code": 200,
  "data": [
    {
      "id": 4821,
      "webhook_id": 1,
      "event_id": "evt_9f3a1c7e2b8d4a6f0c5e1b7a3d9f2e4c",
      "event_type": "order.created",
      "status": "dead",
      "attempts": 12,
      "max_attempts": 12,
      "next_attempt_at": null,
      "last_attempt_at": "2026-08-18T04:11:07.000Z",
      "sent_at": null,
      "response_status": 500,
      "response_body": "Internal Server Error",
      "duration_ms": 812,
      "last_error": "Internal Server Error",
      "created_at": "2026-08-17T14:02:55.000Z"
    }
  ]
}