Conventions

Embed
Preview of the card
<a href="https://forumulate.com/reference/conventions"><img src="https://forumulate.com/reference/_api/public/orgs/046a9bc0-d530-43ae-9bae-af7945008cda/spaces/8042f004-e3d9-445f-b7a4-b6c1f86836e6/pages/12aedfab-161e-434f-8408-0c261f447073/social-card.svg?v=3e7ae33eec8b" alt="Conventions" width="600" height="315"></a>

Six rules that hold everywhere in this API. Each one is here because somebody asked it with the whole specification open, which makes it a line that was missing rather than a line that went unread.

An organization takes an id or a name

/api/orgs/{orgId}/… accepts the uuid or the slug. They are interchangeable on every route.

GET /api/orgs/forumulate-sandbox/spaces
GET /api/orgs/4766b8a4-57da-48f0-91ff-c46da0f8d205/spaces

A name that is not yours answers 404 — the same as a name that does not exist. An organization you cannot see is one you cannot learn the existence of.

A collection is keyed after its path

/spaces answers { spaces }. /webhooks answers { webhooks }. /orgs answers { orgs } — and { organizations } as well, which is what it has always answered and always will.

State your version and you get the envelope

Forumulate-Version: 2026-09-01

With it, every collection carries page (limit, has_more, next_cursor, total) and a walk also carries sync.checkpoint. Without it you get the pre-envelope shape, plus Deprecation and Sunset headers saying how long that lasts.

page.limit is the limit that was applied, not the number of rows returned. A final page shorter than the limit is ordinary; has_more is the only thing that decides whether to keep walking.

Rate limits are per minute

Every response:

RateLimit-Limit: 600
RateLimit-Policy: 600;w=60
RateLimit-Remaining: 597
RateLimit-Reset: 41

RateLimit-Policy names the window in seconds, so nobody has to infer it. A 429 also carries Retry-After.

Removals stay discoverable for 30 days

?include_deleted=true carries tombstones — deleted: true with the id and slug. A client on any sane cadence sees every removal without falling back to a full list. Longer than 30 days away, reconcile with a full list.

Deliveries are signed with the X- prefix

X-Forumulate-Signature: v1,sha256=<hex>
X-Forumulate-Timestamp: 1755490000
X-Forumulate-Event: page.published
X-Forumulate-Delivery: dl_01J…

HMAC-SHA256 over ${timestamp}.${rawBody}, hex. X-Forumulate-Delivery is the key to deduplicate on. See Verifying a webhook.

The Forumulate teamUpdated