Endpoint management
Create, list, update, delete webhook endpoints. Rotate secrets without dropping deliveries.
Each organization can register multiple webhook endpoints. Each endpoint has its own URL, its own signing secret, and its own subscription set (which events it wants to receive). This page is the CRUD how-to.
Create an endpoint
POST /v1/webhook_endpoints HTTP/1.1
Authorization: Bearer sk_test_…
Idempotency-Key: <uuid>
Content-Type: application/json
{
"url": "https://your-app.example.com/blendfi-webhooks",
"event_types": [
"conversion.completed",
"conversion.completed",
"conversion.failed",
"user.kyc_approved"
],
"description": "production handler"
}curl -X POST $BLENDFI_BASE/v1/webhook_endpoints \
-H "Authorization: Bearer $BLENDFI_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-H "content-type: application/json" \
-d '{
"url": "https://your-app.example.com/blendfi-webhooks",
"event_types": ["conversion.completed", "conversion.completed"],
"description": "production handler"
}'import crypto from "node:crypto";
const res = await fetch(`${process.env.BLENDFI_BASE}/v1/webhook_endpoints`, {
method: "POST",
headers: {
"authorization": `Bearer ${process.env.BLENDFI_KEY}`,
"idempotency-key": crypto.randomUUID(),
"content-type": "application/json",
},
body: JSON.stringify({
url: "https://your-app.example.com/blendfi-webhooks",
event_types: ["conversion.completed", "conversion.completed"],
description: "production handler",
}),
});
const endpoint = await res.json();
console.log("secret (store securely):", endpoint.secret);import os, uuid, requests
res = requests.post(
f"{os.environ['BLENDFI_BASE']}/v1/webhook_endpoints",
headers={
"authorization": f"Bearer {os.environ['BLENDFI_KEY']}",
"idempotency-key": str(uuid.uuid4()),
"content-type": "application/json",
},
json={
"url": "https://your-app.example.com/blendfi-webhooks",
"event_types": ["conversion.completed", "conversion.completed"],
"description": "production handler",
},
)
endpoint = res.json()
print("secret (store securely):", endpoint["secret"])The response includes a secret, this is the only time the plaintext secret is returned. Store it in your secrets manager immediately. BlendFi keeps a hashed copy for signature verification but cannot return the plaintext again.
{
"id": "we_01J…",
"url": "https://your-app.example.com/blendfi-webhooks",
"event_types": ["conversion.completed", "conversion.completed"],
"secret": "whsec_…",
"status": "active",
"description": "production handler",
"created_at": "2026-05-04T13:00:00Z"
}List endpoints
curl $BLENDFI_BASE/v1/webhook_endpoints \
-H "Authorization: Bearer $BLENDFI_KEY"Returns paginated endpoints. The plaintext secret is not included on list/get responses.
Update an endpoint
PATCH is partial, send only the fields you want to change.
curl -X PATCH $BLENDFI_BASE/v1/webhook_endpoints/we_01J... \
-H "Authorization: Bearer $BLENDFI_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-H "content-type: application/json" \
-d '{
"event_types": ["conversion.completed", "conversion.completed", "conversion.failed"],
"status": "active"
}'Common patches:
- Update event subscriptions. Add or remove from the
event_typesarray. - Pause an endpoint. Set
status: "disabled"to stop deliveries without losing the endpoint config. Set back to"active"to resume. - Change URL. Use this when migrating between environments.
Delete an endpoint
curl -X DELETE $BLENDFI_BASE/v1/webhook_endpoints/we_01J... \
-H "Authorization: Bearer $BLENDFI_KEY" \
-H "Idempotency-Key: $(uuidgen)"Soft-delete; in-flight deliveries continue retrying until exhausted, but no new events are queued.
Rotate the signing secret
Rotation is the right response to: a compromised host, a developer leaving the team, a routine cadence (every 90 days, etc.), or anything that smells off.
curl -X POST $BLENDFI_BASE/v1/webhook_endpoints/we_01J.../rotate_secret \
-H "Authorization: Bearer $BLENDFI_KEY" \
-H "Idempotency-Key: $(uuidgen)"Response:
{
"id": "we_01J…",
"secret": "whsec_NEW…",
"rotated_at": "2026-05-04T14:00:00Z"
}Cutover plan
Rotation is an immediate cutover: the moment it completes, the old secret stops working and BlendFi signs every subsequent delivery, including retries of earlier events, with the new secret. Deploy the new secret to your verifier promptly. Because a delivery signed with the old secret may already be in flight to your endpoint at the instant you rotate, it is prudent to accept both the old and new secrets for a few seconds during the swap, then drop the old one. Each X-Blendfi-Signature header carries a single t=<unix>,v1=<hex> value, so "accepting both" means trying each secret against that one signature, not parsing multiple signatures from the header.
Errors specific to endpoint management
Full descriptions in the errors catalog:
| Code | Status | When |
|---|---|---|
invalid_webhook_url | 400 | URL not HTTPS, or otherwise malformed |
invalid_webhook_event_types | 400 | Empty array or contains an unknown event name |
max_webhook_endpoints_reached | 422 | Organization at the cap; delete an unused endpoint |
webhook_endpoint_not_found | 404 | ID doesn't exist or out of tenant scope |
invalid_webhook_endpoint_state | 422 | Operation not allowed in current endpoint state (e.g. patching a deleted endpoint) |
Read next
- Signature verification, how to verify deliveries on the receiving side
- Retries and replay, what happens when your endpoint isn't 2xx
- Reference → Webhooks, full schemas for every endpoint-management operation
