openapi: 3.1.0
info:
  title: Stampify Public Site API
  version: 1.0.0
  summary: Read-only discovery API for the Stampify mobile app website.
  description: "Official machine-readable interface for https://getstampify.app. Use it to fetch site identity, page catalogs, developer metadata, and sandbox credentials. It does not upload photos or mutate a user’s Stampify collection. Public GET access is the free tier. The self-serve sandbox key is `stampify-public`."
  contact:
    name: OtterSpark Labs
    email: "support@otterspark.xyz"
    url: "https://getstampify.app/contact"
  license:
    name: Public documentation
    url: "https://getstampify.app/developers"
servers:
  -     url: "https://getstampify.app"
        description: Production
tags:
  -     name: Public
        description: Unauthenticated or sandbox-scoped read operations.
  -     name: Auth
        description: Scoped sandbox credentials.
paths:
  /openapi.json:
    get:
      operationId: getOpenApiJson
      summary: Download the OpenAPI document as JSON.
      description: Returns this specification so agents can bind function-calling tools to Stampify endpoints.
      tags:
        - Public
      security:
        -           SandboxApiKey:
                      - "read:docs"
        -           OAuth2:
                      - "read:docs"
        - {}
      responses:
        200:
          description: Download the OpenAPI document as JSON.
          headers:
            RateLimit:
              description: "RFC rate-limit snapshot: limit, remaining, reset."
              schema:
                type: string
                examples:
                  - "limit=120, remaining=119, reset=60"
            RateLimit-Policy:
              description: Declared policy window.
              schema:
                type: string
                examples:
                  - 120;w=60
            X-RateLimit-Limit:
              schema:
                type: string
            X-RateLimit-Remaining:
              schema:
                type: string
            X-RateLimit-Reset:
              schema:
                type: string
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/OpenApiDocument"
        401:
          description: "Structured JSON error with a code, message, and resolution hint."
          headers:
            RateLimit:
              description: "RFC rate-limit snapshot: limit, remaining, reset."
              schema:
                type: string
                examples:
                  - "limit=120, remaining=119, reset=60"
            RateLimit-Policy:
              description: Declared policy window.
              schema:
                type: string
                examples:
                  - 120;w=60
            X-RateLimit-Limit:
              schema:
                type: string
            X-RateLimit-Remaining:
              schema:
                type: string
            X-RateLimit-Reset:
              schema:
                type: string
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        403:
          description: "Structured JSON error with a code, message, and resolution hint."
          headers:
            RateLimit:
              description: "RFC rate-limit snapshot: limit, remaining, reset."
              schema:
                type: string
                examples:
                  - "limit=120, remaining=119, reset=60"
            RateLimit-Policy:
              description: Declared policy window.
              schema:
                type: string
                examples:
                  - 120;w=60
            X-RateLimit-Limit:
              schema:
                type: string
            X-RateLimit-Remaining:
              schema:
                type: string
            X-RateLimit-Reset:
              schema:
                type: string
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        404:
          description: "Structured JSON error with a code, message, and resolution hint."
          headers:
            RateLimit:
              description: "RFC rate-limit snapshot: limit, remaining, reset."
              schema:
                type: string
                examples:
                  - "limit=120, remaining=119, reset=60"
            RateLimit-Policy:
              description: Declared policy window.
              schema:
                type: string
                examples:
                  - 120;w=60
            X-RateLimit-Limit:
              schema:
                type: string
            X-RateLimit-Remaining:
              schema:
                type: string
            X-RateLimit-Reset:
              schema:
                type: string
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        405:
          description: "Structured JSON error with a code, message, and resolution hint."
          headers:
            RateLimit:
              description: "RFC rate-limit snapshot: limit, remaining, reset."
              schema:
                type: string
                examples:
                  - "limit=120, remaining=119, reset=60"
            RateLimit-Policy:
              description: Declared policy window.
              schema:
                type: string
                examples:
                  - 120;w=60
            X-RateLimit-Limit:
              schema:
                type: string
            X-RateLimit-Remaining:
              schema:
                type: string
            X-RateLimit-Reset:
              schema:
                type: string
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        429:
          description: "Structured JSON error with a code, message, and resolution hint."
          headers:
            RateLimit:
              description: "RFC rate-limit snapshot: limit, remaining, reset."
              schema:
                type: string
                examples:
                  - "limit=120, remaining=119, reset=60"
            RateLimit-Policy:
              description: Declared policy window.
              schema:
                type: string
                examples:
                  - 120;w=60
            X-RateLimit-Limit:
              schema:
                type: string
            X-RateLimit-Remaining:
              schema:
                type: string
            X-RateLimit-Reset:
              schema:
                type: string
            Retry-After:
              description: Seconds to wait before retrying.
              schema:
                type: string
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
  /api/openapi.yaml:
    get:
      operationId: getOpenApiYaml
      summary: Download the OpenAPI document as YAML.
      description: "Same contract as /openapi.json, serialized as YAML for clients that expect /api/openapi.yaml."
      tags:
        - Public
      security:
        -           SandboxApiKey:
                      - "read:docs"
        -           OAuth2:
                      - "read:docs"
        - {}
      responses:
        200:
          description: Download the OpenAPI document as YAML.
          headers:
            RateLimit:
              description: "RFC rate-limit snapshot: limit, remaining, reset."
              schema:
                type: string
                examples:
                  - "limit=120, remaining=119, reset=60"
            RateLimit-Policy:
              description: Declared policy window.
              schema:
                type: string
                examples:
                  - 120;w=60
            X-RateLimit-Limit:
              schema:
                type: string
            X-RateLimit-Remaining:
              schema:
                type: string
            X-RateLimit-Reset:
              schema:
                type: string
          content:
            application/json:
              schema:
                type: object
                additionalProperties: true
        401:
          description: "Structured JSON error with a code, message, and resolution hint."
          headers:
            RateLimit:
              description: "RFC rate-limit snapshot: limit, remaining, reset."
              schema:
                type: string
                examples:
                  - "limit=120, remaining=119, reset=60"
            RateLimit-Policy:
              description: Declared policy window.
              schema:
                type: string
                examples:
                  - 120;w=60
            X-RateLimit-Limit:
              schema:
                type: string
            X-RateLimit-Remaining:
              schema:
                type: string
            X-RateLimit-Reset:
              schema:
                type: string
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        403:
          description: "Structured JSON error with a code, message, and resolution hint."
          headers:
            RateLimit:
              description: "RFC rate-limit snapshot: limit, remaining, reset."
              schema:
                type: string
                examples:
                  - "limit=120, remaining=119, reset=60"
            RateLimit-Policy:
              description: Declared policy window.
              schema:
                type: string
                examples:
                  - 120;w=60
            X-RateLimit-Limit:
              schema:
                type: string
            X-RateLimit-Remaining:
              schema:
                type: string
            X-RateLimit-Reset:
              schema:
                type: string
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        404:
          description: "Structured JSON error with a code, message, and resolution hint."
          headers:
            RateLimit:
              description: "RFC rate-limit snapshot: limit, remaining, reset."
              schema:
                type: string
                examples:
                  - "limit=120, remaining=119, reset=60"
            RateLimit-Policy:
              description: Declared policy window.
              schema:
                type: string
                examples:
                  - 120;w=60
            X-RateLimit-Limit:
              schema:
                type: string
            X-RateLimit-Remaining:
              schema:
                type: string
            X-RateLimit-Reset:
              schema:
                type: string
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        405:
          description: "Structured JSON error with a code, message, and resolution hint."
          headers:
            RateLimit:
              description: "RFC rate-limit snapshot: limit, remaining, reset."
              schema:
                type: string
                examples:
                  - "limit=120, remaining=119, reset=60"
            RateLimit-Policy:
              description: Declared policy window.
              schema:
                type: string
                examples:
                  - 120;w=60
            X-RateLimit-Limit:
              schema:
                type: string
            X-RateLimit-Remaining:
              schema:
                type: string
            X-RateLimit-Reset:
              schema:
                type: string
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        429:
          description: "Structured JSON error with a code, message, and resolution hint."
          headers:
            RateLimit:
              description: "RFC rate-limit snapshot: limit, remaining, reset."
              schema:
                type: string
                examples:
                  - "limit=120, remaining=119, reset=60"
            RateLimit-Policy:
              description: Declared policy window.
              schema:
                type: string
                examples:
                  - 120;w=60
            X-RateLimit-Limit:
              schema:
                type: string
            X-RateLimit-Remaining:
              schema:
                type: string
            X-RateLimit-Reset:
              schema:
                type: string
            Retry-After:
              description: Seconds to wait before retrying.
              schema:
                type: string
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
  /api/v1:
    get:
      operationId: getApiIndex
      summary: List public API entry points.
      description: "Returns the sandbox key policy, scopes, and links to OpenAPI, docs, and page catalogs."
      tags:
        - Public
      security:
        -           SandboxApiKey:
                      - "read:docs"
        -           OAuth2:
                      - "read:docs"
        - {}
      responses:
        200:
          description: List public API entry points.
          headers:
            RateLimit:
              description: "RFC rate-limit snapshot: limit, remaining, reset."
              schema:
                type: string
                examples:
                  - "limit=120, remaining=119, reset=60"
            RateLimit-Policy:
              description: Declared policy window.
              schema:
                type: string
                examples:
                  - 120;w=60
            X-RateLimit-Limit:
              schema:
                type: string
            X-RateLimit-Remaining:
              schema:
                type: string
            X-RateLimit-Reset:
              schema:
                type: string
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiIndex"
        401:
          description: "Structured JSON error with a code, message, and resolution hint."
          headers:
            RateLimit:
              description: "RFC rate-limit snapshot: limit, remaining, reset."
              schema:
                type: string
                examples:
                  - "limit=120, remaining=119, reset=60"
            RateLimit-Policy:
              description: Declared policy window.
              schema:
                type: string
                examples:
                  - 120;w=60
            X-RateLimit-Limit:
              schema:
                type: string
            X-RateLimit-Remaining:
              schema:
                type: string
            X-RateLimit-Reset:
              schema:
                type: string
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        403:
          description: "Structured JSON error with a code, message, and resolution hint."
          headers:
            RateLimit:
              description: "RFC rate-limit snapshot: limit, remaining, reset."
              schema:
                type: string
                examples:
                  - "limit=120, remaining=119, reset=60"
            RateLimit-Policy:
              description: Declared policy window.
              schema:
                type: string
                examples:
                  - 120;w=60
            X-RateLimit-Limit:
              schema:
                type: string
            X-RateLimit-Remaining:
              schema:
                type: string
            X-RateLimit-Reset:
              schema:
                type: string
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        404:
          description: "Structured JSON error with a code, message, and resolution hint."
          headers:
            RateLimit:
              description: "RFC rate-limit snapshot: limit, remaining, reset."
              schema:
                type: string
                examples:
                  - "limit=120, remaining=119, reset=60"
            RateLimit-Policy:
              description: Declared policy window.
              schema:
                type: string
                examples:
                  - 120;w=60
            X-RateLimit-Limit:
              schema:
                type: string
            X-RateLimit-Remaining:
              schema:
                type: string
            X-RateLimit-Reset:
              schema:
                type: string
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        405:
          description: "Structured JSON error with a code, message, and resolution hint."
          headers:
            RateLimit:
              description: "RFC rate-limit snapshot: limit, remaining, reset."
              schema:
                type: string
                examples:
                  - "limit=120, remaining=119, reset=60"
            RateLimit-Policy:
              description: Declared policy window.
              schema:
                type: string
                examples:
                  - 120;w=60
            X-RateLimit-Limit:
              schema:
                type: string
            X-RateLimit-Remaining:
              schema:
                type: string
            X-RateLimit-Reset:
              schema:
                type: string
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        429:
          description: "Structured JSON error with a code, message, and resolution hint."
          headers:
            RateLimit:
              description: "RFC rate-limit snapshot: limit, remaining, reset."
              schema:
                type: string
                examples:
                  - "limit=120, remaining=119, reset=60"
            RateLimit-Policy:
              description: Declared policy window.
              schema:
                type: string
                examples:
                  - 120;w=60
            X-RateLimit-Limit:
              schema:
                type: string
            X-RateLimit-Remaining:
              schema:
                type: string
            X-RateLimit-Reset:
              schema:
                type: string
            Retry-After:
              description: Seconds to wait before retrying.
              schema:
                type: string
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
  /api/v1/site:
    get:
      operationId: getSiteIdentity
      summary: Get Stampify site identity.
      description: "Returns canonical URLs, store listings, support contact, and when-to-use guidance for agents."
      tags:
        - Public
      security:
        -           SandboxApiKey:
                      - "read:public"
        -           OAuth2:
                      - "read:public"
        - {}
      responses:
        200:
          description: Get Stampify site identity.
          headers:
            RateLimit:
              description: "RFC rate-limit snapshot: limit, remaining, reset."
              schema:
                type: string
                examples:
                  - "limit=120, remaining=119, reset=60"
            RateLimit-Policy:
              description: Declared policy window.
              schema:
                type: string
                examples:
                  - 120;w=60
            X-RateLimit-Limit:
              schema:
                type: string
            X-RateLimit-Remaining:
              schema:
                type: string
            X-RateLimit-Reset:
              schema:
                type: string
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SiteIdentity"
        401:
          description: "Structured JSON error with a code, message, and resolution hint."
          headers:
            RateLimit:
              description: "RFC rate-limit snapshot: limit, remaining, reset."
              schema:
                type: string
                examples:
                  - "limit=120, remaining=119, reset=60"
            RateLimit-Policy:
              description: Declared policy window.
              schema:
                type: string
                examples:
                  - 120;w=60
            X-RateLimit-Limit:
              schema:
                type: string
            X-RateLimit-Remaining:
              schema:
                type: string
            X-RateLimit-Reset:
              schema:
                type: string
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        403:
          description: "Structured JSON error with a code, message, and resolution hint."
          headers:
            RateLimit:
              description: "RFC rate-limit snapshot: limit, remaining, reset."
              schema:
                type: string
                examples:
                  - "limit=120, remaining=119, reset=60"
            RateLimit-Policy:
              description: Declared policy window.
              schema:
                type: string
                examples:
                  - 120;w=60
            X-RateLimit-Limit:
              schema:
                type: string
            X-RateLimit-Remaining:
              schema:
                type: string
            X-RateLimit-Reset:
              schema:
                type: string
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        404:
          description: "Structured JSON error with a code, message, and resolution hint."
          headers:
            RateLimit:
              description: "RFC rate-limit snapshot: limit, remaining, reset."
              schema:
                type: string
                examples:
                  - "limit=120, remaining=119, reset=60"
            RateLimit-Policy:
              description: Declared policy window.
              schema:
                type: string
                examples:
                  - 120;w=60
            X-RateLimit-Limit:
              schema:
                type: string
            X-RateLimit-Remaining:
              schema:
                type: string
            X-RateLimit-Reset:
              schema:
                type: string
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        405:
          description: "Structured JSON error with a code, message, and resolution hint."
          headers:
            RateLimit:
              description: "RFC rate-limit snapshot: limit, remaining, reset."
              schema:
                type: string
                examples:
                  - "limit=120, remaining=119, reset=60"
            RateLimit-Policy:
              description: Declared policy window.
              schema:
                type: string
                examples:
                  - 120;w=60
            X-RateLimit-Limit:
              schema:
                type: string
            X-RateLimit-Remaining:
              schema:
                type: string
            X-RateLimit-Reset:
              schema:
                type: string
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        429:
          description: "Structured JSON error with a code, message, and resolution hint."
          headers:
            RateLimit:
              description: "RFC rate-limit snapshot: limit, remaining, reset."
              schema:
                type: string
                examples:
                  - "limit=120, remaining=119, reset=60"
            RateLimit-Policy:
              description: Declared policy window.
              schema:
                type: string
                examples:
                  - 120;w=60
            X-RateLimit-Limit:
              schema:
                type: string
            X-RateLimit-Remaining:
              schema:
                type: string
            X-RateLimit-Reset:
              schema:
                type: string
            Retry-After:
              description: Seconds to wait before retrying.
              schema:
                type: string
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
  /api/v1/pages:
    get:
      operationId: listPublicPages
      summary: List public pages.
      description: "Lists official marketing, trust, and developer pages with stable IDs and URLs."
      tags:
        - Public
      security:
        -           SandboxApiKey:
                      - "read:public"
        -           OAuth2:
                      - "read:public"
        - {}
      responses:
        200:
          description: List public pages.
          headers:
            RateLimit:
              description: "RFC rate-limit snapshot: limit, remaining, reset."
              schema:
                type: string
                examples:
                  - "limit=120, remaining=119, reset=60"
            RateLimit-Policy:
              description: Declared policy window.
              schema:
                type: string
                examples:
                  - 120;w=60
            X-RateLimit-Limit:
              schema:
                type: string
            X-RateLimit-Remaining:
              schema:
                type: string
            X-RateLimit-Reset:
              schema:
                type: string
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PageList"
        401:
          description: "Structured JSON error with a code, message, and resolution hint."
          headers:
            RateLimit:
              description: "RFC rate-limit snapshot: limit, remaining, reset."
              schema:
                type: string
                examples:
                  - "limit=120, remaining=119, reset=60"
            RateLimit-Policy:
              description: Declared policy window.
              schema:
                type: string
                examples:
                  - 120;w=60
            X-RateLimit-Limit:
              schema:
                type: string
            X-RateLimit-Remaining:
              schema:
                type: string
            X-RateLimit-Reset:
              schema:
                type: string
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        403:
          description: "Structured JSON error with a code, message, and resolution hint."
          headers:
            RateLimit:
              description: "RFC rate-limit snapshot: limit, remaining, reset."
              schema:
                type: string
                examples:
                  - "limit=120, remaining=119, reset=60"
            RateLimit-Policy:
              description: Declared policy window.
              schema:
                type: string
                examples:
                  - 120;w=60
            X-RateLimit-Limit:
              schema:
                type: string
            X-RateLimit-Remaining:
              schema:
                type: string
            X-RateLimit-Reset:
              schema:
                type: string
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        404:
          description: "Structured JSON error with a code, message, and resolution hint."
          headers:
            RateLimit:
              description: "RFC rate-limit snapshot: limit, remaining, reset."
              schema:
                type: string
                examples:
                  - "limit=120, remaining=119, reset=60"
            RateLimit-Policy:
              description: Declared policy window.
              schema:
                type: string
                examples:
                  - 120;w=60
            X-RateLimit-Limit:
              schema:
                type: string
            X-RateLimit-Remaining:
              schema:
                type: string
            X-RateLimit-Reset:
              schema:
                type: string
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        405:
          description: "Structured JSON error with a code, message, and resolution hint."
          headers:
            RateLimit:
              description: "RFC rate-limit snapshot: limit, remaining, reset."
              schema:
                type: string
                examples:
                  - "limit=120, remaining=119, reset=60"
            RateLimit-Policy:
              description: Declared policy window.
              schema:
                type: string
                examples:
                  - 120;w=60
            X-RateLimit-Limit:
              schema:
                type: string
            X-RateLimit-Remaining:
              schema:
                type: string
            X-RateLimit-Reset:
              schema:
                type: string
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        429:
          description: "Structured JSON error with a code, message, and resolution hint."
          headers:
            RateLimit:
              description: "RFC rate-limit snapshot: limit, remaining, reset."
              schema:
                type: string
                examples:
                  - "limit=120, remaining=119, reset=60"
            RateLimit-Policy:
              description: Declared policy window.
              schema:
                type: string
                examples:
                  - 120;w=60
            X-RateLimit-Limit:
              schema:
                type: string
            X-RateLimit-Remaining:
              schema:
                type: string
            X-RateLimit-Reset:
              schema:
                type: string
            Retry-After:
              description: Seconds to wait before retrying.
              schema:
                type: string
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      parameters:
        -           name: locale
                    in: query
                    required: false
                    description: Locale code such as en or vi.
                    schema:
                      type: string
                      default: en
  /api/v1/pages/{id}:
    get:
      operationId: getPublicPage
      summary: Get one public page.
      description: "Returns a single page record by id (home, about, contact, developers, support, privacy, terms, blog)."
      tags:
        - Public
      security:
        -           SandboxApiKey:
                      - "read:public"
        -           OAuth2:
                      - "read:public"
        - {}
      responses:
        200:
          description: Get one public page.
          headers:
            RateLimit:
              description: "RFC rate-limit snapshot: limit, remaining, reset."
              schema:
                type: string
                examples:
                  - "limit=120, remaining=119, reset=60"
            RateLimit-Policy:
              description: Declared policy window.
              schema:
                type: string
                examples:
                  - 120;w=60
            X-RateLimit-Limit:
              schema:
                type: string
            X-RateLimit-Remaining:
              schema:
                type: string
            X-RateLimit-Reset:
              schema:
                type: string
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Page"
        401:
          description: "Structured JSON error with a code, message, and resolution hint."
          headers:
            RateLimit:
              description: "RFC rate-limit snapshot: limit, remaining, reset."
              schema:
                type: string
                examples:
                  - "limit=120, remaining=119, reset=60"
            RateLimit-Policy:
              description: Declared policy window.
              schema:
                type: string
                examples:
                  - 120;w=60
            X-RateLimit-Limit:
              schema:
                type: string
            X-RateLimit-Remaining:
              schema:
                type: string
            X-RateLimit-Reset:
              schema:
                type: string
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        403:
          description: "Structured JSON error with a code, message, and resolution hint."
          headers:
            RateLimit:
              description: "RFC rate-limit snapshot: limit, remaining, reset."
              schema:
                type: string
                examples:
                  - "limit=120, remaining=119, reset=60"
            RateLimit-Policy:
              description: Declared policy window.
              schema:
                type: string
                examples:
                  - 120;w=60
            X-RateLimit-Limit:
              schema:
                type: string
            X-RateLimit-Remaining:
              schema:
                type: string
            X-RateLimit-Reset:
              schema:
                type: string
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        404:
          description: "Structured JSON error with a code, message, and resolution hint."
          headers:
            RateLimit:
              description: "RFC rate-limit snapshot: limit, remaining, reset."
              schema:
                type: string
                examples:
                  - "limit=120, remaining=119, reset=60"
            RateLimit-Policy:
              description: Declared policy window.
              schema:
                type: string
                examples:
                  - 120;w=60
            X-RateLimit-Limit:
              schema:
                type: string
            X-RateLimit-Remaining:
              schema:
                type: string
            X-RateLimit-Reset:
              schema:
                type: string
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        405:
          description: "Structured JSON error with a code, message, and resolution hint."
          headers:
            RateLimit:
              description: "RFC rate-limit snapshot: limit, remaining, reset."
              schema:
                type: string
                examples:
                  - "limit=120, remaining=119, reset=60"
            RateLimit-Policy:
              description: Declared policy window.
              schema:
                type: string
                examples:
                  - 120;w=60
            X-RateLimit-Limit:
              schema:
                type: string
            X-RateLimit-Remaining:
              schema:
                type: string
            X-RateLimit-Reset:
              schema:
                type: string
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        429:
          description: "Structured JSON error with a code, message, and resolution hint."
          headers:
            RateLimit:
              description: "RFC rate-limit snapshot: limit, remaining, reset."
              schema:
                type: string
                examples:
                  - "limit=120, remaining=119, reset=60"
            RateLimit-Policy:
              description: Declared policy window.
              schema:
                type: string
                examples:
                  - 120;w=60
            X-RateLimit-Limit:
              schema:
                type: string
            X-RateLimit-Remaining:
              schema:
                type: string
            X-RateLimit-Reset:
              schema:
                type: string
            Retry-After:
              description: Seconds to wait before retrying.
              schema:
                type: string
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
      parameters:
        -           name: id
                    in: path
                    required: true
                    description: Public page identifier.
                    schema:
                      type: string
                      enum:
                        - home
                        - about
                        - contact
                        - developers
                        - support
                        - privacy
                        - terms
                        - blog
        -           name: locale
                    in: query
                    required: false
                    description: Locale code such as en or vi.
                    schema:
                      type: string
                      default: en
  /api/v1/scopes:
    get:
      operationId: listApiScopes
      summary: List scoped permissions.
      description: Describes the sandbox scopes an agent can request. Public GET calls already include both scopes.
      tags:
        - Public
      security:
        -           SandboxApiKey:
                      - "read:docs"
        -           OAuth2:
                      - "read:docs"
        - {}
      responses:
        200:
          description: List scoped permissions.
          headers:
            RateLimit:
              description: "RFC rate-limit snapshot: limit, remaining, reset."
              schema:
                type: string
                examples:
                  - "limit=120, remaining=119, reset=60"
            RateLimit-Policy:
              description: Declared policy window.
              schema:
                type: string
                examples:
                  - 120;w=60
            X-RateLimit-Limit:
              schema:
                type: string
            X-RateLimit-Remaining:
              schema:
                type: string
            X-RateLimit-Reset:
              schema:
                type: string
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ScopeList"
        401:
          description: "Structured JSON error with a code, message, and resolution hint."
          headers:
            RateLimit:
              description: "RFC rate-limit snapshot: limit, remaining, reset."
              schema:
                type: string
                examples:
                  - "limit=120, remaining=119, reset=60"
            RateLimit-Policy:
              description: Declared policy window.
              schema:
                type: string
                examples:
                  - 120;w=60
            X-RateLimit-Limit:
              schema:
                type: string
            X-RateLimit-Remaining:
              schema:
                type: string
            X-RateLimit-Reset:
              schema:
                type: string
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        403:
          description: "Structured JSON error with a code, message, and resolution hint."
          headers:
            RateLimit:
              description: "RFC rate-limit snapshot: limit, remaining, reset."
              schema:
                type: string
                examples:
                  - "limit=120, remaining=119, reset=60"
            RateLimit-Policy:
              description: Declared policy window.
              schema:
                type: string
                examples:
                  - 120;w=60
            X-RateLimit-Limit:
              schema:
                type: string
            X-RateLimit-Remaining:
              schema:
                type: string
            X-RateLimit-Reset:
              schema:
                type: string
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        404:
          description: "Structured JSON error with a code, message, and resolution hint."
          headers:
            RateLimit:
              description: "RFC rate-limit snapshot: limit, remaining, reset."
              schema:
                type: string
                examples:
                  - "limit=120, remaining=119, reset=60"
            RateLimit-Policy:
              description: Declared policy window.
              schema:
                type: string
                examples:
                  - 120;w=60
            X-RateLimit-Limit:
              schema:
                type: string
            X-RateLimit-Remaining:
              schema:
                type: string
            X-RateLimit-Reset:
              schema:
                type: string
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        405:
          description: "Structured JSON error with a code, message, and resolution hint."
          headers:
            RateLimit:
              description: "RFC rate-limit snapshot: limit, remaining, reset."
              schema:
                type: string
                examples:
                  - "limit=120, remaining=119, reset=60"
            RateLimit-Policy:
              description: Declared policy window.
              schema:
                type: string
                examples:
                  - 120;w=60
            X-RateLimit-Limit:
              schema:
                type: string
            X-RateLimit-Remaining:
              schema:
                type: string
            X-RateLimit-Reset:
              schema:
                type: string
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        429:
          description: "Structured JSON error with a code, message, and resolution hint."
          headers:
            RateLimit:
              description: "RFC rate-limit snapshot: limit, remaining, reset."
              schema:
                type: string
                examples:
                  - "limit=120, remaining=119, reset=60"
            RateLimit-Policy:
              description: Declared policy window.
              schema:
                type: string
                examples:
                  - 120;w=60
            X-RateLimit-Limit:
              schema:
                type: string
            X-RateLimit-Remaining:
              schema:
                type: string
            X-RateLimit-Reset:
              schema:
                type: string
            Retry-After:
              description: Seconds to wait before retrying.
              schema:
                type: string
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
  /api/v1/health:
    get:
      operationId: getApiHealth
      summary: Health check.
      description: Lightweight liveness document for the public API.
      tags:
        - Public
      security:
        -           SandboxApiKey:
                      - "read:public"
        -           OAuth2:
                      - "read:public"
        - {}
      responses:
        200:
          description: Health check.
          headers:
            RateLimit:
              description: "RFC rate-limit snapshot: limit, remaining, reset."
              schema:
                type: string
                examples:
                  - "limit=120, remaining=119, reset=60"
            RateLimit-Policy:
              description: Declared policy window.
              schema:
                type: string
                examples:
                  - 120;w=60
            X-RateLimit-Limit:
              schema:
                type: string
            X-RateLimit-Remaining:
              schema:
                type: string
            X-RateLimit-Reset:
              schema:
                type: string
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Health"
        401:
          description: "Structured JSON error with a code, message, and resolution hint."
          headers:
            RateLimit:
              description: "RFC rate-limit snapshot: limit, remaining, reset."
              schema:
                type: string
                examples:
                  - "limit=120, remaining=119, reset=60"
            RateLimit-Policy:
              description: Declared policy window.
              schema:
                type: string
                examples:
                  - 120;w=60
            X-RateLimit-Limit:
              schema:
                type: string
            X-RateLimit-Remaining:
              schema:
                type: string
            X-RateLimit-Reset:
              schema:
                type: string
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        403:
          description: "Structured JSON error with a code, message, and resolution hint."
          headers:
            RateLimit:
              description: "RFC rate-limit snapshot: limit, remaining, reset."
              schema:
                type: string
                examples:
                  - "limit=120, remaining=119, reset=60"
            RateLimit-Policy:
              description: Declared policy window.
              schema:
                type: string
                examples:
                  - 120;w=60
            X-RateLimit-Limit:
              schema:
                type: string
            X-RateLimit-Remaining:
              schema:
                type: string
            X-RateLimit-Reset:
              schema:
                type: string
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        404:
          description: "Structured JSON error with a code, message, and resolution hint."
          headers:
            RateLimit:
              description: "RFC rate-limit snapshot: limit, remaining, reset."
              schema:
                type: string
                examples:
                  - "limit=120, remaining=119, reset=60"
            RateLimit-Policy:
              description: Declared policy window.
              schema:
                type: string
                examples:
                  - 120;w=60
            X-RateLimit-Limit:
              schema:
                type: string
            X-RateLimit-Remaining:
              schema:
                type: string
            X-RateLimit-Reset:
              schema:
                type: string
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        405:
          description: "Structured JSON error with a code, message, and resolution hint."
          headers:
            RateLimit:
              description: "RFC rate-limit snapshot: limit, remaining, reset."
              schema:
                type: string
                examples:
                  - "limit=120, remaining=119, reset=60"
            RateLimit-Policy:
              description: Declared policy window.
              schema:
                type: string
                examples:
                  - 120;w=60
            X-RateLimit-Limit:
              schema:
                type: string
            X-RateLimit-Remaining:
              schema:
                type: string
            X-RateLimit-Reset:
              schema:
                type: string
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        429:
          description: "Structured JSON error with a code, message, and resolution hint."
          headers:
            RateLimit:
              description: "RFC rate-limit snapshot: limit, remaining, reset."
              schema:
                type: string
                examples:
                  - "limit=120, remaining=119, reset=60"
            RateLimit-Policy:
              description: Declared policy window.
              schema:
                type: string
                examples:
                  - 120;w=60
            X-RateLimit-Limit:
              schema:
                type: string
            X-RateLimit-Remaining:
              schema:
                type: string
            X-RateLimit-Reset:
              schema:
                type: string
            Retry-After:
              description: Seconds to wait before retrying.
              schema:
                type: string
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
  /api/v1/oauth/token:
    post:
      operationId: createSandboxToken
      summary: Mint a sandbox access token.
      description: "OAuth 2.0 client-credentials endpoint for the public sandbox. Use client_id and client_secret `stampify-public`. No registration or paid plan is required."
      tags:
        - Auth
      security: []
      requestBody:
        required: true
        content:
          application/x-www-form-urlencoded:
            schema:
              $ref: "#/components/schemas/TokenRequest"
          application/json:
            schema:
              $ref: "#/components/schemas/TokenRequest"
      responses:
        200:
          description: Sandbox token.
          headers:
            RateLimit:
              description: "RFC rate-limit snapshot: limit, remaining, reset."
              schema:
                type: string
                examples:
                  - "limit=120, remaining=119, reset=60"
            RateLimit-Policy:
              description: Declared policy window.
              schema:
                type: string
                examples:
                  - 120;w=60
            X-RateLimit-Limit:
              schema:
                type: string
            X-RateLimit-Remaining:
              schema:
                type: string
            X-RateLimit-Reset:
              schema:
                type: string
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/TokenResponse"
        400:
          description: "Structured JSON error with a code, message, and resolution hint."
          headers:
            RateLimit:
              description: "RFC rate-limit snapshot: limit, remaining, reset."
              schema:
                type: string
                examples:
                  - "limit=120, remaining=119, reset=60"
            RateLimit-Policy:
              description: Declared policy window.
              schema:
                type: string
                examples:
                  - 120;w=60
            X-RateLimit-Limit:
              schema:
                type: string
            X-RateLimit-Remaining:
              schema:
                type: string
            X-RateLimit-Reset:
              schema:
                type: string
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        401:
          description: "Structured JSON error with a code, message, and resolution hint."
          headers:
            RateLimit:
              description: "RFC rate-limit snapshot: limit, remaining, reset."
              schema:
                type: string
                examples:
                  - "limit=120, remaining=119, reset=60"
            RateLimit-Policy:
              description: Declared policy window.
              schema:
                type: string
                examples:
                  - 120;w=60
            X-RateLimit-Limit:
              schema:
                type: string
            X-RateLimit-Remaining:
              schema:
                type: string
            X-RateLimit-Reset:
              schema:
                type: string
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        429:
          description: "Structured JSON error with a code, message, and resolution hint."
          headers:
            RateLimit:
              description: "RFC rate-limit snapshot: limit, remaining, reset."
              schema:
                type: string
                examples:
                  - "limit=120, remaining=119, reset=60"
            RateLimit-Policy:
              description: Declared policy window.
              schema:
                type: string
                examples:
                  - 120;w=60
            X-RateLimit-Limit:
              schema:
                type: string
            X-RateLimit-Remaining:
              schema:
                type: string
            X-RateLimit-Reset:
              schema:
                type: string
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
components:
  securitySchemes:
    SandboxApiKey:
      type: apiKey
      in: header
      name: X-API-Key
      description: "Optional. Omit for anonymous public reads, or send `stampify-public` for the documented sandbox scopes."
    OAuth2:
      type: oauth2
      description: Sandbox client-credentials flow. There is no confidential production API.
      flows:
        clientCredentials:
          tokenUrl: "https://getstampify.app/api/v1/oauth/token"
          scopes:
            read:public: "Read public Stampify site content, catalogs, and health."
            read:docs: "Read OpenAPI, authentication metadata, and developer documentation."
  schemas:
    Error:
      type: object
      required:
        - error
      properties:
        error:
          type: object
          required:
            - code
            - message
            - hint
            - status
            - docs
          properties:
            code:
              type: string
              examples:
                - not_found
            message:
              type: string
            hint:
              type: string
            status:
              type: integer
            docs:
              type: string
              format: uri
    OpenApiDocument:
      type: object
      additionalProperties: true
    ApiIndex:
      type: object
      required:
        - name
        - documentation
        - openapi
        - sandbox
        - scopes
      properties:
        name:
          type: string
        documentation:
          type: string
          format: uri
        openapi:
          type: string
          format: uri
        sandbox:
          type: object
          additionalProperties: true
        scopes:
          type: object
          additionalProperties:
            type: string
    SiteIdentity:
      type: object
      required:
        - name
        - url
        - whenToUse
        - contact
      properties:
        name:
          type: string
        url:
          type: string
          format: uri
        whenToUse:
          type: string
        contact:
          type: string
    Page:
      type: object
      required:
        - id
        - title
        - url
        - path
        - markdown
      properties:
        id:
          type: string
        title:
          type: string
        url:
          type: string
          format: uri
        path:
          type: string
        markdown:
          type: boolean
        accept:
          type: string
    PageList:
      type: object
      required:
        - pages
      properties:
        pages:
          type: array
          items:
            $ref: "#/components/schemas/Page"
    ScopeList:
      type: object
      required:
        - scopes
        - sandboxKey
      properties:
        sandboxKey:
          type: string
        scopes:
          type: object
          additionalProperties:
            type: string
    Health:
      type: object
      required:
        - ok
        - service
      properties:
        ok:
          type: boolean
        service:
          type: string
    TokenRequest:
      type: object
      required:
        - grant_type
        - client_id
        - client_secret
      properties:
        grant_type:
          type: string
          enum:
            - client_credentials
        client_id:
          type: string
          examples:
            - stampify-public
        client_secret:
          type: string
          examples:
            - stampify-public
        scope:
          type: string
          examples:
            - "read:public read:docs"
    TokenResponse:
      type: object
      required:
        - access_token
        - token_type
        - expires_in
        - scope
      properties:
        access_token:
          type: string
        token_type:
          type: string
        expires_in:
          type: integer
        scope:
          type: string
