How to Purge Page Cache on Many Sites at Once with the xCloud Public API and MCP

Updated October 30, 2026 · 7 min read

Summarize with:
Share:

You can purge the WordPress page cache on 1 to 100 sites with one request: POST /api/v1/sites/bulk/cache-purge from a script, or the matching tool in any AI agent connected to xCloud MCP. A dry run first shows which sites xCloud can purge, and nothing runs until you confirm. You then read each site’s result from GET /api/v1/sites/bulk-operations/{uuid}.

Use it after a theme or plugin deploy across many client sites, or when one change has to show up everywhere at once. Bulk page cache purge is new in xCloud v2.9.7.4.

What the bulk purge clears

The bulk purge clears the server page cache of each WordPress site: the Nginx page cache on Nginx servers, and the LiteSpeed page cache on OpenLiteSpeed servers. This is the same cache that Purge Cache clears on a site’s Caching page in the dashboard.

On some older Nginx servers the API cannot purge the page cache yet. Those sites show not_eligible, so purge them from the site’s Caching page.

It does not clear:

A site can be purged when it is a provisioned WordPress site on a provisioned, connected Nginx or OpenLiteSpeed server. Any other site in the list is skipped and the rest still run.

Prerequisites

  • An xCloud API token with write:sites to preview and submit, and read:sites to read the results. See How to Access the xCloud API to create one.
  • A team role of Team Admin, Server Admin or Site Admin, with the permission to manage site caching.
  • For MCP, an AI agent connected to xCloud MCP. See How to Connect xCloud MCP to Your AI Agent.
  • The UUIDs of the sites to purge. GET /api/v1/sites lists them, or use the fleet overview.

Step 1: Preview the purge with a dry run

Send the site UUIDs with "dry_run": true. A dry run checks every site and changes nothing: no purge runs and no operation is created.

export XCLOUD_TOKEN='YOUR_API_TOKEN'

curl -X POST 'https://app.xcloud.host/api/v1/sites/bulk/cache-purge' \
  --header "Authorization: Bearer $XCLOUD_TOKEN" \
  --header 'Accept: application/json' \
  --header 'Content-Type: application/json' \
  --data '{
    "sites": [
      "3c4d5e6f-7a8b-4c9d-8e0f-1a2b3c4d5e6f",
      "7e8f9a0b-1c2d-4e3f-8a4b-5c6d7e8f9a0b"
    ],
    "dry_run": true
  }'

Expected result: a 200 response. Each site shows queued (it would be purged) or skipped with a reason:

{
  "success": true,
  "message": "Dry run complete. The payload is valid and nothing was created.",
  "data": {
    "dry_run": true,
    "would_create": {
      "uuid": null,
      "status": "dry_run",
      "items": [
        { "site_uuid": "3c4d5e6f-7a8b-4c9d-8e0f-1a2b3c4d5e6f", "status": "queued", "reason": null, "task_uuid": null, "error": null },
        { "site_uuid": "7e8f9a0b-1c2d-4e3f-8a4b-5c6d7e8f9a0b", "status": "skipped", "reason": "not_eligible", "task_uuid": null, "error": null }
      ],
      "next_actions": []
    },
    "warnings": []
  }
}
reason Meaning
null The site can be purged
not_eligible The site is not a provisioned WordPress site on a connected Nginx or OpenLiteSpeed server, or it is on an older Nginx server where the API cannot purge the page cache yet
not_found The UUID does not exist, or you do not have access to that site

The sites list takes 1 to 100 UUIDs, each one only once. A longer list, a repeated UUID or a value that is not a UUID is refused with 422, and nothing runs.

Step 2: Submit the purge

Send the same list with "confirm": true instead of dry_run. Add an Idempotency-Key header so the request is safe to retry: if the connection drops and you send it again with the same key, xCloud returns the purge that already exists instead of starting a second one.

curl -X POST 'https://app.xcloud.host/api/v1/sites/bulk/cache-purge' \
  --header "Authorization: Bearer $XCLOUD_TOKEN" \
  --header 'Accept: application/json' \
  --header 'Content-Type: application/json' \
  --header 'Idempotency-Key: deploy-2026-10-30-cache' \
  --data '{
    "sites": [
      "3c4d5e6f-7a8b-4c9d-8e0f-1a2b3c4d5e6f",
      "7e8f9a0b-1c2d-4e3f-8a4b-5c6d7e8f9a0b"
    ],
    "confirm": true
  }'

Expected result: a 202 response with the operation uuid and a next_actions entry that tells you where to read progress:

{
  "success": true,
  "message": "Bulk page-cache purge admitted.",
  "data": {
    "uuid": "5b6c7d8e-9f0a-4b1c-8d2e-3f4a5b6c7d8e",
    "status": "running",
    "items": [
      { "site_uuid": "3c4d5e6f-7a8b-4c9d-8e0f-1a2b3c4d5e6f", "status": "queued", "reason": null, "task_uuid": null, "error": null },
      { "site_uuid": "7e8f9a0b-1c2d-4e3f-8a4b-5c6d7e8f9a0b", "status": "skipped", "reason": "not_eligible", "task_uuid": null, "error": null }
    ],
    "next_actions": [
      { "action": "poll", "method": "GET", "url": "/api/v1/sites/bulk-operations/5b6c7d8e-9f0a-4b1c-8d2e-3f4a5b6c7d8e" }
    ]
  }
}

