openapi: 3.1.0
info:
  title: Attest Gateway API
  version: 0.5.0
  summary: Verified AI-agent directory, evidence capture, commerce, fulfilment, and mock-credit gateway endpoints for Attest.
  description: >
    Attest exposes agent-readable discovery files, paid-offer pricing,
    mock-credit gateway calls, receipts, and fulfilment intake surfaces. Live
    autonomous money movement is not enabled; Stripe checkout links are used for
    human/self-serve purchases while agent payment rails remain under validation.
    API endpoints of retired products (trust pages, Vendor Pack, NDIS
    Audit-Ready, Attest Tenders and Attest Studio) are not listed here and
    answer 410 {"error":"retired"}.
servers:
  - url: https://getattest.com.au
  - url: https://agentstack-gateway.vercel.app
  - url: /
paths:
  /health:
    get:
      summary: Deployment health
      operationId: getHealth
      responses:
        "200":
          description: Runtime health and live-money boundary.
          content:
            application/json:
              schema:
                type: object
                required: [status, service, live_money_movement, ledger]
                properties:
                  status: { type: string }
                  service: { type: string }
                  live_money_movement: { type: boolean }
                  ledger: { type: string }
  /.well-known/attest.json:
    get:
      summary: Attest service index
      operationId: getAttestIndex
      responses:
        "200":
          description: Service index
          content:
            application/json:
              schema:
                $ref: ./schemas/agentstack-service-index.v0.schema.json
  /api/tools.json:
    get:
      summary: Complete verified AI-agent tool index
      operationId: listVerifiedAgentTools
      responses:
        "200":
          description: Public verified tool records, categories and scoped check evidence.
          content:
            application/json:
              schema:
                type: object
                required: [name, canonical_url, generated_at, verification_scope, count, categories, tools]
                properties:
                  name: { type: string }
                  canonical_url: { type: string, format: uri }
                  generated_at: { type: string, format: date-time }
                  verification_scope: { type: string }
                  count: { type: integer, minimum: 0 }
                  categories: { type: array, items: { type: object } }
                  tools: { type: array, items: { type: object } }
  /api/directory-submit:
    post:
      summary: Submit and verify a public AI-agent tool
      operationId: submitDirectoryTool
      description: Persists the submission as queued, then runs the same scoped verifier used by seed ingestion. Verified listings publish immediately; ambiguous evidence is held for manual review.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [name, url, tagline, description, category, pricing_model, public_information]
              properties:
                name: { type: string, minLength: 2, maxLength: 100 }
                url: { type: string, format: uri }
                tagline: { type: string, minLength: 6, maxLength: 180 }
                description: { type: string, minLength: 10, maxLength: 2000 }
                category: { type: string, enum: [mcp-servers, agent-frameworks, browser-automation, memory-rag, evals, voice, coding-agents, workflow-orchestration, apis-for-agents, misc-dev-tools] }
                pricing_model: { type: string, enum: [free, freemium, paid, open-source, contact] }
                maker: { type: string, maxLength: 120 }
                maker_contact: { type: string, format: email, maxLength: 254 }
                github: { type: string, format: uri }
                public_information: { type: string, const: confirmed }
      responses:
        "200": { description: The verified URL already exists and its public listing is returned. }
        "201": { description: "Submission persisted, verified and published." }
        "202": { description: Submission persisted for manual review or recorded as rejected. }
        "400": { description: Invalid fields or declaration. }
        "429": { description: Hourly IP rate limit exceeded. }
        "503": { description: Durable directory store unavailable. }
  /api/v1/keys:
    post:
      summary: Issue an email-free Attest Capture API key
      operationId: issueCaptureKey
      description: Returns the bearer key once with 25 free credits. Limited to three keys per source IP in a rolling 24-hour window.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [label]
              properties:
                label: { type: string, minLength: 1, maxLength: 80 }
      responses:
        "201": { description: Key issued once with its remaining credit balance. }
        "400": { description: Invalid label. }
        "429": { description: Free-key issuance limit reached. }
        "503": { description: Durable Capture store unavailable. }
  /api/v1/keys/verify:
    get:
      summary: Verify an Attest Capture key and inspect its credit balance
      operationId: verifyCaptureKey
      security:
        - captureBearer: []
      responses:
        "200": { description: "Valid key, remaining credits, tier and rate limit." }
        "401": { description: Missing or invalid bearer key. }
        "503": { description: Durable Capture store unavailable. }
  /api/v1/capture:
    post:
      summary: Capture a public web page as attested PNG, PDF, or rendered HTML
      operationId: createCapture
      description: Public HTTP(S) targets only. PNG and HTML cost one credit; PDF costs two. A signed artifact link expires after 24 hours.
      security:
        - captureBearer: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [url]
              properties:
                url: { type: string, format: uri }
                format: { type: string, enum: [png, pdf, html], default: png }
                full_page: { type: boolean, default: false }
                viewport:
                  type: object
                  required: [width, height]
                  properties:
                    width: { type: integer, minimum: 320, maximum: 2560 }
                    height: { type: integer, minimum: 240, maximum: 2000 }
                attest: { type: boolean, default: true }
      responses:
        "201": { description: "Capture stored with signed artifact URL, SHA-256 digest, timestamp, and optional public evidence URL." }
        "400": { description: Invalid input or blocked private/non-HTTP target. }
        "401": { description: Missing or invalid bearer key. }
        "402": { description: Insufficient credits. }
        "429": { description: Free-key rate limit of ten captures per minute reached. }
        "502": { description: Browser renderer could not complete the capture. }
        "503": { description: Capture storage or renderer unavailable. }
  /api/capture/redeem:
    post:
      summary: Retired Capture pack redemption endpoint
      operationId: retiredCapturePackRedemption
      deprecated: true
      description: Returns HTTP 410 and directs clients to the Stripe Checkout Session claim page.
      responses:
        "410": { description: Gone. Response points to `/capture/claim`. }
  /capture/claim:
    get:
      summary: Collect a one-time Capture key after Stripe checkout
      operationId: claimCapturePurchase
      parameters:
        - name: session_id
          in: query
          required: true
          schema: { type: string, pattern: "^cs_" }
      responses:
        "200": { description: "Paper-receipt page showing a newly claimed key once, an already-collected notice, or a pending webhook notice." }
  /api/capture/refund-request:
    post:
      summary: Queue a Capture or Featured Launch refund request
      operationId: requestCaptureRefund
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [reason]
              properties:
                session_id: { type: string, pattern: "^cs_" }
                receipt_email: { type: string, format: email }
                reason: { type: string, minLength: 10, maxLength: 2000 }
      responses:
        "201": { description: Refund request stored with queued status. }
        "400": { description: Missing purchase identity or invalid request fields. }
        "503": { description: Durable Capture store unavailable. }
  /e/{captureId}:
    get:
      summary: Render a public Attest Capture evidence receipt
      operationId: getCaptureEvidence
      parameters:
        - name: captureId
          in: path
          required: true
          schema: { type: string, format: uuid }
      responses:
        "200": { description: "Public receipt showing source URL, capture time, format, SHA-256 digest, and honest evidence scope." }
        "404": { description: Public capture evidence not found. }
  /badge/{slug}:
    get:
      summary: Embeddable Attested SVG badge
      operationId: getDirectoryBadge
      parameters:
        - name: slug
          in: path
          required: true
          schema: { type: string, pattern: "^[a-z0-9]+(?:-[a-z0-9]+)*$" }
      responses:
        "200":
          description: SVG badge for a verified tool.
          content:
            image/svg+xml:
              schema: { type: string }
        "404": { description: Verified tool not found. }
  /services:
    get:
      summary: List gateway services
      operationId: listServices
      responses:
        "200":
          description: Service entries from the Attest index.
          content:
            application/json:
              schema:
                type: object
                required: [services]
                properties:
                  services:
                    type: array
                    items:
                      type: object
  /services/{serviceId}:
    get:
      summary: Get a service manifest by id
      operationId: getService
      parameters:
        - name: serviceId
          in: path
          required: true
          schema: { type: string }
      responses:
        "200":
          description: Service manifest
          content:
            application/json:
              schema:
                $ref: ./schemas/agentstack-service.v0.schema.json
        "404":
          description: Service not found
  /services/{serviceId}/call:
    post:
      summary: Execute a mock-credit gateway call
      operationId: callService
      parameters:
        - name: serviceId
          in: path
          required: true
          schema: { type: string }
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [action, agent_id, principal_id, amount, currency, rail]
              properties:
                action: { type: string }
                agent_id: { type: string }
                principal_id: { type: string }
                amount: { type: number }
                currency: { type: string }
                rail: { type: string }
                payload: { type: object }
      responses:
        "200":
          description: Policy result, ledger event, and receipt. Mock-credit only.
          content:
            application/json:
              schema:
                type: object
                required: [status, policy, ledger_event, receipt]
                properties:
                  status:
                    type: string
                    enum: [allowed, blocked]
                  policy: { type: object }
                  ledger_event:
                    $ref: ./schemas/agentstack-ledger-event.v0.schema.json
                  receipt:
                    $ref: ./schemas/agentstack-receipt.v0.schema.json
  /receipts/{receiptId}:
    get:
      summary: Fetch a generated mock-credit receipt
      operationId: getReceipt
      parameters:
        - name: receiptId
          in: path
          required: true
          schema: { type: string }
      responses:
        "200":
          description: Receipt
          content:
            application/json:
              schema:
                $ref: ./schemas/agentstack-receipt.v0.schema.json
        "404":
          description: Receipt not found
  /ledger:
    get:
      summary: Fetch the current mock-credit ledger snapshot
      operationId: getLedger
      responses:
        "200":
          description: Ledger events and receipts stored by the current runtime.
          content:
            application/json:
              schema:
                type: object
                required: [events, receipts]
                properties:
                  events:
                    type: array
                    items:
                      $ref: ./schemas/agentstack-ledger-event.v0.schema.json
                  receipts:
                    type: array
                    items:
                      $ref: ./schemas/agentstack-receipt.v0.schema.json
  /services/pricing.json:
    get:
      summary: Pricing and exclusions
      operationId: getPricing
      responses:
        "200":
          description: Pricing document with Stripe checkout_url fields.
          content:
            application/json:
              schema:
                $ref: ./schemas/agentstack-pricing.v0.schema.json
  /services/policy.json:
    get:
      summary: Validation-stage policy
      operationId: getPolicy
      responses:
        "200":
          description: Policy document
          content:
            application/json:
              schema:
                $ref: ./schemas/agentstack-policy.v0.schema.json
  /schemas/agentstack-readiness-report.v0.schema.json:
    get:
      summary: Readiness report JSON twin schema
      operationId: getReadinessReportSchema
      responses:
        "200":
          description: JSON Schema for paid readiness-report deliverables.
          content:
            application/json:
              schema:
                type: object
  /intake:
    get:
      summary: Static paid-buyer intake form
      operationId: getIntake
      parameters:
        - name: order
          in: query
          required: false
          schema: { type: string }
        - name: tier
          in: query
          required: false
          schema:
            type: string
            enum: [readiness_report, manifest_policy_pack, endpoint_kit]
      responses:
        "200":
          description: HTML mailto intake form.
          content:
            text/html:
              schema: { type: string }
  /t/{slug}:
    get:
      summary: Render a verified directory tool page
      operationId: getDirectoryToolPage
      parameters:
        - name: slug
          in: path
          required: true
          schema: { type: string, maxLength: 64, pattern: "^[a-z0-9]+(?:-[a-z0-9]+)*$" }
      responses:
        "200": { description: Tool page HTML with SoftwareApplication schema and the verification record. Outbound links carry rel="sponsored" while a paid featured placement is active. }
        "404": { description: Verified tool not found. }
  /api/stripe-webhook:
    post:
      summary: Stripe checkout completion webhook
      operationId: postStripeWebhook
      description: >
        Verifies Stripe signatures and records checkout.session.completed events.
        Requires STRIPE_WEBHOOK_SECRET in the deployment environment. Current
        Vercel storage is ephemeral unless AGENTSTACK_DATA_DIR is connected to a
        durable sink.
      responses:
        "200":
          description: Event received or ignored.
        "400":
          description: Invalid Stripe signature.
        "500":
          description: Missing webhook secret.
  /llms.txt:
    get:
      summary: Agent-readable text instructions
      operationId: getLlmsTxt
      responses:
        "200":
          description: Agent instructions
          content:
            text/plain:
              schema:
                type: string
  # BEGIN GENERATED attest-tools
  "/api/v1/airports":
    get:
      summary: "Airport reference data"
      operationId: "callAirports"
      description: "Airport reference data. Use when a task needs the static facts about an airport: what an IATA or ICAO code means, where the airport is (city, region, country, coordinates, elevation), whether it has scheduled airline service, which airports a country has, or the straight-line distance and initial bearing between two of them. 1 credit per successful call from the shared Attest credit balance. Docs: https://getattest.com.au/tools/airports"
      tags:
        - "Attest tools"
      security:
        - captureBearer: []
      parameters:
        - name: "code"
          in: "query"
          required: false
          description: "One IATA (LHR) or ICAO (EGLL) code. Returns that single airport. Cannot be combined with q, country or from/to."
          schema:
            type: "string"
        - name: "q"
          in: "query"
          required: false
          description: "Free-text search over airport, city and code. Returns a list."
          schema:
            type: "string"
        - name: "country"
          in: "query"
          required: false
          description: "ISO 3166-1 alpha-2 country code. Returns that country's airports as a list."
          schema:
            type: "string"
        - name: "from"
          in: "query"
          required: false
          description: "Origin IATA or ICAO code for a distance query. Must be sent with to."
          schema:
            type: "string"
        - name: "to"
          in: "query"
          required: false
          description: "Destination IATA or ICAO code. Must be sent with from."
          schema:
            type: "string"
        - name: "type"
          in: "query"
          required: false
          description: "Filters a q or country list by airport size. Refused on a code or from/to query, which have no list to shape."
          schema:
            type: "string"
        - name: "limit"
          in: "query"
          required: false
          description: "Page size for a q or country list."
          schema:
            type: "integer"
        - name: "offset"
          in: "query"
          required: false
          description: "Rows to skip for a q or country list."
          schema:
            type: "integer"
      responses:
        "200":
          description: "Success. 1 credit charged from the shared Attest balance."
          content:
            application/json:
              schema:
                type: "object"
                properties:
                  call_id:
                    type: "string"
                    description: "Receipt id for this call."
                  credits_charged:
                    type: "integer"
                    description: "Credits taken for this call."
                  credits_remaining:
                    type: "integer"
                    description: "Credits left on the key."
                  "query":
                    description: "The parsed query echoed back, in the same words the response uses."
                  "found":
                    description: "Whether the code matched an airport (code queries)."
                  "matched_on":
                    description: "Which field the code matched: iata or icao."
                  "airport":
                    description: "The matched airport: name, city, region, country, coordinates, elevation and whether it has scheduled service (code queries)."
                  "airports":
                    description: "The page of matching airports (q and country queries)."
                  "count":
                    description: "Rows returned in this page."
                  "total":
                    description: "Rows the query matched in total, so a caller knows whether another page exists."
                  "data_snapshot":
                    description: "The date the bundled OurAirports snapshot was taken."
                  "data_age_days":
                    description: "Whole days between data_snapshot and this call."
                  "notice":
                    description: "What this data is and is not: reference information, not an operational or flight-planning source."
        "400":
          description: "query_required, conflicting_query, from_required, to_required, invalid_q, q_too_long, invalid_country, invalid_type."
        "401":
          description: "invalid_api_key — the key is missing or unknown."
        "402":
          description: "insufficient_credits — with credits_required and credits_remaining."
        "429":
          description: "rate_limit_exceeded — with limit and window_seconds."
  "/api/v1/jobs/company":
    post:
      summary: "Company open roles"
      operationId: "callCompanyJobs"
      description: "Company open roles. Use when a task needs the roles one named company is hiring for right now: the live list from that company's own Greenhouse, Lever or Ashby job board, with title, location, department, team, employment type, remote flag, posted date and a link to apply, and optionally the description as plain text. Give a board token or the careers-page URL; the provider is detected either way. 2 credits per successful call from the shared Attest credit balance. Docs: https://getattest.com.au/tools/company_jobs"
      tags:
        - "Attest tools"
      security:
        - captureBearer: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: "object"
              properties:
                "company":
                  type: "string"
                  description: "The company's board token, as it appears in its job-board URL. Required unless careers_url is sent."
                "careers_url":
                  type: "string"
                  description: "The company's Greenhouse, Lever or Ashby careers page. The provider and board token are derived from it."
                "provider":
                  type: "string"
                  description: "auto (default), greenhouse, lever or ashby. Refused if it disagrees with careers_url."
                "include_description":
                  type: "boolean"
                  description: "Include each role's description as plain text. Off by default, because it makes the response much larger."
      responses:
        "200":
          description: "Success. 2 credits charged from the shared Attest balance."
          content:
            application/json:
              schema:
                type: "object"
                properties:
                  call_id:
                    type: "string"
                    description: "Receipt id for this call."
                  credits_charged:
                    type: "integer"
                    description: "Credits taken for this call."
                  credits_remaining:
                    type: "integer"
                    description: "Credits left on the key."
                  "provider":
                    description: "The job board that answered."
                  "company":
                    description: "The board token the roles were read from."
                  "count":
                    description: "Roles returned."
                  "jobs":
                    description: "Each role: title, location, department, team, employment type, remote flag, posted date and a link to apply."
                  "truncated":
                    description: "Whether the board had more roles than were returned."
                  "source":
                    description: "The board API that was read and the public board URL."
                  "attribution":
                    description: "That the wording is the employer's own, and that Attest is not affiliated with the board vendor."
                  "checked_at":
                    description: "When the board was read, not when the request arrived."
        "400":
          description: "company_required, invalid_careers_url, careers_url_unsupported, provider_mismatch, company_mismatch, board_not_found."
        "401":
          description: "invalid_api_key — the key is missing or unknown."
        "402":
          description: "insufficient_credits — with credits_required and credits_remaining."
        "429":
          description: "rate_limit_exceeded — with limit and window_seconds."
        "502":
          description: "board_rate_limited, board_unavailable."
        "503":
          description: "board_busy."
  "/api/v1/currency/convert":
    post:
      summary: "Currency conversion (reference rates)"
      operationId: "callCurrencyConvert"
      description: "Currency conversion (reference rates). Use when a task needs an indicative conversion of an amount between two of about 30 major currencies (AUD, USD, GBP, JPY, NZD, CAD, CNY and others) at the latest European Central Bank reference rates, for estimates or reports, not for transactions. The ECB publishes the euro rates free of charge on its website. 1 credit per successful call from the shared Attest credit balance. Docs: https://getattest.com.au/tools/currency_convert"
      tags:
        - "Attest tools"
      security:
        - captureBearer: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: "object"
              properties:
                "amount":
                  type: "number"
                  description: "The amount to convert, as a JSON number. A numeric string is refused rather than guessed at."
                "from":
                  type: "string"
                  description: "Three-letter code of the currency the amount is in."
                "to":
                  type: "string"
                  description: "Three-letter code to convert to."
              required: ["amount", "from", "to"]
      responses:
        "200":
          description: "Success. 1 credit charged from the shared Attest balance."
          content:
            application/json:
              schema:
                type: "object"
                properties:
                  call_id:
                    type: "string"
                    description: "Receipt id for this call."
                  credits_charged:
                    type: "integer"
                    description: "Credits taken for this call."
                  credits_remaining:
                    type: "integer"
                    description: "Credits left on the key."
                  "rate":
                    description: "The rate used, derived from the ECB euro reference rates."
                  "result":
                    description: "The converted amount, rounded for money."
                  "result_raw":
                    description: "The unrounded conversion, for callers doing their own rounding."
                  "rates_date":
                    description: "The date of the ECB rate table used."
                  "source":
                    description: "The ECB table and its date."
                  "source_url":
                    description: "The ECB page the rates are published on, free of charge."
                  "note":
                    description: "That these are indicative reference rates for estimates and reports, not transaction rates."
        "400":
          description: "amount_required, invalid_amount, amount_too_large, unknown_currency, result_too_large."
        "401":
          description: "invalid_api_key — the key is missing or unknown."
        "402":
          description: "insufficient_credits — with credits_required and credits_remaining."
        "429":
          description: "rate_limit_exceeded — with limit and window_seconds."
        "502":
          description: "rates_unavailable."
  "/api/v1/currency/rates":
    get:
      summary: "Currency reference rates"
      operationId: "callCurrencyRates"
      description: "Currency reference rates. Use when a task needs today's European Central Bank reference exchange rates for about 30 major currencies (AUD, USD, GBP, JPY, NZD, CAD, CNY and others) against any of them as base, for information such as estimates or reports, not for transactions. The ECB publishes the euro rates free of charge on its website. 1 credit per successful call from the shared Attest credit balance. Docs: https://getattest.com.au/tools/currency_rates"
      tags:
        - "Attest tools"
      security:
        - captureBearer: []
      parameters:
        - name: "base"
          in: "query"
          required: false
          description: "Three-letter code to quote the rates against. Defaults to EUR, the currency the ECB publishes."
          schema:
            type: "string"
      responses:
        "200":
          description: "Success. 1 credit charged from the shared Attest balance."
          content:
            application/json:
              schema:
                type: "object"
                properties:
                  call_id:
                    type: "string"
                    description: "Receipt id for this call."
                  credits_charged:
                    type: "integer"
                    description: "Credits taken for this call."
                  credits_remaining:
                    type: "integer"
                    description: "Credits left on the key."
                  "base":
                    description: "The base currency the rates are quoted against."
                  "rates":
                    description: "One rate per currency in the ECB table."
                  "rates_date":
                    description: "The date of the ECB rate table."
                  "source":
                    description: "The ECB table and its date."
                  "source_url":
                    description: "The ECB page the rates are published on, free of charge."
                  "note":
                    description: "That a non-euro base is derived by cross-rate, and that these are reference rates, not transaction rates."
        "400":
          description: "unknown_currency."
        "401":
          description: "invalid_api_key — the key is missing or unknown."
        "402":
          description: "insufficient_credits — with credits_required and credits_remaining."
        "429":
          description: "rate_limit_exceeded — with limit and window_seconds."
        "502":
          description: "rates_unavailable."
  "/api/v1/design-tokens":
    post:
      summary: "Website design tokens"
      operationId: "callDesignTokens"
      description: "Website design tokens. Use when a task needs the design of a live web page as data: the colour palette with where each colour is used, the font families, weights, sizes and line heights actually rendering, the spacing steps, corner radii, box shadows, CSS custom properties on :root, container widths, and whether the page has a dark mode. It reads one page at one viewport width; it does not return the site's stylesheets or a screenshot unless you ask for one. 2 credits per successful call from the shared Attest credit balance. Docs: https://getattest.com.au/tools/design_tokens"
      tags:
        - "Attest tools"
      security:
        - captureBearer: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: "object"
              properties:
                "url":
                  type: "string"
                  description: "The public http(s) page to read. Private and reserved addresses are refused."
                "viewport_width":
                  type: "integer"
                  description: "The viewport width to render at. The tokens are what rendered at that width."
                "include_screenshot":
                  type: "boolean"
                  description: "Also return a screenshot of the rendered page as base64."
              required: ["url"]
      responses:
        "200":
          description: "Success. 2 credits charged from the shared Attest balance."
          content:
            application/json:
              schema:
                type: "object"
                properties:
                  call_id:
                    type: "string"
                    description: "Receipt id for this call."
                  credits_charged:
                    type: "integer"
                    description: "Credits taken for this call."
                  credits_remaining:
                    type: "integer"
                    description: "Credits left on the key."
                  "colors":
                    description: "The colour palette, with where each colour is used."
                  "fonts":
                    description: "The font families, weights, sizes and line heights actually rendering."
                  "spacing":
                    description: "The spacing steps found, with spacing_base_px as the inferred base."
                  "radii":
                    description: "The corner radii in use."
                  "shadows":
                    description: "The box shadows in use."
                  "custom_properties":
                    description: "CSS custom properties resolved on the root element."
                  "containers":
                    description: "Container widths found on the page."
                  "dark_mode":
                    description: "Whether the page has a dark mode."
                  "stats":
                    description: "What was examined, including stylesheets the browser was not allowed to read."
                  "limits":
                    description: "The caps this read applied."
                  "final_url":
                    description: "The URL after redirects."
        "400":
          description: "Invalid input. The body is {\"error\":\"<code>\"}; validate() rejects before any credit is reserved."
        "401":
          description: "invalid_api_key — the key is missing or unknown."
        "402":
          description: "insufficient_credits — with credits_required and credits_remaining."
        "429":
          description: "rate_limit_exceeded — with limit and window_seconds."
        "502":
          description: "render_timeout, render_failed."
  "/api/v1/dev":
    post:
      summary: "Developer utilities: cron, regex, UUID, slug and JSON"
      operationId: "callDevUtils"
      description: "Developer utilities: cron, regex, UUID, slug and JSON. Use when a task needs one of the small developer answers that would otherwise cost a round trip to a web tool: the next times a cron expression fires (in a named time zone and in UTC, with a plain-English reading and a note on which non-standard extensions it uses), what a regular expression matches in a piece of text (run on RE2, so no pattern can backtrack its way into exponential time, and a pattern whose compiled program is too large for the input it was given is refused rather than run), fresh UUIDs (version 4, or time-ordered version 7), a URL slug for a title, or JSON pretty-printed, minified or key-sorted with the line and column of a syntax error. Free, and no data is kept. Free per successful call from the shared Attest credit balance. Docs: https://getattest.com.au/tools/dev_utils"
      tags:
        - "Attest tools"
      security:
        - captureBearer: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: "object"
              properties:
                "operation":
                  type: "string"
                  description: "One of cron_next_runs, regex_test, uuid, slugify, json_format. Each one reads its own further fields."
                "expression":
                  type: "string"
                  description: "The cron expression, for cron_next_runs."
                "timezone":
                  type: "string"
                  description: "IANA time zone name for cron_next_runs, such as Europe/London. Defaults to UTC."
                "start":
                  type: "string"
                  description: "ISO instant to start the cron walk from, for cron_next_runs."
                "count":
                  type: "integer"
                  description: "How many cron runs, or how many UUIDs, to return."
                "pattern":
                  type: "string"
                  description: "The regular expression, for regex_test. Run on RE2."
                "flags":
                  type: "string"
                  description: "Distinct letters from i, m, s and u, for regex_test."
                "input":
                  type: "string"
                  description: "The text to run the pattern over, for regex_test."
                "limit":
                  type: "integer"
                  description: "Maximum matches to return, for regex_test."
                "version":
                  type: "integer"
                  description: "4 (random) or 7 (time-ordered), for uuid. Defaults to 4."
                "text":
                  type: "string"
                  description: "The title to slugify, or the JSON document to format."
                "max_length":
                  type: "integer"
                  description: "Cap on the slug length, for slugify."
                "separator":
                  type: "string"
                  description: "The slug separator. Defaults to a hyphen."
                "indent":
                  type: "integer"
                  description: "Spaces per level for json_format; 0 minifies."
                "sort_keys":
                  type: "boolean"
                  description: "Sort object keys, for json_format."
              required: ["operation"]
      responses:
        "200":
          description: "Success. Free charged from the shared Attest balance."
          content:
            application/json:
              schema:
                type: "object"
                properties:
                  call_id:
                    type: "string"
                    description: "Receipt id for this call."
                  credits_charged:
                    type: "integer"
                    description: "Credits taken for this call."
                  credits_remaining:
                    type: "integer"
                    description: "Credits left on the key."
                  "operation":
                    description: "The operation that ran."
                  "next_runs":
                    description: "The next fire times, in the named zone and in UTC (cron_next_runs)."
                  "normalized":
                    description: "The cron expression as the parser read it (cron_next_runs)."
                  "matches":
                    description: "The matches found, with their groups and offsets (regex_test)."
                  "engine":
                    description: "The regex engine and version that ran the pattern (regex_test)."
                  "program_size":
                    description: "The compiled program size RE2 produced, which is what the cost guard measures (regex_test)."
                  "uuids":
                    description: "The generated UUIDs (uuid)."
                  "slug":
                    description: "The ASCII slug (slugify)."
                  "unicode_slug":
                    description: "The slug with non-Latin scripts kept (slugify)."
                  "text":
                    description: "The formatted JSON document (json_format)."
                  "limits":
                    description: "The caps this operation applied."
                  "notice":
                    description: "That the answer is computed from the caller's own input and nothing is stored."
        "400":
          description: "operation_required, invalid_operation, invalid_cron, invalid_timezone, invalid_start, invalid_pattern, unsupported_regex, pattern_too_costly, invalid_flags, invalid_version, invalid_json, json_too_deep, output_too_large."
        "401":
          description: "invalid_api_key — the key is missing or unknown."
        "402":
          description: "insufficient_credits — with credits_required and credits_remaining."
        "429":
          description: "rate_limit_exceeded — with limit and window_seconds."
  "/api/v1/directory/dataset":
    post:
      summary: "Directory dataset"
      operationId: "callDirectoryDataset"
      description: "Directory dataset. Use when an agent needs a paged export or change feed of verified Attest directory facts. 10 credits per successful call from the shared Attest credit balance. Docs: https://getattest.com.au/tools/directory_dataset"
      tags:
        - "Attest tools"
      security:
        - captureBearer: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: "object"
              properties:
                "format":
                  type: "string"
                  description: "json (default) or csv. CSV remains inside the JSON response envelope."
                "category":
                  type: "string"
                  description: "An Attest directory category slug."
                "since":
                  type: "string"
                  description: "ISO date or timestamp with timezone; includes rows verified OR updated at or after it."
                "cursor":
                  type: "string"
                  description: "Opaque next_cursor from the previous page. Keep category and since unchanged. If matching data changes, restart without a cursor."
                "limit":
                  type: "integer"
                  description: "1–500 rows; defaults to 500. Each successful page costs 10 credits, including an empty page."
      responses:
        "200":
          description: "Success. 10 credits charged from the shared Attest balance."
          content:
            application/json:
              schema:
                type: "object"
                properties:
                  call_id:
                    type: "string"
                    description: "Receipt id for this call."
                  credits_charged:
                    type: "integer"
                    description: "Credits taken for this call."
                  credits_remaining:
                    type: "integer"
                    description: "Credits left on the key."
                  "rows":
                    description: "JSON array of whitelisted facts, or CSV text with the same columns (checks is JSON in a cell). Taglines are capped at 160 characters; descriptions and maker data are excluded. CSV formula-like cells get an apostrophe prefix."
                  "next_cursor":
                    description: "Next page token, or null on the last page. Stable slug order; no featured ranking."
                  "total_matching":
                    description: "Unique verified rows matching filters in the supplied listing, before paging; never a fixed advertised count."
                  "generated_at":
                    description: "Attest server generation time, not a new verification time."
                  "licence":
                    description: "Data-licence note and verification scope; third-party marks remain with their owners."
        "400":
          description: "invalid_input, invalid_format, invalid_category, invalid_since, invalid_limit, invalid_cursor."
        "401":
          description: "invalid_api_key — the key is missing or unknown."
        "402":
          description: "insufficient_credits — with credits_required and credits_remaining."
        "429":
          description: "rate_limit_exceeded — with limit and window_seconds."
        "503":
          description: "services_unavailable, directory_unavailable."
  "/api/v1/directory/search":
    get:
      summary: "Directory search"
      operationId: "callDirectorySearch"
      description: "Directory search. Use when an agent needs to find AI-agent tools (MCP servers, frameworks, browser automation, memory, evals, voice, coding agents and more) by keyword or category before choosing one. Free per successful call from the shared Attest credit balance. Docs: https://getattest.com.au/tools/directory_search"
      tags:
        - "Attest tools"
      security:
        - captureBearer: []
      parameters:
        - name: "q"
          in: "query"
          required: false
          description: "Keyword to search over the verified tool listings."
          schema:
            type: "string"
        - name: "category"
          in: "query"
          required: false
          description: "One of the Attest directory category slugs."
          schema:
            type: "string"
        - name: "limit"
          in: "query"
          required: false
          description: "Maximum tools to return."
          schema:
            type: "integer"
      responses:
        "200":
          description: "Success. Free charged from the shared Attest balance."
          content:
            application/json:
              schema:
                type: "object"
                properties:
                  call_id:
                    type: "string"
                    description: "Receipt id for this call."
                  credits_charged:
                    type: "integer"
                    description: "Credits taken for this call."
                  credits_remaining:
                    type: "integer"
                    description: "Credits left on the key."
                  "query":
                    description: "The query as it was read."
                  "count":
                    description: "Tools returned."
                  "tools":
                    description: "Each tool: name, slug, tagline, category, pricing model, its own URL, its Attest page, GitHub, verified_at, and whether it holds a paid placement."
                  "ranking":
                    description: "How the results were ordered."
                  "verification_scope":
                    description: "Exactly what Attested means, and what it does not claim."
        "400":
          description: "invalid_category, invalid_limit."
        "401":
          description: "invalid_api_key — the key is missing or unknown."
        "402":
          description: "insufficient_credits — with credits_required and credits_remaining."
        "429":
          description: "rate_limit_exceeded — with limit and window_seconds."
        "503":
          description: "services_unavailable."
  "/api/v1/email/check":
    post:
      summary: "Email address check"
      operationId: "callEmailCheck"
      description: "Email address check. Use when an agent needs to screen an email address before a sign-up, lead import or send: syntax, whether the domain can receive mail (MX), disposable domains, role accounts and free mailbox providers — without contacting the mail server. 1 credit per successful call from the shared Attest credit balance. Docs: https://getattest.com.au/tools/email_check"
      tags:
        - "Attest tools"
      security:
        - captureBearer: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: "object"
              properties:
                "email":
                  type: "string"
                  description: "The address to screen. Nothing is sent to the mail server."
              required: ["email"]
      responses:
        "200":
          description: "Success. 1 credit charged from the shared Attest balance."
          content:
            application/json:
              schema:
                type: "object"
                properties:
                  call_id:
                    type: "string"
                    description: "Receipt id for this call."
                  credits_charged:
                    type: "integer"
                    description: "Credits taken for this call."
                  credits_remaining:
                    type: "integer"
                    description: "Credits left on the key."
                  "email":
                    description: "The address as it was parsed."
                  "domain":
                    description: "The domain part."
                  "syntax_valid":
                    description: "Whether the address parses as a valid address."
                  "mx":
                    description: "The MX records found for the domain."
                  "accepts_mail":
                    description: "Whether the domain publishes a way to receive mail."
                  "implicit_mx":
                    description: "Whether delivery would fall back to the A/AAAA record."
                  "disposable":
                    description: "Whether the domain is on the disposable-domain list."
                  "role_account":
                    description: "Whether the local part is a role account such as info or support."
                  "free_provider":
                    description: "Whether the domain is a free mailbox provider."
                  "verdict":
                    description: "The overall read, with reasons."
                  "mailbox_checked":
                    description: "Always false: the mailbox itself is never probed."
        "400":
          description: "email_required, invalid_email, email_too_long."
        "401":
          description: "invalid_api_key — the key is missing or unknown."
        "402":
          description: "insufficient_credits — with credits_required and credits_remaining."
        "429":
          description: "rate_limit_exceeded — with limit and window_seconds."
        "502":
          description: "dns_lookup_failed."
  "/api/v1/email/domain-auth":
    post:
      summary: "Email sending-domain check"
      operationId: "callEmailDomainAuth"
      description: "Email sending-domain check. Use when a task needs to know whether a domain is set up to send email that inboxes accept: MX, SPF (with the 10-lookup limit), DKIM keys, DMARC policy, MTA-STS, TLS-RPT and BIMI, with a 0-100 score and plain-English fixes. 1 credit per successful call from the shared Attest credit balance. Docs: https://getattest.com.au/tools/email_domain_auth"
      tags:
        - "Attest tools"
      security:
        - captureBearer: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: "object"
              properties:
                "domain":
                  type: "string"
                  description: "The sending domain to check. Required unless email is sent."
                "email":
                  type: "string"
                  description: "An address to take the domain from. Refused if it disagrees with domain."
                "dkim_selectors":
                  type: "array"
                  description: "Extra DKIM selectors to look up, on top of the common ones this service tries."
      responses:
        "200":
          description: "Success. 1 credit charged from the shared Attest balance."
          content:
            application/json:
              schema:
                type: "object"
                properties:
                  call_id:
                    type: "string"
                    description: "Receipt id for this call."
                  credits_charged:
                    type: "integer"
                    description: "Credits taken for this call."
                  credits_remaining:
                    type: "integer"
                    description: "Credits left on the key."
                  "domain":
                    description: "The domain that was checked."
                  "mx":
                    description: "MX records, including a null MX (RFC 7505)."
                  "spf":
                    description: "The SPF record, its mechanisms and its count against the 10-lookup limit."
                  "dkim":
                    description: "The DKIM keys found, per selector."
                  "dmarc":
                    description: "The DMARC record and its policy."
                  "mta_sts":
                    description: "The MTA-STS record and the policy file when one is advertised."
                  "tls_rpt":
                    description: "The TLS-RPT record."
                  "bimi":
                    description: "The BIMI record."
                  "score":
                    description: "A 0-100 score for the published configuration."
                  "score_breakdown":
                    description: "What each section contributed to the score."
                  "score_unchecked":
                    description: "Sections that could not be checked, so a low score is not read as a failure."
                  "recommendations":
                    description: "Plain-English fixes for what is missing."
        "400":
          description: "domain_required, invalid_domain, invalid_email, domain_email_mismatch, invalid_dkim_selectors, too_many_dkim_selectors."
        "401":
          description: "invalid_api_key — the key is missing or unknown."
        "402":
          description: "insufficient_credits — with credits_required and credits_remaining."
        "429":
          description: "rate_limit_exceeded — with limit and window_seconds."
        "502":
          description: "dns_lookup_failed."
  "/api/v1/files/convert":
    post:
      summary: "File converter"
      operationId: "callFileConvert"
      description: "File converter. Use when a task has a file in one format and needs it in another: a Word document (.docx) to HTML, Markdown or plain text; HTML to Markdown or plain text; Markdown to HTML; CSV to JSON; JSON to CSV; or CSV and TSV either way. Send the file as a URL or base64, or paste the text. Input is capped at 6 MB, or 1 MB when the target is Markdown, and nothing is stored. 1 credit per successful call from the shared Attest credit balance. Docs: https://getattest.com.au/tools/file_convert"
      tags:
        - "Attest tools"
      security:
        - captureBearer: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: "object"
              properties:
                "from":
                  type: "string"
                  description: "The input format: docx, html, markdown, csv, json or tsv."
                "to":
                  type: "string"
                  description: "The output format. Supported pairs are returned on every response and on an unsupported_conversion error."
                "text":
                  type: "string"
                  description: "The document as text. Not accepted for docx, which is binary."
                "url":
                  type: "string"
                  description: "A public http(s) URL to read the document from."
                "file_base64":
                  type: "string"
                  description: "The document as base64. Exactly one of text, url or file_base64."
              required: ["from", "to"]
      responses:
        "200":
          description: "Success. 1 credit charged from the shared Attest balance."
          content:
            application/json:
              schema:
                type: "object"
                properties:
                  call_id:
                    type: "string"
                    description: "Receipt id for this call."
                  credits_charged:
                    type: "integer"
                    description: "Credits taken for this call."
                  credits_remaining:
                    type: "integer"
                    description: "Credits left on the key."
                  "result_text":
                    description: "The converted document."
                  "from":
                    description: "The input format."
                  "to":
                    description: "The output format."
                  "input_source":
                    description: "Which of text, url or file_base64 was used."
                  "input_encoding":
                    description: "The character encoding the input was read as."
                  "bytes_in":
                    description: "Bytes read."
                  "bytes_out":
                    description: "Bytes produced."
                  "truncated":
                    description: "Whether the output was cut at a cap."
                  "stats":
                    description: "Counts from the conversion, such as rows and columns for tabular formats."
                  "warnings":
                    description: "What was dropped or changed in the conversion."
                  "limits":
                    description: "The caps that applied to this conversion."
                  "supported_pairs":
                    description: "Every from -> to pair this service converts."
        "400":
          description: "unsupported_conversion, input_required, too_many_inputs, text_input_not_supported, input_too_large, invalid_file_base64, invalid_json, json_not_tabular, invalid_docx, compression_ratio_rejected."
        "401":
          description: "invalid_api_key — the key is missing or unknown."
        "402":
          description: "insufficient_credits — with credits_required and credits_remaining."
        "429":
          description: "rate_limit_exceeded — with limit and window_seconds."
        "502":
          description: "source_http_error."
  "/api/v1/image/transform":
    post:
      summary: "Image transform"
      operationId: "callImageTransform"
      description: "Image transform. Use when a task needs an image resized, cropped to a box, rotated, flipped, greyscaled, blurred, tinted, trimmed, padded, compressed or converted between JPEG, PNG, WebP and AVIF; or needs a favicon set built from a logo; or needs to read a photo's EXIF and ICC details (with GPS withheld unless asked for) before the metadata is stripped. 1 credit per successful call from the shared Attest credit balance. Docs: https://getattest.com.au/tools/image_transform"
      tags:
        - "Attest tools"
      security:
        - captureBearer: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: "object"
              properties:
                "url":
                  type: "string"
                  description: "A public http(s) image URL. Exactly one of url or file_base64."
                "file_base64":
                  type: "string"
                  description: "The image as base64."
                "operation":
                  type: "string"
                  description: "A single-shot operation: metadata or favicon_set. Cannot be combined with operations."
                "operations":
                  type: "array"
                  description: "A pipeline, applied in order. Each entry names one of resize, rotate, flip, flop, convert, compress, grayscale, blur, tint, flatten, strip_metadata, trim, extend, with that operation's own options."
                "include_gps":
                  type: "boolean"
                  description: "For operation metadata: return the GPS tag as well. Withheld by default."
                "auto_orient":
                  type: "boolean"
                  description: "Apply the EXIF orientation before the pipeline runs. On by default."
                "bundle":
                  type: "string"
                  description: "For operation favicon_set: how to return the files, as separate files or a zip."
      responses:
        "200":
          description: "Success. 1 credit charged from the shared Attest balance."
          content:
            application/json:
              schema:
                type: "object"
                properties:
                  call_id:
                    type: "string"
                    description: "Receipt id for this call."
                  credits_charged:
                    type: "integer"
                    description: "Credits taken for this call."
                  credits_remaining:
                    type: "integer"
                    description: "Credits left on the key."
                  "operation":
                    description: "The operation that ran, for a single-shot call."
                  "operations_applied":
                    description: "The pipeline that ran, in order."
                  "format":
                    description: "The format of the produced image."
                  "width":
                    description: "Width of the produced image."
                  "height":
                    description: "Height of the produced image."
                  "bytes":
                    description: "Size of the produced image."
                  "sha256":
                    description: "SHA-256 of the produced bytes."
                  "file_base64":
                    description: "The produced image."
                  "files":
                    description: "For favicon_set: each generated icon with its size, bytes and hash."
                  "exif":
                    description: "For operation metadata: the camera details found, with GPS withheld unless asked for."
                  "icc":
                    description: "For operation metadata: the colour profile found."
                  "limits":
                    description: "The caps that applied."
                  "notice":
                    description: "That metadata is stripped from every returned image, so results are sRGB with no camera or GPS details."
        "400":
          description: "input_required, input_conflict, unknown_operation, operation_conflict, operations_required, resize_requires_width_or_height, unsupported_image_format, image_too_many_pixels, file_too_large, output_too_large, output_dimensions_too_large."
        "401":
          description: "invalid_api_key — the key is missing or unknown."
        "402":
          description: "insufficient_credits — with credits_required and credits_remaining."
        "429":
          description: "rate_limit_exceeded — with limit and window_seconds."
        "502":
          description: "fetch_failed."
  "/api/v1/ip/lookup":
    post:
      summary: "IP address lookup"
      operationId: "callIpLookup"
      description: "IP address lookup. Use when a task needs to know what an IPv4 or IPv6 address is: public or private/reserved (per IANA registries), which network (ASN) announced it in a recent public routing snapshot, and — for public addresses — the approximate country of that network. An IPv6 address that wraps an IPv4 one (IPv4-mapped, NAT64, 6to4, Teredo) returns it in embedded_ipv4; look that address up to get its network and country. The country describes the network, not a person or device. IP geolocation by DB-IP (CC BY 4.0). 1 credit per successful call from the shared Attest credit balance. Docs: https://getattest.com.au/tools/ip_lookup"
      tags:
        - "Attest tools"
      security:
        - captureBearer: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: "object"
              properties:
                "ip":
                  type: "string"
                  description: "One IPv4 or IPv6 address."
              required: ["ip"]
      responses:
        "200":
          description: "Success. 1 credit charged from the shared Attest balance."
          content:
            application/json:
              schema:
                type: "object"
                properties:
                  call_id:
                    type: "string"
                    description: "Receipt id for this call."
                  credits_charged:
                    type: "integer"
                    description: "Credits taken for this call."
                  credits_remaining:
                    type: "integer"
                    description: "Credits left on the key."
                  "ip":
                    description: "The address, normalised."
                  "version":
                    description: "4 or 6."
                  "scope":
                    description: "What the address is: public, private, reserved or another IANA special purpose."
                  "globally_reachable":
                    description: "Whether the IANA registry marks the address as globally reachable."
                  "special_purpose":
                    description: "The IANA special-purpose registry entry, when the address is in one."
                  "embedded_ipv4":
                    description: "The IPv4 address wrapped inside an IPv4-mapped, NAT64, 6to4 or Teredo address. Look that one up for its network and country."
                  "asn":
                    description: "The autonomous system number that announced the address in a recent public routing snapshot."
                  "as_name":
                    description: "The name published for that network."
                  "network_cidr":
                    description: "The announced prefix the address falls in."
                  "country":
                    description: "The approximate country of the network. It describes the network, not a person or device."
                  "source":
                    description: "Each dataset used, with its snapshot date and age in days."
                  "notice":
                    description: "What the answer does and does not say about the address."
        "400":
          description: "ip_required, invalid_ip, ip_too_long."
        "401":
          description: "invalid_api_key — the key is missing or unknown."
        "402":
          description: "insufficient_credits — with credits_required and credits_remaining."
        "429":
          description: "rate_limit_exceeded — with limit and window_seconds."
  "/api/v1/links/verify":
    post:
      summary: "Backlink check"
      operationId: "callLinksVerify"
      description: "Backlink check. Use when a task needs to confirm that a page links to a site or URL: whether the link is there, whether it is followed (no nofollow, sponsored or ugc) and whether the linking page can be indexed, based on Google's published robots and link rules. 1 credit per successful call from the shared Attest credit balance. Docs: https://getattest.com.au/tools/links_verify"
      tags:
        - "Attest tools"
      security:
        - captureBearer: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: "object"
              properties:
                "page_url":
                  type: "string"
                  description: "The public page that should carry the link."
                "target":
                  type: "string"
                  description: "The site or URL the link should point at."
              required: ["page_url", "target"]
      responses:
        "200":
          description: "Success. 1 credit charged from the shared Attest balance."
          content:
            application/json:
              schema:
                type: "object"
                properties:
                  call_id:
                    type: "string"
                    description: "Receipt id for this call."
                  credits_charged:
                    type: "integer"
                    description: "Credits taken for this call."
                  credits_remaining:
                    type: "integer"
                    description: "Credits left on the key."
                  "found":
                    description: "Whether a link to the target is on the page."
                  "match_count":
                    description: "How many matching links were found."
                  "links":
                    description: "Each matching link: href, anchor text, rel and whether it is followed."
                  "anchors_scanned":
                    description: "How many links on the page were examined."
                  "page":
                    description: "Whether the page can be indexed, per its robots meta tag and X-Robots-Tag."
                  "page":
                    description: "Whether a page-level nofollow applies to its links."
                  "page":
                    description: "The robots rules read from the page."
                  "page":
                    description: "The robots rules read from the response headers."
                  "page":
                    description: "The canonical URL the page declares, and whether it matches the page."
                  "verdict":
                    description: "The overall read of the link."
                  "final_url":
                    description: "The URL after redirects."
                  "http_status":
                    description: "The status the page returned."
        "400":
          description: "page_url_required, invalid_page_url, page_url_too_long, target_required, invalid_target."
        "401":
          description: "invalid_api_key — the key is missing or unknown."
        "402":
          description: "insufficient_credits — with credits_required and credits_remaining."
        "429":
          description: "rate_limit_exceeded — with limit and window_seconds."
        "502":
          description: "fetch_failed."
  "/api/v1/media/probe":
    post:
      summary: "Media file probe"
      operationId: "callMediaProbe"
      description: "Media file probe. Use when a task needs to know what a media file actually is: its container and codecs, how long it runs, its resolution and frame rate, its sample rate and channel count, and the bitrate of each stream — from a public URL or an inline upload, without downloading it into a media player. 1 credit per successful call from the shared Attest credit balance. Docs: https://getattest.com.au/tools/media_probe"
      tags:
        - "Attest tools"
      security:
        - captureBearer: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: "object"
              properties:
                "url":
                  type: "string"
                  description: "A public http(s) media URL. Exactly one of url or file_base64."
                "file_base64":
                  type: "string"
                  description: "The media file as base64."
      responses:
        "200":
          description: "Success. 1 credit charged from the shared Attest balance."
          content:
            application/json:
              schema:
                type: "object"
                properties:
                  call_id:
                    type: "string"
                    description: "Receipt id for this call."
                  credits_charged:
                    type: "integer"
                    description: "Credits taken for this call."
                  credits_remaining:
                    type: "integer"
                    description: "Credits left on the key."
                  "container":
                    description: "The container format the file declares."
                  "format":
                    description: "A readable description of that format."
                  "duration_seconds":
                    description: "How long the file runs."
                  "overall_bitrate":
                    description: "The overall bitrate declared."
                  "streams":
                    description: "Each stream: type, codec, resolution, frame rate, sample rate, channels and bitrate."
                  "size_bytes":
                    description: "The file size."
                  "bytes_read":
                    description: "How much of the file was actually read."
                  "truncated":
                    description: "Whether the read stopped before the end of the file, with truncated_because saying why."
                  "notes":
                    description: "What a partial read means for the figures above."
                  "limits":
                    description: "The byte, stream and time budgets this probe applied."
                  "library":
                    description: "The reader used, with its version and licence."
        "400":
          description: "media_input_required, conflicting_media_input, empty_file, file_too_large, unrecognised_media, too_many_streams."
        "401":
          description: "invalid_api_key — the key is missing or unknown."
        "402":
          description: "insufficient_credits — with credits_required and credits_remaining."
        "429":
          description: "rate_limit_exceeded — with limit and window_seconds."
        "502":
          description: "media_fetch_failed."
  "/api/v1/media/open-search":
    get:
      summary: "Public-domain art and media search"
      operationId: "callOpenMediaSearch"
      description: "Public-domain art and media search. Use when a task needs an image or artwork that is free to use: public-domain works from The Metropolitan Museum of Art and the Art Institute of Chicago, each with title, artist, date, medium, a full-size image URL, a thumbnail, the museum's page for the work, the licence the museum publishes and a ready-made credit line. Only items the museum itself flags as public domain are returned. 1 credit per successful call from the shared Attest credit balance. Docs: https://getattest.com.au/tools/open_media_search"
      tags:
        - "Attest tools"
      security:
        - captureBearer: []
      parameters:
        - name: "q"
          in: "query"
          required: true
          description: "What to search the museum collections for."
          schema:
            type: "string"
        - name: "source"
          in: "query"
          required: false
          description: "all (default), met for The Metropolitan Museum of Art, or aic for the Art Institute of Chicago."
          schema:
            type: "string"
        - name: "limit"
          in: "query"
          required: false
          description: "Maximum items to return."
          schema:
            type: "integer"
        - name: "has_image"
          in: "query"
          required: false
          description: "Only return items that have an image. On by default."
          schema:
            type: "boolean"
      responses:
        "200":
          description: "Success. 1 credit charged from the shared Attest balance."
          content:
            application/json:
              schema:
                type: "object"
                properties:
                  call_id:
                    type: "string"
                    description: "Receipt id for this call."
                  credits_charged:
                    type: "integer"
                    description: "Credits taken for this call."
                  credits_remaining:
                    type: "integer"
                    description: "Credits left on the key."
                  "query":
                    description: "The query as it was read."
                  "count":
                    description: "Items returned."
                  "items":
                    description: "Each work: title, artist, date, medium, a full-size image URL, a thumbnail, the museum's page for it, the licence the museum publishes and a ready-made credit line."
                  "truncated":
                    description: "Whether a museum held more than was returned."
                  "sources":
                    description: "The museums that answered, with their own licence terms."
                  "sources_unavailable":
                    description: "Museums that did not answer, so an empty result is never read as nothing existing."
                  "attribution":
                    description: "That the values are each museum's own, and that Attest is not affiliated with either museum."
        "400":
          description: "q_required, invalid_q."
        "401":
          description: "invalid_api_key — the key is missing or unknown."
        "402":
          description: "insufficient_credits — with credits_required and credits_remaining."
        "429":
          description: "rate_limit_exceeded — with limit and window_seconds."
        "502":
          description: "source_unavailable, source_response_unreadable."
  "/api/v1/pdf/inspect":
    post:
      summary: "PDF readability check"
      operationId: "callPdfInspect"
      description: "PDF readability check. Use when a task needs to know what automated software gets when it reads a PDF: whether there is a real text layer or only scanned pictures, which fonts are embedded, whether the page is multi-column, whether the text comes out in reading order, and — for a CV — whether contact details, section headings, bullets and dates can be found at all. 1 credit per successful call from the shared Attest credit balance. Docs: https://getattest.com.au/tools/pdf_inspect"
      tags:
        - "Attest tools"
      security:
        - captureBearer: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: "object"
              properties:
                "url":
                  type: "string"
                  description: "A public http(s) PDF URL. Exactly one of url or file_base64."
                "file_base64":
                  type: "string"
                  description: "The PDF as base64."
                "profile":
                  type: "string"
                  description: "general (default) or resume. The resume profile also looks for contact details, section headings, bullets and dates."
                "file_name":
                  type: "string"
                  description: "The original file name, used only in the report."
      responses:
        "200":
          description: "Success. 1 credit charged from the shared Attest balance."
          content:
            application/json:
              schema:
                type: "object"
                properties:
                  call_id:
                    type: "string"
                    description: "Receipt id for this call."
                  credits_charged:
                    type: "integer"
                    description: "Credits taken for this call."
                  credits_remaining:
                    type: "integer"
                    description: "Credits left on the key."
                  "profile":
                    description: "The profile that ran."
                  "pages":
                    description: "Page count."
                  "findings":
                    description: "What automated software would get from this file, as a list of findings."
                  "stats":
                    description: "The measurements behind the findings: text layer, fonts, columns, reading order, and the resume checks when that profile ran."
                  "limits":
                    description: "The byte, page, pixel and decompression budgets this read applied."
                  "sources":
                    description: "The parser and the standards the report's terms come from."
                  "notice":
                    description: "What the report is: a readability check, not a statement about the document's content."
        "400":
          description: "url_or_file_base64_required, url_and_file_base64_conflict, not_a_pdf, invalid_pdf, pdf_password_required, pdf_too_complex, file_too_large, empty_file."
        "401":
          description: "invalid_api_key — the key is missing or unknown."
        "402":
          description: "insufficient_credits — with credits_required and credits_remaining."
        "429":
          description: "rate_limit_exceeded — with limit and window_seconds."
        "502":
          description: "fetch_failed."
        "422":
          description: "pdf_read_failed."
  "/api/v1/pdf":
    post:
      summary: "PDF tools"
      operationId: "callPdfTools"
      description: "PDF tools. Use when a task has a PDF to inspect or reshape without a desktop app: page count and page sizes, text extraction, merging several files, splitting or pulling out pages, rotating, or rendering pages to PNG. 1 credit per successful call from the shared Attest credit balance. Docs: https://getattest.com.au/tools/pdf_tools"
      tags:
        - "Attest tools"
      security:
        - captureBearer: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: "object"
              properties:
                "operation":
                  type: "string"
                  description: "One of info, extract_text, merge, split, extract_pages, rotate, to_png."
                "url":
                  type: "string"
                  description: "A public http(s) PDF URL, for every operation except merge."
                "file_base64":
                  type: "string"
                  description: "The PDF as base64, for every operation except merge."
                "files":
                  type: "array"
                  description: "The PDFs to merge, each as a url or file_base64 entry. merge only."
                "pages":
                  type: "string"
                  description: "A page selection such as 1-3,7. Required for extract_pages; optional for extract_text, split, rotate and to_png."
                "rotate":
                  type: "integer"
                  description: "Degrees to rotate, for operation rotate."
                "scale":
                  type: "number"
                  description: "Render scale, for operation to_png."
              required: ["operation"]
      responses:
        "200":
          description: "Success. 1 credit charged from the shared Attest balance."
          content:
            application/json:
              schema:
                type: "object"
                properties:
                  call_id:
                    type: "string"
                    description: "Receipt id for this call."
                  credits_charged:
                    type: "integer"
                    description: "Credits taken for this call."
                  credits_remaining:
                    type: "integer"
                    description: "Credits left on the key."
                  "operation":
                    description: "The operation that ran."
                  "source":
                    description: "Whether the input came from a url or file_base64."
                  "bytes_in":
                    description: "Bytes read."
                  "pages":
                    description: "Page count and page sizes, for operation info."
                  "text":
                    description: "The extracted text, for operation extract_text."
                  "file_base64":
                    description: "The produced PDF, for merge, extract_pages and rotate."
                  "files":
                    description: "The produced parts, for split and to_png."
                  "truncated":
                    description: "Whether the output stopped at the response cap, with the parts that fit returned."
                  "effective_max_input_bytes":
                    description: "The limit that actually binds this operation."
                  "effective_input_note":
                    description: "Why that limit binds, and what to do when a document is larger."
        "400":
          description: "operation_required, invalid_operation, source_required, source_conflict, files_required, too_few_files, too_many_files, pages_required, page_out_of_range, rotate_required, invalid_rotate, pdf_encrypted, invalid_pdf."
        "401":
          description: "invalid_api_key — the key is missing or unknown."
        "402":
          description: "insufficient_credits — with credits_required and credits_remaining."
        "429":
          description: "rate_limit_exceeded — with limit and window_seconds."
        "502":
          description: "source_http_error."
        "413":
          description: "output_too_large."
  "/api/v1/phone/parse":
    post:
      summary: "Phone number check"
      operationId: "callPhoneParse"
      description: "Phone number check. Use when a task needs to know whether a phone number is valid for its country, what kind of number it is (mobile, landline, toll-free, premium rate, VoIP) and its E.164, national and international formats. Formats, country and type are only returned for valid numbers; an invalid number keeps its E.164 form only when its length is possible, and e164 is null for any number longer than the 15 digits E.164 allows. The phone input may be a plain number or an RFC 3966 tel: URI, so the uri from an earlier answer can be fed straight back in. Checked offline: no carrier or live-line lookup. 1 credit per successful call from the shared Attest credit balance. Docs: https://getattest.com.au/tools/phone_parse"
      tags:
        - "Attest tools"
      security:
        - captureBearer: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: "object"
              properties:
                "phone":
                  type: "string"
                  description: "The number, as digits or as an RFC 3966 tel: URI, so the uri from an earlier answer can be fed straight back in."
                "default_country":
                  type: "string"
                  description: "ISO 3166-1 alpha-2 region code to read a national-format number against."
              required: ["phone"]
      responses:
        "200":
          description: "Success. 1 credit charged from the shared Attest balance."
          content:
            application/json:
              schema:
                type: "object"
                properties:
                  call_id:
                    type: "string"
                    description: "Receipt id for this call."
                  credits_charged:
                    type: "integer"
                    description: "Credits taken for this call."
                  credits_remaining:
                    type: "integer"
                    description: "Credits left on the key."
                  "valid":
                    description: "Whether the number is valid for its country."
                  "possible":
                    description: "Whether the length is possible even when the number is not valid."
                  "reason":
                    description: "Why an invalid number was rejected."
                  "e164":
                    description: "The E.164 form. Null for any number longer than the 15 digits E.164 allows."
                  "national":
                    description: "The national format, for valid numbers."
                  "international":
                    description: "The international format, for valid numbers."
                  "country":
                    description: "The country the number belongs to, for valid numbers."
                  "country_calling_code":
                    description: "The calling code."
                  "type":
                    description: "Mobile, landline, toll-free, premium rate, VoIP and so on, for valid numbers."
                  "extension":
                    description: "Any extension carried on the number."
                  "uri":
                    description: "The RFC 3966 tel: URI for the number."
        "400":
          description: "phone_required, invalid_phone, phone_too_long, invalid_default_country."
        "401":
          description: "invalid_api_key — the key is missing or unknown."
        "402":
          description: "insufficient_credits — with credits_required and credits_remaining."
        "429":
          description: "rate_limit_exceeded — with limit and window_seconds."
  "/api/v1/psd/inspect":
    post:
      summary: "Photoshop file inspector"
      operationId: "callPsdInspect"
      description: "Photoshop file inspector. Use when a task needs to know what is inside a .psd or .psb without opening Photoshop: canvas size, colour mode and profile, the layer tree with blend modes and effects, which layers are text (and the fonts they need), smart objects, adjustment layers and guides, with an optional small PNG preview. Bitmap, grayscale, indexed and RGB files only. 3 credits per successful call from the shared Attest credit balance. Docs: https://getattest.com.au/tools/psd_inspect"
      tags:
        - "Attest tools"
      security:
        - captureBearer: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: "object"
              properties:
                "url":
                  type: "string"
                  description: "A public http(s) .psd or .psb URL. Exactly one of url or file_base64."
                "file_base64":
                  type: "string"
                  description: "The file as base64."
                "include_preview":
                  type: "boolean"
                  description: "Also return a small PNG preview of the composite."
                "include_text":
                  type: "boolean"
                  description: "Also return the text content of text layers."
                "preview_max_px":
                  type: "integer"
                  description: "Longest side of the preview, when one is asked for."
      responses:
        "200":
          description: "Success. 3 credits charged from the shared Attest balance."
          content:
            application/json:
              schema:
                type: "object"
                properties:
                  call_id:
                    type: "string"
                    description: "Receipt id for this call."
                  credits_charged:
                    type: "integer"
                    description: "Credits taken for this call."
                  credits_remaining:
                    type: "integer"
                    description: "Credits left on the key."
                  "format":
                    description: "psd or psb."
                  "width":
                    description: "Canvas width."
                  "height":
                    description: "Canvas height."
                  "mode":
                    description: "Colour mode. Bitmap, grayscale, indexed and RGB are readable."
                  "bit_depth":
                    description: "Bits per channel."
                  "channels":
                    description: "Channel count."
                  "resolution":
                    description: "The document resolution."
                  "color_profile":
                    description: "The embedded colour profile, when there is one."
                  "layers":
                    description: "The layer tree with blend modes, effects, smart objects and adjustment layers."
                  "fonts":
                    description: "The fonts the text layers need."
                  "guides":
                    description: "Guides saved in the document."
                  "created_with":
                    description: "The writer name stored in the file."
                  "preview_base64":
                    description: "The PNG preview, when one was asked for and could be built."
                  "limits":
                    description: "The byte, layer, text, font and preview budgets this read applied."
        "400":
          description: "url_or_file_required, url_and_file_conflict, file_empty, invalid_psd, color_mode_not_supported, invalid_file_base64."
        "401":
          description: "invalid_api_key — the key is missing or unknown."
        "402":
          description: "insufficient_credits — with credits_required and credits_remaining."
        "429":
          description: "rate_limit_exceeded — with limit and window_seconds."
        "502":
          description: "fetch_failed."
        "413":
          description: "file_too_large."
  "/api/v1/sheets/build":
    post:
      summary: "Spreadsheet builder"
      operationId: "callSheetsBuild"
      description: "Spreadsheet builder. Use when a task has to hand back a real spreadsheet rather than a wall of rows: typed columns (text, number, date, currency, percent) with number formats applied, a bold header, optional frozen header row, column widths and an autofilter, returned as a base64 .xlsx or .csv. Up to 10 sheets and 50,000 cells in total (the header row counts). Values that could be read back as formulas are neutralised. Dates go in as YYYY-MM-DD or YYYY-MM-DDTHH:MM:SS; percent cells store a fraction (0.15 is 15%) unless the column sets percent_basis to \"percent\". CSV takes one sheet. 1 credit per successful call from the shared Attest credit balance. Docs: https://getattest.com.au/tools/sheets_build"
      tags:
        - "Attest tools"
      security:
        - captureBearer: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: "object"
              properties:
                "format":
                  type: "string"
                  description: "xlsx (default) or csv. CSV takes one sheet."
                "sheets":
                  type: "array"
                  description: "Up to 10 sheets. Each has a name, a columns list and an optional rows list, plus freeze_header and autofilter flags."
                "sheets[].columns":
                  type: "array"
                  description: "Each column: key, label and type (text, number, date, currency, percent), with optional width and percent_basis."
                "sheets[].rows":
                  type: "array"
                  description: "Each row is an object keyed by column key. Up to 50,000 cells in total, header row included."
              required: ["sheets", "sheets[].columns"]
      responses:
        "200":
          description: "Success. 1 credit charged from the shared Attest balance."
          content:
            application/json:
              schema:
                type: "object"
                properties:
                  call_id:
                    type: "string"
                    description: "Receipt id for this call."
                  credits_charged:
                    type: "integer"
                    description: "Credits taken for this call."
                  credits_remaining:
                    type: "integer"
                    description: "Credits left on the key."
                  "format":
                    description: "The format produced."
                  "content_type":
                    description: "The media type of the produced file."
                  "filename":
                    description: "A suggested file name."
                  "sheets":
                    description: "Each sheet with its row and column counts."
                  "cells_written":
                    description: "Cells written."
                  "cells_repaired":
                    description: "Cells where characters no XML document can hold were dropped."
                  "formula_guard":
                    description: "How many cells carry the formula guard, what triggers it and how it is applied."
                  "dates":
                    description: "How dates are stored in this format."
                  "text_storage":
                    description: "How text is stored in this format."
                  "bytes":
                    description: "Size of the produced file."
                  "sha256":
                    description: "SHA-256 of the produced bytes. The same rows always produce the same hash."
                  "file_base64":
                    description: "The produced file."
        "400":
          description: "sheets_required, invalid_format, csv_multiple_sheets, too_many_sheets, columns_required, too_many_columns, too_many_rows, too_many_cells, input_too_large."
        "401":
          description: "invalid_api_key — the key is missing or unknown."
        "402":
          description: "insufficient_credits — with credits_required and credits_remaining."
        "429":
          description: "rate_limit_exceeded — with limit and window_seconds."
        "413":
          description: "output_too_large."
  "/api/v1/subtitles":
    post:
      summary: "Subtitle tools: convert, retime, merge and read caption files"
      operationId: "callSubtitleTools"
      description: "Subtitle tools: convert, retime, merge and read caption files. Use when a task involves a subtitle or caption file: converting between SubRip (.srt), WebVTT (.vtt), ASS/SSA and YouTube SBV, shifting timings or rescaling them for a frame-rate change (23.976 to 25 and back), merging several files onto one timeline, pulling a plain-text transcript out of captions, or reporting a file's cue count, duration and reading speed. The converted file comes back in result_text; the info operation leaves result_text empty and answers in the info block. Send the file as text, as a public URL, or as base64 up to 4 MB. 1 credit per successful call from the shared Attest credit balance. Docs: https://getattest.com.au/tools/subtitle_tools"
      tags:
        - "Attest tools"
      security:
        - captureBearer: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: "object"
              properties:
                "operation":
                  type: "string"
                  description: "convert (default), shift, merge, to_text or info."
                "text":
                  type: "string"
                  description: "The caption file as text. Not allowed with operation merge."
                "url":
                  type: "string"
                  description: "A public http(s) URL to read the caption file from."
                "file_base64":
                  type: "string"
                  description: "The caption file as base64, up to 4 MB."
                "files":
                  type: "array"
                  description: "The files to merge onto one timeline. merge only."
                "from_format":
                  type: "string"
                  description: "auto (default), srt, vtt, ass or sbv."
                "to_format":
                  type: "string"
                  description: "srt, vtt, ass or sbv. Required for convert; refused for info and to_text."
                "offset_seconds":
                  type: "number"
                  description: "Seconds to shift every cue, for operation shift."
                "scale":
                  type: "number"
                  description: "Timing multiplier for a frame-rate change, for operation shift."
                "merge_gap_seconds":
                  type: "number"
                  description: "Gap to leave between files, for operation merge."
                "strip_tags":
                  type: "boolean"
                  description: "Drop styling tags from the cue text."
      responses:
        "200":
          description: "Success. 1 credit charged from the shared Attest balance."
          content:
            application/json:
              schema:
                type: "object"
                properties:
                  call_id:
                    type: "string"
                    description: "Receipt id for this call."
                  credits_charged:
                    type: "integer"
                    description: "Credits taken for this call."
                  credits_remaining:
                    type: "integer"
                    description: "Credits left on the key."
                  "operation":
                    description: "The operation that ran."
                  "from_format":
                    description: "The format the file was read as."
                  "to_format":
                    description: "The format written, or null for info and to_text."
                  "cues":
                    description: "Cue count."
                  "duration_seconds":
                    description: "Where the last cue ends."
                  "result_text":
                    description: "The converted file, the transcript, or empty for operation info."
                  "truncated":
                    description: "Whether the output stopped at a cap."
                  "applied":
                    description: "The offset, scale, merge gap, tag stripping and file count actually applied."
                  "info":
                    description: "Cue count, duration and reading speed."
                  "warnings":
                    description: "What the parser had to repair or drop."
                  "limits":
                    description: "The caps that applied."
                  "sources":
                    description: "The format specifications this parser and writer follow."
        "400":
          description: "text_required, conflicting_input, files_not_allowed, files_required, too_few_files, to_format_required, to_format_not_allowed, invalid_to_format, offset_or_scale_required, unknown_subtitle_format, too_many_cues, input_too_large."
        "401":
          description: "invalid_api_key — the key is missing or unknown."
        "402":
          description: "insufficient_credits — with credits_required and credits_remaining."
        "429":
          description: "rate_limit_exceeded — with limit and window_seconds."
        "502":
          description: "fetch_failed."
  "/api/v1/techstack":
    post:
      summary: "Tech Stack lookup"
      operationId: "callTechstack"
      description: "Tech Stack lookup. Use when a task depends on what a website is built with: CMS, ecommerce platform, hosting, analytics, ad pixels, payments, chat or forms. 1 credit per successful call from the shared Attest credit balance. Docs: https://getattest.com.au/tools/techstack"
      tags:
        - "Attest tools"
      security:
        - captureBearer: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: "object"
              properties:
                "url":
                  type: "string"
                  description: "The public http(s) page to look up. A bare domain is treated as https://."
              required: ["url"]
      responses:
        "200":
          description: "Success. 1 credit charged from the shared Attest balance."
          content:
            application/json:
              schema:
                type: "object"
                properties:
                  call_id:
                    type: "string"
                    description: "Receipt id for this call."
                  credits_charged:
                    type: "integer"
                    description: "Credits taken for this call."
                  credits_remaining:
                    type: "integer"
                    description: "Credits left on the key."
                  "url":
                    description: "The URL as it was read."
                  "final_url":
                    description: "The URL after redirects."
                  "http_status":
                    description: "The status the page returned."
                  "technologies":
                    description: "Each detection: name, category, confidence and the header, cookie or page snippet that proved it."
                  "checked_at":
                    description: "When the page was fetched."
        "400":
          description: "url_required, invalid_url, private_address_not_allowed, unsupported_content_type, response_too_large, redirect_limit_exceeded."
        "401":
          description: "invalid_api_key — the key is missing or unknown."
        "402":
          description: "insufficient_credits — with credits_required and credits_remaining."
        "429":
          description: "rate_limit_exceeded — with limit and window_seconds."
        "502":
          description: "fetch_timeout, fetch_failed."
  "/api/v1/render":
    post:
      summary: "Document and card renderer"
      operationId: "callTemplateRender"
      description: "Document and card renderer. Use when a task needs a PNG or PDF built from content the caller already has — HTML, Markdown, or a built-in social card, invoice, certificate or pull-quote template — for example an OG image, a receipt, a one-page report or a printable summary. It renders content you supply; it does not visit or screenshot a live website (use /api/v1/capture for that). 2 credits per successful call from the shared Attest credit balance. Docs: https://getattest.com.au/tools/template_render"
      tags:
        - "Attest tools"
      security:
        - captureBearer: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: "object"
              properties:
                "html":
                  type: "string"
                  description: "HTML to render. Exactly one of html, markdown or data."
                "markdown":
                  type: "string"
                  description: "Markdown to render."
                "data":
                  type: "object"
                  description: "Fields for a built-in template. Name the template with data.template: og_card, invoice, certificate or quote."
                "format":
                  type: "string"
                  description: "png (default) or pdf."
                "width":
                  type: "integer"
                  description: "Render width in pixels, 200-2400."
                "height":
                  type: "integer"
                  description: "Render height in pixels, 200-4000. PNG only."
                "scale":
                  type: "integer"
                  description: "Device pixel ratio, 1-3. PNG only."
                "page_size":
                  type: "string"
                  description: "Page size such as A4. PDF only."
                "landscape":
                  type: "boolean"
                  description: "Landscape orientation. PDF only."
                "margin_mm":
                  type: "integer"
                  description: "Page margin in millimetres, 0-50."
      responses:
        "200":
          description: "Success. 2 credits charged from the shared Attest balance."
          content:
            application/json:
              schema:
                type: "object"
                properties:
                  call_id:
                    type: "string"
                    description: "Receipt id for this call."
                  credits_charged:
                    type: "integer"
                    description: "Credits taken for this call."
                  credits_remaining:
                    type: "integer"
                    description: "Credits left on the key."
                  "format":
                    description: "png or pdf."
                  "source_format":
                    description: "Whether the content came from html, markdown or a template."
                  "template":
                    description: "The built-in template used, when one was."
                  "width":
                    description: "Width of the output, in unit."
                  "height":
                    description: "Height of the output, in unit."
                  "pages":
                    description: "Page count, for a PDF."
                  "content_type":
                    description: "The media type of the produced file."
                  "bytes":
                    description: "Size of the produced file."
                  "sha256":
                    description: "SHA-256 of the produced bytes."
                  "file_base64":
                    description: "The produced file."
                  "subresources":
                    description: "What the page was allowed to load while rendering."
                  "templates":
                    description: "Every built-in template name."
                  "limits":
                    description: "The caps that applied."
        "400":
          description: "content_required, multiple_content_sources, height_not_supported_for_pdf, scale_not_supported_for_pdf, page_size_not_supported_for_png, landscape_not_supported_for_png, invalid_template, template_field_required, unknown_template_field, data_uri_not_allowed, navigation_not_allowed, content_too_complex."
        "401":
          description: "invalid_api_key — the key is missing or unknown."
        "402":
          description: "insufficient_credits — with credits_required and credits_remaining."
        "429":
          description: "rate_limit_exceeded — with limit and window_seconds."
        "502":
          description: "render_timeout, render_too_large, render_failed."
  "/api/v1/diff":
    post:
      summary: "Text and JSON compare"
      operationId: "callTextDiff"
      description: "Text and JSON compare. Use when a task needs to know exactly what changed between two versions of a text, document, config file or JSON payload: line, word or character changes with a unified patch, or a JSON Pointer list of structural changes. Inputs are capped at 1,000,000 characters a side and 1,500,000 combined; lines and words mode handle that whole range, while chars mode on a heavily rewritten document falls back to block-level changes (coarse: true in the response) rather than taking longer. 1 credit per successful call from the shared Attest credit balance. Docs: https://getattest.com.au/tools/text_diff"
      tags:
        - "Attest tools"
      security:
        - captureBearer: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: "object"
              properties:
                "a":
                  type: "string"
                  description: "The first version. Up to 1,000,000 characters."
                "b":
                  type: "string"
                  description: "The second version. a and b together are capped at 1,500,000 characters."
                "mode":
                  type: "string"
                  description: "lines (default), words, chars or json."
                "ignore_whitespace":
                  type: "boolean"
                  description: "Treat runs of whitespace as equal."
                "ignore_case":
                  type: "boolean"
                  description: "Compare without case."
                "context_lines":
                  type: "integer"
                  description: "Lines of context in the unified patch, 0-20."
              required: ["a", "b"]
      responses:
        "200":
          description: "Success. 1 credit charged from the shared Attest balance."
          content:
            application/json:
              schema:
                type: "object"
                properties:
                  call_id:
                    type: "string"
                    description: "Receipt id for this call."
                  credits_charged:
                    type: "integer"
                    description: "Credits taken for this call."
                  credits_remaining:
                    type: "integer"
                    description: "Credits left on the key."
                  "mode":
                    description: "The mode that ran."
                  "unit":
                    description: "What a change is counted in: lines, words, characters or JSON pointers."
                  "identical":
                    description: "Whether the two sides are the same."
                  "stats":
                    description: "Added, removed and, for json, changed counts."
                  "changes":
                    description: "Each change, with its position."
                  "unified_patch":
                    description: "A unified diff, for the text modes."
                  "coarse":
                    description: "True when chars mode fell back to block-level changes rather than taking longer."
                  "truncated":
                    description: "Whether the change list stopped at a cap."
                  "options":
                    description: "The options that were applied."
        "400":
          description: "a_required, b_required, input_too_long, too_many_lines, invalid_json_a, invalid_json_b, json_too_deep."
        "401":
          description: "invalid_api_key — the key is missing or unknown."
        "402":
          description: "insufficient_credits — with credits_required and credits_remaining."
        "429":
          description: "rate_limit_exceeded — with limit and window_seconds."
        "502":
          description: "diff_too_complex."
  "/api/v1/text/stats":
    post:
      summary: "Text Stats: words, characters, tokens and SMS segments"
      operationId: "callTextStats"
      description: "Text Stats: words, characters, tokens and SMS segments. Use when a task needs counts for a piece of text: words, user-perceived characters, bytes, sentences, paragraphs, lines, reading or speaking time, OpenAI token counts, SMS segments, or a check against length limits such as a character, word, SMS or prompt-token budget. 1 credit per successful call from the shared Attest credit balance. Docs: https://getattest.com.au/tools/text_stats"
      tags:
        - "Attest tools"
      security:
        - captureBearer: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: "object"
              properties:
                "text":
                  type: "string"
                  description: "The text to count. Up to 200,000 UTF-16 code units. Whitespace-only text is valid and counts zero words."
                "limits":
                  type: "array"
                  description: "Up to 20 budgets to check the text against. Each is { name, max, unit } where unit is characters, words, tokens_o200k, tokens_cl100k, bytes or sms_segments."
              required: ["text"]
      responses:
        "200":
          description: "Success. 1 credit charged from the shared Attest balance."
          content:
            application/json:
              schema:
                type: "object"
                properties:
                  call_id:
                    type: "string"
                    description: "Receipt id for this call."
                  credits_charged:
                    type: "integer"
                    description: "Credits taken for this call."
                  credits_remaining:
                    type: "integer"
                    description: "Credits left on the key."
                  "characters":
                    description: "User-perceived characters (graphemes)."
                  "code_points":
                    description: "Unicode code points."
                  "utf16_units":
                    description: "JavaScript string length."
                  "bytes_utf8":
                    description: "UTF-8 byte length."
                  "words":
                    description: "Word count."
                  "sentences":
                    description: "Sentence count."
                  "paragraphs":
                    description: "Paragraph count."
                  "lines":
                    description: "Line count."
                  "reading_time_minutes":
                    description: "At 238 words per minute, adult silent reading of non-fiction."
                  "speaking_time_minutes":
                    description: "At 183 words per minute, adult reading aloud."
                  "tokens":
                    description: "OpenAI o200k_base and cl100k_base token counts, with a note on which models each is listed for."
                  "sms":
                    description: "SMS encoding, segment count and concatenation limit, with the assumptions spelled out."
                  "limits":
                    description: "Each budget sent, with the measured value and whether it fits."
                  "sources":
                    description: "The research and specifications behind the reading, token and SMS figures."
        "400":
          description: "text_required, invalid_text, text_too_long, invalid_limits, too_many_limits, invalid_limit_unit, invalid_limit_max, limit_name_required."
        "401":
          description: "invalid_api_key — the key is missing or unknown."
        "402":
          description: "insufficient_credits — with credits_required and credits_remaining."
        "429":
          description: "rate_limit_exceeded — with limit and window_seconds."
  "/api/v1/read":
    post:
      summary: "Read a page as Markdown"
      operationId: "callUrlMarkdown"
      description: "Read a page as Markdown. Use when a task needs the readable text of one web page instead of its HTML: an article, a documentation page, a changelog or a product page, returned as Markdown with its headings, lists, tables and code blocks intact, plus the page's title, byline, language and links. 1 credit per successful call from the shared Attest credit balance. Docs: https://getattest.com.au/tools/url_markdown"
      tags:
        - "Attest tools"
      security:
        - captureBearer: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: "object"
              properties:
                "url":
                  type: "string"
                  description: "The public http(s) page to read."
                "include_links":
                  type: "boolean"
                  description: "Return the page's links as a list. On by default."
                "include_images":
                  type: "boolean"
                  description: "Return the page's images as a list. Off by default."
                "max_chars":
                  type: "integer"
                  description: "Cap on the Markdown returned."
              required: ["url"]
      responses:
        "200":
          description: "Success. 1 credit charged from the shared Attest balance."
          content:
            application/json:
              schema:
                type: "object"
                properties:
                  call_id:
                    type: "string"
                    description: "Receipt id for this call."
                  credits_charged:
                    type: "integer"
                    description: "Credits taken for this call."
                  credits_remaining:
                    type: "integer"
                    description: "Credits left on the key."
                  "markdown":
                    description: "The readable article as Markdown, with headings, lists, tables and code blocks intact."
                  "title":
                    description: "The page title."
                  "byline":
                    description: "The byline, when the page marks one."
                  "site_name":
                    description: "The site name, when the page declares one."
                  "published_at":
                    description: "The publication date, when the page declares one."
                  "lang":
                    description: "The page language."
                  "word_count":
                    description: "Words in the whole article, even when the Markdown was cut."
                  "truncated":
                    description: "Whether max_chars or the extraction budget cut the Markdown."
                  "extracted_by":
                    description: "Which extractor produced the article."
                  "links":
                    description: "The page's links, when include_links is on."
                  "images":
                    description: "The page's images, when include_images is on."
                  "final_url":
                    description: "The URL after redirects."
                  "http_status":
                    description: "The status the page returned."
        "400":
          description: "url_required, invalid_url, private_address_not_allowed, unsupported_content_type, response_too_large."
        "401":
          description: "invalid_api_key — the key is missing or unknown."
        "402":
          description: "insufficient_credits — with credits_required and credits_remaining."
        "429":
          description: "rate_limit_exceeded — with limit and window_seconds."
        "502":
          description: "fetch_timeout, fetch_failed."
        "422":
          description: "page_too_complex, page_too_slow."
  # END GENERATED attest-tools

components:
  securitySchemes:
    captureBearer:
      type: http
      scheme: bearer
      bearerFormat: Attest Capture API key
