Release Notes Feed & Webhooks
Public RSS/Atom feed and HMAC-signed webhook subscriptions for Chipp platform release notes
Chipp publishes an official, maintained programmatic surface for platform release notes — the same content shown on the in-builder What’s New page, with no sign-in required. Read the public RSS/Atom feed, or register a webhook to be notified the moment a new period is published, instead of scraping or polling manually.
Both surfaces read from the same release-notes data as the What’s New page. There is no separate publish step — when a new period appears in the builder UI, the feed and any matching webhook subscriptions update immediately.
Both surfaces are public and unauthenticated. No API key is required to read the feed or subscribe to webhooks.
RSS/Atom feed
GET /api/v1/release-notes/feed
GET /api/v1/release-notes/feed?area=integrationsReturns an RSS 2.0 (with Atom namespace) XML document, newest period first. Each <item> maps one release-note period:
| Field | Source |
|---|---|
title | A human-readable period label, e.g. “Release notes: August 1, 2026” |
link | The public What’s New page URL |
guid | The period’s stable id (not a permalink) |
pubDate | periodStart |
atom:updated | periodEnd |
category | One entry per distinct change kind in the period (feature, improvement, fix, other) |
description / content:encoded | The rendered release-note markdown body |
The optional ?area= query param filters to periods whose items mention that keyword (case-insensitive substring match over each item’s title + body, or the raw markdown for periods with no structured items) — the same area-matching semantics used by webhook subscriptions below. Omit area for the full, unfiltered feed.
The feed is rate-limited per client IP; a 429 response includes a Retry-After header (seconds).
Webhook subscriptions
Register a callback URL to be notified the moment a new release-note period is published, instead of polling the feed.
Create a subscription
POST /api/v1/release-notes/subscriptions
Content-Type: application/json
{
"callbackUrl": "https://your-service.example.com/webhooks/chipp-release-notes",
"areas": ["integrations"],
"categories": ["feature", "fix"]
}| Field | Required | Description |
|---|---|---|
callbackUrl | yes | HTTPS endpoint that receives delivery POSTs. Must not point to a private, loopback, or link-local address — validated at subscribe time and again at every delivery. |
areas | no | Case-insensitive keyword filter. A period matches if any subscribed area appears as a substring in an item’s title or body (or the raw markdown when a period has no structured items). Omit for no area filtering. |
categories | no | One or more of feature, improvement, fix, other — the structured change-category Chipp already derives from each release note. A period matches if it contains at least one item in the requested categories. Omit for no category filtering. |
Response (201 Created):
{
"data": {
"id": "5b1e6b8a-1c2d-4e3f-9a0b-7c8d9e0f1a2b",
"callbackUrl": "https://your-service.example.com/webhooks/chipp-release-notes",
"areas": ["integrations"],
"categories": ["feature", "fix"],
"isActive": true,
"maskedSecret": "whsec_••••••1a2b",
"secret": "whsec_9f1c...redacted...4d2e",
"createdAt": "2026-08-01T12:00:00.000Z",
"updatedAt": "2026-08-01T12:00:00.000Z"
}
}secret is returned in full exactly once, in the create response. Store it immediately — every later response only shows maskedSecret. There is no way to retrieve the full secret again; delete and recreate the subscription if it’s lost.
Creating a subscription immediately backfills the 5 most recent periods matching your filters, delivered through the same signed-payload path as live notifications — so your system has recent history without waiting for the next release.
List your subscription
There is no Chipp account behind a webhook subscriber, so management is gated by possession of the subscription’s own secret rather than a login:
GET /api/v1/release-notes/subscriptions
Authorization: Bearer whsec_9f1c...redacted...4d2eReturns { "data": [...] } containing the one subscription that secret belongs to (or an empty array if the secret doesn’t match anything).
Delete a subscription
DELETE /api/v1/release-notes/subscriptions/{id}
Authorization: Bearer whsec_9f1c...redacted...4d2eReturns 204 No Content on success. A missing or mismatched secret, or an unknown id, returns 404 — the endpoint deliberately never reveals whether an id exists to a caller who doesn’t hold the matching secret.
Rate limits
Both surfaces are rate-limited per client IP: creating subscriptions and listing/deleting a subscription are each capped per client IP. A 429 response includes a Retry-After header (seconds).
Delivery payload
Every webhook delivery (live or backfill) POSTs this JSON body:
{
"event": "release_notes.period_published",
"periodStart": "2026-08-01T00:00:00.000Z",
"periodEnd": "2026-08-02T00:00:00.000Z",
"markdown": "## New Features\n### Slack integration\n...",
"categories": ["feature", "fix"],
"areas": ["Slack integration"],
"timestamp": "2026-08-02T01:00:03.512Z"
}categories is the distinct set of structured change-categories present in this period. areas lists this period’s item titles as a hint for client-side filtering — Chipp’s release notes don’t carry a separate “product area” tag today, so this is not a fixed taxonomy.
Verifying signatures
Every delivery includes an X-Chipp-Signature header:
X-Chipp-Signature: sha256=8f434346648f6b96df89dda901c5176b10a6d83961dd3c1ac88b59b2dc327aaThe value is an HMAC-SHA256 hex digest of the raw JSON request body, computed with your subscription’s secret. Verify it before trusting a delivery:
import { createHmac, timingSafeEqual } from "node:crypto";
function isValidSignature(rawBody, signatureHeader, secret) {
const expected = `sha256=${createHmac("sha256", secret).update(rawBody).digest("hex")}`;
const a = Buffer.from(expected);
const b = Buffer.from(signatureHeader);
return a.length === b.length && timingSafeEqual(a, b);
}Use the raw request body bytes, not a re-serialized JSON object — re-serializing can reorder keys or change whitespace and will not match the signature.
Retry and redelivery behavior
A delivery attempt that fails with a network error, a timeout, or an HTTP 408/429/5xx response is retried up to twice more with a short backoff (roughly 1s, then 3s), for up to 3 total attempts. A 4xx response other than 408/429 is treated as a permanent rejection and is not retried — fix your endpoint and Chipp will deliver the next period normally.
There is no indefinite retry queue: if all attempts for a period fail, that period is not redelivered later. If you suspect you missed a delivery, recreate your subscription (backfills the last 5 matching periods) or read the RSS/Atom feed directly — it always reflects the full set of currently-published periods, independent of any subscription’s delivery history.
Deliveries are POSTed with a 10 second timeout and Content-Type: application/json. Your endpoint should return a 2xx status quickly; do heavy processing asynchronously after acknowledging receipt.
Deliveries are at-least-once: a period can be delivered more than once (for example, if a subscription’s backfill overlaps a live delivery of the same newly-published period). Treat delivery as idempotent, keying on periodStart + periodEnd, so a duplicate is a no-op on your side.