A 202 means xCloud accepted the request, not that the caches are already clear. Without "confirm": true (and without "dry_run": true) the request is refused with 422.

To purge sites in another team granted to your token, add the X-Team-Id header. See Multi-Team API Tokens and MCP Access.

Step 3: Poll each site’s result

Read the operation with the URL from next_actions. This call needs read:sites and changes nothing.

curl 'https://app.xcloud.host/api/v1/sites/bulk-operations/5b6c7d8e-9f0a-4b1c-8d2e-3f4a5b6c7d8e' \
  --header "Authorization: Bearer $XCLOUD_TOKEN" \
  --header 'Accept: application/json'

Expected result: the same shape as Step 2, with each site’s current status. Poll every few seconds until the operation status is no longer running.

Site status Meaning
queued Waiting for its turn on its server
running The purge is running on the server
done The purge finished successfully
failed The purge did not finish, or it did not start in time. error says which
skipped Not purged. reason says why

The operation status is completed when no site failed (sites that were skipped count as not failed), completed_with_failures when some failed and some finished, and failed when sites failed and none finished. An operation where every site was skipped is also completed, so check each site’s status instead of trusting the operation status alone.

xCloud purges one site at a time on each server, and different servers run side by side. Sites that have not started within five minutes of the request are marked failed and nothing ran on them.

If you lose access to a site after submitting, that site shows skipped with not_found in the results.

Step 4: Retry or check failed sites

The error text of a failed site tells you what to do next:

error What to do
Not started before the five-minute deadline; nothing ran. Retry with a new Idempotency-Key. Submit those sites again with a new key
Admission stopped before this purge started; nothing ran. Retry with a new Idempotency-Key. Submit those sites again with a new key
Purge completion was not confirmed. Check the site before retrying. Open a page of the site first. The purge may have run. Submit again only if the page is still out of date

xCloud never retries a failed purge on its own. Send only the failed site UUIDs in the new request.

On OpenLiteSpeed sites, open a page after the purge to confirm visitors see the new version.

Purge with an AI agent over MCP

In an MCP client connected to xCloud, ask in plain language:

Purge the page cache on all my WordPress sites on the server docs-demo.
Do a dry run first and show me which sites will be skipped, then wait for my OK.

The agent calls the sites_bulk_cache-purge tool. A dry run needs no confirmation. The real purge is marked as a destructive tool, so most MCP clients ask you to approve it before it runs. Check your client’s approval setting. On the compact MCP profile, the agent runs the sites.bulk.cache-purge operation through xcloud_execute_destructive, and reads the result with sites.bulk-operations.show through xcloud_execute_read, which changes nothing.

Expected result: the agent lists the sites it will purge and skip, waits for your approval if your client asks for it, then reports each site’s final status.

Troubleshooting

Response Cause Fix
401 No bearer token, or the token was revoked Send Authorization: Bearer <token> with an active token
403 on submit The token lacks write:sites, or your role cannot manage site caching Use a token with write:sites and ask the team owner for caching access
403 on poll The token lacks read:sites Use a token with read:sites
404 on poll The operation UUID is wrong or belongs to another team Use the URL from next_actions with the same team
409 A request with the same Idempotency-Key is still being accepted Wait a moment and send it again with the same key
422 Invalid list, missing confirm, or the Idempotency-Key was already used with a different body Fix the body, or use a new key for a different list
429 More than 30 purge requests in a minute Wait a minute. Put more sites in one request instead of many small ones

Frequently asked questions

Does the bulk purge clear Cloudflare, Edge Full Page Cache or Redis?

No. It clears only the server page cache of each WordPress site, the same cache the Purge Cache button on the site’s Caching page clears. Cloudflare and Edge Full Page Cache, Redis Object Cache and Object Cache Pro are not touched.

Why does a site show skipped with the reason not_eligible?

The site is not a provisioned WordPress site on a connected Nginx or OpenLiteSpeed server that xCloud can purge from the API. Some older Nginx servers also show not_eligible, because the API cannot purge their page cache yet. Check that the site and server are provisioned and connected. If the site looks healthy, purge it from its Caching page in the dashboard, or contact support.

Is it safe to send the same purge request twice?

Yes, when you send an Idempotency-Key header. A repeated request with the same key and the same body returns the operation that already exists instead of starting a second purge. The same key with a different body is refused with 422.

Why does polling return 403 when submitting worked?

Submitting needs the write:sites permission, but reading the result needs read:sites. Create a token that has both permissions if one script submits and polls.

Next steps

If you run into any issues with bulk page cache purge, feel free to reach out to our support team for help.