# Xbow Webhooks API

**Canonical:** https://apis.io/apis/xbow/xbow-webhooks-api/  
**Provider:** Xbow — https://apis.io/providers/xbow/  
**Base URL:** https://console.xbow.com/api/v1  
**Documentation:** https://docs.xbow.com/api/

Xbow Webhooks API is one of 9 APIs that [Xbow](https://apis.io/providers/xbow/) publishes on the [APIs.io](https://apis.io/) network, described by a machine-readable OpenAPI specification. Tagged areas include Webhook. The published artifact set on APIs.io includes an OpenAPI specification and API documentation.

Manage webhook subscriptions and receive event notifications. When creating an organization, you may provide an HTTPS webhook URL to receive events related to the organization's resources. We implement _best-effort_ delivery of events, soon after they occur. We will not retry delivery if it fails for any reason. ## Webhook Versioning Webhook payloads follow the API version of the subscription. When a version reaches its end-of-life date, webhook subscriptions for that version will stop emitting events. Ensure your integration is updated to a supported version before the EOL date. ## Signature Verification Each request will be a `POST` request sent with the following headers: * `X-Signature-Timestamp`: A Unix timestamp in seconds. * `X-Signature-Ed25519`: An hex string representing an Ed25519 signature of the concatenation of the timestamp and the request body, signed with XBOW's private key. You must verify the signature using the public key from the `GET /api/v1/meta/webhooks-signing-keys` endpoint. You must verify that the timestamp is within a valid range from the current time to prevent replay attacks. An example of a valid range might be +/-5 minutes. You should respond with a 2xx status code if the signature is valid, and a 401 status code otherwise. Before organization creation, we will send two test `ping` events. One signed with XBOW's private key, and one signed with an invalid key. This allows you to verify that your signature verification is working correctly. For example, if you're using Node.js: ```javascript import consumers from "node:stream/consumers"; // Fetch the public key from the API (cache this - it rarely changes) const keysResponse = await fetch("https://console.xbow.com/api/v1/meta/webhooks-signing-keys", { headers: { Authorization: "Bearer your-api-key", "X-XBOW-API-Version": "2026-02-01" } }); const keys = await keysResponse.json(); const publicKeyBase64 = keys[0].publicKey; // Import the public key (SPKI format, base64-encoded) const publicKey = await crypto.subtle.importKey( "spki", Buffer.from(publicKeyBase64, "base64"), { name: "Ed25519" }, false, ["verify"], ); const timestamp = req.headers["x-signature-timestamp"]; const timestampTime = parseInt(timestamp, 10); const now = Math.floor(Date.now() / 1000); const isValidTimestamp = (Math.abs(now - timestampTime) < 300); if (!isValidTimestamp) { throw new Error("Invalid timestamp"); } const signature = req.headers["x-signature-ed25519"]; const body = await consumers.text(req.body); const isVerified = await crypto.subtle.verify( { name: "Ed25519" }, publicKey, Buffer.from(signature, "hex"), Buffer.from(timestamp + body), ); if (!isVerified) { throw new Error("Invalid request signature"); } ``` ## Upgrading webhook subscriptions Each subscription is pinned to an API version. When we release a new version, you should plan to migrate your subscriptions to it. Once a version reaches its end-of-life date we stop emitting events for subscriptions on that version, so an unmigrated subscription will silently stop receiving deliveries. Upgrading is a single `PATCH` per subscription. The snippet below lists every subscription on your organization, bumps any pinned to a given older version to a specified newer one, and skips subscriptions on `next` (which track the latest stable version automatically). It uses cursor pagination so it works for organizations with any number of subscriptions. ```typescript // Upgrade webhook subscriptions from 2026-02-01 -> 2026-04-01. Skip "next". const BASE = "https://console.xbow.com"; const ORG_ID = "your-organization-id"; const API_KEY = "your-api-key"; const OLD = "2026-02-01"; const NEW = "2026-04-01"; const headers = { Authorization: `Bearer ${API_KEY}`, "X-XBOW-API-Version": NEW }; async function* paginate<T>(url: string): AsyncGenerator<T> { let cursor: string | null = null; do { const u = new URL(url); if (cursor) u.searchParams.set("cursor", cursor); const res = await fetch(u, { headers }); if (!res.ok) throw new Error(`${res.status} ${await res.text()}`); const page = (await res.json()) as { items: T[]; nextCursor: string | null }; yield* page.items; cursor = page.nextCursor; } while (cursor); } type Sub = { id: string; apiVersion: string }; for await (const wh of paginate<Sub>(`${BASE}/api/v1/organizations/${ORG_ID}/webhooks`)) { if (wh.apiVersion === "next") { console.log(`skip ${wh.id} (next)`); continue; } if (wh.apiVersion !== OLD) { console.log(`skip ${wh.id} (${wh.apiVersion})`); continue; } const res = await fetch(`${BASE}/api/v1/webhooks/${wh.id}`, { method: "PATCH", headers: { ...headers, "Content-Type": "application/json" }, body: JSON.stringify({ apiVersion: NEW }), }); if (!res.ok) throw new Error(`${res.status} ${await res.text()}`); console.log(`bump ${wh.id} ${OLD} -> ${NEW}`); } ``` An `apiVersion`-only `PATCH` does not re-validate your endpoint, so the upgrade is cheap and safe to run for many subscriptions at once. A `PATCH` that changes `targetUrl` does re-send the validation pings described above, and must receive a 2xx for the valid ping to succeed.

## Machine-readable artifacts (2)

- **OpenAPI** — https://raw.githubusercontent.com/api-evangelist/xbow/refs/heads/main/openapi/xbow-webhooks-api-openapi.yml
- **Documentation** — https://docs.xbow.com/api/

## Other Xbow APIs (8)

- [Xbow Assessments API](https://apis.io/apis/xbow/xbow-assessments-api/)
- [Xbow Assets API](https://apis.io/apis/xbow/xbow-assets-api/)
- [Xbow Findings API](https://apis.io/apis/xbow/xbow-findings-api/)
- [Xbow Lightspeed API](https://apis.io/apis/xbow/xbow-lightspeed-api/)
- [Xbow Meta API](https://apis.io/apis/xbow/xbow-meta-api/)
- [Xbow Organizations API](https://apis.io/apis/xbow/xbow-organizations-api/)
- [Xbow Reports API](https://apis.io/apis/xbow/xbow-reports-api/)
- [Xbow Resources API](https://apis.io/apis/xbow/xbow-resources-api/)

## Tags

Webhook

---

Profiled by [API Evangelist](https://apievangelist.com) and published on [APIs.io](https://apis.io/apis/xbow/xbow-webhooks-api/). The API's provider profile, Kin Score and agent-readiness rating are at https://apis.io/providers/xbow/.
