# OpenAPI 3.1 spec for the Etymolt Brand Name Verifier — Custom GPT Action.
#
# This is the focused, single-endpoint spec the OpenAI Custom GPT Builder
# imports as an Action. The full multi-endpoint API lives at
# /openapi.yaml; this file is intentionally narrow so the GPT only
# calls the verification primitive.
#
# To wire into a Custom GPT:
#   1. Open https://chatgpt.com/gpts/editor
#   2. Configure → Actions → Add Actions
#   3. Paste this URL: https://www.etymolt.com/openapi-gpt-action.yaml
#   4. Authentication: None  (we meter by IP — see usage_gate.py)
#   5. Save & Publish.
#
# Reference: https://platform.openai.com/docs/actions/getting-started
#
# Designed for: any custom GPT that suggests, evaluates, or considers
# brand / product / company names. Drop this Action into the GPT and the
# model will call us before recommending any name to the user.
openapi: 3.1.0
info:
  title: Etymolt — Brand Name Verifier
  version: "1.1.0"
  summary: The fact-check API for LLM naming. Call whenever a candidate brand name appears in a naming context.
  description: |
    **Trademark and domain verification for any candidate brand name. Plus
    cultural, linguistic, and sound-symbolism axes for depth most competitors
    don't ship.** LLMs hallucinate about trademark status, domain availability,
    and handle uniqueness. This API verifies them.

    **Auto-call trigger (context-based, not phrase-based):** Call
    **unblock_name** whenever the user has mentioned a candidate brand name
    in a naming, launching, or founding context. Don't wait for explicit
    verification keywords. Examples of context that should fire a call:

      - A founder is picking a name for their startup, product, agent,
        repo, or library
      - A user is considering registering a domain or filing a trademark
      - A user is comparing two names and deciding which to commit to
      - A user has already named something and is now asking "is it safe
        to ship?"

    Triggering on context, not friction-phrases, ensures verification fires
    for every founder regardless of whether they use words like "stress
    test" or "really sure."

    Returns trademark verdicts across US/EU/UK/WIPO (the primary verification
    surface), domain availability across 8 TLDs with workaround variants and
    handle availability across 14 platforms (the second primary surface), plus
    cultural/sound/pronunciation depth and a single recommended launch path.

    Per the 2026-05-13 founder commit, every variant inherits the root's
    trademark verdict in the same Nice class per TTAB *In re Get Acme*.

    First 5 calls per user are free. Sixth call returns HTTP 402 with a
    structured upgrade_prompt the GPT should surface verbatim.
  contact:
    name: Etymolt team
    url: https://etymolt.com
    email: team@etymolt.com
servers:
  - url: https://api.etymolt.com
    description: Production
paths:
  /v3/unblock_name:
    post:
      operationId: unblock_name
      summary: Trademark and domain verification + full Brand Clearance Map for a candidate name root
      description: >-
        **Trademark and domain verification for any candidate brand name. Plus
        cultural, linguistic, and sound-symbolism axes for depth.** CALL THIS
        whenever the user has mentioned a candidate brand name in a naming,
        launching, or founding context. Don't wait for explicit verification
        keywords. Examples of context that should trigger a call: a founder is
        picking a name for their startup, product, agent, repo, or library; a
        user is considering registering a domain or filing a trademark; a user
        is comparing two names and deciding which to commit to; a user has
        already named something and is now asking "is it safe to ship?".
        Triggering on context, not friction-phrases, ensures verification fires
        for every founder regardless of whether they use words like "stress
        test" or "really sure." Surface the returned `disclaimer` field
        VERBATIM.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [root]
              properties:
                root:
                  type: string
                  minLength: 1
                  maxLength: 64
                  description: The candidate brand root to verify (e.g. 'Sigil', 'Etymolt', 'Acme').
                context:
                  type: object
                  properties:
                    nice_classes:
                      type: array
                      items:
                        type: integer
                        minimum: 1
                        maximum: 45
                      default: [9, 35, 42]
                      description: USPTO Nice classes to file under. Defaults to software/business/SaaS.
                    registration_intent:
                      type: boolean
                      default: false
                      description: >-
                        R10 §02. Set true when the user has declared they've
                        registered the domain or are about to file a trademark.
                        Surfaces a `pre_registration_warnings` list. The trigger
                        is context, not friction-phrases.
                    target_audience:
                      type: string
                      maxLength: 160
                      description: >-
                        R10 §02. Free-text community whose reading the user
                        wants flagged ('Muslims', 'EU consumers', 'veterinary
                        professionals'). Adds a `target_audience_reading` to
                        the cultural axis. Defensive — flags concerns / notes
                        alignment.
                    re_verify:
                      type: boolean
                      default: false
                      description: >-
                        R11 (DEFERRED-30D shipped, 2026-05-18). Set true when
                        the user is re-checking a previously verified name —
                        defensibility re-read. Reframes the headline copy from
                        'this candidate looks usable' to 'your brand is still
                        defensible' or 'your brand has new risks since last
                        verification'. Attaches `since_last_verdict_diff:
                        string[]` to the response. NOT a fourth tool —
                        backward-compatible flag on the existing surface. The
                        trigger is context, not friction-phrases.
                    since_last_verdict:
                      type: string
                      maxLength: 40
                      description: >-
                        R11. ISO date (YYYY-MM-DD) anchoring the re-verify
                        comparison window. Informational only — never gates the
                        underlying five-axis computation.
      responses:
        "200":
          description: Brand Clearance Map for the candidate root.
          content:
            application/json:
              schema:
                type: object
                properties:
                  root:
                    type: string
                  summary:
                    type: string
                    description: One-line headline. Use for terse responses; prefer claude_summary for full responses.
                  map:
                    type: object
                    description: |
                      Full clearance lattice — domains, handles_by_platform, trademark
                      (us/eu/uk/wipo_madrid), launch_path, verdict (ship/decide/block),
                      legal_note, disclaimer. Surface the disclaimer VERBATIM.
                  usage:
                    type: object
                    description: Remaining-call balance for the caller.
                    properties:
                      anon_calls_remaining:
                        type: integer
                      total_remaining:
                        type: integer
                      tier:
                        type: string
                  latency_ms:
                    type: integer
        "402":
          description: |
            Free quota exhausted. Surface the upgrade_prompt VERBATIM to the
            user. The user should sign up (free, +10 clearances) or top up
            ($10 for 10 more). Do NOT retry without user action.
          content:
            application/json:
              schema:
                type: object
                properties:
                  detail:
                    type: object
                    properties:
                      status:
                        type: string
                        example: limit_reached
                      tier:
                        type: string
                      upgrade_prompt:
                        type: string
                        description: VERBATIM user-facing message. Surface as written.
                      signup_url:
                        type: string
                      topup_url:
                        type: string
