The Content Sync Protocol

Embed
Preview of the card
<a href="https://forumulate.com/reference/sync-protocol"><img src="https://forumulate.com/reference/_api/public/orgs/046a9bc0-d530-43ae-9bae-af7945008cda/spaces/8042f004-e3d9-445f-b7a4-b6c1f86836e6/pages/f2334099-45c6-4842-b8c4-d4042babb84c/social-card.svg?v=3e7ae33eec8b" alt="The Content Sync Protocol" width="600" height="315"></a>

Everything a documentation platform needs to be syncable correctly, written down and runnable against any platform — including ours, and including one that is not.

npx @forumulate/cli conformance https://forumulate.com/api/orgs/{org}/spaces/{space}/items

The twelve checks

Check

What it asks

Why it matters

CSP-1

The description is findable from any response

Without it an integrator probes five paths, finds nothing, and writes a defensive parser instead of generating a client.

CSP-2

The collection is keyed after its path

A collection named after its controller forces every reader to learn your internals before they can read a row.

CSP-3

The page carries limit, has_more, next_cursor and total

A caller cannot tell a short page from the last page, so a sync silently stops early.

CSP-4

A cursor walk visits every row exactly once

A cursor that repeats or skips rows corrupts a corpus without ever erroring.

CSP-5

The walk agrees with the reported total

A total nobody can reconcile against is a number that hides a truncated sync.

CSP-6

A server-defined checkpoint comes back with the page

Without one, every client invents its own watermark out of its own clock and loses rows to skew.

CSP-7

The checkpoint narrows the answer

An incremental sync that returns everything is a full sync wearing a parameter.

CSP-8

An unparseable window is refused, not ignored

Silently ignoring it hands back a full list that looks like a successful incremental sync.

CSP-9

Removals are explicit, not inferred from absence

Absence means "archived" on a full sync and "not on this page" on an incremental one. Conflating them deletes a corpus.

CSP-10

Each item carries a content hash

Without it a client re-embeds everything to discover that nothing changed.

CSP-11

A conditional request answers 304

Polling costs a full transfer to learn nothing moved.

CSP-12

Rate limits are stated, with their window

A limit with no period is a number per something, and a client that guesses wrong either crawls or is refused.

Tombstones, specifically

This is the part everyone gets wrong, so it is written down rather than implied:

  • On a full list, a piece that is absent has been removed.

  • On an incremental list (updated_since=…), a piece that is absent has simply not changed.

Conflating the two deletes a customer's corpus on the first incremental sync. Ask for include_deleted=true and a removal arrives as a row with deleted: true — for 30 days, after which reconcile with a full list.

Why the suite uses no SDK

It is plain fetch against whatever URL you give it. A conformance suite that only runs against the platform that wrote it proves nothing and convinces nobody.

The Forumulate teamUpdated