openapi: 3.2.0 info: title: PageAudit Audit API version: f5ac3ca0 description: 'Technical SEO auditor that ships the fix. Main client: AI agents. Browsable index at GET /api/.' servers: - url: https://pageaudit.online tags: - name: Audit paths: /api/audit: post: operationId: audit_url summary: Audits a URL and returns the full report in one call, without a token or a tab description: 'This is the product for agents. Past the IP''s daily allowance the response is **402 with `accepts[]`** — pay and repeat the same call. It also carries `sitekey` and `code`, which are the path for a human with a browser; an agent ignores those two. The free alternative: sign up and confirm the e-mail to get the trial. Returns: { id, score, issues[{severity,code,message}], summary{finalUrl,status,contentType,title,metaDescription,canonical,robots,viewport,charset,lang,favicon,faviconSource,h1s,openGraph,twitter,jsonLdCount,jsonLdBlocks,jsonLdDropped,jsonLdTypes,images,links,words,hreflang,legacy,redirects,robotsTxt,sitemap}, counts{errors,warnings,info}, headers, htmlTruncated, jsonLd, jsonLdStored, truncated, fixes[{code,severity,classe,alvo,snippet,arquivo,fonte,nota}], quota{free_per_day,price_usd}, _links{self?,patch,share?,api_index} }' security: [] requestBody: required: true content: application/json: schema: type: object properties: url: type: string description: The page to audit, `http` or `https`. guest_token: type: string description: Guest `pa_…` so the audit is tied to it and shows up in the tabs. cf_turnstile_response: type: string description: Turnstile response; it is the human path, agents use x402. required: - url example: url: https://example.com/ guest_token: pa_… (optional, ties the audit) responses: '200': description: '{ id, score, issues[{severity,code,message}], summary{finalUrl,status,contentType,title,metaDescription,canonical,robots,viewport,charset,lang,favicon,faviconSource,h1s,openGraph,twitter,jsonLdCount,jsonLdBlocks,jsonLdDropped,jsonLdTypes,images,links,words,hreflang,legacy,redirects,robotsTxt,sitemap}, counts{errors,warnings,info}, headers, htmlTruncated, jsonLd, jsonLdStored, truncated, fixes[{code,severity,classe,alvo,snippet,arquivo,fonte,nota}], quota{free_per_day,price_usd}, _links{self?,patch,share?,api_index} }' content: application/json: schema: $ref: '#/components/schemas/Audit' '400': description: Body is not JSON, or `url` missing/not http. '402': description: 'Quota exceeded. The response carries `accepts[]` (x402, USDC on Base): pay and repeat the same call with `X-PAYMENT`.' '403': description: Wrong Turnstile answer. A wrong captcha is not an invitation to pay. '429': description: Past `MAX_AUDITS_PER_HOUR` on the same IP. Wait an hour. tags: - Audit components: schemas: LinksAudit: type: object properties: self: type: string description: This audit, to re-read without re-auditing. patch: type: string description: '`GET /api/audits/:id/patch` — the consolidated patch of this audit.' nullable: true share: type: string description: Where to publish this audit under a public slug. api_index: type: string description: Self-describing API index. required: - patch - api_index description: Addresses of the audit just created. Without a stored `id`, only `api_index` comes. ContagemAchados: type: object properties: errors: type: integer description: Serious findings. warnings: type: integer description: Findings that deserve attention. info: type: integer description: Observations without severity. required: - errors - warnings - info description: How many findings of each severity — the summary that fits in a badge. ResumoPagina: type: object properties: finalUrl: type: string description: URL after following every redirect. status: type: integer description: Final HTTP status of the target. contentType: type: string description: Content-Type of the final response. nullable: true title: type: string description: Content of `