Add Records

Add records, or replace records with the same id. They become searchable within a few seconds. Send a JSON array (up to 1,000 records and 8 MiB), NDJSON (one record per line, up to 100,000 records and 64 MiB) or CSV with a header row (the NDJSON limits). Each record is a JSON object with an id and the index’s fields. See Records for how to structure a record.

Authentication

AuthorizationBearer

A write key, issued by Captain. Server side only. Sent as Authorization: Bearer <key>.

Path parameters

indexstringRequiredformat: "^[a-z0-9][a-z0-9_-]{0,47}$"
index name

Headers

Idempotency-KeystringOptional<=255 characters

Replays within 24 hours return the stored response (header Idempotent-Replayed: true). The same key on a different request answers 422. A concurrent duplicate answers 409. Failed requests do not keep the key.

Query parameters

on_errorenumOptionalDefaults to fail

fail: one bad record rejects the request (400, details names every bad row). skip: the good records are added and the bad ones returned in rejected

Allowed values:
on_duplicateenumOptionalDefaults to warn

an id sent more than once in one upload. warn: the last copy is kept and the answer carries duplicates and a DUPLICATE_ID warning. fail: the request is rejected (400, details names each repeated id and its lines)

Allowed values:
line_offsetintegerOptional>=0Defaults to 0

CSV: added to every line the answer names, so a client that splits a big file (repeating the header) reports the file’s own lines

Request

This endpoint expects a list of objects.

Response

Accepted. The records are searchable within a few seconds.
indexstringOptional
acceptedintegerOptional
Records accepted from this request.
newintegerOptional
Accepted records with an id the index did not have.
replacedintegerOptional
Accepted records that replaced a record with the same id.
record_countintegerOptional
Records the index holds after this request, built or not.
max_recordsintegerOptional
The most records the index can hold.
rejectedlist of objectsOptional

on_error=skip: the first 100 rows left out

rejected_countintegerOptional

on_error=skip: every row left out

id_suggestionobjectOptional

every record lacked the id field: the field the data points to, for you to name as id_field when creating the index (nothing is set for you)

duplicatesintegerOptional

records that repeat an id sent earlier in this upload (the last copy is kept); 0 when none. A repeat across uploads is a replace, counted in replaced

warningslist of objectsOptional

DUPLICATE_ID when duplicates > 0: count, ids (the first 20, each with its lines or indexes) and message

seqintegerOptional
This change's place in order. Get Update Status reports the last applied seq.
accepted_atdoubleOptional
regions_appliedlist of stringsOptional
regions_pendinglist of stringsOptional
© 2026 Captain