# 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
