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
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

inventory.stock-received
{
  "_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 (with impersonatedBy or viaPartner when someone acted for them), an app acting under its own token, or a system job 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 the x-request-id header on the answer. A fact recorded in reaction to another keeps its correlationId, and its causationId names 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
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
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