OdyDocs

Webhook endpoints

Register HTTPS endpoints for event notifications, rotate signing secrets, send test pings and inspect delivery history.

A webhook endpoint is an HTTPS URL Ody POSTs signed events to. This page covers managing endpoints. For what gets delivered and how to verify it, see Webhooks, Event types and Verifying signatures.

Endpoints are managed only through this API. There's no webhook screen in the app and no MCP tool for it yet.

#The webhook endpoint object

  • id uuid
  • url string — HTTPS only.
  • events array of strings — Subscribed event types, or ["*"] for every current and future type.
  • label string | null — Your own name for it.
  • status "enabled" | "disabled"
  • apiVersion string | null — The payload version pinned when the endpoint was created.
  • createdAt timestamp
  • secret string — whsec_… signing secret. Returned only by create and rotate. Store it right away.

A workspace can have up to 50 endpoints.

#List event types

GET/v1/api/webhook-events

Returns the catalog of event types you can subscribe to.

Scope: webhooks:manage

Returns { events: string[] }.

curl https://api.ody.co/v1/api/webhook-events \
  -H "Authorization: Bearer $ODY_API_KEY"

#List endpoints

GET/v1/api/webhooks

Secrets are never included.

Scope: webhooks:manage

Returns { webhooks: WebhookEndpoint[] }.

curl https://api.ody.co/v1/api/webhooks \
  -H "Authorization: Bearer $ODY_API_KEY"

#Create an endpoint

POST/v1/api/webhooks

Scope: webhooks:manage

Body

  • url string required — Public HTTPS URL.
  • events array of strings required — Event types, or ["*"].
  • label string

Returns 201 with { webhook }, including secret. Returns 400 for a non-HTTPS URL, an unknown event type, or when you'd exceed 50 endpoints.

curl https://api.ody.co/v1/api/webhooks \
  -H "Authorization: Bearer $ODY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://example.com/ody/webhooks",
    "events": ["message.received", "call.completed", "call.summary.completed"],
    "label": "Production CRM sync"
  }'
Response
{
  "webhook": {
    "id": "3a8f…",
    "url": "https://example.com/ody/webhooks",
    "events": ["message.received", "call.completed", "call.summary.completed"],
    "label": "Production CRM sync",
    "status": "enabled",
    "apiVersion": "2026-06-01",
    "createdAt": "2026-10-14T18:20:00.000Z",
    "secret": "whsec_MfKQ9r8GKYqrTwjUPD8ILPZIo2LaLaSw"
  }
}

#Retrieve an endpoint

GET/v1/api/webhooks/:id

Scope: webhooks:manage

Returns { webhook } (without the secret).

curl https://api.ody.co/v1/api/webhooks/3a8f… \
  -H "Authorization: Bearer $ODY_API_KEY"

#Update an endpoint

PATCH/v1/api/webhooks/:id

Change the URL, subscriptions or label, or pause deliveries with status: "disabled".

Scope: webhooks:manage

Body: any of url, events, label (null clears it), status.

Returns { webhook }.

curl -X PATCH https://api.ody.co/v1/api/webhooks/3a8f… \
  -H "Authorization: Bearer $ODY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"status":"disabled"}'

#Delete an endpoint

DELETE/v1/api/webhooks/:id

Scope: webhooks:manage

Returns { "deleted": true }.

curl -X DELETE https://api.ody.co/v1/api/webhooks/3a8f… \
  -H "Authorization: Bearer $ODY_API_KEY"

#Rotate the signing secret

POST/v1/api/webhooks/:id/rotate

Issues a new whsec_ secret and returns it once. Signatures made with the old secret stop validating immediately. Deploy the new secret to your verifier first, or accept both secrets briefly (see Verifying signatures).

Scope: webhooks:manage

Returns { webhook }, including the new secret.

curl -X POST https://api.ody.co/v1/api/webhooks/3a8f…/rotate \
  -H "Authorization: Bearer $ODY_API_KEY"

#Send a test delivery

POST/v1/api/webhooks/:id/test

POSTs a ping event to the endpoint, signed exactly like a real delivery, and returns the result straight away. This is the fastest way to check your signature verification.

Scope: webhooks:manage

Returns { delivered: boolean, attempt: { at, statusCode, error?, durationMs } }. delivered is true for any 2xx response.

curl -X POST https://api.ody.co/v1/api/webhooks/3a8f…/test \
  -H "Authorization: Bearer $ODY_API_KEY"
Response
{
  "delivered": true,
  "attempt": { "at": "2026-10-14T18:21:03.114Z", "statusCode": 200, "durationMs": 143 }
}

#List deliveries

GET/v1/api/webhooks/:id/deliveries

Recent deliveries, newest first, with every attempt's status code or error. This is your debugging view.

Scope: webhooks:manage

Query parameters

  • limit integer — 1–200, default 50.

Returns { deliveries: [{ id, webhookId, eventId, status, attempts, createdAt }] }. status is pending, success or failed.

curl "https://api.ody.co/v1/api/webhooks/3a8f…/deliveries?limit=20" \
  -H "Authorization: Bearer $ODY_API_KEY"
Last updated Wed Oct 14 2026 00:00:00 GMT+0000 (Coordinated Universal Time)Something wrong on this page? Tell us