Skip to content

Sites API

The Sites API is the core of Pageflare. You upload a zip of your built site, poll until optimization is complete, then download the result.

https://pageflare.dev/_api

All requests require an Authorization: Bearer <your-token> header. See Authentication for details.

queued → running → complete
↘ errored

After uploading, a site moves through these statuses:

StatusMeaning
queuedUpload received; job is waiting in the processing queue
runningOptimization is actively in progress
completeOptimization finished successfully; download is available
erroredOptimization failed; see the error field for details

Upload a zip archive of your built site for optimization.

Multipart upload (zip + optional config together):

POST /_api/sites
Content-Type: multipart/form-data
Authorization: Bearer <your-token>
file=<zip-binary>
config={"minify_html":true,"minify_css":true}

Raw upload (zip body only):

POST /_api/sites
Content-Type: application/octet-stream
Authorization: Bearer <your-token>
<zip-binary>

Constraints:

  • Maximum file size: 50 MB
  • config (optional): JSON string with optimization flags. Omitting it uses your account defaults.

Config fields:

FieldTypeDefaultDescription
minify_htmlbooleantrueCollapse whitespace and remove comments from HTML
minify_cssbooleantrueMinify inline and linked CSS
minify_jsbooleantrueMinify inline and linked JavaScript
js_deferbooleantrueAdd defer to non-critical script tags
lazy_imagesbooleantrueAdd loading="lazy" to below-the-fold images
img_dimensionsbooleantrueInject missing width/height attributes on <img> tags
font_swapbooleantrueAdd font-display: swap to @font-face rules
self_host_fontsbooleanfalseDownload and inline Google Fonts (Pro)
critical_cssbooleanfalseExtract and inline critical CSS (Pro)
youtube_facadesbooleanfalseReplace YouTube embeds with click-to-load facades (Pro)

201 Created

{
"id": "site_abc123"
}

Use the returned id to poll for status and to download the result.

POST/sites
Request
Response
Click Send to make a request
StatusMeaning
400 Bad RequestMissing or invalid zip file, or malformed config JSON
401 UnauthorizedInvalid or missing token
413 Content Too LargeFile exceeds the 50 MB limit

Poll for the status of an optimization job.

GET /_api/sites/site_abc123
Authorization: Bearer <your-token>

200 OK

{
"id": "site_abc123",
"status": "complete",
"fileCount": 42,
"bytesIn": 524288,
"bytesOut": 327680,
"bytesSaved": 196608,
"error": null,
"createdAt": "2026-03-12T10:30:00.000Z",
"completedAt": "2026-03-12T10:30:12.000Z"
}

Response fields:

FieldTypeDescription
idstringSite identifier
statusstringOne of queued, running, complete, errored
fileCountnumber | nullNumber of files processed (available when complete)
bytesInnumber | nullTotal input size in bytes
bytesOutnumber | nullTotal output size in bytes
bytesSavednumber | nullBytes saved (bytesIn - bytesOut)
errorstring | nullError message if status is errored, otherwise null
createdAtstringISO 8601 timestamp of when the job was created
completedAtstring | nullISO 8601 timestamp of completion, or null if still in progress
GET/sites/:id
Request
Response
Click Send to make a request
StatusMeaning
401 UnauthorizedInvalid or missing token
404 Not FoundNo site with the given ID

Download the optimized zip archive once a job has reached complete status.

GET /_api/sites/site_abc123/download
Authorization: Bearer <your-token>

200 OK — binary zip stream

Content-Type: application/zip
Content-Disposition: attachment; filename="site_abc123.zip"

202 Accepted — if the job is still queued or running:

{
"status": "running"
}

Retry after a short delay when you receive 202.

async function waitForOptimization(id, token) {
const headers = { Authorization: `Bearer ${token}` };
while (true) {
const res = await fetch(`/_api/sites/${id}`, { headers });
const data = await res.json();
if (data.status === 'complete') break;
if (data.status === 'errored') throw new Error(data.error);
await new Promise(r => setTimeout(r, 2000)); // wait 2 s
}
const download = await fetch(`/_api/sites/${id}/download`, { headers });
return download.blob();
}
StatusMeaning
401 UnauthorizedInvalid or missing token
404 Not FoundNo site with the given ID
500 Internal Server ErrorJob errored; check status endpoint for details