Orbit

Orbit Webhooks

Webhooks push a signed HTTP POST to a URL of your choosing every time a deployment changes state, so your team hears about a failed build in the channel they already watch instead of finding out from a customer.

Where Webhooks Live

Open Orbit, click the project, and choose Webhooks under the Configure group in the project tab strip. The page is titled Webhooks and describes itself as receiving HTTP POST notifications when deployments change state, with Slack, Discord and generic JSON supported.

Webhooks and Hooks are different things and sit next to each other in the same menu. Webhooks are outgoing: Orbit tells you something happened. Deploy hooks are incoming: something tells Orbit to deploy. For those, see Triggering Deployments Via Deploy Hooks.

Webhooks page for an Orbit project

Adding a Webhook

  1. In the Add a webhook card, give it a Label. Something like the destination it posts to.
  2. Paste the URL. It must start with https://.
  3. Under Trigger on, tick the events you want.
  4. Click Add webhook.

The signing secret is shown once, immediately after creation, with a warning that it will not be shown again. Copy it before you navigate away.

A project can hold up to ten webhooks. Adding an eleventh is refused with a message naming the limit.

The Five Events

EventFires when
QueuedThe deployment enters the queue
BuildingThe build starts
SucceededThe deployment is live
FailedThe build or deploy errored
CancelledThe deployment was stopped before finishing

Pick deliberately. Subscribing to all five on a busy project turns a useful alert channel into noise that everyone mutes. For most teams, Failed alone is the right starting point, with Succeeded added only where a deploy notification is genuinely useful, such as a production channel.

Slack and Discord

If the URL is a Slack incoming webhook or a Discord webhook, Orbit detects it from the URL and sends a formatted message rather than raw JSON. The page says so under the URL field: Slack and Discord URLs are auto-detected.

The formatted message carries the project name, the event, the branch, the short commit, the build time, the deployed URL, and the error text when something failed. Colour follows the event, so a red card in the channel means a failure without anyone reading it.

Nothing else is needed. Create the incoming webhook in Slack or Discord, paste the URL here, choose your events, and you are finished.

Generic JSON Payloads

Any other URL receives a JSON body. The fields are:

FieldContents
eventOne of the five event names, prefixed deployment.
projectId, projectName, projectSlugWhich project
deploymentIdThe deployment this is about
gitCommit, gitBranch, gitCommitMessageThe code being deployed
buildDurationMsBuild time, where known
deployedUrlWhere it went live
panelUrlA link back into KPanel
errorMessagePresent on failures
triggeredAtISO 8601 timestamp
deliveryIdUnique per delivery, for deduplication

Use deliveryId to make your endpoint idempotent. If you retry a delivery, or a network hiccup causes a duplicate, the id lets you recognise that you have already handled it.

Verifying the Signature

Every delivery carries three headers:

  • X-Orbit-Signature-256, an HMAC-SHA256 of the exact request body using your signing secret, formatted as sha256= followed by the hex digest.
  • X-Orbit-Event, the event name.
  • X-Orbit-Delivery, the delivery id.

Verify the signature before you act on a payload. Compute the same HMAC over the raw body bytes, and compare using a constant-time comparison rather than string equality.

const expected = 'sha256=' + crypto
  .createHmac('sha256', process.env.ORBIT_WEBHOOK_SECRET)
  .update(rawBody)
  .digest('hex');

if (!crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(received))) {
  return res.status(401).end();
}

Compute the HMAC over the raw request body, before any JSON parsing and re-serialising. A body that has been parsed and stringified again is usually byte-different, and the signature will never match no matter how correct your code looks.

Testing a Webhook

Each webhook row has Send test delivery. It fires a real delivery to your endpoint immediately and reports the HTTP code it got back, or the failure detail.

Use it right after adding a webhook, before you rely on it. A firewall rule or a route that only accepts GET is much easier to find now than during an incident.

Delivery History

Each row carries a sparkbar of the last seven days with the delivery count, success percentage and average duration, plus the last fired time and its result.

Expand Show delivery history for the individual deliveries: the event, the response code, the duration, and the error text where there was one. Any delivery can be re-sent with Retry delivery, which reports the code it got back.

Deliveries time out after twelve seconds. If your endpoint does slow work, acknowledge with a 200 first and process afterwards, rather than holding the connection open.

Rotating the Secret

Click Rotate secret. The new secret is displayed once, and the tooltip is explicit that the old secret becomes invalid immediately.

That means a short window where deliveries are signed with a secret your endpoint does not know. Plan for it: rotate at a quiet moment, and update your endpoint as the very next action.

Rotate when someone with access to the secret leaves, or if it has ever been pasted into a shared channel or a ticket.

Disabling and Deleting

Disable webhook stops deliveries but keeps the configuration and the history, and the row shows a Disabled badge. That is the right choice when you are pausing alerts, for example during a planned migration that will produce a lot of noise.

Delete webhook removes it entirely. Use disable unless you are certain.

Other Ways To Be Notified

Webhooks are the flexible option. Two lighter alternatives sit in Settings:

  • Deploy email notifications, with three settings: all deploys, failures only, or off.
  • Notification channels, which post to a webhook URL on deploy success or failure, build regressions and bundle regressions, with their own delivery history and test button.

See Orbit Project Settings for both.

Troubleshooting

Deliveries show as failed with an HTTP code. Your endpoint returned an error. The code tells you which: 404 means the path is wrong, 401 or 403 usually means your own signature check is rejecting it, and 500 means your handler threw.

Deliveries fail with a timeout. Your endpoint took longer than twelve seconds. Return 200 immediately and do the work asynchronously.

Nothing is delivered at all. Check the webhook is enabled and that the event you expected is ticked. A build that never queued does not fire a queued event.

The signature never validates. Almost always the raw-body problem described above. Log the exact bytes you are hashing and compare their length with the Content-Length header.

A Slack URL is being sent raw JSON. Slack incoming webhooks live under hooks.slack.com. A different Slack URL will not be detected as one.

Where To Go Next

Still need help?

Email us at support@kapsulehost.com or open a chat in KPanel.

Open KPanel
Orbit Webhooks