Facts and the journal
Every change Manifold makes is written down as a fact, at the moment it happens, and never edited.
The rule
A fact is a record that something happened: stock was received, an order was placed, a payment
came in. Each one is named for what happened, such as inventory.stock-received or fulfillment.payment-recorded.
- Written with the change. The change and its fact are saved together, or neither is. There is no change without a fact.
- Never edited or deleted. Facts cannot be changed. A mistake is put right by a new fact: an adjustment, a refund, an edit to the order.
- Kept per service. Inventory, fulfillment, purchasing and each other service keep their own journal: the list of their facts, in order, for each organization.
Why
Every figure in Manifold can be traced to the facts behind it: who, what and when. The same facts are what make retries safe and what other systems read to stay in step.
What a call records
Each operation's page lists, under Facts appended, the facts it can record. This
call records inventory.stock-received:
curl -X POST 'https://inventory.getmanifold.io/items/WIDGET-BLUE/receive' \
-H "Authorization: Bearer $MANIFOLD_TOKEN" \
-H 'Content-Type: application/json' \
-d '{
"quantity": 10,
"reference": "dock-note-8841"
}'Some calls record nothing, and that is part of the contract:
- A refused call (
4xx) records nothing. See Errors. - A retry of work already done records nothing. See Idempotency and retries.
- A write that changes nothing, such as setting a value the record already has, records nothing.
Each step of a flow shows the facts it records, for example buying stock and paying for it and selling it and getting paid.
What a fact looks like
{
"_tag": "inventory.stock-received",
"eventId": "evt_0192f3a4-81c0-7a11-9b2e-3c4d5e6f7a80",
"txId": "tx_0192f3a4-81c0-7a11-9b2e-3c4d5e6f7a7f",
"tenantId": "org_0192e8b1-4a3b-7c2d-9e1f-0a1b2c3d4e5f",
"sequence": 42,
"occurredAt": "2026-10-21T04:12:09.512Z",
"source": "inventory-manager",
"version": 1,
"actor": { "_tag": "user", "id": "usr_0192e8b1-5d2a-7c3b-8e4f-1a2b3c4d5e6f" },
"correlationId": "req_0192f3a4-81bf-7f02-a3c4-5d6e7f8a9b0c",
"payload": {
"sku": "WIDGET-BLUE",
"locationId": "loc_0192e8b1-6a7b-7c8d-9e0f-1a2b3c4d5e6f",
"quantity": 10,
"reference": "dock-note-8841"
}
}_tag- What happened. Switch on this.
eventId,txId- The fact's own id, and the id of the write that recorded it. Facts recorded by one write share a
txId. tenantId- The organization it belongs to.
sequence- Its place in this service's journal for this organization. It only goes up. Each service counts its own.
occurredAt,source- When it happened, and which service recorded it.
version- The shape of this kind of fact's
payload. Check it before you read the payload. A changed shape gets a new version, and older facts keep theirs. actor- Who did it: a
user(withimpersonatedByorviaPartnerwhen someone acted for them), anappacting under its own token, or asystemjob named by what it does. correlationId,causationId- The request that began the work. For the facts your write records, it is the same
req_…id as thex-request-idheader on the answer. A fact recorded in reaction to another keeps itscorrelationId, and itscausationIdnames the fact or delivery it answered. payload- What this kind of fact says. Every kind's shape is in the OpenAPI document of its service, under
GET /events.
Reading facts
Every service with a journal answers GET /events: your organization's facts, oldest
first, from since. A page holds up to limit facts (500 by default, at most
5000). Ask again with since set to the last fact's sequence plus one,
until a page comes back shorter than limit.
curl -X GET 'https://inventory.getmanifold.io/events?since=0&limit=500' \
-H "Authorization: Bearer $MANIFOLD_TOKEN"Save the last sequence you handled, per service, and next time ask from that plus
one. Then you read every fact once. See GET /events for the scopes it needs.
One SKU's history across every kind of fact, newest first:
curl -X GET 'https://inventory.getmanifold.io/items/WIDGET-BLUE/events?limit=50' \
-H "Authorization: Bearer $MANIFOLD_TOKEN"Each page carries next while older facts remain; pass it as before. See GET /items/{sku}/events.
To read a journal as it stood at a moment, take its head with GET /events/head and replay up to it
with upTo. More in Paging, events and as-of reads.
Hearing facts as they happen
An app hears about changes through webhooks, not by polling journals. See Webhooks. A script that keeps its own copy in step can poll GET /events as above.
Related: Idempotency and retries · Identifiers · Errors