---
title: "Register a webhook endpoint"
method: POST
path: "/api/v1/webhooks"
---

# Register a webhook endpoint

`POST /api/v1/webhooks`

## Request

- Base URL: `https://podcaststotext.com`
- URL: `https://podcaststotext.com/api/v1/webhooks`
- Auth: HTTP bearer

Subscribe to events instead of polling for them, which is also how you stay inside the rate limits. The `secret` in the response is shown ONCE and is never retrievable; deliveries are signed with it (HMAC-SHA256 over the raw body). Requires the "shows:write" scope.

## Request body

- object
  - `url` string, required: Public HTTPS endpoint. Private and link-local addresses are refused.
  - `description` string
  - `events` string[]: Omit or leave empty to subscribe to all of them
  - `payload` object: Opt in to carrying the transcript in the delivery, for a receiver that cannot call the API back. Omitted above 256 KB, with text_omitted saying why.
    - `text` boolean
    - `format` 'txt' | 'srt' | 'vtt' | 'json'

## Response `201`

Endpoint registered. Store `secret` now.

- object
  - `id` string
  - `url` string
  - `events` string[]
  - `secret` string: Shown once. Never returned again by any endpoint.

## Other responses

- `400`: Unusable URL or unknown event
- `401`: Missing or invalid API key
- `403`: The account's plan does not allow this: either it includes no API access, or the requested scope needs write access. `error.code` is "plan_required". No plan is in that state today, so in practice you will see 402 insufficient_credits instead, which means the plan is fine and the balance is empty.

---

[API](https://skmtc.dev/podcaststotext/apis/podcaststotext-api.md) · [All operations](https://skmtc.dev/podcaststotext/apis/podcaststotext-api/llms.txt) · [OpenAPI document](https://skmtc.dev/podcaststotext/apis/podcaststotext-api/revisions/ef711acf4bc3?raw)
