Skip to main content
Every way of adding content goes through the same path: you submit a command, Quivr stores it and answers with an Ingestion Receipt, then processes it in the background. This page shows each kind of command. The requests are replayed against a running Quivr by the repository’s CI.

Prerequisites

  • A running Quivr and, in your shell, QUIVR_API_URL and a QUIVR_API_KEY with corpora:write, content:write, content:read, blobs:write and search:query. With the local stack, eval "$(make -s env)" sets them (Quickstart).
  • A Corpus to write to:

Send an article with a title

Plain text becomes one body Part. To give an article a title, which search weighs more than the body, send a Manifest with a title Part and a body Part:
The Record is identified by its Corpus, its Source Namespace (namespace) and its Record Key. source_revision is optional: the source’s own version label. When you send it, Quivr uses it to tell corrections from duplicates; without it, the content itself decides. Read the Receipt to know when the article is searchable:

Correct an article

Send new content for the same Record Key. It becomes a new Version of the same Record:
Search now returns the corrected text only. The first Version stays readable, marked as no longer current:
If a correction may arrive out of order, send source_position, a number that grows with each revision at the source, such as a sequence number or a timestamp in digits. An older position never replaces a newer Version.

Send many articles at once

POST /v0/records/batch takes up to 100 commands, 10 MiB in total and 1 MiB each. Each entry gets its own Receipt or its own error, in order, so one invalid entry does not block the others:
After a timeout, send the same batch again: every entry keeps its idempotency key, so you get the same Receipts and no duplicate.

Upload a file

Files go through an upload session. You declare the size, SHA-256 and media type, send the bytes to the URL Quivr returns, and confirm; Quivr reads the bytes back and checks them before they become a Blob. The same request again returns the same session, so the bytes are sent only while it is awaiting_upload.
Then ingest the Blob by reference:
Quivr reads text/* files itself. Other media types need a normalizer plugin routed for them: the local stack routes application/pdf to the first-party pdf-text plugin, which makes one Part per page. Upload a PDF the same way with "media_type": "application/pdf". A media type with no route is refused with 422 unverified_blob. An upload URL expires after 15 minutes, and a file is at most 1 GiB.

Withdraw an article

A withdrawal removes a Record from search and alerts at once, and permanently: a later submission for the same Record Key is a conflict. Its history stays readable.

Limits

A Version over the indexing limits is stored and readable, but not searchable: its Receipt shows ingestion_refused.

Next

Search

Find what you added, by keyword or by meaning.

Collect from a source

Let Quivr pull articles from feeds and mailboxes on a schedule.