# Webhook endpoints API

> Subscribe and unsubscribe webhook URLs from your own code with the Anytime Capital Payments API, REST-hook style, and get each endpoint's signing secret.

Source: https://anytime-capital.com/docs/webhook-endpoints · Markdown: https://anytime-capital.com/docs/webhook-endpoints.md · All docs: https://anytime-capital.com/docs/llms-full.txt

Where we send your [events](https://anytime-capital.com/docs/webhooks.md), managed from your own code: subscribe with `POST`, unsubscribe with `DELETE`, the REST-hook style automation tools use. The rules are the dashboard's: an `https://` URL on a public domain name (no IP addresses or `localhost`), known event types or `["*"]` for every event including ones added later, and at most 10 endpoints per business. Endpoints made here also show in **Settings → Developers**.

| Topic | Detail |
| --- | --- |
| Endpoints | [`POST /api/v1/webhook-endpoints`](#create-webhook-endpoint), [`GET /api/v1/webhook-endpoints`](#list-webhook-endpoints), [`GET /api/v1/webhook-endpoints/{id}`](#get-webhook-endpoint), [`PATCH /api/v1/webhook-endpoints/{id}`](#update-webhook-endpoint), [`DELETE /api/v1/webhook-endpoints/{id}`](#delete-webhook-endpoint) |
| Key permissions | `webhook_endpoints:write`, `webhook_endpoints:read` |
| Samples | curl; Node.js 18+ with the built-in `fetch` (in an ES module); the [Node SDK](https://anytime-capital.com/docs/node-sdk.md) (preview: not on npm yet); Python with `requests`. |
| Every request can also answer | 401 `UNAUTHORIZED`, 401 `API_KEY_EXPIRED`, 403 `NOT_ENROLLED`, 403 `PERMISSION_DENIED`, 403 `IP_NOT_ALLOWED`, 429 `RATE_LIMITED`, 500 `INTERNAL_ERROR`. See [Error codes](https://anytime-capital.com/docs/error-codes.md). |

> **Store the secret when you create it:** The signing secret (`whsec_…`) is in the create response only: read it from `secret`, keep it in a server-side secret store, and use it to [verify every event](https://anytime-capital.com/docs/webhook-signatures.md). A retry of the create with the same Idempotency-Key returns the endpoint again with its secret.

## The webhook endpoint object

```json
{
  "object": "webhook_endpoint",
  "livemode": true,
  "id": "we_Rt2Vb7Nc4Zp9WkLm3Qx8",
  "url": "https://example.com/webhooks/anytime",
  "events": [
    "payment.succeeded",
    "refund.created"
  ],
  "description": "Order fulfilment",
  "enabled": true,
  "createdAt": "2026-10-24T10:00:00.000Z"
}
```

| Field | Type | Description |
| --- | --- | --- |
| `object` | string | The type of object. Always `webhook_endpoint`. |
| `livemode` | boolean | False for test-mode data (an `ak_test_` key); true for live data. |
| `id` | string | `we_` followed by 20 letters and digits. |
| `url` | string (uri) | Where events are sent. |
| `events` | string[] | Event types, or ["*"] for every event. |
| `description` | string or null | Your note. |
| `enabled` | boolean | Receiving events. |
| `createdAt` | string (date-time) | Created. |

## Endpoints

### Create a webhook endpoint

`POST /api/v1/webhook-endpoints`

Permission: `webhook_endpoints:write`. Supports `Idempotency-Key`.

Subscribe a URL to events (REST hooks subscribe here). The signing secret is in this response only. Store `secret` now: it's in this response only. A retry with the same Idempotency-Key returns the endpoint with its current secret.

**Headers**

| Header | Type | Required | Description |
| --- | --- | --- | --- |
| `Idempotency-Key` | string | no | Recommended. A unique key such as a UUID: a retry with the same key within 24 hours gets the first response back instead of acting twice. See [Idempotency](https://anytime-capital.com/docs/idempotency.md). |

**Body**

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `url` | string (uri) | yes | An https:// URL on a public domain name (no IP addresses or localhost). Up to 500 characters. |
| `events` | string[] | yes | Event types to receive, or ["*"] for every event including ones added later. 1–26 items. |
| `description` | string or null | no | Your note. Up to 200 characters. |

**Request (curl)**

```bash
curl -X POST https://anytime-capital.com/api/v1/webhook-endpoints \
  -H "Authorization: Bearer $ANYTIME_API_KEY" \
  -H "Idempotency-Key: endpoint-orders" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://example.com/webhooks/anytime",
    "events": [
      "payment.succeeded",
      "refund.created"
    ],
    "description": "Order fulfilment"
  }'
```

**Request (Node.js)**

```javascript
const res = await fetch("https://anytime-capital.com/api/v1/webhook-endpoints", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.ANYTIME_API_KEY}`,
    "Content-Type": "application/json",
    "Idempotency-Key": "endpoint-orders",
  },
  body: JSON.stringify({
    url: "https://example.com/webhooks/anytime",
    events: ["payment.succeeded", "refund.created"],
    description: "Order fulfilment",
  }),
});
const endpoint = await res.json();
if (!res.ok) throw new Error(`${endpoint.error.code}: ${endpoint.error.message}`);
```

**Request (Node SDK)**

```typescript
import { AnytimeCapital } from "@anytimecapital/node";

const client = new AnytimeCapital({ apiKey: process.env.ANYTIME_API_KEY! });

const endpoint = await client.webhookEndpoints.create(
  {
    url: "https://example.com/webhooks/anytime",
    events: ["payment.succeeded", "refund.created"],
    description: "Order fulfilment",
  },
  { idempotencyKey: "endpoint-orders" },
);
```

**Request (Python)**

```python
import os

import requests

res = requests.post(
    "https://anytime-capital.com/api/v1/webhook-endpoints",
    headers={
        "Authorization": f"Bearer {os.environ['ANYTIME_API_KEY']}",
        "Idempotency-Key": "endpoint-orders",
    },
    json={
        "url": "https://example.com/webhooks/anytime",
        "events": ["payment.succeeded", "refund.created"],
        "description": "Order fulfilment",
    },
    timeout=30,
)
endpoint = res.json()
if not res.ok:
    raise RuntimeError(f"{endpoint['error']['code']}: {endpoint['error']['message']}")
```

**Response** (201)

```json
{
  "object": "webhook_endpoint",
  "livemode": true,
  "id": "we_Rt2Vb7Nc4Zp9WkLm3Qx8",
  "url": "https://example.com/webhooks/anytime",
  "events": [
    "payment.succeeded",
    "refund.created"
  ],
  "description": "Order fulfilment",
  "enabled": true,
  "createdAt": "2026-10-24T10:00:00.000Z",
  "secret": "whsec_…"
}
```

**Errors**

| Status | Code | When |
| --- | --- | --- |
| 400 | `INVALID_JSON` | The body isn't valid JSON, or couldn't be read. An empty body reads as `{}`. Send `Content-Type: application/json` and a JSON object. |
| 400 | `INVALID_INPUT` | A field, filter, `limit` or `cursor` is missing or invalid. The message starts with the field's name, as in `amountCents: …`, or reads `Invalid cursor.` Fix the named field. Don't retry the same request unchanged. |
| 400 | `INVALID_IDEMPOTENCY_KEY` | The `Idempotency-Key` header is empty, longer than 255 characters, or has characters other than printable ASCII. Use a UUID. See [Idempotency](https://anytime-capital.com/docs/idempotency.md). |
| 409 | `LIMIT_REACHED` | The business already has 10 webhook endpoints. Delete one you no longer use with `DELETE /api/v1/webhook-endpoints/{id}`. |
| 422 | `IDEMPOTENCY_KEY_REUSED` | The `Idempotency-Key` was used in the last 24 hours with a different body or endpoint. Use a new key for a new request; reuse a key only to retry the same request. |
| 503 | `NOT_CONFIGURED` | The part of Anytime Capital Payments this needs isn't available right now. Retry later, with the same `Idempotency-Key` on a write. |

### List webhook endpoints

`GET /api/v1/webhook-endpoints`

Permission: `webhook_endpoints:read`.

Every endpoint (at most 10), oldest first, in one page.

**Request (curl)**

```bash
curl https://anytime-capital.com/api/v1/webhook-endpoints \
  -H "Authorization: Bearer $ANYTIME_API_KEY"
```

**Request (Node.js)**

```javascript
const res = await fetch("https://anytime-capital.com/api/v1/webhook-endpoints", {
  headers: { Authorization: `Bearer ${process.env.ANYTIME_API_KEY}` },
});
const page = await res.json();
if (!res.ok) throw new Error(`${page.error.code}: ${page.error.message}`);
```

**Request (Node SDK)**

```typescript
import { AnytimeCapital } from "@anytimecapital/node";

const client = new AnytimeCapital({ apiKey: process.env.ANYTIME_API_KEY! });

const page = await client.webhookEndpoints.list();
```

**Request (Python)**

```python
import os

import requests

res = requests.get(
    "https://anytime-capital.com/api/v1/webhook-endpoints",
    headers={"Authorization": f"Bearer {os.environ['ANYTIME_API_KEY']}"},
    timeout=30,
)
page = res.json()
if not res.ok:
    raise RuntimeError(f"{page['error']['code']}: {page['error']['message']}")
```

**Response** (200)

```json
{
  "object": "list",
  "data": [
    {
      "object": "webhook_endpoint",
      "livemode": true,
      "id": "we_Rt2Vb7Nc4Zp9WkLm3Qx8",
      "url": "https://example.com/webhooks/anytime",
      "events": [
        "payment.succeeded",
        "refund.created"
      ],
      "description": "Order fulfilment",
      "enabled": true,
      "createdAt": "2026-10-24T10:00:00.000Z"
    }
  ],
  "hasMore": false,
  "nextCursor": null
}
```

### Get a webhook endpoint

`GET /api/v1/webhook-endpoints/{id}`

Permission: `webhook_endpoints:read`.

One endpoint (never its secret).

**Path**

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | string | yes | `we_…` |

**Request (curl)**

```bash
curl https://anytime-capital.com/api/v1/webhook-endpoints/we_Rt2Vb7Nc4Zp9WkLm3Qx8 \
  -H "Authorization: Bearer $ANYTIME_API_KEY"
```

**Request (Node.js)**

```javascript
const res = await fetch("https://anytime-capital.com/api/v1/webhook-endpoints/we_Rt2Vb7Nc4Zp9WkLm3Qx8", {
  headers: { Authorization: `Bearer ${process.env.ANYTIME_API_KEY}` },
});
const endpoint = await res.json();
if (!res.ok) throw new Error(`${endpoint.error.code}: ${endpoint.error.message}`);
```

**Request (Node SDK)**

```typescript
import { AnytimeCapital } from "@anytimecapital/node";

const client = new AnytimeCapital({ apiKey: process.env.ANYTIME_API_KEY! });

const endpoint = await client.webhookEndpoints.retrieve("we_Rt2Vb7Nc4Zp9WkLm3Qx8");
```

**Request (Python)**

```python
import os

import requests

res = requests.get(
    "https://anytime-capital.com/api/v1/webhook-endpoints/we_Rt2Vb7Nc4Zp9WkLm3Qx8",
    headers={"Authorization": f"Bearer {os.environ['ANYTIME_API_KEY']}"},
    timeout=30,
)
endpoint = res.json()
if not res.ok:
    raise RuntimeError(f"{endpoint['error']['code']}: {endpoint['error']['message']}")
```

**Response** (200)

```json
{
  "object": "webhook_endpoint",
  "livemode": true,
  "id": "we_Rt2Vb7Nc4Zp9WkLm3Qx8",
  "url": "https://example.com/webhooks/anytime",
  "events": [
    "payment.succeeded",
    "refund.created"
  ],
  "description": "Order fulfilment",
  "enabled": true,
  "createdAt": "2026-10-24T10:00:00.000Z"
}
```

**Errors**

| Status | Code | When |
| --- | --- | --- |
| 404 | `NOT_FOUND` | No such object on your business (an id from another business reads the same), or no such endpoint under `/api/v1`, which still answers in JSON. Check the id and the path. Ids are case-sensitive. |

### Update a webhook endpoint

`PATCH /api/v1/webhook-endpoints/{id}`

Permission: `webhook_endpoints:write`. Supports `Idempotency-Key`.

Change url, events or description, or switch it off and on.

**Path**

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | string | yes | `we_…` |

**Headers**

| Header | Type | Required | Description |
| --- | --- | --- | --- |
| `Idempotency-Key` | string | no | Recommended. A unique key such as a UUID: a retry with the same key within 24 hours gets the first response back instead of acting twice. See [Idempotency](https://anytime-capital.com/docs/idempotency.md). |

**Body**

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `url` | string (uri) | no | An https:// URL on a public domain name (no IP addresses or localhost). Up to 500 characters. |
| `events` | string[] | no | Event types to receive, or ["*"] for every event including ones added later. 1–26 items. |
| `description` | string or null | no | Your note; null clears it. Up to 200 characters. |
| `enabled` | boolean | no | false switches it off (events waiting are dropped); true back on (new events only). |

**Request (curl)**

```bash
curl -X PATCH https://anytime-capital.com/api/v1/webhook-endpoints/we_Rt2Vb7Nc4Zp9WkLm3Qx8 \
  -H "Authorization: Bearer $ANYTIME_API_KEY" \
  -H "Idempotency-Key: endpoint-orders-all-events" \
  -H "Content-Type: application/json" \
  -d '{
    "events": [
      "*"
    ]
  }'
```

**Request (Node.js)**

```javascript
const res = await fetch("https://anytime-capital.com/api/v1/webhook-endpoints/we_Rt2Vb7Nc4Zp9WkLm3Qx8", {
  method: "PATCH",
  headers: {
    Authorization: `Bearer ${process.env.ANYTIME_API_KEY}`,
    "Content-Type": "application/json",
    "Idempotency-Key": "endpoint-orders-all-events",
  },
  body: JSON.stringify({ events: ["*"] }),
});
const endpoint = await res.json();
if (!res.ok) throw new Error(`${endpoint.error.code}: ${endpoint.error.message}`);
```

**Request (Node SDK)**

```typescript
import { AnytimeCapital } from "@anytimecapital/node";

const client = new AnytimeCapital({ apiKey: process.env.ANYTIME_API_KEY! });

const endpoint = await client.webhookEndpoints.update(
  "we_Rt2Vb7Nc4Zp9WkLm3Qx8",
  { events: ["*"] },
  { idempotencyKey: "endpoint-orders-all-events" },
);
```

**Request (Python)**

```python
import os

import requests

res = requests.patch(
    "https://anytime-capital.com/api/v1/webhook-endpoints/we_Rt2Vb7Nc4Zp9WkLm3Qx8",
    headers={
        "Authorization": f"Bearer {os.environ['ANYTIME_API_KEY']}",
        "Idempotency-Key": "endpoint-orders-all-events",
    },
    json={"events": ["*"]},
    timeout=30,
)
endpoint = res.json()
if not res.ok:
    raise RuntimeError(f"{endpoint['error']['code']}: {endpoint['error']['message']}")
```

**Response** (200)

```json
{
  "object": "webhook_endpoint",
  "livemode": true,
  "id": "we_Rt2Vb7Nc4Zp9WkLm3Qx8",
  "url": "https://example.com/webhooks/anytime",
  "events": [
    "*"
  ],
  "description": "Order fulfilment",
  "enabled": true,
  "createdAt": "2026-10-24T10:00:00.000Z"
}
```

**Errors**

| Status | Code | When |
| --- | --- | --- |
| 400 | `INVALID_JSON` | The body isn't valid JSON, or couldn't be read. An empty body reads as `{}`. Send `Content-Type: application/json` and a JSON object. |
| 400 | `INVALID_INPUT` | A field, filter, `limit` or `cursor` is missing or invalid. The message starts with the field's name, as in `amountCents: …`, or reads `Invalid cursor.` Fix the named field. Don't retry the same request unchanged. |
| 400 | `INVALID_IDEMPOTENCY_KEY` | The `Idempotency-Key` header is empty, longer than 255 characters, or has characters other than printable ASCII. Use a UUID. See [Idempotency](https://anytime-capital.com/docs/idempotency.md). |
| 404 | `NOT_FOUND` | No such object on your business (an id from another business reads the same), or no such endpoint under `/api/v1`, which still answers in JSON. Check the id and the path. Ids are case-sensitive. |
| 422 | `IDEMPOTENCY_KEY_REUSED` | The `Idempotency-Key` was used in the last 24 hours with a different body or endpoint. Use a new key for a new request; reuse a key only to retry the same request. |

### Delete a webhook endpoint

`DELETE /api/v1/webhook-endpoints/{id}`

Permission: `webhook_endpoints:write`. Supports `Idempotency-Key`.

Remove it and its delivery log (REST hooks unsubscribe here). Events stop at once. Without an Idempotency-Key, deleting it again answers `404`.

**Path**

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | string | yes | `we_…` |

**Headers**

| Header | Type | Required | Description |
| --- | --- | --- | --- |
| `Idempotency-Key` | string | no | Recommended. A unique key such as a UUID: a retry with the same key within 24 hours gets the first response back instead of acting twice. See [Idempotency](https://anytime-capital.com/docs/idempotency.md). |

**Request (curl)**

```bash
curl -X DELETE https://anytime-capital.com/api/v1/webhook-endpoints/we_Rt2Vb7Nc4Zp9WkLm3Qx8 \
  -H "Authorization: Bearer $ANYTIME_API_KEY" \
  -H "Idempotency-Key: endpoint-orders-delete"
```

**Request (Node.js)**

```javascript
const res = await fetch("https://anytime-capital.com/api/v1/webhook-endpoints/we_Rt2Vb7Nc4Zp9WkLm3Qx8", {
  method: "DELETE",
  headers: {
    Authorization: `Bearer ${process.env.ANYTIME_API_KEY}`,
    "Idempotency-Key": "endpoint-orders-delete",
  },
});
const deleted = await res.json();
if (!res.ok) throw new Error(`${deleted.error.code}: ${deleted.error.message}`);
```

**Request (Node SDK)**

```typescript
import { AnytimeCapital } from "@anytimecapital/node";

const client = new AnytimeCapital({ apiKey: process.env.ANYTIME_API_KEY! });

const deleted = await client.webhookEndpoints.del(
  "we_Rt2Vb7Nc4Zp9WkLm3Qx8",
  { idempotencyKey: "endpoint-orders-delete" },
);
```

**Request (Python)**

```python
import os

import requests

res = requests.delete(
    "https://anytime-capital.com/api/v1/webhook-endpoints/we_Rt2Vb7Nc4Zp9WkLm3Qx8",
    headers={
        "Authorization": f"Bearer {os.environ['ANYTIME_API_KEY']}",
        "Idempotency-Key": "endpoint-orders-delete",
    },
    timeout=30,
)
deleted = res.json()
if not res.ok:
    raise RuntimeError(f"{deleted['error']['code']}: {deleted['error']['message']}")
```

**Response** (200)

```json
{
  "object": "webhook_endpoint",
  "id": "we_Rt2Vb7Nc4Zp9WkLm3Qx8",
  "deleted": true
}
```

**Errors**

| Status | Code | When |
| --- | --- | --- |
| 400 | `INVALID_IDEMPOTENCY_KEY` | The `Idempotency-Key` header is empty, longer than 255 characters, or has characters other than printable ASCII. Use a UUID. See [Idempotency](https://anytime-capital.com/docs/idempotency.md). |
| 404 | `NOT_FOUND` | No such object on your business (an id from another business reads the same), or no such endpoint under `/api/v1`, which still answers in JSON. Check the id and the path. Ids are case-sensitive. |
| 422 | `IDEMPOTENCY_KEY_REUSED` | The `Idempotency-Key` was used in the last 24 hours with a different body or endpoint. Use a new key for a new request; reuse a key only to retry the same request. |

---

Anytime Capital is a fintech company, not a bank. Payment processing, banking and payout services are provided by Anytime Capital's licensed partners. Rates shown are for US card payments; international cards, currency conversion and disputes may carry additional fees shown in your dashboard before you accept a payment.
