Octri

Webhooks

Webhooks tell another system when something happens in a project: a spec landed, a build failed, a docs release went out. Send them to Slack, Discord, or any HTTPS endpoint.

Find them in Project settings, under Webhooks.

Adding one

  1. Press New webhook

    Choose a destination: Slack, Discord or a generic HTTPS endpoint.

  2. Add a label and URL

    The URL must start with https://. The label is just for you.

  3. Pick the events

    Forward only what you need, or use Select all.

  4. Save the secret

    Octri shows a signing secret after you create the webhook. You use it to verify deliveries.

Press Send test to check it works, and Deliveries to see each attempt and whether it succeeded.

Events

EventFires when
spec.ingestedA spec has been imported
spec.validation_failedA spec could not be validated
spec.update_detectedSpec sync found a new version
doc.generatedEndpoint pages have been generated
doc.editedAn endpoint page was edited
changelog.generatedA new changelog was written
guide.createdA page was created
guide.updatedA page was updated
guide.deletedA page was deleted
guide.publishedA page was published
docs.release_publishedA docs release went live
deployment.failedA deployment failed
chat.session.createdA reader started an AI chat
ai.limit_reachedThe project hit its AI limit
sdk.build_completedAn SDK build finished
sdk.build_failedAn SDK build failed
sdk.publishedAn SDK was published
sdk.publish_failedAn SDK could not be published

What a generic webhook receives

A generic endpoint gets a JSON POST with these headers:

HeaderValue
User-Agentoctri-webhook/1
X-DocsPlatform-EventThe event name
X-DocsPlatform-SignatureThe signature, described below
X-DocsPlatform-DeliveryThe attempt number

Verifying a delivery

The signature is the hex HMAC-SHA256 of the raw request body, using your webhook's secret. Compute it yourself and compare in constant time before trusting the payload.

javascript
import { createHmac, timingSafeEqual } from "node:crypto";

function isFromOctri(rawBody, header, secret) {
  const expected = createHmac("sha256", secret).update(rawBody).digest("hex");
  return (
    header.length === expected.length &&
    timingSafeEqual(Buffer.from(header), Buffer.from(expected))
  );
}

Verify the raw bytes you received, before parsing them. Parsing and re-serializing the JSON can change the bytes and break the match.

Retries and failures

A failed delivery is tried up to four times in all, with a growing delay between attempts. Redirects are followed, up to three.

After ten failures in a row, Octri turns the webhook off and marks it Auto-disabled. Fix the endpoint, then turn it back on.

From the CLI

Webhooks can be created, tested and updated, and their deliveries read, with octri webhooks.