Skip to main content
A document is a record with an id, flat filterable attributes, and state: the JSON content that judgments are made about.
  • attributes is a flat map of strings, numbers, booleans, string arrays and nulls, at most 64 keys. Attributes are filterable and sortable. They are never sent to an engine unless a judgment’s context recipe names them.
    • A number reads back as you wrote it. An integer keeps its exact value anywhere in the signed or unsigned 64-bit range, so 1790799482246605123 comes back as 1790799482246605123, and filters and ranking compare integers exactly. A number written with a fraction or an exponent, such as 2.5 or 3.0, is a 64-bit float and comes back as one. 3 and 3.0 are equal in a filter.
    • A null means no value: an upsert leaves that attribute out, and a patch removes it. A get does not return it, and Exists false matches it.
  • state is any JSON object up to 1 MB. It is never filterable.
  • revision increases every time the document changes. It is the namespace’s sequence number at the change, so it is monotonic but not contiguous.
  • incarnation is the sequence at which the document was created. Deleting a document and writing the same id again starts a new incarnation with no answers and no history.
  • created_at is when the document was created: the time of the write that created it, or the created_at that write gave, such as a record’s original creation time when you import existing data. A given created_at may be at most 5 minutes in the future. A later write never changes it; a new incarnation gets a new one. Relations read related documents newest created first.

Writing

POST /namespaces/{ns} takes up to 1,000 documents or 64 MB, and applies its operations in this order: upsert, patch, append, delete. They commit atomically, and a request is never split across two commits. Every write is idempotent by construction, so retrying a request is always safe; system behavior says exactly what a late retry does. A write returns once its batch is durable, in roughly 100 to 200 ms in the service’s region (measured). With wait_for, it also waits until the named judgments have answers for this revision, up to wait_timeout_ms: 5,000 by default, and a value above 10,000 is lowered to 10,000. An empty wait_for is the same as leaving it out. On timeout the write is still committed, and those answers come back pending, which here means only that they were not ready within the wait. A large write waits on its first 16 documents at interactive priority; the rest are judged with ordinary catch-up and usually come back pending. A get works freshness out from the stored answer instead, so the same answer can read unavailable there if the document was never judged in its current incarnation, or stale under a policy that will not judge the new revision on its own.

Conditional upserts

An upsert may carry if_revision: the write commits only if the document’s current revision is exactly that, and 0 means only if the document does not exist (it was never written, or it was deleted). Use it to write back a document you read without overwriting a change someone made since:
POST /v1/namespaces/acme%2Fprod
If any document’s revision differs, the whole request is refused with conflict and nothing in it is written. details.revisions gives each mismatched id’s current revision, or null when it does not exist or has a write that has not committed yet:
Read the document again and decide what to write. A retry of a conditional write whose first attempt did commit is conflict too, since the revision moved on; read the document to tell. if_revision is for upsert only: a patch or append always applies. A document written by a request that has not committed yet has no revision to match, so a conditional write racing it is conflict, with null for that document, until it lands. Writes to one document are applied in the order they commit, so concurrent patch and append writes from different clients all stand. During a failover a write can be refused with rate_limited; retry it, as the SDKs do. See system behavior.

Reading

GET /namespaces/{ns}/documents/{id} returns the document with its answers. Add include=history for its evaluations, newest first, and include=history,context,raw for the compiled context and raw engine response of each. POST /namespaces/{ns}/query filters, ranks and pages. See answers.