# PageAudit — full API reference > Generated from the catalog at https://www.pageaudit.online · build `20c4f6b2` > 63 endpoints · 38 structures > Short index: https://www.pageaudit.online/llms.txt · Spec: https://www.pageaudit.online/openapi.json · MCP: https://www.pageaudit.online/mcp > Technical SEO auditor in one call: title, meta, canonical, OG, headings, JSON-LD, > robots, alt, links, hreflang, redirects and selected discovery/delivery checks. > llms.txt, security.txt, API catalog, function-matched well-known files, favicon and missing-page evidence. No key to start. ## How to read - Every endpoint lists path, auth, parameters, body, response structure, errors and a call that runs. - `Pagina` is a reference: the fields are under **Structures**, at the end, once. - `(optional)` on a field means it may be absent; `(may be null)` means it comes with a null value. - Slice what you need: `https://www.pageaudit.online/llms-full.txt?prefix=/api/` returns only that branch. ## Authentication - `credito` — Prepaid credit token in `Authorization: Bearer cred_…` (or the `X-Credito` header). Not an account: it is a bearer of balance. - `none` — Public, no credential. - `guest` — Guest token (`POST /api/guest`) in `X-Guest-Token: pa_…`, `Authorization: Bearer pa_…` or `?guest_token=pa_…`. Only a token this site issued is accepted. A signed-in account (cookie) also works and takes precedence; after the claim the token owns nothing. - `session` — Global account: HttpOnly cookie `__Host-mm-auth`, set when you sign in on this site's `/conta/global` page. An ended session answers 401 `session_ended` (it never falls back to the guest). Writes need the same Origin and `X-CSRF-Token` from `/api/auth/bootstrap`. No bearer token is issued to humans. - `token` — Operator token in `Authorization: Bearer …` (`METRICS_TOKEN`). ## Endpoints ## Discovery ### `GET /agent.json` Agent card: identity, operator, documentation, the MCP endpoint and the tools it serves. Same document as `/.well-known/agent-card.json`. - **URL:** `https://www.pageaudit.online/agent.json` - **Auth:** `none` — Public, no credential. **Response `200`** `application/json`: `name`, `provider`, `protocol` (`mcp`), `interfaces[]` and `skills[]`. **Example** ```sh curl -s https://www.pageaudit.online/agent.json ``` ### `GET /okf/:arquivo` OKF bundle (Open Knowledge Format v0.1): markdown with frontmatter so an agent reads the whole product without parsing HTML. - **URL:** `https://www.pageaudit.online/okf/:arquivo` - **Auth:** `none` — Public, no credential. **Path parameters** - `arquivo` (string, required) — `index.md`, `sobre.md`, `api.md` or `faq.md`. e.g.: `index.md`. **Response `200`** `text/markdown`. Start at `/okf/index.md`, which lists the bundle. **Errors** - `404` — File outside the bundle. **Example** ```sh curl -s https://www.pageaudit.online/okf/index.md ``` ### `GET /.well-known/:arquivo` Machine discovery before the home page: `api-catalog` (RFC 9727, a linkset with the API and the MCP), `security.txt` (RFC 9116), `x402` (payment manifest: network, wallet and the routes that charge) and `mcp-registry-auth` (the official MCP registry key). - **URL:** `https://www.pageaudit.online/.well-known/:arquivo` - **Auth:** `none` — Public, no credential. **Path parameters** - `arquivo` (string, required) — `api-catalog`, `security.txt`, `x402`, `mcp-registry-auth` or `apis.json`. e.g.: `api-catalog`. **Response `200`** `application/linkset+json` for the api-catalog; `application/json` for x402 and apis.json; `text/plain` for the other two. **Errors** - `404` — Name outside the five published. **Example** ```sh curl -s https://www.pageaudit.online/.well-known/api-catalog ``` ### `GET /apis.json` APIs.json (apisjson.org, 0.19): the index APIs.io harvests — the API, the MCP, OpenAPI, guide and OKF bundle in one file. Also at `/.well-known/apis.json`. - **URL:** `https://www.pageaudit.online/apis.json` - **Auth:** `none` — Public, no credential. **Response `200`** `application/json` in the APIs.json 0.19 format: `apis[]` with `baseURL`, `humanURL` and `properties[]`. **Example** ```sh curl -s https://www.pageaudit.online/apis.json ``` ### `GET /api/` Self-describing index: the whole API surface, with quota and retention policy. - **URL:** `https://www.pageaudit.online/api/` - **Auth:** `none` — Public, no credential. **Response `200`** - `name` (string) — Product name. - `description` (string) — What the product does, in one sentence. - `build` (string) — Deployed commit. - `base_url` (string) — Origin this API is serving from. - `docs` (object) — Links to llms.txt, llms-full.txt, openapi.json, MCP and the UI. - `conventions` (object) — Error format, CORS, x402 and the UI↔API parity rule. - `auth` (object) — Each authentication mode and how to obtain it. - `endpoints` (object[]) — Every endpoint with method, path, auth, absolute URL and what it returns. - `data_retention` (object) — What is stored from each run and what is discarded. - `quota` (object) — What is free, what costs and how to pay — before you spend a call. - `mcp` (object) — Address and transport of the MCP server. - `quickstart` (string[]) — The calls that take you from zero to the first report. ### `GET /api/health` Liveness and the commit deployed right now — it is how the smoke waits for its own deploy. - **URL:** `https://www.pageaudit.online/api/health` - **Auth:** `none` — Public, no credential. **Response `200`** - `ok` (bool) — Always `true` when the Worker answers. - `app` (string) — Product name. - `build` (string) — Deployed commit; CI passes the short SHA on deploy. - `ts` (string) — Time of the response (UTC, ISO-8601). ### `POST /mcp` MCP server over HTTP (Streamable HTTP, JSON-RPC 2.0) — plugs into the client with nothing to install. The tools are the operations of this same catalog; the MCP has no backend of its own. `GET /mcp` returns the server card. - **URL:** `https://www.pageaudit.online/mcp` - **Auth:** `none` — Public, no credential. - Credentials go in the usual headers (X-Guest-Token, Authorization, X-PAYMENT) and are forwarded to the API. - An exhausted quota comes back as a 402 with accepts[] inside the tool result — pay and repeat. **Response `200`** JSON-RPC 2.0 response (`initialize`, `tools/list` or `tools/call`). **Example** ```sh curl -s -XPOST https://www.pageaudit.online/mcp -H 'content-type: application/json' -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}' ``` ### `GET /api/pricing` Current prices and free allowances. - **URL:** `https://www.pageaudit.online/api/pricing` - **Auth:** `none` — Public, no credential. **Response `200`** - `product` (string) — Product name. - `quota` (PaymentQuota) — Public allowances and current list prices; not personal usage. → see `PaymentQuota` under **Structures**. - `pricing` (string) — Absolute URL of the current price list. - `billing` (string) — Absolute URL of payment discovery or the existing billing summary. - `api_index` (string) — Absolute URL of the API catalog. **Errors** - `405` — Use GET or HEAD. **Example** ```sh curl -s https://www.pageaudit.online/api/pricing ``` ## Audit ### `POST /api/audit` Audits a URL and returns the full report in one call, without a token or a tab. This is the product for agents. Past the IP's daily allowance the response is **402 with `accepts[]`** and `code: allowance_spent` — pay and repeat the same call. There is no captcha: people and agents pay the same way. The free alternative: a person signs in with an account to get the trial. - **URL:** `https://www.pageaudit.online/api/audit` - **Auth:** `none` — Public, no credential. **Body** (`application/json`) - `url` (string, required) — The page to audit, `http` or `https`. - `guest_token` (string) — Guest `pa_…` so the audit is tied to it and shows up in the tabs. **Body example** ```json { "url": "https://example.com/", "guest_token": "pa_… (optional, ties the audit)" } ``` **Response `200`** Structure: `Audit`. - `id` (string, may be null) — ID of the stored audit; `null` when the database was unavailable. - `score` (int) — 0–100 for measured checks: error -18, warn -8, info 0. Not a security/accessibility certification. Older saved scores keep their original weights. - `issues` (Achado[]) — Everything found, from most to least severe. → see `Achado` under **Structures**. - `summary` (ResumoPagina) — What the page declares: title, meta, canonical, OG, headings, links… → see `ResumoPagina` under **Structures**. - `counts` (ContagemAchados) — How many findings of each severity. → see `ContagemAchados` under **Structures**. - `headers` (object) — Every header of the target's response. `Set-Cookie` is removed on purpose: it is a third party's credential. - `htmlTruncated` (bool) — `true` when the page passed 2 MB and was read only that far. - `jsonLd` (object[]) — The raw JSON-LD blocks, as they were on the page. - `jsonLdStored` (int) — How many blocks survived the size cap — compare with `summary.jsonLdBlocks`. - `truncated` (string[]) — What was cut and why: `jsonld_size`, `jsonld_nodes_over_50`, `result_size`. Empty means nothing cut. - `fixes` (Correcao[]) — The ready fix of each finding, without a model — paste, fill in or decide. The consolidated one is at `_links.patch`. → see `Correcao` under **Structures**. - `quota` (CotaAudit) — How much is still free and what it costs past that. → see `CotaAudit` under **Structures**. - `_links` (LinksAudit) — This audit, the patch, the share and the API index. → see `LinksAudit` under **Structures**. **Errors** - `400` — Body is not JSON, or `url` missing/not http. - `402` — Quota exceeded. The response carries `accepts[]` (x402, USDC on Base): pay and repeat the same call with `X-PAYMENT`. - `429` — Past `MAX_AUDITS_PER_HOUR` on the same IP. Wait an hour. - `502` — The target failed to answer, or a firewall or rate limit answered instead of the page: `code` `target_blocked` or `target_rate_limited`, with `blocked.fix`. Nothing was audited. **Example** ```sh curl -s -XPOST https://www.pageaudit.online/api/audit -H 'content-type: application/json' -d '{"url":"https://example.com/"}' ``` ### `GET /api/audits/:id` Re-reads an audit already made, in full, without re-auditing the page. Re-reading costs nothing and does not count against the allowance — the page's HTML is not kept, but the report is. - **URL:** `https://www.pageaudit.online/api/audits/:id` - **Auth:** `guest` — Guest token (`POST /api/guest`) in `X-Guest-Token: pa_…`, `Authorization: Bearer pa_…` or `?guest_token=pa_…`. Only a token this site issued is accepted. A signed-in account (cookie) also works and takes precedence; after the claim the token owns nothing. **Path parameters** - `id` (string, required) — Audit ID, from `Audit.id`. e.g.: `9f3c2b1d-7a4e-4c58-9b02-1f6d5e8a2c34`. **Response `200`** Structure: `AuditGravado`. - `audit_id` (string) — ID of the audit. - `url` (string) — Final audited URL, after following the redirects. - `score` (int) — Score from 0 to 100. - `summary` (ResumoPagina, may be null) — What the page declared at the time of the run. → see `ResumoPagina` under **Structures**. - `counts` (ContagemAchados) — How many findings of each severity. → see `ContagemAchados` under **Structures**. - `issues` (Achado[]) — Everything found in that run. → see `Achado` under **Structures**. - `fixes` (Correcao[]) — The ready fix of each finding; an audit stored before this existed gets the computation on read. → see `Correcao` under **Structures**. - `jsonLd` (object[]) — The raw JSON-LD blocks stored. - `headers` (object) — Headers of the target's response, as they were in the run. - `truncated` (string[]) — What was cut by size when storing. - `share_slug` (string, may be null) — Public slug, if this audit was shared. - `created_at` (string) — When the run happened (UTC). **Errors** - `401` — No credential, or an invalid one. See this endpoint's auth. - `404` — The resource does not exist (or is not yours — the API does not tell the two apart on purpose). **Example** ```sh curl -s https://www.pageaudit.online/api/audits/AUDIT_ID -H "X-Guest-Token: $PA" ``` ### `GET /api/audits/:id/patch` The consolidated patch of an audit: the block ready to paste, the files to create at the root and the templates for what only the owner can fill in — no model, only facts from the page itself. Each finding becomes a fix in one of three classes: `deterministico` (comes whole from what the page declares: final URL, title, description, OG), `molde` (a tag with a marked placeholder, like `{{TITULO}}`, and the suggested source) or `sem_patch` (a decision or infrastructure, with the instruction). Nothing is invented by a model. - **URL:** `https://www.pageaudit.online/api/audits/:id/patch` - **Auth:** `guest` — Guest token (`POST /api/guest`) in `X-Guest-Token: pa_…`, `Authorization: Bearer pa_…` or `?guest_token=pa_…`. Only a token this site issued is accepted. A signed-in account (cookie) also works and takes precedence; after the claim the token owns nothing. **Path parameters** - `id` (string, required) — Audit ID, from `Audit.id`. e.g.: `9f3c2b1d-7a4e-4c58-9b02-1f6d5e8a2c34`. **Response `200`** Structure: `Patch`. - `url` (string, may be null) — Final audited URL. - `audit` (string, may be null) — Absolute link of the source audit. - `head` (string) — The deterministic tags, one per line, in order (charset first). Empty when there are none. - `arquivos` (ArquivoPatch[]) — Files to create at the host root. → see `ArquivoPatch` under **Structures**. - `moldes` (MoldePatch[]) — What only the owner can fill in. → see `MoldePatch` under **Structures**. - `sem_patch` (SemPatch[]) — What is a decision or infrastructure. → see `SemPatch` under **Structures**. - `resumo` (ResumoPatch) — Count per class. → see `ResumoPatch` under **Structures**. - `como_aplicar` (string) — One-sentence instruction. - `_links` (object) — `api_index`. **Errors** - `401` — No credential, or an invalid one. See this endpoint's auth. - `404` — The resource does not exist (or is not yours — the API does not tell the two apart on purpose). **Example** ```sh curl -s https://www.pageaudit.online/api/audits/AUDIT_ID/patch -H "X-Guest-Token: $PA" ``` ### `POST /api/audits/:id/lab` Starts a lab test of the audited page: Lighthouse run by Google PageSpeed Insights (performance, accessibility, best practices, SEO). Answers **202** at once; the test runs for ~25 s to over 2 minutes and its summary is stored in the audit (`summary.lab.`), so it comes back in `GET /api/audits/:id`, in the tab and in the shared report. It does not change the audit score. Calling again while the same strategy is running does not start a second test. Limits: 4 tests at a time on the server, 6 per network per hour and 500 per day for the whole product. Free: no x402 charge. - **URL:** `https://www.pageaudit.online/api/audits/:id/lab` - **Auth:** `guest` — Guest token (`POST /api/guest`) in `X-Guest-Token: pa_…`, `Authorization: Bearer pa_…` or `?guest_token=pa_…`. Only a token this site issued is accepted. A signed-in account (cookie) also works and takes precedence; after the claim the token owns nothing. **Path parameters** - `id` (string, required) — Audit ID, from `Audit.id`. e.g.: `9f3c2b1d-7a4e-4c58-9b02-1f6d5e8a2c34`. **Body** (`application/json`) - `strategy` (string) — `mobile` (default) or `desktop`. **Body example** ```json { "strategy": "mobile" } ``` **Response `200`** - `ok` (bool) — Always `true` on 202. - `audit_id` (string) — The audit the test belongs to. - `strategy` (string) — `mobile` or `desktop`. - `lab` (LabTeste) — `status: running` and when it started. → see `LabTeste` under **Structures**. - `_links` (object) — `poll` (the GET with `wait`) and `audit`. **Errors** - `400` — `strategy` is not `mobile` or `desktop`. - `401` — No credential, or an invalid one. See this endpoint's auth. - `404` — The resource does not exist (or is not yours — the API does not tell the two apart on purpose). - `429` — A limit was reached: `lab_busy` (4 running), `lab_rate_limited` (6 per network per hour) or `lab_daily_cap`. - `503` — `lab_unavailable`: the server has no PageSpeed key configured. **Example** ```sh curl -s -XPOST https://www.pageaudit.online/api/audits/AUDIT_ID/lab -H "X-Guest-Token: $PA" -H 'content-type: application/json' -d '{"strategy":"mobile"}' ``` ### `GET /api/audits/:id/lab` The lab tests of an audit — running, finished or failed — waiting up to `wait` seconds for a running one to finish. Long-poll: with `wait` the answer comes as soon as a running test finishes, or after `wait` seconds with `status: running`. Repeat until it is not running. - **URL:** `https://www.pageaudit.online/api/audits/:id/lab` - **Auth:** `guest` — Guest token (`POST /api/guest`) in `X-Guest-Token: pa_…`, `Authorization: Bearer pa_…` or `?guest_token=pa_…`. Only a token this site issued is accepted. A signed-in account (cookie) also works and takes precedence; after the claim the token owns nothing. **Path parameters** - `id` (string, required) — Audit ID, from `Audit.id`. e.g.: `9f3c2b1d-7a4e-4c58-9b02-1f6d5e8a2c34`. **Query** - `wait` (string) — Seconds to wait for a running test, 0 to 25. Default 0 (answer at once). **Response `200`** - `audit_id` (string) — The audit. - `lab` (object) — `mobile` and `desktop`, each a `LabTeste` or `null` when never run. - `_links` (object) — `self` and `audit`. **Errors** - `401` — No credential, or an invalid one. See this endpoint's auth. - `404` — The resource does not exist (or is not yours — the API does not tell the two apart on purpose). **Example** ```sh curl -s "https://www.pageaudit.online/api/audits/AUDIT_ID/lab?wait=25" -H "X-Guest-Token: $PA" ``` ## Micro-tools ### `GET /api/tools` The micro-tools: one landing per check, all driven by the same engine as the audit. - **URL:** `https://www.pageaudit.online/api/tools` - **Auth:** `none` — Public, no credential. **Response `200`** - `tools` (Ferramenta[]) — Every published tool. → see `Ferramenta` under **Structures**. - `_links` (object) — The hub in HTML and the API index. ### `GET /api/tools/:slug` Metadata and copy of one micro-tool. - **URL:** `https://www.pageaudit.online/api/tools/:slug` - **Auth:** `none` — Public, no credential. **Path parameters** - `slug` (string, required) — Tool slug, e.g. `title-tag-checker`. **Response `200`** Structure: `Ferramenta`. - `slug` (string) — Identifier in the URL, e.g. `title-tag-checker`. - `title` (string) — Page title, used in ``. - `h1` (string) — The landing's H1. - `description` (string) — Meta description of the landing. - `lead` (string) — Opening paragraph. - `category` (string) — Grouping of the tool in the hub. - `icon` (string) — Name of the icon used in the card. - `checks` (string[]) — Finding codes this tool highlights — they are the `Achado.code`s. - `serp` (object) — How the result looks in the search preview. - `sections` (object[]) — Content blocks of the landing. - `_links` (object) — This tool in JSON and in HTML. **Errors** - `404` — Unknown slug. **Example** ```sh curl -s https://www.pageaudit.online/api/tools/title-tag-checker ``` ### `GET /tools` HTML hub of the micro-tools, indexable. For JSON use `GET /api/tools`. - **URL:** `https://www.pageaudit.online/tools` - **Auth:** `none` — Public, no credential. **Response `200`** `text/html` — the hub page, rendered on the server. ### `GET /tools/:slug` HTML landing of one check, indexable. An unknown slug returns a real 404. The 404 is real, not a 200 with an empty shell: mass soft-404s burn the whole domain in the index. - **URL:** `https://www.pageaudit.online/tools/:slug` - **Auth:** `none` — Public, no credential. **Path parameters** - `slug` (string, required) — Tool slug, e.g. `title-tag-checker`. **Response `200`** `text/html` — the tool's landing. **Errors** - `404` — Unknown slug — a real 404, not an empty shell. ## Share ### `POST /api/audits/:id/share` Publishes the audit under a non-enumerable slug. Calling again returns the same slug. - **URL:** `https://www.pageaudit.online/api/audits/:id/share` - **Auth:** `guest` — Guest token (`POST /api/guest`) in `X-Guest-Token: pa_…`, `Authorization: Bearer pa_…` or `?guest_token=pa_…`. Only a token this site issued is accepted. A signed-in account (cookie) also works and takes precedence; after the claim the token owns nothing. **Path parameters** - `id` (string, required) — ID of the audit to publish. e.g.: `9f3c2b1d-7a4e-4c58-9b02-1f6d5e8a2c34`. **Response `200`** Structure: `Compartilhamento`. - `ok` (bool) — Always `true`. - `shared` (bool) — Whether the audit is published at the end of the call. - `slug` (string) — Public, non-enumerable slug. - `path` (string) — Path of the report's HTML page. - `badge` (string) — Path of the score badge SVG. - `_links` (object) — Report, JSON and badge, as absolute URLs. **Errors** - `401` — No credential, or an invalid one. See this endpoint's auth. - `404` — The resource does not exist (or is not yours — the API does not tell the two apart on purpose). **Example** ```sh curl -s -XPOST https://www.pageaudit.online/api/audits/AUDIT_ID/share -H "X-Guest-Token: $PA" ``` ### `DELETE /api/audits/:id/share` Revokes the share; the slug stops serving the report. The badge keeps answering 200 with the grey `n/a` SVG — same box, so the layout of whoever pasted it in a README does not break. - **URL:** `https://www.pageaudit.online/api/audits/:id/share` - **Auth:** `guest` — Guest token (`POST /api/guest`) in `X-Guest-Token: pa_…`, `Authorization: Bearer pa_…` or `?guest_token=pa_…`. Only a token this site issued is accepted. A signed-in account (cookie) also works and takes precedence; after the claim the token owns nothing. **Path parameters** - `id` (string, required) — ID of the audit to unpublish. e.g.: `9f3c2b1d-7a4e-4c58-9b02-1f6d5e8a2c34`. **Response `200`** - `ok` (bool) — Always `true`. - `shared` (bool) — Always `false` at the end of this call. **Errors** - `401` — No credential, or an invalid one. See this endpoint's auth. - `404` — The resource does not exist (or is not yours — the API does not tell the two apart on purpose). **Example** ```sh curl -s -XDELETE https://www.pageaudit.online/api/audits/AUDIT_ID/share -H "X-Guest-Token: $PA" ``` ### `GET /api/shared/:slug` Shared report as JSON, without credentials — the machine twin of `/r/:slug`. - **URL:** `https://www.pageaudit.online/api/shared/:slug` - **Auth:** `none` — Public, no credential. **Path parameters** - `slug` (string, required) — Public slug of the share. e.g.: `k7m2p9r4t6v8w1y3z5b7c9d1`. **Response `200`** Structure: `AuditGravado`. - `audit_id` (string) — ID of the audit. - `url` (string) — Final audited URL, after following the redirects. - `score` (int) — Score from 0 to 100. - `summary` (ResumoPagina, may be null) — What the page declared at the time of the run. → see `ResumoPagina` under **Structures**. - `counts` (ContagemAchados) — How many findings of each severity. → see `ContagemAchados` under **Structures**. - `issues` (Achado[]) — Everything found in that run. → see `Achado` under **Structures**. - `fixes` (Correcao[]) — The ready fix of each finding; an audit stored before this existed gets the computation on read. → see `Correcao` under **Structures**. - `jsonLd` (object[]) — The raw JSON-LD blocks stored. - `headers` (object) — Headers of the target's response, as they were in the run. - `truncated` (string[]) — What was cut by size when storing. - `share_slug` (string, may be null) — Public slug, if this audit was shared. - `created_at` (string) — When the run happened (UTC). **Errors** - `404` — Unknown slug, or share revoked. **Example** ```sh curl -s https://www.pageaudit.online/api/shared/SLUG ``` ### `GET /r/:slug` HTML page of the shared report, indexable, canonical at `/r/:slug`. A public report is content: indexable, with its own canonical. Revoked or unknown slugs answer 404 (that one is `noindex`). The JSON twin is `/api/shared/:slug`. - **URL:** `https://www.pageaudit.online/r/:slug` - **Auth:** `none` — Public, no credential. **Path parameters** - `slug` (string, required) — Public slug of the share. e.g.: `k7m2p9r4t6v8w1y3z5b7c9d1`. **Response `200`** `text/html` — the rendered report, with `rel=canonical`. **Errors** - `404` — Unknown or revoked slug. ### `GET /api/badge/:slug` Metadata of the score badge, including the markdown ready for the README. - **URL:** `https://www.pageaudit.online/api/badge/:slug` - **Auth:** `none` — Public, no credential. **Path parameters** - `slug` (string, required) — Public slug of the share. e.g.: `k7m2p9r4t6v8w1y3z5b7c9d1`. **Response `200`** Structure: `Badge`. - `slug` (string) — Slug of the shared report. - `score` (int, may be null) — Score shown in the badge. - `label` (string) — Text on the left of the badge. - `available` (bool) — `false` when the share was revoked — the SVG turns grey `n/a`. - `markdown` (string) — The markdown line ready to paste in the README. - `_links` (object) — The SVG and the report. **Errors** - `404` — Unknown slug. Revoked is different: it returns 200 with `available: false`. **Example** ```sh curl -s https://www.pageaudit.online/api/badge/SLUG ``` ### `GET /badge/:slug.svg` SVG score badge, to paste in the README of the audited project. A revoked share returns **200** with the grey `n/a` SVG — the same box, so the README of whoever pasted it does not end up with a broken image. - **URL:** `https://www.pageaudit.online/badge/:slug.svg` - **Auth:** `none` — Public, no credential. **Path parameters** - `slug` (string, required) — Public slug, with the `.svg` extension in the path. e.g.: `k7m2p9r4t6v8w1y3z5b7c9d1`. **Response `200`** `image/svg+xml` — the badge, coloured by the score or grey `n/a` if revoked. **Errors** - `404` — Malformed slug. ## Embed ### `GET /api/embed` The embeddable widget's contract: what you can configure and the snippet to paste. One script tag puts the audit form on your own site, with your name and colour, and no account or key. Send the same query you would send to `/embed` and the answer comes back with `snippet` already assembled. The widget never asks the visitor for an e-mail. - **URL:** `https://www.pageaudit.online/api/embed` - **Auth:** `none` — Public, no credential. **Query** - `brand` (string) — Your site's name, shown above the form (up to 40 characters). - `color` (string) — Accent colour in hex (`#0a7` or `#00aa77`); anything else falls back to ours. - `theme` (string) — `auto` (follows the visitor), `light` or `dark`. - `url` (string) — Optional http(s) URL to pre-fill in the field. **Response `200`** - `config` (object) — Each option, its type and what it does. - `current` (object) — The configuration read from this call's query. - `snippet` (string) — The `<script>` (plus a `<noscript>` link) ready to paste. - `limits` (object) — The allowance the widget runs under, and the lead capture it does not do. **Example** ```sh curl -s "https://www.pageaudit.online/api/embed?brand=Acme&color=%2300aa77" ``` ### `GET /embed.js` The loader you paste: it creates the widget's iframe and keeps it the right height. Configuration travels in `data-brand`, `data-color`, `data-theme` and `data-url` on the script tag itself. Nothing else of ours touches the host page: the widget lives inside the iframe, so neither the site's CSS reaches it nor our code reaches the site's DOM. - **URL:** `https://www.pageaudit.online/embed.js` - **Auth:** `none` — Public, no credential. **Response `200`** `application/javascript` — the loader, cached for an hour. ### `GET /embed` The widget page itself, made to be framed (`frame-ancestors *`) and not indexed. Open it directly to preview a configuration before pasting the snippet. It calls `POST /api/audit` like any visitor would, so the free daily allowance per network applies. - **URL:** `https://www.pageaudit.online/embed` - **Auth:** `none` — Public, no credential. **Response `200`** `text/html` — the widget, self-contained, with no third-party resource. ## Identity ### `POST /api/guest` Creates a guest `pa_…` — it is what gives access to the tab workspace without an account. Keep the token: it is the identity of the tabs and of the audits tied to them. - **URL:** `https://www.pageaudit.online/api/guest` - **Auth:** `none` — Public, no credential. **Response `200`** - `token` (string) — The guest, prefix `pa_`. Send it in `X-Guest-Token`, as Bearer or in `?guest_token=`. **Example** ```sh curl -s -XPOST https://www.pageaudit.online/api/guest ``` ## Tabs ### `GET /api/tabs` The owner's whole workspace, with the active tab's result already rehydrated. One call draws the whole screen: tabs, the focused tab, its last report, remaining allowance and prices. - **URL:** `https://www.pageaudit.online/api/tabs` - **Auth:** `guest` — Guest token (`POST /api/guest`) in `X-Guest-Token: pa_…`, `Authorization: Bearer pa_…` or `?guest_token=pa_…`. Only a token this site issued is accepted. A signed-in account (cookie) also works and takes precedence; after the claim the token owns nothing. **Response `200`** Structure: `Workspace`. - `tabs` (Aba[]) — Every tab of the owner. → see `Aba` under **Structures**. - `active_id` (string, may be null) — Which tab is in focus. - `active_result` (AuditGravado, may be null) — The last result of the active tab, so a second call is not needed. → see `AuditGravado` under **Structures**. - `limit` (int) — How many tabs fit before paying. - `owner` (string) — Identifier of this workspace's owner. - `gate` (Gate) — How much of the IP's free allowance remains. → see `Gate` under **Structures**. - `billing` (object) — Prices and usage, the same `GET /api/billing` returns. **Errors** - `401` — No credential, or an invalid one. See this endpoint's auth. **Example** ```sh curl -s https://www.pageaudit.online/api/tabs -H "X-Guest-Token: $PA" ``` ### `POST /api/tabs` Opens a tab for the URL, or focuses the one that already exists for it. Past the free tab allowance it answers 402 with `accepts[]`: pay and repeat. - **URL:** `https://www.pageaudit.online/api/tabs` - **Auth:** `guest` — Guest token (`POST /api/guest`) in `X-Guest-Token: pa_…`, `Authorization: Bearer pa_…` or `?guest_token=pa_…`. Only a token this site issued is accepted. A signed-in account (cookie) also works and takes precedence; after the claim the token owns nothing. **Body** (`application/json`) - `url` (string, required) — The URL the tab will follow. - `alias` (string) — Label to recognise the tab in the list. **Body example** ```json { "url": "https://example.com/", "alias": "optional label" } ``` **Response `200`** - `ok` (bool) — Always `true`. - `tab` (Aba) — The opened tab (or the one that already existed for that URL). → see `Aba` under **Structures**. **Errors** - `400` — `url` missing or not http. - `401` — No credential, or an invalid one. See this endpoint's auth. - `402` — Quota exceeded. The response carries `accepts[]` (x402, USDC on Base): pay and repeat the same call with `X-PAYMENT`. **Example** ```sh curl -s -XPOST https://www.pageaudit.online/api/tabs -H "X-Guest-Token: $PA" -H 'content-type: application/json' -d '{"url":"https://example.com/"}' ``` ### `GET /api/tabs/:id` One tab with the full report of its last run. - **URL:** `https://www.pageaudit.online/api/tabs/:id` - **Auth:** `guest` — Guest token (`POST /api/guest`) in `X-Guest-Token: pa_…`, `Authorization: Bearer pa_…` or `?guest_token=pa_…`. Only a token this site issued is accepted. A signed-in account (cookie) also works and takes precedence; after the claim the token owns nothing. **Path parameters** - `id` (string, required) — Tab ID, from `Aba.id`. e.g.: `tab_9f3c2b1d7a4e58b0c2d4`. **Response `200`** - `tab` (Aba) — The requested tab. → see `Aba` under **Structures**. - `result` (AuditGravado, may be null) — The report of the last run; `null` if the tab never ran. → see `AuditGravado` under **Structures**. **Errors** - `401` — No credential, or an invalid one. See this endpoint's auth. - `404` — The resource does not exist (or is not yours — the API does not tell the two apart on purpose). **Example** ```sh curl -s https://www.pageaudit.online/api/tabs/TAB_ID -H "X-Guest-Token: $PA" ``` ### `PATCH /api/tabs/:id` Renames the tab, puts it in focus or turns the daily watch on and off. With `monitor: true` the page is re-audited once a day and an e-mail goes out when the score drops or a new error/warning appears — never on an improvement. Watching needs an account (the alert has to reach someone) and each account watches a limited number of pages. - **URL:** `https://www.pageaudit.online/api/tabs/:id` - **Auth:** `guest` — Guest token (`POST /api/guest`) in `X-Guest-Token: pa_…`, `Authorization: Bearer pa_…` or `?guest_token=pa_…`. Only a token this site issued is accepted. A signed-in account (cookie) also works and takes precedence; after the claim the token owns nothing. **Path parameters** - `id` (string, required) — ID of the tab to change. e.g.: `tab_9f3c2b1d7a4e58b0c2d4`. **Body** (`application/json`) - `alias` (string) — New label of the tab. - `active` (bool) — `true` focuses this tab (and unfocuses the other). - `monitor` (bool) — `true` watches the page daily; `false` stops watching it. - `monitor_email` (string) — Where the alert goes. Empty or `null` uses the account's e-mail. **Body example** ```json { "alias": "new label", "active": true, "monitor": true } ``` **Response `200`** - `ok` (bool) — Always `true`. - `tab` (Aba) — The tab with the change applied. → see `Aba` under **Structures**. **Errors** - `400` — No changeable field in the body, or `monitor_email` is not an e-mail. - `401` — No credential, or an invalid one. See this endpoint's auth. - `403` — Watching needs an account: a guest token has no e-mail to be warned at (`account_required`). - `404` — The resource does not exist (or is not yours — the API does not tell the two apart on purpose). - `409` — The account already watches the maximum number of pages (`monitor_limit`). **Example** ```sh curl -s -XPATCH https://www.pageaudit.online/api/tabs/TAB_ID -H "X-Guest-Token: $PA" -H 'content-type: application/json' -d '{"active":true}' ``` ### `DELETE /api/tabs/:id` Closes the tab. Its audit history keeps existing. - **URL:** `https://www.pageaudit.online/api/tabs/:id` - **Auth:** `guest` — Guest token (`POST /api/guest`) in `X-Guest-Token: pa_…`, `Authorization: Bearer pa_…` or `?guest_token=pa_…`. Only a token this site issued is accepted. A signed-in account (cookie) also works and takes precedence; after the claim the token owns nothing. **Path parameters** - `id` (string, required) — ID of the tab to close. e.g.: `tab_9f3c2b1d7a4e58b0c2d4`. **Response `200`** Structure: `Ok`. - `ok` (bool) — Always `true` — failure comes as a 4xx/5xx status, not as `ok:false`. **Errors** - `401` — No credential, or an invalid one. See this endpoint's auth. - `404` — The resource does not exist (or is not yours — the API does not tell the two apart on purpose). **Example** ```sh curl -s -XDELETE https://www.pageaudit.online/api/tabs/TAB_ID -H "X-Guest-Token: $PA" ``` ### `POST /api/tabs/:id/run` Re-audits the tab's URL and stores a new report. Consumes the same daily allowance as `POST /api/audit` — past it, 402 with `accepts[]`. - **URL:** `https://www.pageaudit.online/api/tabs/:id/run` - **Auth:** `guest` — Guest token (`POST /api/guest`) in `X-Guest-Token: pa_…`, `Authorization: Bearer pa_…` or `?guest_token=pa_…`. Only a token this site issued is accepted. A signed-in account (cookie) also works and takes precedence; after the claim the token owns nothing. **Path parameters** - `id` (string, required) — ID of the tab to re-audit. e.g.: `tab_9f3c2b1d7a4e58b0c2d4`. **Response `200`** - `ok` (bool) — Always `true`. - `tab` (Aba) — The tab with the new run's score. → see `Aba` under **Structures**. - `gate` (Gate) — How much of the allowance is left after this run. → see `Gate` under **Structures**. - `result` (AuditGravado) — The report just stored. → see `AuditGravado` under **Structures**. **Errors** - `401` — No credential, or an invalid one. See this endpoint's auth. - `402` — Quota exceeded. The response carries `accepts[]` (x402, USDC on Base): pay and repeat the same call with `X-PAYMENT`. - `404` — The resource does not exist (or is not yours — the API does not tell the two apart on purpose). **Example** ```sh curl -s -XPOST https://www.pageaudit.online/api/tabs/TAB_ID/run -H "X-Guest-Token: $PA" ``` ### `GET /api/tabs/:id/history` Previous runs of that tab and what changed between each one and the one before it. Every run has always been kept; this is where you read the series. Each entry carries the score, the counts and a `change` with the point delta and the findings that appeared (`broke`) or disappeared (`fixed`) since the previous run — compared by finding code, never by message. Runs older than the watch feature are matched by URL. - **URL:** `https://www.pageaudit.online/api/tabs/:id/history` - **Auth:** `guest` — Guest token (`POST /api/guest`) in `X-Guest-Token: pa_…`, `Authorization: Bearer pa_…` or `?guest_token=pa_…`. Only a token this site issued is accepted. A signed-in account (cookie) also works and takes precedence; after the claim the token owns nothing. **Path parameters** - `id` (string, required) — ID of the tab whose runs you want. e.g.: `tab_9f3c2b1d7a4e58b0c2d4`. **Query** - `limit` (int) — How many runs to bring, newest first. Default 20, maximum 100. **Response `200`** - `tab` (Aba) — The tab the runs belong to. → see `Aba` under **Structures**. - `runs` (RunHistorico[]) — Runs from newest to oldest. → see `RunHistorico` under **Structures**. - `limit` (int) — The limit actually applied. **Errors** - `401` — No credential, or an invalid one. See this endpoint's auth. - `404` — The resource does not exist (or is not yours — the API does not tell the two apart on purpose). **Example** ```sh curl -s "https://www.pageaudit.online/api/tabs/TAB_ID/history?limit=10" -H "X-Guest-Token: $PA" ``` ### `GET /api/gate` How many free audits remain for this IP and whether the next one pays. Check before spending a call: it is the number IN FORCE, not the allowance in the documentation. - **URL:** `https://www.pageaudit.online/api/gate` - **Auth:** `none` — Public, no credential. **Response `200`** Structure: `Gate`. - `ip` (string) — Your IP as the server sees it — echoed back to you, never stored. - `now` (int) — Time of the query, in epoch. - `free_allowance` (int) — Free audits per day. - `free_remaining` (int) — How many remain today for this IP. - `needs_payment` (bool) — `true` when the next audit answers 402 — unless an account in its trial makes it. ## Billing ### `GET /api/billing` Tab allowance, prices, full x402 configuration and the state of the trial. - **URL:** `https://www.pageaudit.online/api/billing` - **Auth:** `none` — Public, no credential. **Response `200`** Structure: `Billing`. - `provider` (string) — Always `x402` — the only billing protocol accepted. - `mode` (string) — Seller mode: `live` charges for real, `dev` lets calls through unpaid. - `network` (string) — USDC network: `base` in production, `base-sepolia` in staging. - `chain_id` (int) — EVM chain ID of the network above, so the wallet signs on the right chain. - `pay_to` (string, may be null) — Address that receives the payment. - `homolog` (bool) — Staging seam on: the loop can be closed without spending USDC. - `dev` (bool) — Development mode: the 402 is simulated. - `dev_gate` (bool) — A homologation credential is configured; this grants no access. - `gratis` (string[], optional) — Temporarily free SKUs. - `facilitator` (string) — URL of the facilitator that verifies and settles the payment. - `asset` (string) — Accepted currency — always `USDC`. - `asset_address` (string) — USDC contract on the network above. - `faucet` (string, may be null) — Test-USDC faucet; only on base-sepolia. - `wallets` (object) — Links to wallets that speak x402 (metamask, coinbase, base_app). - `product` (string) — Name of the product charging. - `free_max_tabs` (int) — Free tabs per owner. - `prices` (Precos) — What each paid action costs, in USD. → see `Precos` under **Structures**. - `usage` (Uso) — How much of the free allowance has been used. → see `Uso` under **Structures**. - `trial` (Trial) — The account's trial, when there is a session. → see `Trial` under **Structures**. **Example** ```sh curl -s https://www.pageaudit.online/api/billing -H "X-Guest-Token: $PA" ``` ### `POST /api/visit` Ping from the interface that increments the day's visits. Agents need not call it. Smoke does not count: `X-MM-Smoke`, User-Agent `mm-smoke` or `smoke: true` in the body come in as `counted: false`. - **URL:** `https://www.pageaudit.online/api/visit` - **Auth:** `none` — Public, no credential. **Body** (`application/json`) - `p` (string) — Path of the visited page. - `smoke` (bool) — `true` marks the call as a test and it does not enter the count. **Body example** ```json { "p": "/" } ``` **Response `200`** - `ok` (bool) — Always `true`. - `counted` (bool) — Whether the visit entered the day's count. - `reason` (string, optional) — Why it did not count, when `counted` is `false`. **Example** ```sh curl -s -XPOST https://www.pageaudit.online/api/visit -H 'content-type: application/json' -d '{"p":"/","smoke":true}' ``` ### `GET /api/metrics` Metrics of the last 7 days and the most frequent findings across audits. With the operator token, includes payments. Without credentials it returns visits, usage and accounts. With `METRICS_TOKEN` as Bearer it adds `payments` — and only on Base mainnet, because staging numbers on a finance panel mislead. - **URL:** `https://www.pageaudit.online/api/metrics` - **Auth:** `none` — Public, no credential. **Headers** - `Authorization` (string) — `Bearer <METRICS_TOKEN>` to include the finance block. **Response `200`** Structure: `Metricas`. - `app` (string) — Product name. - `today` (string) — Reference day (UTC, YYYY-MM-DD). - `today_visits` (int) — Visits counted today. - `today_contacts` (int, optional) — Contact messages received today. Only with `METRICS_TOKEN`: contact does not leave without a token. - `days` (object[]) — One record per day of the window, with the counts of each metric. - `usage` (object) — Usage per product resource — here, audits and tabs. - `accounts` (object) — Total guests and accounts. - `financeiro` (object, optional) — Aggregate of the day: `hoje_usd`, `hoje_count`, `rede`. Only with `METRICS_TOKEN`: money does not leave without a token; the full series is `payments`. - `payments` (object, optional) — Finance summary; only with METRICS_TOKEN. - `achados` (object, may be null) — Which findings appear across stored audits: `audits` (total) and `por_codigo[]` with `code`, `n`, `audits` and `fracao_audits`. Aggregate, no URL and no owner; 1 h cache. `null` if the database did not answer. **Example** ```sh curl -s https://www.pageaudit.online/api/metrics -H "Authorization: Bearer $METRICS_TOKEN" ``` ## Account ### `GET /api/me` The session's account, its last 50 audits and the state of the trial. The account is the global account you sign in to at `/conta/global`, the same in every product; `user.id` is its id, which owns the tabs and audits here. There is no activation step. - **URL:** `https://www.pageaudit.online/api/me` - **Auth:** `session` — Global account: HttpOnly cookie `__Host-mm-auth`, set when you sign in on this site's `/conta/global` page. An ended session answers 401 `session_ended` (it never falls back to the guest). Writes need the same Origin and `X-CSRF-Token` from `/api/auth/bootstrap`. No bearer token is issued to humans. **Response `200`** - `user` (Conta) — The person who owns the session. → see `Conta` under **Structures**. - `profile` (object) — Global profile: `name`, `locale`, `timeZone`, `theme`, `revision`. - `audits` (AuditGravado[]) — The account's 50 most recent audits. → see `AuditGravado` under **Structures**. - `trial` (Trial) — The account's trial: how many days, whether active and when it ends. → see `Trial` under **Structures**. **Errors** - `401` — invalid_session - `503` — auth_unavailable **Example** ```js await fetch("https://www.pageaudit.online/api/me", {credentials: "same-origin"}).then(r => r.json()); ``` ### `GET /api/auth/bootstrap` Prepare the browser for global sign-in. Sets a host-only HttpOnly browser cookie. CSRF is bound to the current session. No CORS. - **URL:** `https://www.pageaudit.online/api/auth/bootstrap` - **Auth:** `none` — Public, no credential. **Response `200`** - `csrf` (string) — X-CSRF-Token - `context` (string) — Opaque view context, also in X-MM-Context; not a credential / contexto opaco da vista, não é credencial. **Errors** - `400` — invalid_request - `403` — invalid_origin / invalid_csrf - `503` — auth_unavailable: a sessão anterior é preservada / the previous session is preserved ### `GET /api/account/profile` Read your global profile. Reads current preferences from the account. Edit them on your account page; products never own a separate profile. - **URL:** `https://www.pageaudit.online/api/account/profile` - **Auth:** `session` — Global account: HttpOnly cookie `__Host-mm-auth`, set when you sign in on this site's `/conta/global` page. An ended session answers 401 `session_ended` (it never falls back to the guest). Writes need the same Origin and `X-CSRF-Token` from `/api/auth/bootstrap`. No bearer token is issued to humans. **Response `200`** {profile:{name,locale,timeZone,theme,revision}} **Errors** - `401` — invalid_session - `503` — auth_unavailable **Example** ```js await fetch("https://www.pageaudit.online/api/account/profile", {credentials: "same-origin"}).then(r => r.json()); ``` ### `GET /api/account/avatar` Read your global profile photo. Private WebP, up to 64 KiB, no cache. Change it on your account. No user ID or object URL accepted. - **URL:** `https://www.pageaudit.online/api/account/avatar` - **Auth:** `session` — Global account: HttpOnly cookie `__Host-mm-auth`, set when you sign in on this site's `/conta/global` page. An ended session answers 401 `session_ended` (it never falls back to the guest). Writes need the same Origin and `X-CSRF-Token` from `/api/auth/bootstrap`. No bearer token is issued to humans. **Response `200`** image/webp; Cache-Control: no-store **Errors** - `401` — invalid_session - `404` — not_found: no photo / sem foto - `503` — auth_unavailable **Example** ```js await fetch("https://www.pageaudit.online/api/account/avatar", {credentials: "same-origin"}).then(r => {if (!r.ok) throw new Error("HTTP " + r.status); return r.blob();}); ``` ### `POST /api/auth/logout` Revoke this product session. Bootstrap/CSRF must belong to this browser and session. Other product sessions remain active. - **URL:** `https://www.pageaudit.online/api/auth/logout` - **Auth:** `session` — Global account: HttpOnly cookie `__Host-mm-auth`, set when you sign in on this site's `/conta/global` page. An ended session answers 401 `session_ended` (it never falls back to the guest). Writes need the same Origin and `X-CSRF-Token` from `/api/auth/bootstrap`. No bearer token is issued to humans. **Response `200`** - `ok` (bool) — true **Errors** - `400` — invalid_request - `403` — invalid_origin / invalid_csrf - `503` — auth_unavailable: a sessão anterior é preservada / the previous session is preserved **Example** ```js // Execute no console da página do produto / Run in the product page console. (async () => { const origin = "https://www.pageaudit.online"; const {csrf} = await fetch(origin + "/api/auth/bootstrap").then(r => r.json()); const r = await fetch(origin + "/api/auth/logout", { method: "POST", credentials: "same-origin", headers: {"Content-Type": "application/json", "X-CSRF-Token": csrf}, body: JSON.stringify({}) }); if (!r.ok) throw new Error("Auth HTTP " + r.status); return r.json(); })(); ``` ### `GET /api/account/keys` List your API keys in this product. Never returns the key itself: name, last 4 characters, organization, creation, last use (hourly) and whether it still works. - **URL:** `https://www.pageaudit.online/api/account/keys` - **Auth:** `session` — Global account: HttpOnly cookie `__Host-mm-auth`, set when you sign in on this site's `/conta/global` page. An ended session answers 401 `session_ended` (it never falls back to the guest). Writes need the same Origin and `X-CSRF-Token` from `/api/auth/bootstrap`. No bearer token is issued to humans. **Response `200`** - `keys` (object[]) — `id`, `name`, `organizationId`, `last4`, `createdAt`, `lastUsedAt`, `revokedAt`, `active` (false when revoked or stopped by a password change / ending all sessions). **Errors** - `401` — invalid_session - `503` — auth_unavailable **Example** ```js await fetch("https://www.pageaudit.online/api/account/keys", {credentials: "same-origin"}).then(r => r.json()); ``` ### `POST /api/account/keys/create` Create an API key for agents and scripts. Needs a sign-in in the last 5 minutes; an organization key also needs a second factor in the session and the owner/admin role with this product enabled. At most 10 live keys per account and product. The key (`secret`) is returned ONCE. - **URL:** `https://www.pageaudit.online/api/account/keys/create` - **Auth:** `session` — Global account: HttpOnly cookie `__Host-mm-auth`, set when you sign in on this site's `/conta/global` page. An ended session answers 401 `session_ended` (it never falls back to the guest). Writes need the same Origin and `X-CSRF-Token` from `/api/auth/bootstrap`. No bearer token is issued to humans. **Body** (`application/json`) - `name` (string, required) — Up to 60 characters. - `organizationId` (string, required) — `null` for an account key. **Body example** ```json { "name": "agent", "organizationId": null } ``` **Response `200`** - `key` (object) — `id`, `name`, `organizationId`, `last4`, `createdAt`. - `secret` (string) — `mmk_…`, shown once. **Errors** - `400` — invalid_key_name / invalid_organization - `401` — invalid_session / reauth_required - `403` — invalid_origin / invalid_csrf / organization_forbidden / organization_mfa_required - `409` — key_limit_reached - `503` — auth_unavailable **Example** ```js (async () => { const {csrf} = await fetch("https://www.pageaudit.online/api/auth/bootstrap").then(r => r.json()); const r = await fetch("https://www.pageaudit.online/api/account/keys/create", {method: "POST", credentials: "same-origin", headers: {"Content-Type": "application/json", "X-CSRF-Token": csrf}, body: JSON.stringify({name: "agent", organizationId: null})}); return r.json(); })(); ``` ### `POST /api/account/keys/revoke` Revoke one of your API keys. Stops the key at once. Repeating is harmless. - **URL:** `https://www.pageaudit.online/api/account/keys/revoke` - **Auth:** `session` — Global account: HttpOnly cookie `__Host-mm-auth`, set when you sign in on this site's `/conta/global` page. An ended session answers 401 `session_ended` (it never falls back to the guest). Writes need the same Origin and `X-CSRF-Token` from `/api/auth/bootstrap`. No bearer token is issued to humans. **Body** (`application/json`) - `id` (string, required) — The key `id`. **Body example** ```json { "id": "…" } ``` **Response `200`** - `ok` (bool) — true **Errors** - `400` — invalid_key_id - `401` — invalid_session - `403` — invalid_origin / invalid_csrf - `404` — key_not_found - `503` — auth_unavailable **Example** ```js (async () => { const {csrf} = await fetch("https://www.pageaudit.online/api/auth/bootstrap").then(r => r.json()); const r = await fetch("https://www.pageaudit.online/api/account/keys/revoke", {method: "POST", credentials: "same-origin", headers: {"Content-Type": "application/json", "X-CSRF-Token": csrf}, body: JSON.stringify({id: "…"})}); return r.json(); })(); ``` ### `POST /api/auth/claim` Moves what the guest created to the signed-in account: tabs and audits. Bootstrap/CSRF of this browser required; the page does it right after sign-in. Only what the guest still owns moves, in one transaction, and anything that collides with what the account already has stays with the guest. What the guest bought moves too. An old unsigned token that owns nothing here is refused. Repeating it is harmless (moves zero). - **URL:** `https://www.pageaudit.online/api/auth/claim` - **Auth:** `session` — Global account: HttpOnly cookie `__Host-mm-auth`, set when you sign in on this site's `/conta/global` page. An ended session answers 401 `session_ended` (it never falls back to the guest). Writes need the same Origin and `X-CSRF-Token` from `/api/auth/bootstrap`. No bearer token is issued to humans. **Body** (`application/json`) - `guest_token` (string, required) — Guest `pa_…` of this browser. **Body example** ```json { "guest_token": "pa_…" } ``` **Response `200`** - `ok` (bool) — Whether the guest was recognized and moved. - `claimed` (object) — `product.movidos` (rows moved, per table), `product.apagados` (guest duplicates dropped) and `product.direitos` (purchases moved). **Errors** - `400` — invalid_product_claim / invalid_body - `401` — invalid_session - `403` — invalid_origin / invalid_csrf - `409` — unknown_guest (em `claimed.reason` / in `claimed.reason`) - `503` — product_claim_pending / auth_unavailable **Example** ```js (async () => { const {csrf} = await fetch("https://www.pageaudit.online/api/auth/bootstrap").then(r => r.json()); const r = await fetch("https://www.pageaudit.online/api/auth/claim", {method: "POST", credentials: "same-origin", headers: {"Content-Type": "application/json", "X-CSRF-Token": csrf}, body: JSON.stringify({guest_token: localStorage.getItem("pageaudit_guest")})}); return r.json(); })(); ``` ## Contact ### `POST /api/contact` Write to the people behind the product — free, for people and agents alike. One route for a question and for a sponsorship, partnership or ad proposal (`tipo`, with the placements of `GET /api/partners`). No captcha, no account, no payment. One message every 10 seconds per network: one that arrives sooner waits its turn and then goes out — no error. The message reaches the team by e-mail, with `email` as the reply address. - **URL:** `https://www.pageaudit.online/api/contact` - **Auth:** `none` — Public, no credential. **Body** (`application/json`) - `name` (string, required) — What to call the person writing. - `email` (string, required) — Where to reply. - `message` (string, required) — What you want to say. - `tipo` (string) — Proposal: `patrocinio`, `parceria` or `anuncio`. Turns on the fields below. - `empresa` (string) — Who is proposing, when it is a company. - `site` (string) — Website of who is proposing. - `orcamento` (string) — `ate_100`, `100_500`, `500_2000`, `2000_mais` or `a_combinar`. - `espaco` (string[]) — Placement ids from `GET /api/partners`, up to 6. - `duracao` (string) — Exposure in days: `30`, `90` or `365`. - `pagamento` (string) — `usdc`, `deposito` or `a_combinar`. **Body example** ```json { "name": "Agent", "email": "agent@example.com", "message": "hello from an agent" } ``` **Response `200`** - `ok` (bool) — Always `true` when the message was accepted. **Errors** - `400` — Validation: `code` names the field. - `503` — Contact is not configured on this server. **Example** ```sh curl -s -XPOST https://www.pageaudit.online/api/contact -H 'content-type: application/json' -d '{"name":"Agent","email":"agent@example.com","message":"hello from an agent"}' ``` ## Operations ### `POST /api/erro-cliente` Browser error report, sent by the interface itself. Agents need not call it. The interface reports on its own JS errors, unhandled rejections, scripts/CSS that failed to load and CSP blocks — once per session — and the app reports handled failures through `window.mmErro.relata`. The server validates the envelope, redacts credentials, e-mails and phone numbers, merges repeats of the same failure per minute and records an operational event; nothing is written to a database. It keeps no IP, cookie, query string or full User-Agent. Always answers 204, even for an invalid report. - **URL:** `https://www.pageaudit.online/api/erro-cliente` - **Auth:** `none` — Public, no credential. **Body** (`application/json`) - `code` (string, required) — Failure code, `UI-` + letters/digits (`UI-JS-001` global error, `UI-PROMESSA-001`, `UI-RECURSO-001`, `UI-CSP-001`, `UI-APP-001` app report). - `phase` (string, required) — Where it broke, lowercase: `global`, `promessa`, `script`, `load_list`… - `path` (string) — Path of the open page, without query; numbers, hashes and tokens in it are kept as `:id`. - `message` (string) — Error message, up to 2000 characters. - `stack` (string) — Stack trace, up to 12000 characters. - `source` (string) — Originating script; only its path is kept. - `line` (int) — Line in the originating script. - `column` (int) — Column in the originating script. - `visivel` (bool) — Whether the tab was visible when it broke. - `build` (string) — Build of the reporting page (its `<meta name="build">`), up to 64 letters, digits, `.`, `_` or `-`; it dates the failure. **Body example** ```json { "code": "UI-APP-001", "phase": "carregar_lista", "path": "/", "message": "lista 500" } ``` **Response `200`** 204 with no body, always — an invalid, repeated or over-cap report also gets 204. **Example** ```sh curl -s -XPOST https://www.pageaudit.online/api/erro-cliente -H 'content-type: application/json' -d '{"code":"UI-APP-001","phase":"carregar_lista","path":"/","message":"lista 500"}' ``` ### `POST /api/pagamento/aberto` The interface reports a visible payment prompt. Agents must not call this route. An empty same-origin report, sent automatically when a payment prompt becomes visible. It starts no payment, grants no access and receives no identity or credentials. It writes no database row per report. Counts events, not unique people. The private operator dashboard separates API payment requests and browser payment views per UTC day; the two counts may overlap. - **URL:** `https://www.pageaudit.online/api/pagamento/aberto` - **Auth:** `none` — Public, no credential. **Headers** - `Origin` (string, required) — The page origin, identical to this route's origin. - `Sec-Fetch-Site` (string, required) — `same-origin`, set by the browser. - `X-MM-Payment-View` (string, required) — `1`, set by the shared component. **Response `202`** 202 with no body when accepted; 204 when ignored. Always no-store. ### `POST /api/funil` The interface reports the steps of a visit (conversion funnel). Agents must not call this route. A same-origin batch sent by the page itself: page views, engagement, offer in view, buy click, payment window, payment sent or accepted. It keeps the browser's random id, the path without query, the referring host and the utm tags; never IP, e-mail or account. It writes no database row: one line per batch in the day's journal, with a cap. Declared robots and smoke tests are left out. - **URL:** `https://www.pageaudit.online/api/funil` - **Auth:** `none` — Public, no credential. **Headers** - `Origin` (string) — The page origin, identical to this route's origin. - `Content-Type` (string, required) — `application/json` or `text/plain`. **Body** (`application/json`) - `v` (number, required) — Batch version: `1`. - `vid` (string, required) — This browser's random id (UUID v4). - `sid` (string, required) — Session id (30 idle minutes end it). - `sn` (number, required) — This browser's session number. - `pv` (string, required) — Page view id. - `e` (object[], required) — Up to 40 events `{ t, n, p? }` from the funnel vocabulary. **Response `202`** 202 with no body when stored; 204 when ignored. Always no-store. **Example** ```sh curl -s -XPOST https://www.pageaudit.online/api/funil -H 'content-type: text/plain' -H 'x-mm-smoke: 1' -d '{"v":1,"vid":"0f8b9c1e-2a3b-4c5d-8e6f-7a8b9c0d1e2f","sid":"s1abcdefgh","sn":1,"pv":"p1abcdefgh","e":[{"t":0,"n":"pagina"}]}' ``` ### `GET /api/funil/arquivos` Operator: the funnel journal days kept by this app, with the size of each. - **URL:** `https://www.pageaudit.online/api/funil/arquivos` - **Auth:** `none` — Public, no credential. **Headers** - `Authorization` (string, required) — `Bearer <METRICS_TOKEN>`. **Response `200`** - `v` (number) — Stored batch version. - `produto` (string) — The product. - `teto` (object) — `bytesDia` and `dias` kept. - `dias` (object[]) — `{ dia, bytes }`, oldest to today. **Errors** - `401` — Unauthorized - `503` — Not configured **Example** ```sh curl -s https://www.pageaudit.online/api/funil/arquivos -H "Authorization: Bearer $METRICS_TOKEN" ``` ### `GET /api/funil/arquivo` Operator: a slice of one funnel journal day, as NDJSON, from a byte offset. Up to 4 MiB per response, cut at the last whole line. `X-MM-Funil-Proximo` says where to ask for the rest; `X-MM-Funil-Tamanho`, the day's size now. - **URL:** `https://www.pageaudit.online/api/funil/arquivo` - **Auth:** `none` — Public, no credential. **Query** - `dia` (string, required) — The day, `YYYY-MM-DD` (UTC). - `desde` (number) — The byte to read from; `0` at the start. **Headers** - `Authorization` (string, required) — `Bearer <METRICS_TOKEN>`. **Response `200`** JSON lines, one per stored batch. **Errors** - `400` — Invalid parameters - `401` — Unauthorized - `503` — Not configured **Example** ```sh curl -s "https://www.pageaudit.online/api/funil/arquivo?dia=2026-09-27&desde=0" -H "Authorization: Bearer $METRICS_TOKEN" ``` ## Public stats ### `GET /api/vitrine` The product's public numbers: traffic, agents, usage and reliability, no money. Projection published hourly by the house collector, rounded to two significant digits; `null` is a missing measurement, never zero. 15-minute cache with ETag (`If-None-Match` → 304). There is no way to send numbers through this route: publishing belongs to the collector, with its own token. - **URL:** `https://www.pageaudit.online/api/vitrine` - **Auth:** `none` — Public, no credential. **Response `200`** - `v` (int) — Contract version (1). - `produto` (string) — Product id. - `publicado` (bool) — `false` before the collector's first publication; then only these five keys come. - `atualizado_em` (string, may be null) — When the collector published (ISO 8601). - `stale` (bool) — `true` when the projection is older than 26 h. - `nome` (string, optional) — Product name. - `desde` (string, optional, may be null) — First day the series covers. - `fuso` (string, optional) — Time zone of the days (`UTC`). - `hoje` (object, optional) — Today: pages by class (human, AI, bot), API calls by class, machine-surface reads and product usage. - `dias` (object[], optional) — Up to 31 days, oldest first: `dia`, `paginas`, `api`, `api_ia`, `maquina`, `visitantes`, `uso`. - `janelas` (object, optional) — 7- and 30-day sums (`d7`, `d30`). - `visitantes` (object, optional) — Unique visitors at the edge over 7 days. - `pessoas` (object, optional, may be null) — GA4 when available: users, sessions, countries, devices and who arrived from AI. - `agentes` (object, optional) — The AI agents and bots that read the most, 7 days. - `superficies` (object, optional) — Reads of OKF, llms, well-known, OpenAPI and MCP over 7 days. - `mcp` (object, optional) — MCP calls over 7 days. - `uso` (object, optional) — Real product usage per resource: label, today, 7 and 30 days. - `contas` (object, optional, may be null) — Users and guests. - `confiabilidade` (object, optional) — Share of requests without 5xx over 7 days, and the live build. - `catalogo` (object, optional, may be null) — Size of the catalog, when the product has one. - `apoio` (object, optional) — Impressions and clicks per sponsor, when any. **Example** ```sh curl -s https://www.pageaudit.online/api/vitrine ``` ### `GET /api/vitrine/operador` The product's full document on the operator panel — operator token only. - **URL:** `https://www.pageaudit.online/api/vitrine/operador` - **Auth:** `none` — Public, no credential. **Headers** - `Authorization` (string, required) — `Bearer <METRICS_TOKEN>` — the operator class. **Response `200`** - `produto` (string) — Product id. - `atualizado_em` (string, may be null) — When the collector published. - `operador` (object, may be null) — The collector's full document, with what the public projection leaves out. **Errors** - `401` — No token, wrong token or a token of another class. - `503` — Worker without `METRICS_TOKEN` or without the control plane. **Example** ```sh curl -s https://www.pageaudit.online/api/vitrine/operador -H "Authorization: Bearer $METRICS_TOKEN" ``` ### `GET /api/vitrine/painel` The whole house panel, in the shape the gm reads — operator token only. - **URL:** `https://www.pageaudit.online/api/vitrine/painel` - **Auth:** `none` — Public, no credential. **Headers** - `Authorization` (string, required) — `Bearer <METRICS_TOKEN>` — the operator class. **Response `200`** - `apps` (object[]) — One operator document per product, ordered by id. - `updated` (string, optional) — When the collector closed the round. - `totals` (object, optional) — House totals. **Errors** - `401` — No token, wrong token or a token of another class. - `503` — Worker without `METRICS_TOKEN` or without the control plane. **Example** ```sh curl -s https://www.pageaudit.online/api/vitrine/painel -H "Authorization: Bearer $METRICS_TOKEN" ``` ### `GET /api/vitrine/cursores` The resolved-error cursor per product (`borda`, `cli`) — operator token only. - **URL:** `https://www.pageaudit.online/api/vitrine/cursores` - **Auth:** `none` — Public, no credential. **Headers** - `Authorization` (string, required) — `Bearer <METRICS_TOKEN>` — the operator class. **Response `200`** JSON: `{ [product]: { borda?: ISO, cli?: ISO } }`; empty is `{}`. **Errors** - `401` — No token, wrong token or a token of another class. - `503` — Worker without `METRICS_TOKEN` or without the control plane. **Example** ```sh curl -s https://www.pageaudit.online/api/vitrine/cursores -H "Authorization: Bearer $METRICS_TOKEN" ``` ## Partnership ### `GET /api/partners` Partnership, sponsorship and advertising: the product's placements with a suggested price, the public numbers next to them and how to propose. Information on request, no activation: placements from the house catalogue priced in USD per 30 days (90 and 365 days discounted), sponsors in effect, an excerpt of `/api/vitrine`, the house wallet (USDC on Base) and the contact path — bank deposit, PIX or invoice are arranged in the reply. Cached for 1 hour. - **URL:** `https://www.pageaudit.online/api/partners` - **Auth:** `none` — Public, no credential. **Response `200`** - `status` (string) — `sob_consulta`: information and proposal, no activation and no charge. - `produto` (string) — Product name. - `idioma` (string) — Language of the texts (the product's). - `titulo` (string) — Title of the offer. - `descricao` (string) — One sentence about the offer. - `publico` (string) — Who uses the product — the audience a sponsor reaches. - `modalidades` (object[]) — `{ id, nome }`: patrocinio, parceria, anuncio. - `placements` (object[]) — The product's placements: `id`, `nome`, `onde`, `formato`, `exclusivo`, `medicao`, `price_usd_30d` (suggested; `null` is on request), `exposure[{ dias, price_usd }]` for 30, 90 and 365 days, `disponivel`. - `house_bundle` (object) — The house bundle: footer and agent mention across the ten products, discounted. - `parcerias` (string[]) — Partnership ideas the product is open to discuss. - `current_sponsors` (object[]) — Sponsors in effect: `id`, `nome`, `url`, `frase`, `espacos`, `ate`. - `stats` (object) — Excerpt of the public numbers (`hoje`, `janelas`, `agentes`, `confiabilidade`) and the `link` to `/api/vitrine`; `publicado: false` before the first publication. - `payment` (object) — How to pay: `rede`, `chain_id`, `ativo`, `pay_to`, `eip681` (the house wallet, when declared), `alternativas` and the `nota` — bank deposit, PIX or invoice in the reply. - `contact` (object) — `email`, `form_url`, `api_url` (`POST /api/contact`, free: one message every 10 s per network), `campos` (required), `campos_proposta` (the optional proposal fields, each with its accepted values), `message_template`, `instructions`. - `politica` (object) — Placement label, refused sectors, prepayment, deadlines. - `_links` (object) — `self`, `stats`, `page` (`null` until the page exists), `contact`, `casa` (the same path on the ten products). **Example** ```sh curl -s https://www.pageaudit.online/api/partners ``` ## Credit ### `POST /api/credito` Top up prepaid credit: pay once with x402 and get the token that debits on any API of the house. - **URL:** `https://www.pageaudit.online/api/credito` - **Auth:** `none` — Public, no credential. **Query** - `usd` (int, required) — Package: 1, 5, 10 ou 25 dollars. **Response `200`** - `token` (string) — Bearer token for the balance (`cred_…`). Shown ONCE — it cannot be recovered. - `saldo_usd` (string) — Credited balance. - `guarde` (string) — Warning that the token is the bearer of the credit. - `usar` (string) — How to present the token on paid routes. - `saldo_em` (string) — Where to check balance and statement. **Errors** - `400` — Package outside the list (1, 5, 10 ou 25). - `402` — Unpaid — the body carries the x402 `accepts[]`. **Example** ```sh curl -s -XPOST 'https://www.pageaudit.online/api/credito?usd=10' ``` ### `GET /api/credito` Credit balance and statement — the latest movements, without returning the token. - **URL:** `https://www.pageaudit.online/api/credito` - **Auth:** `credito` — Prepaid credit token in `Authorization: Bearer cred_…` (or the `X-Credito` header). Not an account: it is a bearer of balance. **Response `200`** - `saldo_micros` (int) — Balance in micro-dollars (1e-6 USD). - `saldo_usd` (string) — Formatted balance. - `criado_em` (string) — When the credit was opened. - `movimentos` (object[]) — Recent credits and debits, with product and resource. **Errors** - `401` — No token, or unknown token. **Example** ```sh curl -s https://www.pageaudit.online/api/credito -H 'Authorization: Bearer cred_…' ``` ### `GET /api/credito/pix` Credit by Pix (Brazil): the key, the fixed rate, the packs in reais and what the receipt accepts. - **URL:** `https://www.pageaudit.online/api/credito/pix` - **Auth:** `none` — Public, no credential. **Response `200`** - `chave` (string) — The Pix key that receives the payment. - `brl_por_usd` (number) — Fixed rate used for the packs. - `pacotes` (object[]) — The packs (1, 5, 10 ou 25 dollars), each with `brl_centavos` and `copia_e_cola` (the Pix copy-and-paste code for the amount, the same text as the QR: the bank app comes with the amount filled in). - `comprovante` (object) — Accepted types (photo or PDF) and the maximum size, in bytes. - `liberacao` (string) — `manual`: the owner checks the Pix and releases it. **Example** ```sh curl -s https://www.pageaudit.online/api/credito/pix ``` ### `POST /api/credito/pix` Request credit paid by Pix: multipart with `usd`, `comprovante` (photo or PDF up to 2 MB) and `email`; the rest is optional. The credit code comes back in the response and works once the owner checks the Pix and releases it (by hand, usually the same day). `email` is required: it is how the owner reaches the person. Optional: `nome`, `pagina` (the page the request came from, up to 2,000 characters) and what the person was buying when the 402 came — `recurso` (up to 2,000), `descricao` (up to 300) and `preco_usd` (decimal, e.g. `0.50`); and `navegador_id` (a UUID that links the requests from the same browser). Everything that arrives is recorded with the request — the receipt included —, with the signed-in account (checked by the session cookie), the network and browser. - **URL:** `https://www.pageaudit.online/api/credito/pix` - **Auth:** `none` — Public, no credential. **Response `200`** - `id` (string) — Request id, to follow it. - `estado` (string) — `pendente` until the decision. - `credito` (string) — The `cred_…` token, shown ONCE; it works after the release. - `estado_em` (string) — Where to follow the request. **Errors** - `400` — Pack outside the list (1, 5, 10 ou 25), no receipt or no valid e-mail. - `413` — Receipt above 2 MB. - `415` — Receipt that is neither a photo (JPEG, PNG, WebP) nor a PDF. - `429` — This network already sent today's requests. - `502` — The e-mail to the owner did not go out: the request is recorded as `falhou`; send it again. - `503` — Review queue full, or Pix not available in this app. **Example** ```sh curl -s -XPOST https://www.pageaudit.online/api/credito/pix -F usd=5 -F email=you@company.com -F comprovante=@pix.pdf ``` ### `GET /api/credito/pix/:id` Status of a Pix credit request: `pendente`, `liberado`, `recusado` or `falhou`. - **URL:** `https://www.pageaudit.online/api/credito/pix/:id` - **Auth:** `none` — Public, no credential. **Path parameters** - `id` (string, required) — Request id (32 hex). e.g.: `0123456789abcdef0123456789abcdef`. **Response `200`** - `estado` (string) — `pendente`, `liberado`, `recusado` or `falhou` (the e-mail to the owner did not go out; send again). - `usd` (int) — The requested pack. - `decidido_em` (string) — When the owner decided, or `null`. **Errors** - `404` — Unknown request. **Example** ```sh curl -s https://www.pageaudit.online/api/credito/pix/0123456789abcdef0123456789abcdef ``` ## Structures ### `Audit` The report of one audit: score, findings and everything observed on the page. - `id` (string, may be null) — ID of the stored audit; `null` when the database was unavailable. - `score` (int) — 0–100 for measured checks: error -18, warn -8, info 0. Not a security/accessibility certification. Older saved scores keep their original weights. - `issues` (Achado[]) — Everything found, from most to least severe. → see `Achado` under **Structures**. - `summary` (ResumoPagina) — What the page declares: title, meta, canonical, OG, headings, links… → see `ResumoPagina` under **Structures**. - `counts` (ContagemAchados) — How many findings of each severity. → see `ContagemAchados` under **Structures**. - `headers` (object) — Every header of the target's response. `Set-Cookie` is removed on purpose: it is a third party's credential. - `htmlTruncated` (bool) — `true` when the page passed 2 MB and was read only that far. - `jsonLd` (object[]) — The raw JSON-LD blocks, as they were on the page. - `jsonLdStored` (int) — How many blocks survived the size cap — compare with `summary.jsonLdBlocks`. - `truncated` (string[]) — What was cut and why: `jsonld_size`, `jsonld_nodes_over_50`, `result_size`. Empty means nothing cut. - `fixes` (Correcao[]) — The ready fix of each finding, without a model — paste, fill in or decide. The consolidated one is at `_links.patch`. → see `Correcao` under **Structures**. - `quota` (CotaAudit) — How much is still free and what it costs past that. → see `CotaAudit` under **Structures**. - `_links` (LinksAudit) — This audit, the patch, the share and the API index. → see `LinksAudit` under **Structures**. ### `AuditGravado` The same report re-read from the database. It has no `quota` and no `_links` (it is a read, not a run) and gains the date and the share slug. - `audit_id` (string) — ID of the audit. - `url` (string) — Final audited URL, after following the redirects. - `score` (int) — Score from 0 to 100. - `summary` (ResumoPagina, may be null) — What the page declared at the time of the run. → see `ResumoPagina` under **Structures**. - `counts` (ContagemAchados) — How many findings of each severity. → see `ContagemAchados` under **Structures**. - `issues` (Achado[]) — Everything found in that run. → see `Achado` under **Structures**. - `fixes` (Correcao[]) — The ready fix of each finding; an audit stored before this existed gets the computation on read. → see `Correcao` under **Structures**. - `jsonLd` (object[]) — The raw JSON-LD blocks stored. - `headers` (object) — Headers of the target's response, as they were in the run. - `truncated` (string[]) — What was cut by size when storing. - `share_slug` (string, may be null) — Public slug, if this audit was shared. - `created_at` (string) — When the run happened (UTC). ### `Patch` The consolidated patch of an audit, ready for the agent that builds the site to apply. - `url` (string, may be null) — Final audited URL. - `audit` (string, may be null) — Absolute link of the source audit. - `head` (string) — The deterministic tags, one per line, in <head> order (charset first). Empty when there are none. - `arquivos` (ArquivoPatch[]) — Files to create at the host root. → see `ArquivoPatch` under **Structures**. - `moldes` (MoldePatch[]) — What only the owner can fill in. → see `MoldePatch` under **Structures**. - `sem_patch` (SemPatch[]) — What is a decision or infrastructure. → see `SemPatch` under **Structures**. - `resumo` (ResumoPatch) — Count per class. → see `ResumoPatch` under **Structures**. - `como_aplicar` (string) — One-sentence instruction. - `_links` (object) — `api_index`. ### `Ferramenta` A micro-tool: the landing of one isolated check, with the same engine as the full audit. - `slug` (string) — Identifier in the URL, e.g. `title-tag-checker`. - `title` (string) — Page title, used in `<title>`. - `h1` (string) — The landing's H1. - `description` (string) — Meta description of the landing. - `lead` (string) — Opening paragraph. - `category` (string) — Grouping of the tool in the hub. - `icon` (string) — Name of the icon used in the card. - `checks` (string[]) — Finding codes this tool highlights — they are the `Achado.code`s. - `serp` (object) — How the result looks in the search preview. - `sections` (object[]) — Content blocks of the landing. - `_links` (object) — This tool in JSON and in HTML. ### `Compartilhamento` The result of publishing an audit under a non-enumerable slug. - `ok` (bool) — Always `true`. - `shared` (bool) — Whether the audit is published at the end of the call. - `slug` (string) — Public, non-enumerable slug. - `path` (string) — Path of the report's HTML page. - `badge` (string) — Path of the score badge SVG. - `_links` (object) — Report, JSON and badge, as absolute URLs. ### `Badge` The score badge metadata, to build the README markdown. - `slug` (string) — Slug of the shared report. - `score` (int, may be null) — Score shown in the badge. - `label` (string) — Text on the left of the badge. - `available` (bool) — `false` when the share was revoked — the SVG turns grey `n/a`. - `markdown` (string) — The markdown line ready to paste in the README. - `_links` (object) — The SVG and the report. ### `LabTeste` One lab test (Google PageSpeed Insights running Lighthouse). Does not change the audit score. - `status` (string) — `running`, `ok` or `error`. - `strategy` (string, optional) — `mobile` or `desktop`. - `startedAt` (string, optional, may be null) — When a running test started (ISO-8601). - `fetchedAt` (string, optional) — When Lighthouse loaded the page. - `lighthouseVersion` (string, optional, may be null) — Lighthouse version used by Google. - `scores` (object, optional) — `performance`, `accessibility`, `bestPractices`, `seo`, 0–100. - `metrics` (object, optional) — `lcpMs`, `fcpMs`, `tbtMs`, `cls`, `siMs`, `ttfbMs`. - `opportunities` (object[], optional) — Up to 6 biggest savings: `id`, `title`, `displayValue`, `savingsMs`. - `failing` (object[], optional) — Up to 12 failed accessibility, best-practice and SEO audits: `category`, `id`, `title`. - `message` (string, optional) — Why the test failed (`status: error`). ### `Workspace` The owner's whole workspace, with the active tab's result already rehydrated — one call to draw the screen. - `tabs` (Aba[]) — Every tab of the owner. → see `Aba` under **Structures**. - `active_id` (string, may be null) — Which tab is in focus. - `active_result` (AuditGravado, may be null) — The last result of the active tab, so a second call is not needed. → see `AuditGravado` under **Structures**. - `limit` (int) — How many tabs fit before paying. - `owner` (string) — Identifier of this workspace's owner. - `gate` (Gate) — How much of the IP's free allowance remains. → see `Gate` under **Structures**. - `billing` (object) — Prices and usage, the same `GET /api/billing` returns. ### `Aba` A workspace tab: one followed URL, with the last result kept. - `id` (string) — ID of the tab. - `url` (string) — URL the tab follows. - `alias` (string, may be null) — Label the person gave the tab. - `active` (bool) — Whether it is the focused tab in the workspace. - `audit_id` (string, may be null) — Audit of this tab's last run. - `score` (int, may be null) — Score of the last run. - `monitor` (bool) — Whether the daily watch is on for this tab. - `monitor_email` (string, may be null) — Where the watch writes; `null` means the account's e-mail. - `monitor_checked_at` (string, may be null) — When the watch last checked this page (UTC). - `created_at` (string) — When the tab was opened (UTC). ### `Ok` Write confirmation with no body of its own to return. - `ok` (bool) — Always `true` — failure comes as a 4xx/5xx status, not as `ok:false`. ### `Gate` How much of the daily allowance still exists for this IP, and whether the next audit pays. - `ip` (string) — Your IP as the server sees it — echoed back to you, never stored. - `now` (int) — Time of the query, in epoch. - `free_allowance` (int) — Free audits per day. - `free_remaining` (int) — How many remain today for this IP. - `needs_payment` (bool) — `true` when the next audit answers 402 — unless an account in its trial makes it. ### `RunHistorico` One run of a tab in the series, with what changed since the run before it. `change` is null on the oldest run read — with no base there is no change to state. - `audit_id` (string) — The stored audit, readable at `GET /api/audits/:id`. - `score` (int, may be null) — Score of this run. - `counts` (object) — How many errors, warnings and infos this run had. - `created_at` (string) — When the run happened (UTC). - `change` (Mudanca, may be null) — What changed since the previous run. → see `Mudanca` under **Structures**. - `shared` (string, may be null) — Public report URL, when this run was shared. - `api` (string) — This run in the API. ### `Billing` Everything that decides whether the next call will cost: the x402 configuration, the prices, the usage and the trial. - `provider` (string) — Always `x402` — the only billing protocol accepted. - `mode` (string) — Seller mode: `live` charges for real, `dev` lets calls through unpaid. - `network` (string) — USDC network: `base` in production, `base-sepolia` in staging. - `chain_id` (int) — EVM chain ID of the network above, so the wallet signs on the right chain. - `pay_to` (string, may be null) — Address that receives the payment. - `homolog` (bool) — Staging seam on: the loop can be closed without spending USDC. - `dev` (bool) — Development mode: the 402 is simulated. - `dev_gate` (bool) — A homologation credential is configured; this grants no access. - `gratis` (string[], optional) — Temporarily free SKUs. - `facilitator` (string) — URL of the facilitator that verifies and settles the payment. - `asset` (string) — Accepted currency — always `USDC`. - `asset_address` (string) — USDC contract on the network above. - `faucet` (string, may be null) — Test-USDC faucet; only on base-sepolia. - `wallets` (object) — Links to wallets that speak x402 (metamask, coinbase, base_app). - `product` (string) — Name of the product charging. - `free_max_tabs` (int) — Free tabs per owner. - `prices` (Precos) — What each paid action costs, in USD. → see `Precos` under **Structures**. - `usage` (Uso) — How much of the free allowance has been used. → see `Uso` under **Structures**. - `trial` (Trial) — The account's trial, when there is a session. → see `Trial` under **Structures**. ### `Conta` The person behind the session. - `id` (string) — ID of the global account — the owner of the tabs and audits. - `email` (string) — The account's verified e-mail. ### `Trial` The paywall-free period of an account, counted from its first use of PageAudit — once per account. It is the alternative to paying. - `days` (int) — Trial length in days. - `active` (bool) — Whether it is in force now. - `days_left` (int, optional) — How many days remain. - `ends_at` (string, may be null) — When it ends (UTC). ### `Metricas` 7-day panel. `payments` only shows with the operator token and only on Base mainnet. - `app` (string) — Product name. - `today` (string) — Reference day (UTC, YYYY-MM-DD). - `today_visits` (int) — Visits counted today. - `today_contacts` (int, optional) — Contact messages received today. Only with `METRICS_TOKEN`: contact does not leave without a token. - `days` (object[]) — One record per day of the window, with the counts of each metric. - `usage` (object) — Usage per product resource — here, audits and tabs. - `accounts` (object) — Total guests and accounts. - `financeiro` (object, optional) — Aggregate of the day: `hoje_usd`, `hoje_count`, `rede`. Only with `METRICS_TOKEN`: money does not leave without a token; the full series is `payments`. - `payments` (object, optional) — Finance summary; only with METRICS_TOKEN. - `achados` (object, may be null) — Which findings appear across stored audits: `audits` (total) and `por_codigo[]` with `code`, `n`, `audits` and `fracao_audits`. Aggregate, no URL and no owner; 1 h cache. `null` if the database did not answer. ### `PaymentQuota` - `free` (PaymentFree[]) — Free allowances and their windows. → see `PaymentFree` under **Structures**. - `paid` (PaymentPrice[]) — List prices in USD. The operation's 402 is the payable quote. → see `PaymentPrice` under **Structures**. - `how_to_pay` (string) — Payment instructions and availability restrictions. - `live` (string, may be null) — Authoritative product quota endpoint. - `free_now` (string[], optional) — SKUs temporarily free despite their list price. - `trial` (PaymentTrial, optional) — Registration trial, when offered. → see `PaymentTrial` under **Structures**. ### `Achado` A problem (or a pass) found on the page. - `severity` (string) — Severity of the finding. - `code` (string) — Stable check code, e.g. `title_missing`. It is what you filter by. - `message` (string) — The finding in one sentence, ready to show a person. ### `ResumoPagina` Everything the page declares about itself. It is the most consulted object of the API. - `finalUrl` (string) — URL after following every redirect. - `status` (int) — Final HTTP status of the target. - `contentType` (string, may be null) — Content-Type of the final response. - `title` (string, may be null) — Content of `<title>`. - `metaDescription` (string, may be null) — Content of `<meta name=description>`. - `canonical` (string, may be null) — Canonical URL declared by the page. - `robots` (string, may be null) — Content of `<meta name=robots>`. - `viewport` (string, may be null) — Content of `<meta name=viewport>`. - `charset` (string, may be null) — Declared encoding. - `lang` (string, may be null) — Language declared in `<html lang>`. - `favicon` (string, may be null) — URL of the favicon found. - `faviconSource` (string, may be null) — How the favicon was found: declared or by the default path. - `h1s` (string[]) — Every `<h1>` on the page, in order. - `openGraph` (object) — The `og:*` tags found, key by key. - `twitter` (object) — The `twitter:*` tags found. - `jsonLdCount` (int) — How many JSON-LD nodes the page had. - `jsonLdBlocks` (int) — How many `<script type=application/ld+json>` blocks existed. - `jsonLdErrors` (int, optional) — Invalid JSON syntax or non-object root values; not full JSON-LD/schema.org validation. - `jsonLdDropped` (bool) — `true` when nodes were dropped for passing the cap. - `jsonLdTypes` (string[]) — The `@type`s found, e.g. `Organization`, `WebSite`. - `images` (object) — Image count and how many have no `alt`. - `links` (object) — Count of internal, external and text-less links. - `words` (int) — Words in the visible content. - `hreflang` (object[]) — The declared language alternates. - `legacy` (object) — Old markup still present (e.g. `<font>`, layout tables). - `redirects` (object[]) — The redirect chain followed to the final URL. - `robotsTxt` (RobotsTxt, may be null) — The origin's `robots.txt`: status, sitemaps and each crawler's decision for this URL. → see `RobotsTxt` under **Structures**. - `sitemap` (object) — Whether the URL appears in the sitemap the origin declares. - `discovery` (Discovery, optional, may be null) — Selected discovery and delivery checks; optional files missing do not lower the score. Up to 15 additional GETs, concurrency 2, 8s total deadline and 64 KiB per text body. → see `Discovery` under **Structures**. - `xRobotsTag` (string, optional, may be null) — The `X-Robots-Tag` response header, raw. A noindex here (general, googlebot or bingbot) raises the same `noindex` finding as the meta tag. - `canonicalHeader` (string, optional, may be null) — Canonical declared in the HTTP `Link` header (`rel="canonical"`), absolute. Differing from the HTML one raises `canonical_conflict`. - `timing` (object, optional, may be null) — `responseMs`: time until the headers of the final response, redirects included, measured from our server. Over 1500 ms raises `slow_response` (info). - `headings` (object, optional) — `order`: heading levels in document order (up to 100); `skips`: pairs where a level was jumped, e.g. `[2, 4]`. - `scripts` (object, optional) — `total` script tags and `emptyRoot`: the id of an empty app root (`root`, `__next`…) when the HTML is a JavaScript shell. - `crux` (Crux, optional, may be null) — Real-user Core Web Vitals from the Chrome UX Report. → see `Crux` under **Structures**. - `lab` (object, optional) — On-demand lab tests (`mobile`, `desktop`), each a `LabTeste`. Absent until one is run with `POST /api/audits/:id/lab`. ### `ContagemAchados` How many findings of each severity — the summary that fits in a badge. - `errors` (int) — Serious findings. - `warnings` (int) — Findings that deserve attention. - `info` (int) — Observations without severity. ### `Correcao` The ready fix of one finding. `classe` says whether it is to paste, to fill in or to decide. - `code` (string) — The same `code` as the finding (`Achado.code`). - `severity` (string) — Severity of the source finding. - `classe` (string) — `deterministico` comes whole from the page; `molde` has a `{{…}}` placeholder; `sem_patch` is an instruction. - `alvo` (string) — Where to apply: `head`, `corpo`, `img`, `arquivo` or `pagina` (instruction). - `snippet` (string, may be null) — The ready tag (or with a placeholder). `null` for files and for `sem_patch`. - `arquivo` (object, may be null) — `path` and `conteudo` when the fix is a file at the host root. - `fonte` (string, may be null) — Where the value came from, or what the page already had (for the template or to check the cut). - `nota` (string, may be null) — How to apply, or what to decide. ### `CotaAudit` How much is still free and what it costs past that. - `free_per_day` (int) — Free audits per IP per day. - `price_usd` (number) — Price of an audit beyond the allowance, in USD. ### `LinksAudit` Addresses of the audit just created. Without a stored `id`, only `api_index` comes. - `self` (string, optional) — This audit, to re-read without re-auditing. - `patch` (string, may be null) — `GET /api/audits/:id/patch` — the consolidated patch of this audit. - `share` (string, optional) — Where to publish this audit under a public slug. - `api_index` (string) — Self-describing API index. ### `ArquivoPatch` A file to create at the host root. - `code` (string) — Finding that originated it (`robots_txt_missing`, `sitemap_missing`). - `path` (string) — Absolute path on the host, e.g. `/robots.txt`. - `conteudo` (string) — Full content of the file. ### `MoldePatch` A tag with a marked placeholder: content missing that only the owner knows. - `code` (string) — Source finding. - `alvo` (string) — `head`, `corpo` or `img`. - `snippet` (string) — The tag with `{{PLACEHOLDER}}`. - `fonte` (string, may be null) — Suggestion taken from the page itself (H1, og:description…), if any. - `nota` (string) — What to fill in and the limit. ### `SemPatch` Finding without an automatic fix: it is a decision or infrastructure. - `code` (string) — Source finding. - `nota` (string) — What to check or decide. ### `ResumoPatch` How many fixes of each class. - `deterministicos` (int) — Ready to paste (head + files). - `moldes` (int) — With a placeholder. - `sem_patch` (int) — Instruction only. - `total` (int) — Findings considered. ### `Mudanca` The difference between two runs of the same page. Findings are compared by code, never by message: the message carries the measured value and would change without anything getting worse. - `score` (int, may be null) — Point delta, signed (positive means it improved). - `from` (int, may be null) — Score of the previous run. - `to` (int, may be null) — Score of this run. - `broke` (object[]) — Findings that appeared, each with `code`, `severity` and `message`. - `fixed` (object[]) — Findings that disappeared, in the same shape. ### `Precos` Prices in force, in dollars. Read them here, not from the documentation. - `extra_tab_usd` (number) — Cost of a tab beyond the allowance. ### `Uso` How much of the free allowance the owner has used. - `tabs` (int) — Tabs open now. - `free_slots_left` (int) — Free tabs still available. ### `PaymentFree` - `o_que` (string) — Operation or allowance. - `limite` (string) — Allowance and eligibility. - `janela` (string, may be null) — Reset window, when applicable. ### `PaymentPrice` - `o_que` (string) — Operation and billing unit. - `price_usd` (number) — Current list price in USD. ### `PaymentTrial` - `days` (int) — Trial duration in days. - `how` (string) — Eligibility and activation steps. ### `RobotsTxt` The origin's robots.txt as fetched for the audit (up to 64 KiB, 3 redirects, 8 s). - `url` (string) — Where it was fetched from, after redirects. - `ok` (bool) — `true` when a text robots.txt was read. - `status` (int) — HTTP status; 0 when the fetch failed. - `error` (string, optional) — Why it was not read (`HTTP 404`, `robots.txt served as HTML`…). - `sitemaps` (string[], optional) — Declared `Sitemap:` lines (up to 20). - `userAgents` (string[], optional) — User-agent names that have groups. - `disallowAll` (bool, optional) — `true` when the `*` group has `Disallow: /`. - `access` (AcessoRobos, optional) — Each crawler's decision for this URL. Absent in older reports and when the fetch failed. → see `AcessoRobos` under **Structures**. ### `Discovery` Five fixed probes plus well-known extras only when the page declares them or matches their function. Absent in older reports; rerun to measure. No recursive crawling. - `llms` (DiscoveryCheck) — Root llms.txt or the most specific same-origin describedby guide found on the page. → see `DiscoveryCheck` under **Structures**. - `security` (DiscoveryCheck) — /.well-known/security.txt: selected RFC 9116 checks. → see `DiscoveryCheck` under **Structures**. - `apiCatalog` (DiscoveryCheck) — /.well-known/api-catalog: selected RFC 9727 Linkset checks. → see `DiscoveryCheck` under **Structures**. - `changePassword` (DiscoveryCheck, optional) — /.well-known/change-password when the page uses a password field. Redirect only; the form is never submitted. → see `DiscoveryCheck` under **Structures**. - `assetlinks` (DiscoveryCheck, optional) — /.well-known/assetlinks.json when Android app association is indicated. App binary is not compared. → see `DiscoveryCheck` under **Structures**. - `appleApp` (DiscoveryCheck, optional) — /.well-known/apple-app-site-association when Apple associated domains are indicated. No redirects. Entitlements are not checked. → see `DiscoveryCheck` under **Structures**. - `oauthResource` (DiscoveryCheck, optional) — OAuth protected resource metadata when WWW-Authenticate, MCP or the well-known URL is declared. Authorization servers are not fetched. → see `DiscoveryCheck` under **Structures**. - `oauthServer` (DiscoveryCheck, optional) — /.well-known/oauth-authorization-server when this host declares itself as the issuer. → see `DiscoveryCheck` under **Structures**. - `openidConfig` (DiscoveryCheck, optional) — /.well-known/openid-configuration when this host declares OpenID Provider discovery. → see `DiscoveryCheck` under **Structures**. - `agentCard` (DiscoveryCheck, optional) — A2A Agent Card when declared. MCP identity JSON at this URL is not an A2A pass. → see `DiscoveryCheck` under **Structures**. - `webauthn` (DiscoveryCheck, optional) — /.well-known/webauthn when related origins are declared. Same-host passkeys do not need it. → see `DiscoveryCheck` under **Structures**. - `favicon` (DiscoveryCheck) — HTTP status/media type of the selected favicon; no image decoding. → see `DiscoveryCheck` under **Structures**. - `notFound` (DiscoveryCheck) — One randomly generated missing path, checking for 404/410 or a possible soft 404. → see `DiscoveryCheck` under **Structures**. ### `Crux` Chrome UX Report: p75 of real Chrome users over 28 days, for the URL or, without URL data, the origin. Queried from Google, not from the target. - `status` (string) — `ok`, `no_data` (too little traffic), `unverified` (quota, timeout) or `not_configured`. - `source` (string) — Always `chrome-ux-report`. - `scope` (string, optional) — `url` or `origin`. - `key` (string, optional, may be null) — The URL or origin the data belongs to. - `period` (object, optional) — `first` and `last` day of the collection window. - `metrics` (object, optional) — `lcp`, `inp`, `cls`, `fcp`, `ttfb`, each with `p75`, `rating` (`good`, `needs_improvement`, `poor`) and the share of visits `good`/`needsImprovement`/`poor`. - `assessment` (string, optional, may be null) — Core Web Vitals over LCP, INP and CLS: `good`, `needs_improvement` (raises `cwv_needs_improvement`, info) or `poor` (raises `cwv_poor`, warn). - `check` (object) — `status` (`pass`, `warn`, `info` or `unverified`) and `message`, the text the report shows. ### `AcessoRobos` Per-crawler decision for THIS URL from the origin's robots.txt (RFC 9309 groups, longest match wins, Allow wins a tie), inside `summary.robotsTxt.access`. Absent when robots.txt could not be fetched. - `source` (string) — `robots.txt`, `no robots.txt` (4xx: all allowed) or `robots.txt error` (5xx/429: all disallowed). - `path` (string) — Path and query that were evaluated. - `bots` (object[]) — `token`, `owner`, `use` (`search`, `ai_search`, `ai_user`, `ai_training`), `allowed`, the deciding `rule`, `group` (`own`, `*`, `none`) and `mayIgnore` for user-request agents that say they may ignore robots.txt. - `contentSignal` (object, may be null) — Declared Content-Signal (`search`, `ai-input`, `ai-train` → yes/no). - `checks` (object) — `search`, `aiSearch` and `aiTraining`, each with `status` and `message`. Search blocked raises `robots_blocks_search` (warn); AI search blocked raises `ai_crawlers_blocked` (info). ### `DiscoveryCheck` A measured observation with scope and reference. pass is limited to the checks stated in message. - `status` (string) — pass: measured checks passed; warn: issue; info: optional resource absent; unverified: blocked, incomplete, timeout or unavailable. - `url` (string, may be null) — Final public resource URL; null when it cannot safely be probed. - `httpStatus` (int) — Final observed HTTP status, or 0 if unavailable. - `contentType` (string) — Observed Content-Type, or empty when unavailable. - `message` (string) — Measured evidence and limitations; plain text, never instructions to execute. - `phrases` (object[], optional) — The sentences of message, each { key, vars? }, so the report can write them in the page language. message stays the English text. Absent in older reports. - `reference` (string) — Fixed authoritative reference for the check. ## Public data archives Browse addresses and procurement by location, then open the records you need. Up to 20 items per page, in formats ready for people and agents. Check coverage and the reference date before using a result. Access options are shown by each product. - [Postal codes and addresses](https://api.pontofato.com/enderecos/index.json): Find addresses by location, with coordinates and a 2022 reference date. Not a current postal-code certification. State → municipality → locality → street → addresses. [HTML](https://api.pontofato.com/enderecos/) · [llms.txt](https://api.pontofato.com/enderecos/llms.txt) · [OKF](https://api.pontofato.com/enderecos/okf/index.md) - [Public procurement](https://api.editalmd.com/licitacoes/index.json): Find public procurement by location and date. View documents and reading options in EditalMD. Procedure → state → year → month → day → municipality → purchases. [HTML](https://api.editalmd.com/licitacoes/) · [llms.txt](https://api.editalmd.com/licitacoes/llms.txt) · [OKF](https://api.editalmd.com/licitacoes/okf/index.md) ## Quota - Free: audit (`POST /api/audit`) — 10 per IP per day. - Free: audit — rate ceiling — 300 per IP per hour. - Free: workspace tabs — 20 per owner. - Paid: audit beyond the daily allowance — **$0.02** USDC via x402. - Paid: tab beyond the allowance — **$0.05** USDC via x402. - **Not charging right now**: *. Call it directly — no 402. The price above is the list price and comes back without notice. - Trial: sign up and CONFIRM the e-mail → **90 days** of full access, free. Loop: Sign in with an account at /conta/global (browser: e-mail code or link, password or passkey) → 90 days without paywall, counted from the account's first use of PageAudit Past the allowance → **402** with `accepts[]` (x402, USDC on Base). Pay and repeat the same call with `X-PAYMENT` — people and agents alike, no captcha. Free alternative: a person signs in with an account (trial below). Numbers in force: https://www.pageaudit.online/api/billing