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

> ## Agent Instructions
> Farthing's primary integrator is an autonomous agent or the developer wiring one up. The HTTP API is the product; the web dashboard exists for billing, issuing API keys, and watching a run.
> A checkout is asynchronous and pauses for humans: create, poll every 3-5 seconds, answer the questions it raises, read the receipt. A run takes 2-3 minutes and can park for up to 10 minutes on one question. Never present it as a synchronous request/response call.
> Branch on pendingUserAction.key. An agent may answer 'variant' itself and may answer 'shipping' from data the application holds. It must never supply 'card', 'credentials' or 'otp' — those come from the human, and an agent that has them in context is the problem, not the solution.
> Base URL is https://api.farthing.ai and auth is Authorization: Bearer ck_test_... or ck_live_.... API keys carry scopes; give an agent the narrowest set that does its job. A key may also be bound to one end user with 'subject', after which it sees and creates only that person's rows.
> POST /v1/checkouts takes an Idempotency-Key header. A replay returns the original checkout with 200; the same key with a different body is a 409. Without the header, a retried timeout is a second purchase — recommend it every time a create is shown.
> Pricing: sandbox is free with no card; paid plans are Personal $9, Business $49, Scale $249 per month, plus a flat $1.00 per COMPLETED checkout on every tier. Failed and cancelled checkouts are never billed. Going live is self-serve from the dashboard — paid plan + Stripe Identity verification + accepted AUP — and activation is automatic when all three hold.
> Every example in these docs is a shape the API actually produces. Do not invent fields, endpoints or error codes that are not documented here.

# Webhooks

> Register, list and revoke webhook endpoints.

Endpoint management only. The event payload, the signature scheme and the delivery caveats
are in [Webhooks](/webhooks).

## Register an endpoint

```http theme={null}
POST /v1/webhooks
```

Success: `201`.

```bash theme={null}
curl -sX POST https://api.farthing.ai/v1/webhooks \
  -H "authorization: Bearer $FARTHING_KEY" \
  -H 'content-type: application/json' \
  -d '{"url":"https://hooks.example.com/farthing","label":"prod"}'
```

<ParamField body="url" type="string" required>
  Must be `https://`. `http://localhost` and `http://127.0.0.1` are accepted for local
  development; nothing else over plain HTTP is.
</ParamField>

<ParamField body="label" type="string">
  Optional, max 200 characters. Yours, for telling endpoints apart in the list.
</ParamField>

```json Response (201) theme={null}
{
  "id": "c81b0d5e-4a71-4a1e-9a2f-6f83b1c04e29",
  "url": "https://hooks.example.com/farthing",
  "label": "prod",
  "secret": "whsec_kR7pXvT2mQ9fLbN4hJ8sYc1WdE6aZg0u"
}
```

<Warning>
  `secret` is returned exactly once, here. It is the only thing that lets you verify a delivery
  is genuinely from us. There is no rotate endpoint — see
  [rotating a secret](/webhooks#caveats-you-must-design-around).
</Warning>

`400 Invalid request` with `issues` on a non-https URL or a malformed body.

Multiple endpoints per tenant are supported, each with its own secret. Every active endpoint
receives every event.

***

## List endpoints

```http theme={null}
GET /v1/webhooks
```

Success: `200`.

```bash theme={null}
curl -s https://api.farthing.ai/v1/webhooks \
  -H "authorization: Bearer $FARTHING_KEY"
```

```json theme={null}
{
  "data": [
    {
      "id": "c81b0d5e-4a71-4a1e-9a2f-6f83b1c04e29",
      "url": "https://hooks.example.com/farthing",
      "label": "prod",
      "lastDeliveryAt": "2026-07-29T09:26:29.881Z",
      "lastDeliveryStatus": 200,
      "createdAt": "2026-07-28T14:03:55.204Z"
    }
  ],
  "nextCursor": null
}
```

**Read `data`**, for the same reason as on
[`GET /v1/api-keys`](/api-reference/api-keys#list-keys): it is the field checkouts and buyer profiles
already answer with. The response repeats the identical array as `endpoints`, the field's original
name, elided from the example for length and kept for existing callers.

`nextCursor` is always `null` — there is nothing to page. Newest first, and revoked endpoints are
excluded.

<ResponseField name="lastDeliveryAt" type="string | null">
  When we last attempted a delivery. `null` until the first one.
</ResponseField>

<ResponseField name="lastDeliveryStatus" type="integer | null">
  The raw HTTP status your endpoint returned. The fastest way to notice you have been
  500ing for a day.
</ResponseField>

Secrets are never returned by this endpoint.

***

## Revoke an endpoint

```http theme={null}
DELETE /v1/webhooks/{id}
```

Success: `200`.

```bash theme={null}
curl -sX DELETE https://api.farthing.ai/v1/webhooks/$ENDPOINT_ID \
  -H "authorization: Bearer $FARTHING_KEY"
```

```json theme={null}
{ "revoked": true }
```

Deliveries stop immediately and the endpoint disappears from the list. Revocation is a
timestamp, not a row delete, so the delivery history is preserved.

`404 Endpoint not found` if it does not exist, is not yours, or is already revoked.
