Skip to content

Search docs

Find pages, headings, and concepts. Press ⌘K or Ctrl+K to toggle.

Webhooks

Inbound webhook receivers, secret rotation, and delivery history.

Webhooks in Alumia are inbound receivers: each webhook resource owns a public URL that third-party systems can POST to. Alumia validates the signature, records the event, and routes it to org-level handlers. The same record also stores an optional outbound url so the platform can forward events to your service.

Endpoints

MethodPathDescription
GET/api/v1/webhooksList webhooks in the org.
POST/api/v1/webhooksCreate a webhook and receive its plaintext secret.
GET/api/v1/webhooks/:idFetch one webhook.
PATCH/api/v1/webhooks/:idUpdate name, URL, source, description, events, status.
DELETE/api/v1/webhooks/:idHard-delete a webhook.
POST/api/v1/webhooks/:id/rotateRotate the signing secret; returns the new plaintext once.
GET/api/v1/webhooks/:id/eventsList recorded events for one webhook.
GET/api/v1/webhooks/:id/deliveriesList outbound delivery attempts.
GET/api/v1/webhooks/eventsRecent events across all webhooks in the org.
POST/api/v1/webhooks/testSend a synthetic event for testing.
POST/api/v1/webhooks/verifyValidate a signed payload.
POST/api/v1/webhooks/receive/:webhookIdPublic receive endpoint (no auth header).
POST/api/v1/webhooks/linearBuilt-in Linear receiver.

List

GET /api/v1/webhooks returns webhook records ordered by createdAt desc. Each item:

{
  "id": "uuid",
  "name": "string",
  "url": "https://...",
  "source": "custom",
  "description": "string|null",
  "events": ["..."],
  "status": "active",
  "enabled": true,
  "deliveryCount": 0,
  "lastDeliveryAt": null,
  "createdAt": "...",
  "updatedAt": "...",
  "receiveUrl": "https://alumia.com/api/v1/webhooks/receive/<id>"
}

receiveUrl is computed from the request origin and is the URL third parties should POST to.

Create

POST /api/v1/webhooks

FieldTypeRequiredDescription
namestringyes1–120 chars.
urlstring | nullnoOutbound forwarding URL. Must be a public HTTP(S) URL; SSRF-protected. Defaults to receiveUrl if omitted.
eventsstring[]noEvent-type allowlist; normalized server-side.
sourcestringnoUp to 100 chars. Defaults to custom.
descriptionstringnoUp to 2,000 chars.

The response includes the plaintext secret once. Store it securely; the server only retains an encrypted copy and a hash.

bash
Sign in to fill in your org and key
curl -X POST https://alumia.com/api/v1/webhooks \
-H "Authorization: Bearer alm_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{ "name": "Stripe events", "events": ["payment_intent.succeeded"] }'

Update

PATCH /api/v1/webhooks/:id accepts any subset of name, url, source, description, events, enabled, status ("active" or "paused"/"disabled"). Setting url to null or "" resets it to the receive URL. Setting status keeps enabled in sync.

Delete

DELETE /api/v1/webhooks/:id performs a hard delete. Returns { "deleted": true }.

Rotate secret

POST /api/v1/webhooks/:id/rotate generates a new secret pair, persists the encrypted form and hash, and returns the new plaintext once. Old signatures stop verifying immediately.

Events and deliveries

  • GET /api/v1/webhooks/:id/events — Events recorded for this webhook.
  • GET /api/v1/webhooks/:id/deliveries — Outbound delivery attempts (status, retry count, response).
  • GET /api/v1/webhooks/events — Recent events across all webhooks in the org (up to 100), joined to webhook name.

Receiving and verification

POST /api/v1/webhooks/receive/:webhookId accepts the third-party payload, verifies the signature using the stored hash, and stores the event. This route does not require an Alumia API key — authentication is signature-based.

POST /api/v1/webhooks/verify lets you check a signed payload independently of the receive endpoint.

POST /api/v1/webhooks/test posts a synthetic event so you can wire end-to-end without involving the upstream provider.

Errors

CodeWhen
UNAUTHORIZEDMissing API key on management routes.
BAD_REQUESTMissing/oversized name, non-public url, invalid status.
NOT_FOUNDWebhook does not belong to the caller's org.