Skip to main content
The HTTP routes a plugin serves, with every field of their JSON bodies, the error envelope and the fixture files quivr plugin test reads. A plugin serves JSON over HTTP; every route is under /v0, the major version of the Plugin API. The schemas in contracts/plugins/v0/ are the source of truth; the SDKs and quivr plugin test implement them.

Discovery and health

GET /v0/discovery

manifest_digest is sha256 over the exact bytes of the quivr-plugin.yaml the plugin was built from; the engine compares it with the pinned manifest. Response body (200) (discovery.schema.json)

GET /v0/health

Returns 200 with this body when the plugin can accept invocations; otherwise 503 with the error envelope. Response body (200) (health.schema.json)

Normalizer

POST /v0/contributions/normalizer

Immutable invocation context plus a reference to the input Blob; bodies are never inline. Request body (normalizer-request.schema.json) Response body (200) (normalizer-response.schema.json)

Alert rule (subscription)

POST /v0/contributions/subscription

Since Plugin API 0.2. One Record Version’s text Parts and metadata (source identity, acceptance time, provenance, extensions) and a batch of distinct evaluations to decide. The core deduplicates Subscriptions that share the same expression and configuration into one evaluation and never sends more evaluations than the manifest’s max_batch_size. Request body (subscription-request.schema.json) Response body (200) (subscription-response.schema.json)

Connector

POST /v0/contributions/connector/check_credential

Since Plugin API 0.3. Check that the source accepts the credential, without fetching items. Used for Connector Health. Request body (connector-check-credential-request.schema.json) Response body (200) (connector-check-credential-response.schema.json)

POST /v0/contributions/connector/describe_attachment

Since Plugin API 0.4. The core asks for the exact size and SHA-256 of one attachment of an item it has not accepted yet, before it issues an upload grant. The plugin reads the bytes from the source, at most attachments.max_bytes, or answers a skip. Request body (connector-describe-attachment-request.schema.json) Response body (200) (connector-describe-attachment-response.schema.json)

POST /v0/contributions/connector/fetch

Since Plugin API 0.3. Fetch one page of new or changed source items after the checkpoint. The plugin is stateless between invocations: the core persists the checkpoint and advances it only after the page’s items are durably accepted. Request body (connector-fetch-request.schema.json) Response body (200) (connector-fetch-response.schema.json)

POST /v0/contributions/connector/receive

Since Plugin API 0.5, for a kind that declares the push mode. The core relays one request a source sent to the instance’s public webhook route: the plugin verifies it with the credential (for example a signature over the raw body), answers any challenge, and returns the items it carries. The core ingests the items, then returns the plugin’s answer to the source. Request body (connector-receive-request.schema.json) Response body (200) (connector-receive-response.schema.json)

POST /v0/contributions/connector/upload_attachment

Since Plugin API 0.4. The plugin uploads the bytes it described to the grant, then answers. The core verifies the stored bytes before it accepts the item. Bytes that changed at the source since describe_attachment are a source error attachment_changed; the core describes the attachment again once. Request body (connector-upload-attachment-request.schema.json) Response body (200) (connector-upload-attachment-response.schema.json)

Ingestion

POST /v0/contributions/ingestion/embed_query

Since Plugin API 0.6. Encode one query into one of the plugin’s spaces, so a query vector always comes from the model that produced the document vectors. Request body (ingestion-embed-query-request.schema.json) Response body (200) (ingestion-embed-query-response.schema.json)

POST /v0/contributions/ingestion/segment_and_embed

Since Plugin API 0.6. One Record Version’s text Parts and the enabled vector spaces to embed each segment in. Request body (ingestion-segment-and-embed-request.schema.json) Response body (200) (ingestion-segment-and-embed-response.schema.json)

Retrieval

POST /v0/contributions/retrieval/search

Since Plugin API 0.7. One round of one search: the query, the scope, the profile, the spaces available, and every candidate the core served in earlier rounds. The plugin answers candidate requests or the final ranking. Request body (retrieval-search-request.schema.json) Response body (200) (retrieval-search-response.schema.json)

Errors

Body of every non-2xx plugin response. retryable is authoritative: true asks the engine to retry within the declared retry intent; false is terminal. Connector errors (since Plugin API 0.3) also carry error_class, and optionally retry_after_seconds.

Fixtures

Local test inputs that quivr plugin dev and quivr plugin test turn into requests. A plugin keeps its own in fixtures/*.json.

Connector fixture

A local test input that tools turn into connector requests: quivr plugin test fetches pages from checkpoint, feeding each returned checkpoint back, checks the credential and, for a push kind, relays each receive case. A file is a connector fixture when it has a top-level connector property. Fixture credentials are test values; the Contract Runner checks they never appear in responses or plugin logs. Schema: connector-fixture.schema.json.

Ingestion fixture

A local test input for an ingestion plugin (since Plugin API 0.6): the text Parts of one Record Version, the queries to encode and what to expect. quivr plugin test turns it into segment_and_embed and embed_query requests. Schema: ingestion-fixture.schema.json.

Normalizer fixture

A language-neutral local test input for a normalizer. Tools (quivr plugin dev, the Contract Runner, SDK test helpers) turn it into a normalizer request: they read input.path relative to the fixture file, compute its size and SHA-256, reference it through an absolute file:// URL, and fill the identity fields with deterministic development values. Schema: plugin-fixture.schema.json.

Retrieval fixture

A local test input for a retrieval plugin (since Plugin API 0.7): a query, the spaces available and a catalogue of candidates. quivr plugin test drives the rounds and serves candidates from the catalogue, offline. Schema: retrieval-fixture.schema.json.

Subscription fixture

A language-neutral local test input for a subscription Contribution, since Plugin API 0.2. Tools (quivr plugin dev, the Contract Runner, SDK test helpers) turn it into a subscription request: they number the evaluations e1, e2, … in order, give each one development Subscription ids, derive the Record Version ids and the idempotency key from the SHA-256 of the fixture bytes, default the record metadata (source dev-namespace/dev-record-<digest>, origin client, accepted_at 2026-01-01T00:00:00Z) when the fixture omits it, and validate every expression and configuration against the manifest schemas. A fixture file is told apart from an invocation fixture by its top-level evaluations property. Schema: subscription-fixture.schema.json.