PageSpeedAudit Developers · Changelog
What changed, when, and what you have to do.
Every entry is dated to the day it reached production and says whether it was additive, a change to existing behaviour, or a fix toward what the contract already promised. A breaking change would ship under a new path version and be announced here first — none has. Dates are the days the repository's history records each surface reaching production.
- Version
- v1.0.0 ·
/api/v1 - Last contract change
- Findings document
pagespeed-audit/findings@1- OpenAPI
- /openapi/v1.json
Entries
-
Additive Dry-run quotes on POST /orders
{ "dryRun": true }resolves the unit price, wholesale discount, daily ceilings and payment route exactly as a real order would, then creates nothing and charges nothing. It needs no Idempotency-Key and is the request the interactive reference sends by default. The operation's burst limit — 5 requests per minute per account — counts dry runs.- Action required
- None. Existing orders behave exactly as before.
- Operations
- POST
/api/v1/orders
Changed Ordering needs an API key; a signed-in session is refused
POST /orders,GET /ordersandGET /orders/{orderId}now answer403 api_key_requiredto a browser session. Scopes narrow keys, not people, so a signed-in session used to pass thepurchasecheck — which meant the request console on the reference page could place a real order for anyone who was merely signed in. The dashboard never ordered through these operations, so nothing that worked by design stops working.- Action required
- None for integrations, which always used a key. A script that reused a browser cookie to order must use a
purchase-scoped key.
Additive 402 problems carry the order they refused
402 authentication_requiredand402 card_declinednow carry the recorded order'sorderIdas a problem member, andauthentication_requiredalso carries thecheckoutUrlthat finishes the payment in a browser. Before, a caller had to listGET /ordersto find either.- Action required
- None. New members beside the existing
code,status,detail. - Operations
- POST
/api/v1/orders
Additive Every problem response links to its catalog entry
Problem responses now carry a
typeofhttps://pagespeedaudit.com/docs/errors#{code}and atitle(the status's reason phrase) beside the unchangedcode,statusanddetail. Ownership failures that answered an empty 404 now carry a problem body with codenot_found. The checkout, newsletter and contact refusals, which carried only a message, now carry codes too:unusable_email,checkout_unavailable,invalid_email,disposable_email,invalid_message— the message moved fromtitletodetailon the two checkout refusals.- Action required
- None for clients that branch on status or
code. A client that read the checkout refusal'stitleas the message readsdetail. - Operations
- GET
/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}POST/api/v1/checkout/sessionsPOST/api/v1/newsletter/subscribePOST/api/v1/contact
Fixed Affiliate validation errors use the documented problem+json shape
Invalid dates, an unknown
groupByorstatus, and an unusable postback answered{ "error": "…" }, contrary to the contract. They are now problem+json with codesinvalid_date,invalid_group_by,invalid_status,invalid_postback_eventsandinvalid_postback_url; an account without an affiliate profile is403 not_an_affiliateon every affiliate operation. Status codes are unchanged.- Action required
- A client that parsed the old
errorfield — on the three operations with input validation, or on the 403 every affiliate operation returns — readsdetail(the same text) andcodeinstead.
Fixed API-key management is documented as dashboard-session only
The OpenAPI document declared the API-keys operations behind the
X-Api-Keyscheme, which they have always refused. They now declare theDashboardSessioncookie scheme, and an API key that calls them gets403 dashboard_session_requiredwith a body instead of an empty 403.409on key creation now carriesduplicate_key_nameorkey_limit_reached.- Action required
- None for correct integrations; keys are still created and revoked at /account/api-keys.
Changed Developer portal at /docs; the interactive reference moved to /docs/reference
/docs is now the guides, quickstart, schemas and error catalog; the generated reference lives at /docs/reference. /openapi/v1.json and /docs/openapi/v1.json are unchanged.
- Action required
- Update bookmarks to the reference; the OpenAPI document URL is the same.
-
Additive Saved-card charging on POST /orders
An account that saved a card under Billing and consented to off-session charging is charged immediately: the response is
202withpaymentRoute: chargeand the credits arrive when settlement lands. A card that needs the cardholder present is402 authentication_requiredwith a Checkout URL on the order; a declined card is402 card_declined. Accounts without a saved card still get201and a Checkout URL.- Action required
- None unless the account saves a card — then poll
GET /orders/{orderId}forcompletedinstead of sending a buyer to a URL.
Additive Ordering through the API: POST /orders, GET /orders, GET /orders/{orderId}
Orders audit credits on the account with a required
Idempotency-Key; an approved reseller's wholesale price is applied server-side. Guardrails: 5 orders per minute, per-account daily ceilings (429 daily_limit_reached), a platform backstop (503 ordering_paused) and a kill switch (503 ordering_disabled).- Action required
- None. Requires a key created with the
purchasescope.
Additive API key scopes: read, run, purchase
Keys carry scopes chosen at creation. A key created without a list gets
readandrun— the authority every existing key already had — so nothing that worked stopped working.purchaseis never implicit. Calling an operation without its scope is403 insufficient_scope, naming the scope. Starting a run and creating a Target Finder analysis needrun; everything else on audits and analyses needsread.- Action required
- None for existing keys. Create a
purchasekey only for an integration that orders.
Additive Lead attribution on affiliate stats
GET /affiliate/statscarries aleadsobject — unconfirmed, confirmed and converted leads, split by source. Lifetime figures; they ignorefrom/to.- Action required
- None.
- Operations
- GET
/api/v1/affiliate/stats
-
Additive Target Finder: POST /target-finder/analyses, GET …/{id}, GET …
Analyzes a site (robots → sitemap → homepage, URL templates, candidate probes, CrUX field-data checks) and recommends the page to audit, with alternates. Available while an audit's URL is still unlocked;
202with a pollable analysis.- Action required
- None.
Additive Recruit-an-affiliate reporting: GET /affiliate/recruiting
The recruit link, override percentage, recruit counts and override earnings by state, plus anonymous per-recruit rows.
- Action required
- None.
- Operations
- GET
/api/v1/affiliate/recruiting
-
Additive API v1 — first recorded in this repository
Checkout sessions, audits and runs (start, poll, timeline, report download as findings JSON or self-contained HTML), dashboard-session API-key management, the affiliate API (profile, stats, referrals, payouts, postback), newsletter subscription and contact intake. OpenAPI 3.1 at /openapi/v1.json; problem+json errors with a stable
code. This is the earliest date the repository's history records for the surface.- Action required
- —
Versioning and deprecation
The rules a change has to follow.
Additive on v1
New operations, new optional fields, new error codes and new example values may appear on /api/v1 at any time. Existing fields are never removed, renamed or retyped; existing status codes and code values keep their meaning.
Breaking means a new path
Anything a correct v1 client could not absorb ships as /api/v2. v1 keeps working through a published sunset window; the window and the migration notes appear on this page before the new version does.
The findings document
The schema id pagespeed-audit/findings@1 covers additive change the same way. A change that breaks a consumer of the document becomes a new schema id, announced here, with both formats available for a window.
Fixes toward the contract
When the implementation is found to differ from what the reference already documents — a wrong error shape, a missing security scheme — it is fixed and recorded as Fixed, with the old and new behaviour stated, so a client that depended on the mistake can see what to do.
Operational status
Live, from the same checks the deploy gate reads.
Checked · refreshed at most once a minute
- API and database Operational
- Audit processing (worker heartbeats) Operational
Machine-readable: /healthz/ready answers 200 when the API can serve and 503 when it cannot. No incident history is published yet; when one is, it will live here.