Where we send your events, 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`, `GET /api/v1/webhook-endpoints`, `GET /api/v1/webhook-endpoints/{id}`, `PATCH /api/v1/webhook-endpoints/{id}`, `DELETE /api/v1/webhook-endpoints/{id}` |
| 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 (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. |
The webhook endpoint object
{
"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
/api/v1/webhook-endpointswebhook_endpoints:writeSupports 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
Idempotency-Keystring- 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.
Body
urlstring (uri)required- An https:// URL on a public domain name (no IP addresses or localhost). Up to 500 characters.
eventsstring[]required- Event types to receive, or ["*"] for every event including ones added later. 1–26 items.
descriptionstring or null- Your note. Up to 200 characters.
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"
}'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}`);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" },
);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']}"){
"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
- 400
INVALID_JSON - The body isn't valid JSON, or couldn't be read. An empty body reads as
{}. SendContent-Type: application/jsonand a JSON object. - 400
INVALID_INPUT - A field, filter,
limitorcursoris missing or invalid. The message starts with the field's name, as inamountCents: …, or readsInvalid cursor.Fix the named field. Don't retry the same request unchanged. - 400
INVALID_IDEMPOTENCY_KEY - The
Idempotency-Keyheader is empty, longer than 255 characters, or has characters other than printable ASCII. Use a UUID. See Idempotency. - 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-Keywas 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-Keyon a write.
List webhook endpoints
/api/v1/webhook-endpointswebhook_endpoints:readEvery endpoint (at most 10), oldest first, in one page.
curl https://anytime-capital.com/api/v1/webhook-endpoints \
-H "Authorization: Bearer $ANYTIME_API_KEY"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}`);import { AnytimeCapital } from "@anytimecapital/node";
const client = new AnytimeCapital({ apiKey: process.env.ANYTIME_API_KEY! });
const page = await client.webhookEndpoints.list();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']}"){
"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
/api/v1/webhook-endpoints/{id}webhook_endpoints:readOne endpoint (never its secret).
Path
idstringrequiredwe_…
curl https://anytime-capital.com/api/v1/webhook-endpoints/we_Rt2Vb7Nc4Zp9WkLm3Qx8 \
-H "Authorization: Bearer $ANYTIME_API_KEY"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}`);import { AnytimeCapital } from "@anytimecapital/node";
const client = new AnytimeCapital({ apiKey: process.env.ANYTIME_API_KEY! });
const endpoint = await client.webhookEndpoints.retrieve("we_Rt2Vb7Nc4Zp9WkLm3Qx8");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']}"){
"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
- 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
/api/v1/webhook-endpoints/{id}webhook_endpoints:writeSupports Idempotency-Key.Change url, events or description, or switch it off and on.
Path
idstringrequiredwe_…
Headers
Idempotency-Keystring- 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.
Body
urlstring (uri)- An https:// URL on a public domain name (no IP addresses or localhost). Up to 500 characters.
eventsstring[]- Event types to receive, or ["*"] for every event including ones added later. 1–26 items.
descriptionstring or null- Your note; null clears it. Up to 200 characters.
enabledboolean- false switches it off (events waiting are dropped); true back on (new events only).
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": [
"*"
]
}'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}`);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" },
);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']}"){
"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
- 400
INVALID_JSON - The body isn't valid JSON, or couldn't be read. An empty body reads as
{}. SendContent-Type: application/jsonand a JSON object. - 400
INVALID_INPUT - A field, filter,
limitorcursoris missing or invalid. The message starts with the field's name, as inamountCents: …, or readsInvalid cursor.Fix the named field. Don't retry the same request unchanged. - 400
INVALID_IDEMPOTENCY_KEY - The
Idempotency-Keyheader is empty, longer than 255 characters, or has characters other than printable ASCII. Use a UUID. See Idempotency. - 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-Keywas 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
/api/v1/webhook-endpoints/{id}webhook_endpoints:writeSupports 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
idstringrequiredwe_…
Headers
Idempotency-Keystring- 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.
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"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}`);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" },
);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']}"){
"object": "webhook_endpoint",
"id": "we_Rt2Vb7Nc4Zp9WkLm3Qx8",
"deleted": true
}Errors
- 400
INVALID_IDEMPOTENCY_KEY - The
Idempotency-Keyheader is empty, longer than 255 characters, or has characters other than printable ASCII. Use a UUID. See Idempotency. - 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-Keywas 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.