API and automation
Use the API when work needs to happen outside the widget.
The API is for server-to-server jobs like creating entries, publishing on a schedule, exporting updates, reacting to webhooks, and sharing signing proof. Most teams only need a few pieces, so start with the job you care about.
Choose the automation path that matches the job
These tools overlap in data, but not in purpose. Pick the one that fits the workflow you are actually trying to run.
API keys
Use these when your backend needs deterministic create, update, publish, or export behavior.
Release schedules
Use these when the calendar is the trigger and the update should happen every month or quarter.
AI draft workflows
Use these when synced artifacts or recurring triggers should produce reviewable drafts automatically.
MCP
Use this when Claude or another agent should search updates, inspect docs, or draft entries without getting publish access.
Webhooks
Use these when another system needs to react after something changes in Chainlog.
Signing
Use this when you need proof of what was published and when, whether that proof is team-visible or reader-visible.
Common automation workflows
Most teams only need a handful of these patterns, but choosing the right one early keeps the implementation simpler.
Create release notes from CI or internal tools
Use REST API keys when your release pipeline, admin tools, or backend services need deterministic create and publish behavior.
Generate reviewable drafts from source systems
Use AI draft workflows when artifacts from GitHub, Jira, Linear, or GitLab should regularly turn into drafts for human review.
Give AI clients read access without handing over publish
Use MCP when an agent should answer what changed, fetch contextual docs, inspect verification material, or draft entries without a publish path.
Notify other systems after something changes
Use webhooks when downstream systems should react to publish events instead of polling the API for changes.
Publish recurring monthly or quarterly updates
Use release schedules when the calendar is the trigger, even if the final draft still gets reviewed by a human.
Prove what went live
Use signing when customers, support teams, or auditors should be able to validate the published history later.
Authentication and common errors
REST APIs use Bearer API keys. Widget tokens are separate and are only for the in-app widget.
| Thing | Value | Notes |
|---|---|---|
| Authorization | Bearer cl_live_... or cl_test_... | Use API keys for server-to-server REST calls. |
| 401 Unauthorized | Invalid or missing API key | The key is missing, malformed, revoked, or expired. |
| 403 Forbidden | API key lacks required scope | The key is valid, but it is not allowed to do that action. |
| 429 Too Many Requests | Rate limit exceeded | Slow down and respect Retry-After when it is present. |
Scope model
Empty scopes currently mean full access. Otherwise, use entries:read, entries:write, or wildcard variants such as entries:* to keep an automation limited to the work it actually needs.
MCP access for AI clients
Use MCP when you want Claude or another agent to search updates, fetch contextual docs, inspect verification data, or draft release notes without giving it a publish tool.
Recommended key presets
entries:readis enough for read-only MCP use.entries:readplusentries:writeallows draft creation and draft updates.- MCP does not expose publish, delete, or tenant-settings mutation tools in v1.
Remote endpoint
https://mcp.chainlog.tech/mcpThe same API keys used for REST can authenticate MCP. For safer agent access, prefer a scoped key over a legacy full-access key.
Example remote MCP config
{
"mcpServers": {
"chainlog": {
"url": "https://mcp.chainlog.tech/mcp",
"headers": {
"Authorization": "Bearer cl_live_..."
}
}
}
}Most-used endpoints
These are the endpoints most teams reach for first.
| Endpoint | Methods | Purpose |
|---|---|---|
| /api/v1/entries | GET, POST | List entries or create a new draft or published update from your backend. |
| /api/v1/entries/:id | GET, PATCH, DELETE | Fetch, update, publish, or remove a specific update. |
| /api/v1/release-schedules | GET, POST, PATCH | Manage recurring updates that should happen every month or quarter. |
| /api/v1/ai/workflows | GET | List AI draft workflows and their cadence, guardrails, and active state. |
| /api/v1/announcements/export | GET | Export published updates as Markdown or JSON for downstream systems. |
| /api/v1/signing/public-key | GET | Fetch the public key and chain metadata used for verification. |
| /api/v1/widget/runtime-config | GET | Read the public widget defaults used by the loader. |
Copyable examples
Start from a working request, then customize it after you see the response shape.
List entries
curl -X GET "https://chainlog.tech/api/v1/entries?status=published&limit=20" \
-H "Authorization: Bearer cl_live_your_api_key"Create or publish an entry
curl -X POST "https://chainlog.tech/api/v1/entries" \
-H "Authorization: Bearer cl_live_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"title": "Billing exports are faster",
"slug": "billing-exports-are-faster",
"summary": "CSV exports now stream in the background.",
"body": "## What changed\nLarge exports now process asynchronously.",
"updateType": "improvement",
"deliveryType": "in_app_widget",
"changeCategory": "product_release",
"platforms": ["web"],
"moduleKey": "billing",
"status": "published"
}'Create a recurring release schedule
curl -X POST "https://chainlog.tech/api/v1/release-schedules" \
-H "Authorization: Bearer cl_live_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"title": "Monthly platform digest",
"cadence": "monthly",
"deliveryType": "email",
"changeCategory": "release_status",
"moduleKey": "platform",
"notifySubscribers": true
}'Rate limits and backpressure
Treat rate limits as a normal part of operating the API, especially for recurring jobs and bulk syncs.
- Entry listing currently allows 240 requests per minute per tenant, API key, and client IP.
- Entry creation and release-schedule writes currently allow 60 requests per minute per tenant, API key, and client IP.
- Widget runtime-config reads currently allow 240 requests per minute per tenant and client IP.
- Widget entry reads currently allow 120 requests per minute per tenant and widget subject.
Webhook events
Webhooks let other systems react when something changes in Chainlog. Verify the raw body before parsing JSON.
| Event | When it fires |
|---|---|
| entry.created | An entry was created, usually in draft status. |
| entry.updated | An existing entry changed. |
| entry.published | An entry became customer-visible and downstream notifications may fire. |
| entry.deleted | An entry was removed. |
Verification snippet
import crypto from "node:crypto";
const digest = crypto
.createHmac("sha256", process.env.CHAINLOG_WEBHOOK_SECRET!)
.update(rawBody)
.digest("hex");
const expected = `sha256=${digest}`;
if (!crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expected))) {
throw new Error("Invalid webhook signature");
}Representative payload
{
"id": "5c5f7b12-0db9-4f8a-aaf3-03c6d20f8dbf",
"event": "entry.published",
"timestamp": "2026-03-19T11:42:00.000Z",
"tenant": {
"id": "tenant_123",
"slug": "acme",
"name": "Acme"
},
"data": {
"entry": {
"id": "entry_123",
"title": "Billing exports are faster",
"slug": "billing-exports-are-faster",
"status": "published",
"updateType": "improvement",
"publishedAt": "2026-03-19T11:42:00.000Z"
}
}
}Headers sent with each webhook
Current deliveries include X-Signature, X-Webhook-Signature, X-Webhook-Event, and X-Webhook-Id.
What to read next