openapi: 3.0.3
info:
  title: "Gamma Auto — public AI API"
  version: "1.0.0"
  description: "Read-only public endpoints exposed by Gamma Auto for AI agents (ChatGPT, Claude, Perplexity, Gemini). Provides semantic search across vehicles + NLT offers + editorial content, structured render context, content provenance verification (C2PA). Canonical corpus: https://www.gamma-auto.it/llms-full.txt"
  contact:
    name: "Gamma Auto"
    url: "https://www.gamma-auto.it"
    email: "privacy@www.gamma-auto.it"
  license:
    name: "CC-BY-4.0"
    url: "https://creativecommons.org/licenses/by/4.0/"
servers:
  - url: "https://www.gamma-auto.it"
    description: "Public dealer site"
paths:
  /llms.txt:
    get:
      operationId: getLlmsTxt
      summary: "Concise dealer corpus (llmstxt.org convention)"
      responses:
        "200":
          description: "Markdown index of dealer-relevant pages with descriptions"
          content:
            text/markdown:
              schema:
                type: string
  /llms-full.txt:
    get:
      operationId: getLlmsFullTxt
      summary: "Full dealer corpus expanded with stable anchors for citation"
      responses:
        "200":
          description: "Full markdown corpus, anchored sections per page"
          content:
            text/markdown:
              schema:
                type: string
  /sitemap-llm.xml:
    get:
      operationId: getSitemapLlm
      summary: "AI-optimized sitemap (per-page .llms.txt URLs included)"
      responses:
        "200":
          description: "XML sitemap with <lastmod> on every URL"
          content:
            application/xml:
              schema:
                type: string
  /opensearch.xml:
    get:
      operationId: getOpenSearchDescription
      summary: "OpenSearch Description Document (OSDD 1.1) for semantic search"
      responses:
        "200":
          description: "XML OpenSearch description"
          content:
            application/xml:
              schema:
                type: string
  /robots.txt:
    get:
      operationId: getRobots
      summary: "robots.txt with AI crawler allowlist + sitemap directives"
      responses:
        "200":
          description: "Plain text robots.txt"
          content:
            text/plain:
              schema:
                type: string
  /public/llm/semantic-search:
    post:
      operationId: semanticSearch
      summary: "Cross-table semantic search (11 types: vehicles, NLT, podcasts, brand, guides, glossary, FAQ, news)"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [q]
              properties:
                q:
                  type: string
                  description: "Query text in Italian or English"
                limit:
                  type: integer
                  default: 10
                  minimum: 1
                  maximum: 30
                types:
                  type: array
                  description: "Subset of [vehicle,nlt,vehicle_podcast,dealer_podcast,brand,guide,glossary,faq,news,brand_news,custom_news]. Omit for all."
                  items:
                    type: string
      responses:
        "200":
          description: "Hit list ordered by score, with type, slug, title, snippet, score, last_modified"
          content:
            application/json:
              schema:
                type: object
                properties:
                  mode:
                    type: string
                    enum: [semantic, fallback_fulltext]
                  query:
                    type: string
                  total:
                    type: integer
                  hits:
                    type: array
                    items:
                      type: object
        "429":
          description: "Rate limit exceeded (60 req/min per IP)"
  /public/render:
    get:
      operationId: getRenderContext
      summary: "Full SSR payload for a given page path (used by AI agents to fetch structured content)"
      parameters:
        - name: path
          in: query
          schema:
            type: string
            default: "/"
          description: "Page path (e.g. /vendita-veicoli/{id}, /noleggio-lungo-termine/{slug}, /guide/{slug})"
      responses:
        "200":
          description: "Render context JSON with state, content, layout, structured_data (JSON-LD @graph), seo, page_meta"
          content:
            application/json:
              schema:
                type: object
  /public/c2pa/verify:
    get:
      operationId: verifyC2PA
      summary: "Verify Content Credentials (C2PA) of a media asset URL"
      parameters:
        - name: url
          in: query
          required: true
          schema:
            type: string
            format: uri
          description: "Public URL of the asset (image/audio) to verify"
      responses:
        "200":
          description: "Verification result with signer, generated_at, manifest details"
          content:
            application/json:
              schema:
                type: object
                properties:
                  verified:
                    type: boolean
                  signer:
                    type: string
                  generated_at:
                    type: string
                    format: date-time
                  error:
                    type: string
        "429":
          description: "Rate limit exceeded (30 req/min per IP)"
