openapi: 3.2.0 info: title: PageAudit Tabs 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: Tabs paths: /api/tabs: get: operationId: list_tabs summary: The owner's whole workspace, with the active tab's result already rehydrated description: 'One call draws the whole screen: tabs, the focused tab, its last report, remaining allowance and prices. Returns: { tabs[{id,url,alias,active,audit_id,score,created_at}], active_id, active_result{audit_id,url,score,summary,counts,issues,fixes,jsonLd,headers,truncated,share_slug,created_at}, limit, owner, gate{ip,now,configured,free_allowance,free_remaining,verified_until,needs_verification,sitekey}, billing }' security: - bearerAuth: [] responses: '200': description: '{ tabs[{id,url,alias,active,audit_id,score,created_at}], active_id, active_result{audit_id,url,score,summary,counts,issues,fixes,jsonLd,headers,truncated,share_slug,created_at}, limit, owner, gate{ip,now,configured,free_allowance,free_remaining,verified_until,needs_verification,sitekey}, billing }' content: application/json: schema: $ref: '#/components/schemas/Workspace' '401': description: No credential, or an invalid one. See this endpoint's auth. tags: - Tabs post: operationId: create_tab summary: Opens a tab for the URL, or focuses the one that already exists for it description: 'Past the free tab allowance it answers 402 with `accepts[]`: pay and repeat. Returns: { ok, tab{id,url,alias,active,audit_id,score,created_at} }' security: - bearerAuth: [] requestBody: required: true content: application/json: schema: type: object properties: url: type: string description: The URL the tab will follow. alias: type: string description: Label to recognise the tab in the list. required: - url example: url: https://example.com/ alias: optional label responses: '200': description: '{ ok, tab{id,url,alias,active,audit_id,score,created_at} }' content: application/json: schema: type: object properties: ok: type: boolean description: Always `true`. tab: allOf: - $ref: '#/components/schemas/Aba' description: The opened tab (or the one that already existed for that URL). required: - ok - tab '400': description: '`url` missing or not http.' '401': description: No credential, or an invalid one. See this endpoint's auth. '402': description: 'Quota exceeded. The response carries `accepts[]` (x402, USDC on Base): pay and repeat the same call with `X-PAYMENT`.' tags: - Tabs /api/tabs/{id}: get: operationId: get_api_tabs_by_id summary: One tab with the full report of its last run description: 'Returns: { tab{id,url,alias,active,audit_id,score,created_at}, result{audit_id,url,score,summary,counts,issues,fixes,jsonLd,headers,truncated,share_slug,created_at} }' security: - bearerAuth: [] parameters: - name: id in: path required: true schema: type: string responses: '200': description: '{ tab{id,url,alias,active,audit_id,score,created_at}, result{audit_id,url,score,summary,counts,issues,fixes,jsonLd,headers,truncated,share_slug,created_at} }' content: application/json: schema: type: object properties: tab: allOf: - $ref: '#/components/schemas/Aba' description: The requested tab. result: allOf: - $ref: '#/components/schemas/AuditGravado' description: The report of the last run; `null` if the tab never ran. nullable: true required: - tab - result '401': description: No credential, or an invalid one. See this endpoint's auth. '404': description: The resource does not exist (or is not yours — the API does not tell the two apart on purpose). tags: - Tabs patch: operationId: patch_api_tabs_by_id summary: Renames the tab or puts it in focus description: 'Returns: { ok, tab{id,url,alias,active,audit_id,score,created_at} }' security: - bearerAuth: [] parameters: - name: id in: path required: true schema: type: string requestBody: required: true content: application/json: schema: type: object properties: alias: type: string description: New label of the tab. active: type: boolean description: '`true` focuses this tab (and unfocuses the other).' example: alias: new label active: true responses: '200': description: '{ ok, tab{id,url,alias,active,audit_id,score,created_at} }' content: application/json: schema: type: object properties: ok: type: boolean description: Always `true`. tab: allOf: - $ref: '#/components/schemas/Aba' description: The tab with the change applied. required: - ok - tab '400': description: No changeable field in the body. '401': description: No credential, or an invalid one. See this endpoint's auth. '404': description: The resource does not exist (or is not yours — the API does not tell the two apart on purpose). tags: - Tabs delete: operationId: delete_api_tabs_by_id summary: Closes the tab. Its audit history keeps existing description: 'Returns: { ok }' security: - bearerAuth: [] parameters: - name: id in: path required: true schema: type: string responses: '200': description: '{ ok }' content: application/json: schema: $ref: '#/components/schemas/Ok' '401': description: No credential, or an invalid one. See this endpoint's auth. '404': description: The resource does not exist (or is not yours — the API does not tell the two apart on purpose). tags: - Tabs /api/tabs/{id}/run: post: operationId: run_tab summary: Re-audits the tab's URL and stores a new report description: 'Consumes the same daily allowance as `POST /api/audit` — past it, 402 with `accepts[]`. Returns: { ok, tab{id,url,alias,active,audit_id,score,created_at}, gate{ip,now,configured,free_allowance,free_remaining,verified_until,needs_verification,sitekey}, result{audit_id,url,score,summary,counts,issues,fixes,jsonLd,headers,truncated,share_slug,created_at} }' security: - bearerAuth: [] parameters: - name: id in: path required: true schema: type: string responses: '200': description: '{ ok, tab{id,url,alias,active,audit_id,score,created_at}, gate{ip,now,configured,free_allowance,free_remaining,verified_until,needs_verification,sitekey}, result{audit_id,url,score,summary,counts,issues,fixes,jsonLd,headers,truncated,share_slug,created_at} }' content: application/json: schema: type: object properties: ok: type: boolean description: Always `true`. tab: allOf: - $ref: '#/components/schemas/Aba' description: The tab with the new run's score. gate: allOf: - $ref: '#/components/schemas/Gate' description: How much of the allowance is left after this run. result: allOf: - $ref: '#/components/schemas/AuditGravado' description: The report just stored. required: - ok - tab - gate - result '401': description: No credential, or an invalid one. See this endpoint's auth. '402': description: 'Quota exceeded. The response carries `accepts[]` (x402, USDC on Base): pay and repeat the same call with `X-PAYMENT`.' '404': description: The resource does not exist (or is not yours — the API does not tell the two apart on purpose). tags: - Tabs components: schemas: AuditGravado: type: object properties: audit_id: type: string description: ID of the audit. url: type: string description: Final audited URL, after following the redirects. score: type: integer description: Score from 0 to 100. summary: allOf: - $ref: '#/components/schemas/ResumoPagina' description: What the page declared at the time of the run. nullable: true counts: allOf: - $ref: '#/components/schemas/ContagemAchados' description: How many findings of each severity. issues: type: array items: $ref: '#/components/schemas/Achado' description: Everything found in that run. fixes: type: array items: $ref: '#/components/schemas/Correcao' description: The ready fix of each finding; an audit stored before this existed gets the computation on read. jsonLd: type: array items: type: object description: The raw JSON-LD blocks stored. headers: type: object description: Headers of the target's response, as they were in the run. truncated: type: array items: type: string description: What was cut by size when storing. share_slug: type: string description: Public slug, if this audit was shared. nullable: true created_at: type: string description: When the run happened (UTC). required: - audit_id - url - score - summary - counts - issues - fixes - jsonLd - headers - truncated - share_slug - created_at description: 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. 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 `