DeployLog manual

13Reference

This page speaks HTTP. Requests go to https://deploylog.dev/api/cli/... and authenticate with an API key in the Authorization: Bearer dk_... header; the CLI and the GitHub Action use the same routes. The CLI is chapter 05, the GitHub Action chapter 06, and API keys chapter 11. Every value below is the one the route's schema enforces.

Limits

An entry is one changelog item: a title, a markdown body, an optional type and an optional version, the release label an entry carries.

Field Limit
Entry title 1 to 200 characters
Entry body (markdown) 1 to 50,000 characters, counted as characters, not bytes
Project name (a project is one changelog you publish to) 1 to 100 characters
Project website URL a valid URL, up to 2,000 characters
Organization name (an organization owns projects and keys) 1 to 100 characters
API key name 1 to 100 characters
List page size 1 to 50, default 50
AI summarize commits up to 200 messages, each up to 500 characters
AI summarize release notes up to 20,000 characters
Manual chapter number up to 16 characters
Manual chapter title up to 200 characters
Version label up to 60 characters; draft is refused
Widget accent (the colour of entry titles in the embedded widget) 6-digit hex, for example #18181b

Exceed any of these and the request comes back 400 with code VALIDATION_ERROR and a details object of per-field errors. Nothing is truncated and nothing is clamped.

Free-plan quotas are counts, not rates: 3 projects, 5 AI summaries per month, 5 manual generations per month (a manual generation is one run that drafts a page of your product manual from its code). On Free, a fourth project, a sixth summary or a sixth generation in a month is refused.

Entry types and statuses

Five types: feature, fix, improvement, breaking, announcement. Send one of those or nothing.

  • Type is optional and may be null. An entry with no type is legal.
  • An entry is draft or published, never toggled. You send the target state as an explicit true or false, so re-running a publish cannot unpublish.
  • Version is optional. It may be omitted or sent as an empty string. When given it must be exactly three dot-separated numbers, 1.2.3, with no leading v. Anything else is 400 VALIDATION_ERROR.
  • A slug, the URL name of an entry, is never supplied at creation. The server derives it from the title. On update you may send a slug override as loose text of up to 200 characters; it is trimmed, normalised server-side, and rejected with 400 VALIDATION_ERROR past 200.

The error envelope

Every error is a JSON object with one error field holding a code and either a message or, for validation, a details object of field errors.

Code Status When Example body
UNAUTHORIZED 401 No usable API key on the request {"error":{"code":"UNAUTHORIZED","message":"Valid API key required"}}
FORBIDDEN 403 Key authenticated, permission missing {"error":{"code":"FORBIDDEN","message":"API key lacks write permission"}}
NOT_FOUND 404 No project with that slug in your organization {"error":{"code":"NOT_FOUND","message":"Project 'acme' not found"}}
VALIDATION_ERROR 400 Body or query failed a limit or format above {"error":{"code":"VALIDATION_ERROR","details":{"formErrors":[],"fieldErrors":{"title":["Title is required"]}}}}
CONFLICT 409 The entry write collides with an existing row {"error":{"code":"CONFLICT","message":"..."}}
RATE_LIMITED 429 Bucket exhausted {"error":{"code":"RATE_LIMITED","message":"Too many requests. Please slow down and try again shortly."}}
SERVER_ERROR 500 The write failed on our side {"error":{"code":"SERVER_ERROR","message":"..."}}

A successful entry create returns 201 with the row under data.

Rate limits

A bucket is one counter for one kind of request. Every bucket is a sliding window. Nothing resets on the minute boundary; the window trails the request. Cross a bucket's limit inside its window and the request is rejected with the 429 described under the table.

Bucket Limit Window
API and CLI writes, counted per organization 60 1 minute
Dashboard AI 60 1 minute
Widget data 60 1 minute
Widget analytics 120 1 minute
Subscribe, counted per client address 5 1 hour
Subscribe, counted per email address 3 1 hour
Unsubscribe 20 1 hour
Billing webhooks (events Stripe sends DeployLog), counted per signature 200 1 minute

Every rate-limited response carries X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset. X-RateLimit-Reset is whole seconds. Retry-After is added only on a rejection, and a rejection is 429 with the RATE_LIMITED body above.

A client-supplied forwarded-for header never changes which address is counted. The address comes from the platform-set headers only, falling back to a single fixed bucket when neither is present.

Keys and plans

Writing through the API is open on every plan, free included; no paid gate is enforced on writes, and the quotas above are the only limits a free organization meets.

An API key defaults to both read and write when no permission is named, and at least one permission is required. Ask for none and the request is 400 VALIDATION_ERROR with the message At least one permission required.