> ## 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.

# AXP Render API: Queue Optimized Page Renders

> Queue asynchronous render jobs that fetch, sanitize, and persist pages on your AXP site so optimized content is ready to deploy from one API call.

## Overview

The AXP Render API queues asynchronous render jobs for paths on a registered AXP site. Each job fetches the live page from your origin, strips noise (scripts, styles, inline event handlers, base64 images), and persists the cleaned HTML as an optimized page that you can then edit, version, and deploy from the Scrunch dashboard.

Use it to seed an AXP site with content programmatically — for example, after a sitemap import or when onboarding a new domain — without clicking through **Add Content** for each path.

Renders run in the background. The endpoint responds as soon as jobs are queued; you can correlate the returned `job_id` with the page that appears in the AXP content list once the job completes.

***

## When to use the AXP Render API

Use this API when you need to:

* Bulk-seed an AXP site with optimized pages for a known list of paths.
* Re-render an archived path to reactivate it as an Active page.
* Refresh stale renders after a marketing-site redeploy, on a schedule.

For interactive, one-off renders, use **Add Content → Render from site** in the Scrunch dashboard. For audit-then-optimize-then-deploy workflows, use the [Optimize and Deploy API](/api-reference/optimize-deploy) instead.

***

## Endpoint

| Method | Path                                                       | Purpose                                          |
| ------ | ---------------------------------------------------------- | ------------------------------------------------ |
| POST   | `/v2/orchestration/render-bulk/{brand_id}/sites/{site_id}` | Queue render jobs for a list of paths on a site. |

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

***

## Request

| Field   | Type       | Required | Description                                                                                                    |
| ------- | ---------- | -------- | -------------------------------------------------------------------------------------------------------------- |
| `paths` | `string[]` | Yes      | Paths to render. Each entry is trimmed and given a leading slash if missing. Capped at **100 paths** per call. |

### Path normalization and deduplication

Before queueing, the API normalizes each path:

* Surrounding whitespace is stripped.
* A leading `/` is added when missing.
* Duplicates after normalization are dropped, preserving input order.

So `["/blog", "blog", " /blog "]` queues a single job for `/blog`.

### Coalescing in-flight jobs

If a path already has a `pending` or `running` job on the same site, the request returns the existing `job_id` instead of queueing a new one. This makes the endpoint safe to retry with the same batch — you won't end up with duplicate renders or duplicate optimized pages.

***

## Response

The response is an array of items, one per unique path:

| Field    | Type      | Description                                                                                                                   |
| -------- | --------- | ----------------------------------------------------------------------------------------------------------------------------- |
| `path`   | `string`  | The normalized path the job was queued for.                                                                                   |
| `job_id` | `integer` | Identifier of the render job. Use it for correlation in logs.                                                                 |
| `status` | `string`  | Job status at response time. `pending` means a fresh job was queued; `running` means the call coalesced onto an existing job. |

Job status values: `pending`, `running`, `succeeded`, `failed`, `cancelled`.

***

## Example: queue renders

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

**Response:**

```json theme={null}
[
  { "path": "/", "job_id": 1842, "status": "pending" },
  { "path": "/pricing", "job_id": 1843, "status": "pending" },
  { "path": "/blog/launch-announcement", "job_id": 1801, "status": "running" }
]
```

In this response the first two paths were freshly queued, and `/blog/launch-announcement` coalesced onto an in-flight job (`1801`) from an earlier call.

***

## Errors

| Status | When                                                                                                                                     |
| ------ | ---------------------------------------------------------------------------------------------------------------------------------------- |
| `400`  | The site is not active for AXP, or has no domain configured.                                                                             |
| `404`  | No site with the supplied ULID exists for the brand.                                                                                     |
| `422`  | The request body failed validation (empty `paths`, more than 100 entries, path longer than 2048 chars).                                  |
| `502`  | Jobs were persisted but at least one dispatch to the background worker failed. The affected jobs are marked `failed`; retry those paths. |

***

## Limits and behavior

* Maximum **100 paths** per request. Split larger batches into multiple calls.
* Each path must be 1–2048 characters after normalization.
* The target site must have `axp_status` set to `active` and a configured domain.
* Re-rendering a path that exists as an archived page reactivates it as **Active** and logs a `CONTENT_CREATED` event.
* Pages rendered through this API show up in the AXP content list with the same statuses as renders started from the dashboard.

***

## Best practices

* Poll the dashboard or correlate job IDs from your logs to confirm completion — `succeeded` jobs produce an optimized page you can deploy.
* Retry idempotently. Because in-flight jobs coalesce, the same batch can be sent again after a network error without creating duplicate work.
* Pair with the [Sitemap API](/api-reference/sitemap/overview) to source the path list. Filter by `is_priority=true` to seed AXP with your most important pages first.
