[FROSTLABS] · home / writing / walmart pagination
2026-04-05 · 7-min read · Walmart API · Odoo

Walmart's /v3/items pagination is broken. Here's the workaround.

Roughly 30% of pages returned by Walmart Marketplace API's documented item-listing endpoint come back as duplicates of pages you've already pulled. The /v3/reports?reportType=ITEM&reportVersion=v4 async endpoint works correctly. If you're syncing prices, status, or inventory against /v3/items, your catalog doesn't match what's actually live on Walmart, and probably hasn't for as long as the bug has been in place.

$The symptom

Three weeks into a 7-month engagement on an Odoo 18 + multi-marketplace platform, I was paginating Walmart's /v3/items endpoint to refresh status on a few thousand listings, and the data kept looking weird. Same SKU appearing on page 4 and page 7. Item counts that didn't reconcile against the Walmart Seller Center dashboard. Status flags that disagreed depending on which page I trusted.

If you're paginating /v3/items and you see any of these patterns, you have the same bug:

None of those symptoms are obvious in the dashboard. They're discoverable only when you reconcile your sync output against what Walmart actually shows on the seller dashboard, which most Odoo + Walmart operators don't do because there's no obvious reason to suspect the documented endpoint.

$The diagnosis

I ran the pagination twice with identical parameters, byte-compared the response bodies, and confirmed it: roughly 30% of the pages Walmart returned were duplicates of pages already in the previous page set. Same items, same metadata, same offsets, just stuffed into different page numbers across calls.

The way Walmart paginates /v3/items is to return a nextCursor in each response that you pass on the next call. The cursor is opaque, so you can't tell from inspection whether it's correctly advancing. But if you byte-compare the responses across two full traversals, the duplicate rate is unmistakable.

Here's the minimum diagnostic. Make two full traversals of your catalog, save the responses, compare:

# Pseudo-diagnostic. Actual implementation uses your http client of choice.
def traverse_v3_items(seller_id, headers):
    pages = []
    cursor = None
    while True:
        params = {"nextCursor": cursor} if cursor else {}
        r = httpx.get("https://marketplace.walmartapis.com/v3/items",
                      headers=headers, params=params)
        body = r.json()
        pages.append(body)
        cursor = body.get("meta", {}).get("nextCursor")
        if not cursor:
            break
    return pages

run_1 = traverse_v3_items(seller_id, headers)
run_2 = traverse_v3_items(seller_id, headers)

# Compare item sets across the two runs.
skus_run_1 = {item["sku"] for page in run_1 for item in page["ItemResponse"]}
skus_run_2 = {item["sku"] for page in run_2 for item in page["ItemResponse"]}

# Symmetric difference reveals SKUs that appeared in one run but not the other.
# If pagination were correct, this should be a small set (only items created/deleted between runs).
# In practice the symmetric difference is large, and so is the per-run duplicate count.

On the client's catalog of ~7,000 active SKUs, run 1 and run 2 differed on more than 30% of returned items. The remaining 70% appeared correctly in both runs. That's the signature: not random gaps, but a stable subset of items consistently appearing while another subset is sometimes missed.

I never figured out exactly why Walmart's pagination behaves this way. Cursor encoding, server-side sharding inconsistency, async indexing lag: all plausible, none verifiable from the client side. The bug is in their infrastructure. Treating it as a fact and routing around it is the only practical option.

$The workaround

Walmart exposes a separate endpoint specifically for bulk catalog retrieval: /v3/reports with reportType=ITEM and reportVersion=v4. It's an async report. You request the report, poll for completion, then download a CSV from the resulting URL. More steps, but the resulting data is complete and consistent.

The flow:

# 1. Request the report.
r = httpx.post(
    "https://marketplace.walmartapis.com/v3/reports/reportRequests",
    headers=headers,
    json={"reportType": "ITEM", "reportVersion": "v4"},
)
request_id = r.json()["requestId"]

# 2. Poll for completion (typical: 2-15 minutes for catalogs in the low thousands).
while True:
    status = httpx.get(
        f"https://marketplace.walmartapis.com/v3/reports/reportRequests/{request_id}",
        headers=headers,
    ).json()
    if status["reportStatus"] == "AVAILABLE":
        report_url = status["downloadURL"]
        break
    if status["reportStatus"] in ("FAILED", "CANCELLED"):
        raise RuntimeError(f"Walmart report failed: {status}")
    time.sleep(15)

# 3. Download the CSV from the signed URL.
csv_bytes = httpx.get(report_url).content
items = list(csv.DictReader(io.StringIO(csv_bytes.decode("utf-8"))))

You get the whole catalog as a CSV, no pagination, no duplicates, no missed items. Trade-off: it's slower (minutes vs seconds), and you can't stream. You wait for the report to complete then download in full. For status reconciliation, inventory recheck, or any operation where you need accurate data, the trade-off is correct.

On the engagement: re-pushed 2,399 corrected prices once I rewrote the sync to use this endpoint. I never found out exactly how much that bug had cost in lost Buy Box share and mispriced sales, but the catalog was systematically wrong against ground truth for as long as the bug had been in place.

$What this means for your Odoo + Walmart integration

If you're on Odoo with a Walmart connector (whether built in-house, sourced from Webkul, Emipro, or anyone else), check what endpoint is used for catalog sync. The diagnostic above is roughly 30 lines of Python and will tell you in 10 minutes whether you have the bug.

Specifically check:

If any of those use /v3/items as their source of truth, they're operating on bad data. The fix is a few hours of work: rewrite the sync to use /v3/reports?reportType=ITEM&reportVersion=v4 and re-push any state that was set incorrectly. If you're catching this on a several-thousand-listing catalog, expect a one-time re-push of a few hundred to a few thousand SKUs.

$Why this is in the post (not just a private finding)

The Walmart Marketplace API documentation does not warn about this. Their support team, when asked, doesn't acknowledge it. The bug has existed for at least the duration of the engagement and likely longer. Operators discover it the same way: their data starts looking inconsistent and they don't know why.

Writing it up here means the next Odoo + Walmart operator who searches for "Walmart /v3/items duplicate pages" or "Walmart pagination broken" has at least one published reference confirming they're not imagining it. That alone is worth the post.

By David H. Frost · Frost Labs LLC More writing · Home · Privacy