A reliable Salla order backfill must preserve the API's sequential page session rather than treating page numbers as independent jobs. Salla's current List Orders documentation says pages must be requested in order, skipped pages can return empty results, the sequence should finish within a 15-minute cached window, and date filters should be used to reduce the dataset. The safe design is therefore a short, single-owner window with durable checkpoints at completed date slices—not a fan-out of page 1 through page N.
This is a practical engineering guide, not a claim that Salla released a new product feature. The official documentation was verified on 19 October 2026. Where this article recommends leases, reconciliation, adaptive windows or database constraints, those are application-side design choices inferred from the documented contract.
Start from the documented contract
The Salla List Orders endpoint currently recommends sequential pagination, a maximum page size of 30 for this endpoint, completion within a 15-minute cached pagination window, and date filters such as from_date and to_date. The platform's general pagination guide describes the pagination object and page/per_page controls, while the rate-limiting guide documents plan-dependent request budgets and the X-RateLimit-Limit, X-RateLimit-Remaining, Retry-After and X-RateLimit-Reset headers.
Those statements create one important engineering consequence: a page is not a durable business checkpoint. Page 8 is meaningful only inside the current ordered traversal. If the run loses its cache window, changes filters, changes page size, or restarts from an arbitrary page, it can no longer prove that page 8 represents the same slice of orders.
The durable checkpoint should instead describe business time and processing state: store ID, closed time-window start and end, filter set, high-water order timestamp or identifier, last successful reconciliation time, and a run ID. Page number is useful only as transient progress inside a live lease.
Choose bounded time windows
Do not ask one pagination session to cover the entire lifetime of a busy store. Partition history into closed windows—such as one day, one hour, or a smaller adaptive interval—and finish one window before moving to the next. Use the largest interval that consistently completes well inside the documented 15-minute window at the store's observed order volume and rate-limit budget.
Closed windows reduce two kinds of drift. First, new orders arriving now do not keep changing an old historical slice. Second, a failed run replays only a bounded interval. Leave a small overlap between adjacent windows or periodically re-read a recent correction window because order records can be updated after creation. Deduplicate by the stable Salla order ID in your database; do not deduplicate by page position.
A high-volume campaign day may require five-minute windows, while a quiet store may safely use a day. Make the partitioner adaptive: if a window finishes quickly with budget remaining, cautiously enlarge the next historical window; if the run approaches its deadline or receives rate-limit pressure, shrink the next one. Never change the filters or page size halfway through a live traversal.
Keep one owner for each store and window
Acquire a lease keyed by store and window before requesting page 1. The lease prevents two workers from racing through the same sequential session. Store the run ID, filter hash, page size, lease expiry, started-at time and current transient page. Renew the lease after a complete page has been written transactionally.
If the worker crashes, a successor should not blindly continue at the stored page. Check whether the original run can still finish inside its cache window and whether every request parameter matches. When that proof is unavailable, start the same bounded business window again at page 1 and rely on idempotent upserts. Re-reading a small window costs requests; silently skipping orders costs correctness.
Run different stores concurrently because their budgets and pagination sessions are independent, but keep each individual store-window traversal sequential. A global queue can still apply fairness so a huge backfill does not delay live order webhooks or small corrective reads. The earlier Salla API budget guide explains per-store admission and fair scheduling; the distinction here is that page concurrency must remain one within an order-list traversal.
Write every page idempotently
Process a page inside a database transaction. Upsert each order by store_id plus Salla order ID, preserve the upstream updated timestamp, and reject an older payload from overwriting a newer record. Record the raw payload or a content hash when auditability matters. Only after every row and its dependent records succeed should the transaction mark that page complete for the current run.
Do not send downstream side effects directly from the pagination loop. Put changes into an outbox in the same transaction, then publish them asynchronously. A replayed page can safely produce the same deterministic event key, while consumers ignore duplicates. Without that boundary, a database retry can send the same ERP command, fulfillment request or customer notification twice.
The following state is sufficient for a recoverable controller:
{
"store_id": "merchant-42",
"window": { "from": "2026-10-01T00:00:00Z", "to": "2026-10-02T00:00:00Z" },
"filter_hash": "sha256:...",
"page_size": 30,
"transient_page": 7,
"started_at": "2026-10-19T16:00:00Z",
"lease_until": "2026-10-19T16:02:00Z",
"run_id": "backfill-01K..."
}The transient page helps observe the live run; it is not permission to resume days later. The durable completion record is the closed window plus its reconciliation result.
Budget against headers, not guesses
Read the rate-limit headers on every response and expose them as metrics. Slow or pause before remaining capacity reaches zero, because the same store may also need live reads or writes. Respect Retry-After when present; HTTP defines it as the time the client should wait before a follow-up request. Add jitter so many workers do not wake at the same instant.
Reserve part of each store's capacity for production-critical traffic. Backfill is usually lower priority than a payment confirmation, order status update or webhook reconciliation. A scheduler can allocate tokens by class—for example live, reconciliation and historical—without hard-coding one request rate for every merchant plan. Treat undocumented limits as changeable and derive behavior from current headers and observed responses.
On 429, do not advance the page. Wait according to Retry-After or the reset header, renew the lease only if the run can still finish safely, and restart the bounded window when the sequential session has become uncertain. On 401, stop and refresh authorization through the application's normal token workflow; repeated retries with the same credential waste the window. On 5xx or transport timeout, retry the same page with bounded exponential backoff, then restart the window if continuity cannot be proven.
Reconcile webhooks with backfills
Webhooks and backfills solve different problems. Webhooks provide low-latency change signals; a bounded order read repairs missed, delayed or failed deliveries. Route both through the same idempotent order projection so arrival order does not decide truth. Compare upstream updated timestamps and keep provenance for the last applied version.
A sensible production cycle is: consume webhooks continuously, re-read a short recent correction window regularly, and run historical backfills in low-priority windows. After a historical window completes, perform a reconciliation query or count check that is meaningful for your local model. Do not declare success merely because totalPages was reached; verify that the run had no failed page transaction, no expired lease and no unresolved rate-limit interruption.
For webhook delivery mechanics, see the Salla and Zid webhook recovery guide. If the integration also synchronizes inventory, keep order ingestion separate from stock movement accounting; the Salla ERP inventory audit design shows why a durable ledger is safer than overwriting the latest quantity.
Best practices and anti-patterns
Use date filters, stable filter hashes, one owner per store-window, sequential page requests, idempotent database upserts and an outbox. Monitor window duration, pages per window, duplicate rate, replay count, 429 responses, remaining budget, lease loss and reconciliation lag. Alert before a typical run approaches the 15-minute boundary rather than after it crosses it.
Avoid launching one job per page. Avoid storing page 37 as the only checkpoint. Avoid changing per_page during a run. Avoid parallel workers for one traversal. Avoid letting historical imports consume the store's entire request budget. Avoid interpreting an empty skipped page as the end of data. And avoid advancing the durable watermark until reconciliation has passed.
When not to use this pattern
Use webhook-only processing when the integration starts now, tolerates no historical import and has a verified recovery mechanism for missed deliveries. Use Salla's documented order export endpoint when the business need is a human-readable CSV or XLSX report rather than an application projection; an export workflow has different completion and delivery semantics. Use a narrow direct query when support needs one known order, not a full traversal.
This backfill pattern is appropriate when an ERP, warehouse, analytics store or search index needs a trustworthy local order history. It deliberately trades page-level parallelism for a provable sequence, then recovers throughput by partitioning time and running independent stores concurrently. The core rule is simple: checkpoint business windows durably, keep pages transient, and restart uncertain windows from page 1.
Implementation checklist
Before production, verify the current Salla contract, select a conservative date window, enforce one active lease, pin filters and page size, write pages transactionally, reserve live-traffic capacity, respect Retry-After, and test crashes after both the API response and the database commit. Prove that a replay does not duplicate side effects. Finally, reconcile the closed window and only then advance the durable watermark.
Official references
These references document the tools discussed. Examples and design decisions are illustrative and should be adapted to the project and its versions.
- Salla — List Orders pagination guidance, last modified 8 October 2026; verified 19 October 2026
- Salla — Pagination response and parameters, verified 19 October 2026
- Salla — Rate limiting and response headers, verified 19 October 2026
- Salla — Export Orders endpoint, last modified 6 October 2026; verified 19 October 2026
- IETF HTTP Semantics — Retry-After, RFC 9110 section 10.2.3
Prepared by: Noor Yasser
Working through a similar engineering challenge?
I help teams turn architecture decisions into a clear scope and dependable, reviewable implementation.




