url_requiredHTTP 400
- When
- The first run of an audit was started without a URL.
- Recovery
- Pass
urlon the first run; it is locked to the audit from then on. - Answered by
- POST
/api/v1/audits/{auditId}/runs
PageSpeedAudit Developers · Error catalog
Every refusal the API makes on purpose is RFC 9457 problem+json. Branch on code — it is
stable — and never on detail, which is free to improve. The type on every
such response is a link to its row on this page, so the error in your terminal is one click from its
recovery. Three answers carry no body: a bare 401, 429 and 500.
{
"type": "https://pagespeedaudit.com/docs/errors#runs_exhausted",
"title": "Conflict",
"status": 409,
"detail": "All included runs have been used.",
"code": "runs_exhausted"
}49 codes
url_requiredHTTP 400
url on the first run; it is locked to the audit from then on./api/v1/audits/{auditId}/runsinvalid_urlHTTP 400
https://example.com/; private, local and non-http addresses are refused.invalid_formatHTTP 400
format was something other than json or html.format=json for the findings document or format=html for the customer report./api/v1/runs/{runId}/reportinvalid_quantityHTTP 400
quantity is below 1 or above the per-order maximum.detail; split larger volumes into several orders./api/v1/ordersidempotency_key_requiredHTTP 400
Idempotency-Key header (or idempotencyKey in the body)./api/v1/ordersunknown_scopeHTTP 400
read, run and purchase./api/v1/apikeysunusable_emailHTTP 400
email and let Checkout collect it./api/v1/checkout/sessionsinvalid_dateHTTP 400
from or to is not an ISO 8601 date.2026-07-01 or 2026-07-01T00:00:00Z./api/v1/affiliate/statsinvalid_group_byHTTP 400
groupBy was something other than subid or campaign.groupBy=subid, groupBy=campaign, or omit it for totals only./api/v1/affiliate/statsinvalid_statusHTTP 400
status was not one of the referral states.pending, approved, reversed or paid, or omit it./api/v1/affiliate/referralsinvalid_postback_eventsHTTP 400
events named an event the postback cannot fire on.sale, approved, reversed; omit the list for sale only./api/v1/affiliate/postbackinvalid_postback_urlHTTP 400
detail says which.url to clear it./api/v1/affiliate/postbackinvalid_emailHTTP 400
disposable_emailHTTP 400
/api/v1/newsletter/subscribeinvalid_messageHTTP 400
/api/v1/contactinvalid_webhook_urlHTTP 400
/api/v1/webhooksemail_mismatchHTTP 400
email is not the authenticated account's address. A message sent through the API is filed under the account's own address.email out, or send the account's own address./api/v1/contactinvalid_accessHTTP 400
detail says what, in plain words (a missing password, a login page on another domain, a cookie that could not be read), and field names the request field.detail names and send the access again. The login page and cookies must belong to the audited site, or to a domain listed in extraHosts./api/v1/audits/{auditId}/accessauthentication_requiredHTTP 402
orderId and a checkoutUrl.checkoutUrl from the problem body in a browser to finish the payment; poll GET /orders/{orderId} for completed. Nothing was charged./api/v1/orderscard_declinedHTTP 402
detail says which. The problem carries the recorded order's orderId.detail says declined, nothing was charged: ask the account holder to update the card under Billing, then order again with a new Idempotency-Key. If detail says the charge did not complete, the outcome is unknown: read GET /orders/{orderId} before retrying./api/v1/ordersinsufficient_scopeHTTP 403
detail names it.purchase is never implicit./api/v1/audits/{auditId}/runsPOST /api/v1/ordersGET /api/v1/orders/{orderId}GET /api/v1/ordersPOST /api/v1/target-finder/analysesGET /api/v1/meGET /api/v1/auditsGET /api/v1/audits/{auditId}GET /api/v1/audits/{auditId}/runsGET /api/v1/runs/{runId}GET /api/v1/runs/{runId}/eventsGET /api/v1/runs/{runId}/reportGET /api/v1/target-finder/analyses/{analysisId}GET /api/v1/target-finder/analysesPOST /api/v1/login-wallGET /api/v1/audits/{auditId}/accessPUT /api/v1/audits/{auditId}/accessDELETE /api/v1/audits/{auditId}/accessPOST /api/v1/audits/{auditId}/access/checkDELETE /api/v1/webhooks/{webhookId}POST /api/v1/webhooks/{webhookId}/testdashboard_session_requiredHTTP 403
api_key_requiredHTTP 403
purchase scope, or buy on /pricing. A session is deliberately never enough to place an order here.not_agency_ownerHTTP 403
/api/v1/orderscustomers_onlyHTTP 403
/api/v1/target-finder/analysesnot_an_affiliateHTTP 403
cross_site_requestHTTP 403
X-Api-Key credential — the supported way to call this API from anywhere — or make the request from this site's own origin. This is a cross-site request forgery guard, not a permission check: the credential is fine, the origin is not./api/v1/audits/{auditId}/runsPOST /api/v1/apikeysDELETE /api/v1/apikeys/{keyId}POST /api/v1/ordersPOST /api/v1/target-finder/analysesPUT /api/v1/affiliate/postbackPOST /api/v1/contactPOST /api/v1/login-wallPUT /api/v1/audits/{auditId}/accessDELETE /api/v1/audits/{auditId}/accessPOST /api/v1/audits/{auditId}/access/checknot_foundHTTP 404
GET /audits, GET /orders or GET /target-finder/analyses listings; an audit listed as Revoked has no readable runs./api/v1/audits/{auditId}GET /api/v1/audits/{auditId}/runsPOST /api/v1/audits/{auditId}/runsGET /api/v1/runs/{runId}GET /api/v1/runs/{runId}/eventsGET /api/v1/runs/{runId}/reportGET /api/v1/orders/{orderId}GET /api/v1/target-finder/analyses/{analysisId}DELETE /api/v1/apikeys/{keyId}GET /api/v1/audits/{auditId}/accessPUT /api/v1/audits/{auditId}/accessDELETE /api/v1/audits/{auditId}/accessPOST /api/v1/audits/{auditId}/access/checkreport_not_readyHTTP 404
GET /runs/{runId} until status is Succeeded; a Failed or TimedOut run has no report and did not consume a run./api/v1/runs/{runId}/reportaccount_not_foundHTTP 404
/api/v1/ordersurl_lockedHTTP 409
url or send the same one. A different page needs its own audit./api/v1/audits/{auditId}/runsrun_in_progressHTTP 409
/api/v1/audits/{auditId}/runsruns_exhaustedHTTP 409
/api/v1/audits/{auditId}/runsexpiredHTTP 409
revokedHTTP 409
/api/v1/audits/{auditId}/runsidempotency_key_reusedHTTP 409
Idempotency-Key was already used for an order with different parameters./api/v1/orderswholesale_unavailableHTTP 409
/api/v1/ordersaccount_email_missingHTTP 409
/api/v1/ordersurl_already_lockedHTTP 409
/api/v1/target-finder/analysesduplicate_key_nameHTTP 409
/api/v1/apikeyskey_limit_reachedHTTP 409
/api/v1/apikeyswebhook_limit_reachedHTTP 409
/api/v1/webhooksdaily_limit_reachedHTTP 429
/api/v1/ordersanalysis_limit_reachedHTTP 429
/api/v1/target-finder/analysestoo_many_checksHTTP 429
outcome named first.checkout_unavailableHTTP 502
/api/v1/checkout/sessionsordering_disabledHTTP 503
/api/v1/ordersordering_pausedHTTP 503
/api/v1/orderstarget_finder_disabledHTTP 503
/api/v1/target-finder/analysesHTTP 401empty body
X-Api-Key header is missing, malformed, or not a live key. Empty body.X-Api-Key. A revoked key never works again — create a new one.HTTP 429empty body
POST /orders (dry runs included). Empty body.HTTP 500empty body
POST /orders, read GET /orders first: the outcome is unknown and a charge may have completed. Elsewhere, retry once after a short wait, then contact support with the time and path.No code matches that filter.
How to branch
switch (problem.code) {
case "run_in_progress": // poll the active run; do not restart
case "runs_exhausted": // buy another audit or an extra run
case "url_locked": // reuse the locked URL
case "insufficient_scope": // create a key with the named scope
case "daily_limit_reached": // wait for 00:00 UTC
default: // surface status + detail; never retry blindly
}Three rules that keep an integration safe
card_declined whose detail says the charge did not complete. On a 500 from POST /orders the outcome is unknown: read GET /orders before retrying.run_in_progress and idempotency_key_reused exist so a retried request can never spend twice.