GuidesSynchronize the catalog

Synchronize the catalog

Keep a local catalog that survives disconnects. You need an API key, persistent storage, a streaming JSON parser, and a server-side WebSocket client that can set an Authorization header. For runnable implementations, see Examples.

1. Stage a complete snapshot

Request GET /api/v1/merchant/items/full-dump with gzip support. Read the complete body into a temporary table or file. Keep ETag, X-Catalog-Cursor, and X-Catalog-Epoch with that snapshot. Verify successful decompression, complete JSON, and items_count before replacing the working catalog.

Publish the completed items and their checkpoint together, atomically. A partial download must leave the previous catalog and checkpoint intact. The ETag describes the snapshot, not changes you apply later through the feed.

A 304 has no body: reuse the matching complete cached snapshot and the checkpoint that belongs to it. Never combine a snapshot checkpoint with a working catalog that has since advanced. If either checkpoint header is absent, keep serving your existing state or use REST while waiting for a newly generated snapshot with both headers. Do not start a complete mirror from a connection without a cursor.

2. Replay from the snapshot cursor

Open the WebSocket with the saved snapshot cursor and Bearer header. Check that the hello epoch matches the snapshot epoch. The hello cursor is a connection-time head; it does not mean those changes have been applied.

For each batch, apply its events in order: insert or replace offer.added, set the absolute price for offer.price_changed, and remove offer.removed. Unknown IDs on price/removal events are safe to ignore. Snapshot and replay may overlap, so reapplying events must be safe.

Commit the whole batch and its cursor together. Do not advance a cursor ahead of durable item changes. See the frame and event contracts for the exact fields.

3. Continue with live updates

Replay and live batches use the same format and connection; no subscribe message is needed. Reply to each JSON ping with the text message {"type":"pong"}. A WebSocket control pong alone does not satisfy this heartbeat. A ping cursor may be saved only after earlier batches on that connection have been applied.

Use an hourly snapshot to refresh attributes outside the feed’s price/visibility changes. Stage the replacement, stop applying the previous stream, publish the new snapshot and checkpoint, then replay from that checkpoint before serving the updated mirror.

4. Recover without skipping changes

SituationNext action
Transport disconnect or 1001 / 4002Back off and reconnect with the last fully applied cursor.
4001 resync_required or an epoch mismatchObtain a newly generated full snapshot and repeat the flow. Do not reconnect indefinitely with the rejected cursor.
JSON ping reports engine: "degraded"Temporarily refresh through REST snapshots; changes may not be entering the feed.
4003 too_many_connectionsCoordinate client instances and keep at most two connections per key.
HTTP 429Wait for Retry-After; full dump requests are limited to one per 60 seconds.
HTTP 503 FEED_NOT_READYBack off; wait for the feed and a usable snapshot checkpoint.

The retained replay tail is bounded; it has no guaranteed duration. A new snapshot is the recovery path when the tail no longer covers your checkpoint. See Reconnect and limits.