Skip to content

Webhooks

Send another app's webhooks to a webhook URL that Albastar Corp. sets up, and read each delivery's outcome.

Access: Webhook URLs set up and issued by Albastar Corp.

A webhook URL turns HTTP requests from another app (a CI, a monitor, a shop) into events of one source, without a publish key. Albastar Corp. sets up the webhook on a source, with the rules that turn each request into events, and hands over the URL.

Send a delivery

The webhook URL is https://api.albastov.com/v1/events/hooks/in/{token}, with a 43-character token. Paste the URL into the sending app's webhook settings. A delivery from curl takes the same path as a delivery from the sending app.

Shell
curl https://api.albastov.com/v1/events/hooks/in/$ALBASTAR_WEBHOOK_TOKEN \
  -H "Content-Type: application/json" \
  -d '{
    "project": "web",
    "deployment": {"id": "dpl_4812", "state": "ERROR", "commit": "9f3c2e1"}
  }'
Response
{
  "ok": true,
  "outcome": "evt_01M6GEVFQHS6V8X2Z4B7D9G1J5",
  "events": ["evt_01M6GEVFQHS6V8X2Z4B7D9G1J5"]
}

The body is JSON, a form (application/x-www-form-urlencoded) or any text, at most 2 MB. An empty body reads the URL's query string as a form. An accepted delivery is answered 200 with ok, the delivery's outcome and the ids of the events the delivery stored.

New webhooks

A new webhook starts pending: the API keeps each delivery, answers held: pending review with "events": [], and publishes nothing until Albastar Corp. activates the webhook. Send one test delivery from the app after pasting the URL; the kept delivery shows Albastar Corp. what the app sends.

Response from a pending webhook
{
  "ok": true,
  "outcome": "held: pending review",
  "events": []
}

Outcomes

outcomeMeaning
evt_…One event, stored; for a repeated idempotency key, the event stored the first time
heldOne event, held: at most 5 events of one webhook source a minute reach readers one by one, and the rest arrive after the minute as one summary event
held: pending reviewNo event: the webhook is pending; the delivery is kept
dropped: <reason>No event: one of the webhook's rules dropped the item (rule 1, case 3, or the rule's own reason)
dropped: duplicate of delivery <id>No event: the same body arrived within the last 10 minutes
dropped: split: 0 itemsNo event: the request held an empty list of items
dropped: invalid: <message>No event: the event the request made fails field validation
dropped: rate limitedNo event: the source is over its rate
error: <message>No event: storing the event failed
2 events: evt_a,held,dropped: rule 1A request that holds several items: one entry per item, in order; the count includes stored and held items only
…; url dropped: host <host> not allowedThe event's url pointed outside the hosts allowed for the webhook and was removed
…; 12 items over 1000 droppedThe request held more than 1,000 items; items past 1,000 make no event
…; mapping error: <message>The webhook's rules failed on this request; the delivery made one plain event of type webhook instead

Duplicates

A sender may deliver one request twice: a retry after a timeout, or a manual resend. The API dedupes on the first key available:

KeyDedupe
An idempotency key the webhook's rules read from the requestAn event with a key stored in the last 7 days returns the stored event
The first of the headers X-GitHub-Delivery, Idempotency-Key, Webhook-Id, X-Webhook-Id, X-Delivery-IdAs the idempotency key
SHA-256 of the body as receiveddropped: duplicate of delivery <id> when the source had a delivery with the same body in the last 10 minutes

The 10 minutes count from the original delivery, not from its duplicates: a body resent every 5 minutes makes one event every 10 minutes. Set one of the delivery headers above, the same on every retry, to dedupe retries of one delivery.

Signatures

Albastar Corp. may set a signature on the webhook: the sending app signs each request body with a secret shared with Albastar Corp., and the API recomputes the signature. A required signature refuses every delivery without a valid one with 401 bad_signature; an optional signature checks only deliveries that carry the header.

SchemeThe sending app sends
hmac-sha256, hmac-sha1The HMAC of the raw body under the secret, in the agreed encoding (hex in any case, or base64), in the agreed header (default X-Signature), after the agreed prefix (for example sha256=)
stripeStripe-Signature: t=…,v1=…: HMAC-SHA256 of t.body; any v1 may match; t within 5 minutes of the API's clock

GitHub's webhook secret, for example, uses scheme hmac-sha256, header X-Hub-Signature-256 and prefix sha256=.

Limits and errors

LimitValue
Body2 MB
Deliveries per source120 a minute, bursts of 30; then 429 rate_limited with Retry-After
Refused requests per client address30, refilling 1 every 2 seconds, across all webhook URLs; past the allowance, every webhook URL answers the address 429 rate_limited

Only refused requests (401, 404) count toward the client address allowance; accepted deliveries never count.

StatusCodeMeaning
400bad_deliveryThe webhook refused the body as malformed
401bad_signatureMissing or invalid signature where one is required or sent
404hook_not_foundUnknown token, a webhook turned off, or an archived source
413body_too_largeBody over 2 MB
429rate_limitedOver a limit above; wait Retry-After seconds
503seal_key_missingWebhook signatures cannot be checked right now; retry later

Token

The token is the webhook's credential: keep the URL out of public repositories and logs. After a leak, ask Albastar Corp. to rotate the token; the old URL then returns 404 hook_not_found at once.

Reference