> ## Documentation Index
> Fetch the complete documentation index at: https://developers.scrunch.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Agent Pages Force Refresh: Update Pages on Demand

> Refetch Agent Pages from your live site now and republish them without waiting for the next scheduled check.

## Overview

Agent Pages are kept fresh automatically: Scrunch checks your pages on a schedule and re-optimizes the ones that changed. Force Refresh lets you skip the wait. It refetches the pages you name from your live site, then re-optimizes and republishes them whether or not they changed.

Use it right after you publish a change on your site, so AI agents see the new version as soon as possible.

***

## When to use Force Refresh

Use this API when you need to:

* Push a content update, correction, or pricing change to agents right after it goes live on your site.
* Refresh a set of pages after a deploy, from your CI or CMS publish hook.
* Re-run optimization on a page you believe is out of date.

Force Refresh only refreshes pages that already have an active Agent Page. New pages are picked up by the regular crawl.

***

## Endpoint

| Method | Path | Purpose |
| - | - | - |
| POST | `/v1/{brand_id}/sites/{site_id}/agent-pages/refresh` | Refresh a list of paths on one site. |

The endpoint requires a bearer token with the `optimize` scope. See [Authentication](/getting-started/authentication).

***

## Request

| Field | Type | Required | Description |
| - | - | - | - |
| `paths` | `string[]` | Yes | Site-relative paths to refresh, for example `/pricing`. **1 to 100 paths** per call. |

### Path rules

* Each path is trimmed and can be up to 2,048 characters.
* Paths must be site-relative. Full URLs (`https://example.com/pricing`) and protocol-relative URLs (`//example.com/pricing`) are rejected with a `422`.
* Paths are normalized the same way Agent Pages are stored: lowercased, with the trailing slash and query string dropped. Duplicates after normalization are merged, keeping the first.
* `/` is the homepage.

***

## Response

The endpoint returns `202 Accepted`: refreshes run in the background after the response. The body holds one result per requested path, in request order, and the brand's remaining quota.

| Field | Type | Description |
| - | - | - |
| `results[].path` | `string` | The normalized path this outcome applies to. |
| `results[].outcome` | `string` | What happened to this path. See the table below. |
| `results[].retry_after` | `string \| null` | For `cooldown`, when this path can be refreshed again (ISO 8601, UTC). |
| `quota.hourly` / `quota.daily` | `object` | The brand's two quota windows, each with `limit`, `remaining`, and `resets_at`. |

### Outcome values

| Outcome | Meaning | What to do |
| - | - | - |
| `queued` | Accepted. The page will be refetched, re-optimized, and republished. | Nothing. |
| `not_found` | The site has no active Agent Page at this path. | Check the path. New pages are picked up by the regular crawl. |
| `excluded` | The site's Ignore or Priority List doesn't allow this path. | Update the list in the Scrunch dashboard if the page should be served. |
| `cooldown` | This page was refreshed in the last 5 minutes. | Retry after `retry_after`. |
| `rate_limited` | The brand's hourly or daily quota ran out partway through this batch. | Retry after `quota.*.resets_at`. |

Only `queued` paths count toward any limit.

***

## Limits

| Limit | Value | When exceeded |
| - | - | - |
| Paths per request | 100 | `422`; nothing is queued. |
| Per path | 1 refresh every 5 minutes | That path returns `cooldown`. |
| Per brand, hourly | 500 refreshes per rolling hour | Extra paths return `rate_limited`; `429` if nothing could be queued. |
| Per brand, daily | 5,000 refreshes per rolling 24 hours | Extra paths return `rate_limited`; `429` if nothing could be queued. |

The hourly and daily quotas are shared by all of a brand's sites. Queued refreshes run a few at a time per site, so a batch of 100 completes over several minutes rather than instantly.

***

## Example: refresh pages after a deploy

```bash theme={null}
curl -X POST \
  "https://api.scrunchai.com/v1/1234/sites/01JEXAMPLE00000000000000/agent-pages/refresh" \
  -H "Authorization: Bearer $SCRUNCH_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "paths": [
      "/pricing",
      "/blog/launch",
      "/careers"
    ]
  }'
```

**Response:**

```json theme={null}
{
  "results": [
    { "path": "/pricing", "outcome": "queued", "retry_after": null },
    { "path": "/blog/launch", "outcome": "cooldown", "retry_after": "2026-10-07T18:42:10Z" },
    { "path": "/careers", "outcome": "not_found", "retry_after": null }
  ],
  "quota": {
    "hourly": { "limit": 500, "remaining": 499, "resets_at": "2026-10-07T19:02:41Z" },
    "daily": { "limit": 5000, "remaining": 4987, "resets_at": "2026-10-08T09:15:03Z" }
  }
}
```

***

## Errors

| Status | When |
| - | - |
| `401` | The API key is missing or invalid. |
| `403` | The API key lacks the `optimize` scope or access to the brand. |
| `404` | No site with the supplied ULID exists for the brand, or Agent Pages aren't enabled for the brand. |
| `409` | Agent Pages aren't active on this site. Nothing is queued and no quota is used. |
| `422` | The request body failed validation (empty `paths`, more than 100 entries, an empty path, a path over 2,048 characters, or a full URL). |
| `429` | The brand's hourly or daily quota is used up and nothing could be queued, or another refresh request for the same brand is still being processed. The `Retry-After` header gives the seconds to wait (`1` for a request in progress). |
| `503` | The refresh couldn't be queued right now. Nothing was queued and no quota was used; retry shortly. |

A path that is in cooldown, not found, or excluded doesn't cause an error: the request still returns `202` with those outcomes.

***

## Best practices

* **Refresh only what changed.** Send the paths your deploy touched rather than your whole site; the scheduled checks already cover everything else.
* **Retry safely.** Re-sending a path within 5 minutes returns `cooldown` and uses no quota.
* **Respect the quota.** On `rate_limited` or `429`, wait for `quota.*.resets_at` or the `Retry-After` header before sending more.
* **Send one request at a time per brand.** Requests for the same brand are processed one at a time; a request sent while another is in progress gets `429` with `Retry-After: 1`. Batch paths into one request (up to 100) rather than sending many single-path requests in parallel.
* **Don't poll for completion yet.** `queued` means the refresh was accepted, not that it finished. Allow a few minutes for a batch to republish.


## Related topics

- [Force Refresh](/api-reference/agent-pages/force-refresh.md)
- [AXP Unpublish API: Take Optimized Pages Off the Edge](/api-reference/axp/unpublish.md)
- [Unpublish Optimized Pages](/api-reference/axp-render/unpublish-optimized-pages.md)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.