---
title: "Send a test delivery to a subscription"
method: POST
path: "/api/v1/webhook-subscriptions/{id}/test"
tags: ["Webhooks"]
---

# Send a test delivery to a subscription

`POST /api/v1/webhook-subscriptions/{id}/test`

Immediately POSTs a synthetic `webhook.test` event to the
subscription's URL (signed with the current secret, 5s timeout,
no retries) and returns the response status + body verbatim.
Use this to verify the receiver's signature-verification path
before real traffic flows.

## Path parameters

- `id` string, required

## Response `200`

Test delivery attempted. The `delivery.ok` field indicates whether the receiver returned a 2xx.

- WebhookSubscriptionTestResponse — Standard success envelope. Endpoint-specific schemas extend this and constrain the `data` property to their concrete shape. Additional legacy keys (`status`, `log`, …) may appear alongside `success`/`data` for backwards compatibility, and some legacy handlers omit `success`, so it is not marked required.
  - `success` boolean — `true` on success (omitted by some legacy handlers).
  - `data` object, required — Endpoint-specific payload.
    - `subscription_id` string, required
    - `event` WebhookEvent, required — Payload **POSTed to your subscription URL**. This is NOT the body of any management endpoint — it is what your receiver parses. Verify the signature first; see the [Webhooks guide](/docs/webhooks#4-verify-the-signature).
      - `id` string, required — Globally unique event identifier. Also sent in the `X-Prezent-Event` header. Dedupe on this if you receive the same event twice (at-least-once delivery).
      - `type` 'autogeneration.completed' | 'autogeneration.failed' | 'template_conversion.completed' | 'template_conversion.failed' | 'webhook.test', required — Catalog of event types emitted by Prezent. New types may be added without notice; clients should ignore unknown values.
      - `api_version` string, required — Schema version for the `data` field. Increments only on breaking changes; legacy versions remain available.
      - `created_at` string, date-time, required
      - `data` object, required — Event-specific payload. For `autogeneration.*` events, contains `callback_id`, `report_id`, `status`, plus `outputs` (on success) or `error_log` (on failure). For `template_conversion.*` events, contains the conversion `callback_id`, `status`, and output URLs.
    - `delivery` object, required
      - `ok` boolean, required — True if the receiver returned a 2xx.
      - `status` integer, required — HTTP status code from the receiver (0 on network error / timeout).
      - `error` string, nullable — Network error code (`timeout`, `ECONNREFUSED`, etc.). `null` on success.
      - `response_body_preview` string — First 8 KiB of the receiver's response body, for debugging.
      - `delivery_id` string, required — Internal delivery id. Also sent to the receiver in the `X-Prezent-Delivery` header.

## Other responses

- `400` — Generic client error. `error.code` is one of `BAD_REQUEST`, `INVALID_JSON`, `MISSING_REQUIRED_FIELD`, `MISSING_QUERY_PARAM`, `MISSING_CALLBACK_ID`, `MISSING_SLIDES_ARRAY`, `MISSING_PROMPT`, `MISSING_TEMPLATE_ID`, `MISSING_FILE_CONTENT`, `MISSING_SHARE_DETAILS`, `INVALID_TYPE`, `INVALID_DATA`, `INVALID_DATA_TYPE`, `INVALID_PAYLOAD`, `INVALID_REQUEST`, `API_REQUEST_FAILED`, or `FILE_UPLOAD_FAILED`.
- `401` — Caller did not present a valid Bearer token, or the token has expired. `error.code` is one of `UNAUTHORIZED`, `INVALID_API_KEY`, `EXPIRED_API_KEY`.
- `403` — Caller is authenticated but not allowed to perform this operation. `error.code` is `FORBIDDEN`.
- `404` — Requested endpoint or resource does not exist. `error.code` is one of `ENDPOINT_NOT_FOUND`, `RESOURCE_NOT_FOUND`, `NOT_FOUND`.
- `429` — Rate limit, usage limit, or gateway-level throttle exceeded. `error.code` is `TOO_MANY_REQUESTS` (gateway throttle), `RATE_LIMIT_EXCEEDED` (per-category), or `USAGE_LIMIT_EXCEEDED` (annual quota). Default limits (all configurable per company/key): - Gateway throttle (per API key) → `TOO_MANY_REQUESTS`: 10 requests/second sustained, 5 burst, 1,000 requests/day. - Per-company, per-category sliding 60-second window → `RATE_LIMIT_EXCEEDED`. The applicable category is given by each operation's `x-rate-limit-category`. - Annual usage quota → `USAGE_LIMIT_EXCEEDED`: 50,000 slide generations/year and 1,000,000 presentation downloads/year. `X-RateLimit-Limit`/`X-RateLimit-Remaining`/`X-RateLimit-Reset` are returned on successful (2xx) responses from rate-limited endpoints and, with `Retry-After`, on the per-category `RATE_LIMIT_EXCEEDED` 429 (the headers declared below). The gateway `TOO_MANY_REQUESTS` and annual `USAGE_LIMIT_EXCEEDED` responses do not carry them. Read `X-RateLimit-Remaining` to self-throttle and honour `Retry-After` on a 429.
- `500` — Unexpected server error. `error.code` is `INTERNAL_SERVER_ERROR`.
- `503` — Service is temporarily unavailable (downstream dependency unhealthy). `error.code` is `SERVICE_UNAVAILABLE` or `EXTERNAL_SERVICE_ERROR`.
- `504` — A downstream call timed out. `error.code` is `GATEWAY_TIMEOUT`.

---

[API](https://skmtc.net/prezent/apis/prezent-platform-api.md) · [All operations](https://skmtc.net/prezent/apis/prezent-platform-api/llms.txt) · [OpenAPI document](https://skmtc-service-staging.skmtc.workers.dev/v1/apis/prezent/prezent-platform-api/revisions/a01cb764a085/schema)
