{
  "openapi": "3.0.1",
  "info": {
    "title": "Brand Name IP Screener",
    "description": "Screens brand names vs curated famous-mark seed datasets (not full registry) for trademark-collision risk across FR/US/EU/WO/UK — visual + phonetic similarity scoped to Nice classes, with a domain co-check. Clear/caution/high-risk per jurisdiction. Informational only — not legal advice.",
    "version": "1.14",
    "x-build-id": "SktPFRK9RqVaaj3hp"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/protocol~brand-name-ip-screener/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-protocol-brand-name-ip-screener",
        "x-openai-isConsequential": false,
        "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
        "tags": [
          "Run Actor"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/inputSchema"
              }
            }
          }
        },
        "parameters": [
          {
            "name": "token",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Enter your Apify token here"
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    },
    "/acts/protocol~brand-name-ip-screener/runs": {
      "post": {
        "operationId": "runs-sync-protocol-brand-name-ip-screener",
        "x-openai-isConsequential": false,
        "summary": "Executes an Actor and returns information about the initiated run in response.",
        "tags": [
          "Run Actor"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/inputSchema"
              }
            }
          }
        },
        "parameters": [
          {
            "name": "token",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Enter your Apify token here"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/runsResponseSchema"
                }
              }
            }
          }
        }
      }
    },
    "/acts/protocol~brand-name-ip-screener/run-sync": {
      "post": {
        "operationId": "run-sync-protocol-brand-name-ip-screener",
        "x-openai-isConsequential": false,
        "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
        "tags": [
          "Run Actor"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/inputSchema"
              }
            }
          }
        },
        "parameters": [
          {
            "name": "token",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Enter your Apify token here"
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "inputSchema": {
        "type": "object",
        "properties": {
          "names": {
            "title": "Brand / startup names to screen",
            "maxItems": 20,
            "type": "array",
            "description": "One or more proposed names to screen (e.g. [\"Brandcraft\", \"Vaultly\"]). Each is screened against every selected jurisdiction. Hard cap 20 per run; each name must be 1–100 characters and non-blank. Duplicate names (same normalized core, e.g. \"Brandcraft\" and \"BRANDCRAFT\") are screened and billed once. Leave empty and fill in `positioning` instead to GENERATE new names first (v1.2.0 closed loop) — exactly one of `names` / `positioning` is required. Billing (screen mode): $1.00 per name × jurisdiction that returns `screened`; a name that normalizes to an empty core (fully non-Latin input) is surfaced as `not_screened` and is free. Cost note: screen mode bills $1.00 per name × jurisdiction, so a large batch needs the run's “Maximum cost per run” set high enough (or left unlimited) — if the cap is reached mid-batch the remaining names are reported not_screened with reason budget_exhausted, and are never charged.",
            "items": {
              "type": "string",
              "minLength": 1,
              "maxLength": 100
            }
          },
          "positioning": {
            "title": "Brand positioning / value proposition (generation mode, v1.2.0)",
            "type": "string",
            "description": "Free-text brand positioning brief, e.g. \"a calmer way to manage freelance invoices\". When set (and `names` is left empty), the run GENERATES candidate names via an LLM, deterministically filters them (profanity/banned-words/dupes + mustInclude/avoid), screens the survivors through the same IP + domain pipeline as `names`, then ranks by a composite score. Billing (generate mode): FREE — generate mode costs $0.00. Every filter-survivor emits `candidate_generated_and_rescreened` at $0.00, and rejected candidates are listed under OUTPUT.filtered, also at no charge."
          },
          "tone": {
            "title": "Naming tone (generation mode)",
            "enum": [
              "Professional",
              "Playful",
              "Premium",
              "Technical",
              "Friendly"
            ],
            "type": "string",
            "description": "Tone the generated names should aim for. Only used when `positioning` is set; ignored in screen mode, so it changes no screen-mode output. In generate mode it biases the candidate names the LLM produces but does not change which candidates survive filtering — generate mode is free ($0.00 per filter-survivor) regardless of tone.",
            "default": "Professional"
          },
          "techniques": {
            "title": "Naming techniques to bias toward (generation mode)",
            "type": "array",
            "description": "Optional. Naming techniques the LLM should favor, e.g. \"compound\", \"affix\", \"invented\", \"metaphor\". Leave empty to let the model choose a mix. Only used when `positioning` is set; ignored in screen mode. In generate mode it biases the style of candidate names produced but does not change filter logic — generate mode is free ($0.00 per filter-survivor) regardless of techniques chosen.",
            "items": {
              "type": "string"
            },
            "default": []
          },
          "mustInclude": {
            "title": "Required fragments (generation mode)",
            "type": "array",
            "description": "Optional. Every generated name must contain at least one of these fragments (normalized, case- and punctuation-insensitive). Deterministically enforced AFTER generation (v1.4.0): a candidate missing every required fragment is rejected at the filter (invalidReason `missing_required_fragment`, listed under OUTPUT.filtered) and is never screened or billed. Only used when `positioning` is set.",
            "items": {
              "type": "string"
            },
            "default": []
          },
          "avoid": {
            "title": "Forbidden fragments (generation mode)",
            "type": "array",
            "description": "Optional. Generated names must never contain any of these fragments (normalized, case- and punctuation-insensitive). Deterministically enforced AFTER generation (v1.4.0): a candidate containing a forbidden fragment is rejected at the filter (invalidReason `forbidden_fragment`, listed under OUTPUT.filtered) and is never screened or billed. Only used when `positioning` is set.",
            "items": {
              "type": "string"
            },
            "default": []
          },
          "count": {
            "title": "Names to generate (generation mode)",
            "minimum": 1,
            "maximum": 20,
            "type": "integer",
            "description": "Optional. How many candidate names to generate before filtering/screening. Capped at 20. Only used when `positioning` is set. Billing: generate mode is free — each filter-survivor emits a $0.00 event, so raising `count` costs nothing.",
            "default": 10
          },
          "maxLength": {
            "title": "Max name length (generation mode)",
            "minimum": 3,
            "maximum": 30,
            "type": "integer",
            "description": "Optional. Maximum character length (excluding spaces) for generated names. Only used when `positioning` is set; ignored in screen mode. In generate mode, candidates exceeding this length are rejected at the filter (listed under `OUTPUT.filtered`) and never screened or billed; survivors emit a $0.00 event each — generate mode is free, so tighter limits change coverage, not cost.",
            "default": 18
          },
          "bannedWords": {
            "title": "Additional banned words (generation mode)",
            "type": "array",
            "description": "Optional. Extra words to reject beyond the built-in profanity list, e.g. a competitor's name. Only used when `positioning` is set; ignored in screen mode. In generate mode, a candidate containing a banned word is rejected at the filter (listed under `OUTPUT.filtered`) and never screened or billed; survivors emit a $0.00 event each — generate mode is free, so adding entries here changes coverage, not cost.",
            "items": {
              "type": "string"
            },
            "default": []
          },
          "llmProvider": {
            "title": "LLM provider (generation mode, v1.8.0)",
            "enum": [
              "openai",
              "anthropic"
            ],
            "type": "string",
            "description": "Optional. Wire protocol for the generation model. \"openai\" = OpenAI-compatible (OpenRouter, OpenAI, Groq, Ollama, LM Studio). \"anthropic\" = native Claude Messages API. Defaults to \"openai\". Only used when `positioning` is set; ignored in screen mode, so it changes no screen-mode output. In generate mode it selects the API protocol used to call the model and does not affect PPE billing — generate mode is free ($0.00 per filter-survivor) regardless of provider; your own LLM provider costs are separate from the Actor charge.",
            "default": "openai"
          },
          "llmApiKey": {
            "title": "LLM API key — bring your own (generation mode, v1.8.0)",
            "type": "string",
            "description": "Your own API key for the chosen provider. When set, it overrides the operator-configured key (OPENROUTER_API_KEY env), so you pay your own LLM provider directly. Marked secret — never logged. REQUIRED for generate mode whenever the operator has NOT configured a key, AND whenever you set `llmBaseUrl` to a non-default endpoint OR set `llmProvider` to anything other than the default \"openai\" — the operator's key is never sent to a custom endpoint or a non-default provider (key-custody). Example providers: OpenRouter (https://openrouter.ai/keys), Groq (https://console.groq.com/keys), OpenAI (https://platform.openai.com/api-keys), Anthropic (https://console.anthropic.com/settings/keys). Effect: enables generate mode when the operator has no key, and unlocks custom endpoints/non-default providers. Billing: this key pays your own LLM provider and does not change the Actor's PPE charge — generate mode is free ($0.00 per filter-survivor); screen mode is unaffected and bills its usual `$1.00` per name × jurisdiction screened."
          },
          "llmBaseUrl": {
            "title": "LLM endpoint URL (generation mode, v1.8.0)",
            "type": "string",
            "description": "Provider chat-completions / messages endpoint. Overrides OPENROUTER_BASE_URL. Must be HTTPS (plain HTTP allowed for localhost only, e.g. a local Ollama/LM Studio). Leave empty for the provider default. Setting this to a non-default endpoint REQUIRES your own `llmApiKey` — the operator's key is never sent to a custom endpoint. Examples — OpenRouter: https://openrouter.ai/api/v1/chat/completions · OpenAI: https://api.openai.com/v1/chat/completions · Groq: https://api.groq.com/openai/v1/chat/completions · Anthropic: https://api.anthropic.com/v1/messages. Effect: routes generation calls to a chosen endpoint (generate mode only); ignored in screen mode. Billing: does not affect the Actor's PPE charge — generate mode is free ($0.00 per filter-survivor) regardless of endpoint; your own endpoint's LLM costs are separate.",
            "default": ""
          },
          "llmModel": {
            "title": "LLM model id (generation mode, v1.8.0)",
            "type": "string",
            "description": "Optional. Single model id to use for generation (overrides the operator's primary/fallback pair). Examples — OpenRouter: anthropic/claude-3.5-sonnet · Groq: llama-3.3-70b-versatile · OpenAI: gpt-4o-mini · Anthropic: claude-haiku-4-5-20251001. Leave empty to use the operator-configured models. Effect: changes which model generates candidate names (generate mode only); ignored in screen mode. Billing: does not affect the Actor's PPE charge — generate mode is free ($0.00 per filter-survivor) regardless of model; the model's own provider costs are separate.",
            "default": ""
          },
          "jurisdictions": {
            "title": "Jurisdictions to screen",
            "uniqueItems": true,
            "type": "array",
            "description": "Which trademark registries to screen against. \"FR\" = INPI (France), \"US\" = USPTO, \"EU\" = EUIPO, \"WO\" = WIPO (international/Madrid), and \"UK\" = UKIPO are all screened against curated seed datasets of well-known registered marks — famous-mark collision screening, not full registry coverage. Defaults to [\"FR\"]. Billing (screen mode): each selected jurisdiction that returns `screened` bills $1.00 per name; a jurisdiction with no enabled source returns `not_screened` and is free. Each verdict carries `marksScreened` (how many in-scope marks were compared) so a weak `clear` can't pass for a strong one.",
            "items": {
              "type": "string",
              "enum": [
                "FR",
                "EU",
                "US",
                "WO",
                "UK"
              ],
              "enumTitles": [
                "France (INPI)",
                "European Union (EUIPO)",
                "United States (USPTO)",
                "International (WIPO)",
                "United Kingdom (UKIPO)"
              ]
            },
            "default": [
              "FR"
            ]
          },
          "niceClasses": {
            "title": "Nice classes (goods/services)",
            "type": "array",
            "description": "Optional but strongly recommended. The Nice classification number(s) for your goods/services (1–45). Trademark conflicts only matter within similar classes, so scoping here removes noise from the output. Leave empty to screen across ALL classes (noisier, more false positives). When left empty AND `industry` is set, v1.1.0 infers classes from a curated keyword table and tags the run `niceClassesSource: inferred` (see output). Billing: scoping does not change the per-jurisdiction charge — screen mode still bills `$1.00` per name × jurisdiction that returns `screened`, and generate mode is free ($0.00), regardless of how many Nice classes are selected; `not_screened` rows stay free.",
            "items": {
              "type": "string"
            },
            "default": []
          },
          "industry": {
            "title": "Industry / sector (optional)",
            "type": "string",
            "description": "Optional free-text industry (e.g. \"fintech\", \"coffee roastery\"). Effect on output: used only for the human-readable recommendation, and (when `niceClasses` is empty) to infer Nice classes via a curated keyword table, tagging the run `niceClassesSource: inferred`. Prefer `niceClasses` for the actual scoping. Billing: no direct effect — screen mode still bills `$1.00` per name × jurisdiction screened and generate mode is free ($0.00); industry never adds or removes a charge on its own."
          },
          "language": {
            "title": "Primary phonetic language",
            "enum": [
              "en",
              "fr"
            ],
            "type": "string",
            "description": "Language whose phonetic rules drive the sounds-alike comparison. Effect on output: \"fr\" applies French phonetics for the INPI path; \"en\" applies English. Defaults to \"en\". Changing it can alter which marks score above `riskThreshold` and therefore which similar marks are listed. Billing: no effect — screen mode still bills `$1.00` per name × jurisdiction screened and generate mode is free ($0.00), regardless of the phonetic language selected.",
            "default": "en"
          },
          "riskThreshold": {
            "title": "Minimum similarity to report",
            "minimum": 0,
            "maximum": 100,
            "type": "integer",
            "description": "Optional. Only similar marks scoring at or above this 0–100 similarity are listed in the output. Defaults to 60. Lower it to see more borderline matches; raise it to list fewer. Effect on output: filters which similar marks appear per verdict (the `marksScreened` count and per-jurisdiction `screened`/`not_screened` status are unaffected). Billing: no effect — screen mode still bills `$1.00` per name × jurisdiction that returns `screened` and generate mode is free ($0.00), regardless of how many marks the threshold surfaces.",
            "default": 60
          },
          "enableDomainCheck": {
            "title": "Run RDAP domain availability co-check (v1.1.0)",
            "type": "boolean",
            "description": "Optional. When true (default), the run probes .com / .io / .ai / .dev via RDAP and surfaces availability + a free/taken/error summary in the OUTPUT record. Set to false to skip the network calls entirely (overrides RDAP_ENABLED env). Effect on output: toggles the domain-availability block in the output; disabling it removes the RDAP summary but leaves trademark verdicts unchanged. Billing: no effect — the RDAP co-check is never charged; screen mode still bills `$1.00` per name × jurisdiction screened and generate mode is free ($0.00), regardless of this flag.",
            "default": true
          }
        }
      },
      "runsResponseSchema": {
        "type": "object",
        "properties": {
          "data": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string"
              },
              "actId": {
                "type": "string"
              },
              "userId": {
                "type": "string"
              },
              "startedAt": {
                "type": "string",
                "format": "date-time",
                "example": "2025-01-08T00:00:00.000Z"
              },
              "finishedAt": {
                "type": "string",
                "format": "date-time",
                "example": "2025-01-08T00:00:00.000Z"
              },
              "status": {
                "type": "string",
                "example": "READY"
              },
              "meta": {
                "type": "object",
                "properties": {
                  "origin": {
                    "type": "string",
                    "example": "API"
                  },
                  "userAgent": {
                    "type": "string"
                  }
                }
              },
              "stats": {
                "type": "object",
                "properties": {
                  "inputBodyLen": {
                    "type": "integer",
                    "example": 2000
                  },
                  "rebootCount": {
                    "type": "integer",
                    "example": 0
                  },
                  "restartCount": {
                    "type": "integer",
                    "example": 0
                  },
                  "resurrectCount": {
                    "type": "integer",
                    "example": 0
                  },
                  "computeUnits": {
                    "type": "integer",
                    "example": 0
                  }
                }
              },
              "options": {
                "type": "object",
                "properties": {
                  "build": {
                    "type": "string",
                    "example": "latest"
                  },
                  "timeoutSecs": {
                    "type": "integer",
                    "example": 300
                  },
                  "memoryMbytes": {
                    "type": "integer",
                    "example": 1024
                  },
                  "diskMbytes": {
                    "type": "integer",
                    "example": 2048
                  }
                }
              },
              "buildId": {
                "type": "string"
              },
              "defaultKeyValueStoreId": {
                "type": "string"
              },
              "defaultDatasetId": {
                "type": "string"
              },
              "defaultRequestQueueId": {
                "type": "string"
              },
              "buildNumber": {
                "type": "string",
                "example": "1.0.0"
              },
              "containerUrl": {
                "type": "string"
              },
              "usage": {
                "type": "object",
                "properties": {
                  "ACTOR_COMPUTE_UNITS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_WRITES": {
                    "type": "integer",
                    "example": 1
                  },
                  "KEY_VALUE_STORE_LISTS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_INTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_EXTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_SERPS": {
                    "type": "integer",
                    "example": 0
                  }
                }
              },
              "usageTotalUsd": {
                "type": "number",
                "example": 0.00005
              },
              "usageUsd": {
                "type": "object",
                "properties": {
                  "ACTOR_COMPUTE_UNITS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_WRITES": {
                    "type": "number",
                    "example": 0.00005
                  },
                  "KEY_VALUE_STORE_LISTS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_INTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_EXTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_SERPS": {
                    "type": "integer",
                    "example": 0
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}