Indexing

Full catalog sync

Replace the whole catalog with a replace session, so products missing from your export disappear from search, without downtime.

When to use a replace session

Upserts and deletes change the documents you name. They cannot remove a product you forgot to delete. A replace session makes the index hold exactly what you send: you open it, send the whole catalog in batches and commit. Search switches to the new catalog in one step, and every document you did not send is gone.

Use a replace session when:

  • your shop exports the full catalog on a schedule, for example every night, and you have no reliable list of deleted products;
  • the index has drifted from the shop and you want a clean copy;
  • you changed the mapping and want to rebuild from your source data instead of from the stored documents.

Use upserts and deletes for changes during the day. They are cheaper, and they keep working while a session is open.

How a session works

Opening a session builds a new, empty version of the index next to the live one, with the saved mapping. Search keeps using the live version the whole time.

  • Batches sent to the session go to the new version only.
  • Normal upserts and deletes sent while the session is open go to both versions, so they survive the commit.
  • Commit waits until every batch is written, then swaps search to the new version in one step.

The index's status is REINDEXING while the session is open, and its buildingVersion is the session's version.

Run a sync

Open a session

POST/v1/projects/:projectId/indices/:indexId/replace-sessionsProject admin or a full-access secret key
curl -X POST https://api.zaproo-search.com/v1/projects/$PROJECT_ID/indices/$INDEX_ID/replace-sessions \
  -H "Authorization: Bearer $ZS_KEY"
{
  "id": "5d2c9a40-8a51-4c3e-b8f1-2f6d0e7c9b13",
  "version": 4,
  "status": "OPEN",
  "expiresAt": "2026-10-16T15:30:00.000Z",
  "commitTaskId": null
}

Only one version can be built at a time. If a reindex or another session is running, the API answers 409 VERSION_BUILDING.

Send the catalog in batches

POST/v1/projects/:projectId/indices/:indexId/replace-sessions/:sessionId/documentsProject admin or a full-access secret key

The body is the same bare array as an upsert, with the same limits: up to 1000 documents and 10 MB per request. Each batch answers 202 with a SESSION_BATCH task. Send an Idempotency-Key with each batch so a retry does not send it twice.

curl -X POST https://api.zaproo-search.com/v1/projects/$PROJECT_ID/indices/$INDEX_ID/replace-sessions/$SESSION_ID/documents \
  -H "Authorization: Bearer $ZS_KEY" -H "Content-Type: application/json" \
  -H "Idempotency-Key: nightly-2026-10-16-batch-1" \
  -d '[{"id": "tv-1", "title": "55 inch OLED TV", "price": 899}]'

Check every batch

Poll each batch task until it finishes. A document that failed in a batch is not in the new version, so it disappears from search when you commit. Fix and resend failed documents before you commit.

Commit

POST/v1/projects/:projectId/indices/:indexId/replace-sessions/:sessionId/commitProject admin or a full-access secret key

The answer is 202 with a SESSION_COMMIT task. The session moves to COMMITTING and takes no more batches. When the task succeeds, the session is COMMITTED, the index's activeVersion is the session's version and search returns the new catalog.

Watch a session

GET/v1/projects/:projectId/indices/:indexId/replace-sessions/:sessionIdProject member or any secret key

The session's status is one of:

StatusMeaning
OPENTakes batches.
COMMITTINGCommit is running. No more batches.
COMMITTEDThe new catalog is live.
ABORTEDYou aborted it. The live index is as it was.
EXPIREDIt stayed open past expiresAt. The live index is as it was.
FAILEDThe commit failed. The live index is as it was, and the index status is FAILED until the next build.

The index itself names its open session in openReplaceSessionId. In the cabinet, the Reindex panel on the index overview and on Fields & mapping shows an open session with its status, version and expiry. Sessions are opened, filled and committed through the API only.

Abort a session

POST/v1/projects/:projectId/indices/:indexId/replace-sessions/:sessionId/abortProject admin or a full-access secret key

Aborting drops the new version and cancels batches that have not finished. Search never sees any of it. In the cabinet, click Abort session in the Reindex panel. Cancel reindex does not apply to a session.

Session lifetime

A session expires 6 hours after it was opened, counted from the open, not from the last batch. Within a minute of expiresAt, an open session becomes EXPIRED and its new version is dropped. Commit before then. A session that is already committing does not expire.

Errors

CodeWhen
409 VERSION_BUILDINGOpening a session while a reindex or another session builds a version.
409 SESSION_NOT_OPENSending a batch, committing or aborting a session that is no longer OPEN.
404 SESSION_NOT_FOUNDThe session does not exist or belongs to another index.
400 INVALID_DOCUMENTSA batch has documents that do not match the mapping. Nothing from that batch is written.

Common mistakes

  • Committing before every batch task has finished without errors. Commit waits for the batches, but it does not check their results. Failed documents are missing from the new catalog.
  • Opening a session and never committing it. The index stays REINDEXING, and no reindex or breaking mapping change can start until the session expires 6 hours later. Abort it instead.
  • Running a full sync for a handful of changes. Upserts are enough, and they do not block other builds.