{
  "openapi": "3.1.0",
  "info": {
    "title": "LogoAPI.sh",
    "version": "1.0.0",
    "summary": "Company, stock ticker and crypto logos by URL. Free, no key.",
    "description": "Logo files by domain, stock ticker or crypto symbol, as SVG or PNG, with versions for dark backgrounds. No key, no signup, no attribution. 2M requests a month per site, free. Every logo route is a plain GET you can put in an img src. Missing logos fall back to the site's favicon or a name tile, and the X-Logo-Fallback response header says so; add ?fallback=404 to get a 404 instead. Full text for agents: https://logoapi.sh/llms.txt",
    "termsOfService": "https://logoapi.sh/terms",
    "contact": { "name": "H. Tech Innovation LLC", "email": "hello@logoapi.sh", "url": "https://logoapi.sh/contact" }
  },
  "externalDocs": { "description": "Docs", "url": "https://logoapi.sh/docs" },
  "servers": [{ "url": "https://logoapi.sh" }],
  "security": [],
  "tags": [
    { "name": "Logos by domain" },
    { "name": "Tickers and crypto" },
    { "name": "Search" }
  ],
  "paths": {
    "/{domain}.svg": {
      "get": {
        "tags": ["Logos by domain"],
        "operationId": "getLogoSvg",
        "summary": "Logo by domain (SVG)",
        "description": "The wordmark logo, or the icon when the company has no wordmark. Always returns an SVG: the logo, else the site's favicon wrapped in an SVG, else a name tile. Add .txt (/{domain}.svg.txt) to get the same SVG as text/plain for canvases that block outside images.",
        "parameters": [{ "$ref": "#/components/parameters/domain" }, { "$ref": "#/components/parameters/fallback" }],
        "responses": { "200": { "$ref": "#/components/responses/Svg" }, "404": { "$ref": "#/components/responses/NotFound" } }
      }
    },
    "/{domain}.png": {
      "get": {
        "tags": ["Logos by domain"],
        "operationId": "getLogoPng",
        "summary": "Logo by domain (PNG)",
        "description": "PNG rendered from the SVG, for email clients that block SVG. Brands with only a PNG logo return their original file unchanged. On a miss: the site's favicon as a PNG, else 404.",
        "parameters": [
          { "$ref": "#/components/parameters/domain" },
          { "name": "size", "in": "query", "description": "Longest side in px. Other values snap to the nearest.", "schema": { "type": "integer", "enum": [128, 256, 512, 1024], "default": 512 } },
          { "name": "bg", "in": "query", "description": "white for a white background instead of transparent.", "schema": { "type": "string", "enum": ["white"] } },
          { "$ref": "#/components/parameters/fallback" }
        ],
        "responses": { "200": { "$ref": "#/components/responses/Png" }, "404": { "$ref": "#/components/responses/NotFound" } }
      }
    },
    "/icon/{domain}.svg": {
      "get": {
        "tags": ["Logos by domain"],
        "operationId": "getIconSvg",
        "summary": "Square icon by domain (SVG)",
        "description": "Square mark for avatars, lists and favicons. Also /icon/{domain}.png.",
        "parameters": [{ "$ref": "#/components/parameters/domain" }, { "$ref": "#/components/parameters/fallback" }],
        "responses": { "200": { "$ref": "#/components/responses/Svg" }, "404": { "$ref": "#/components/responses/NotFound" } }
      }
    },
    "/{version}/{domain}.svg": {
      "get": {
        "tags": ["Logos by domain"],
        "operationId": "getLogoVersion",
        "summary": "Colour version by domain (SVG)",
        "description": "The logo recoloured for a background: dark, white, black or grey. Generated, not official, unless the brand publishes that version. Also /{version}/icon/{domain}.svg for the square icon. SVG only. A miss returns a name tile (X-Logo-Fallback: tile); add ?fallback=404 for a 404.",
        "parameters": [
          { "name": "version", "in": "path", "required": true, "schema": { "type": "string", "enum": ["dark", "white", "black", "grey"] } },
          { "$ref": "#/components/parameters/domain" },
          { "$ref": "#/components/parameters/fallback" }
        ],
        "responses": { "200": { "$ref": "#/components/responses/Svg" }, "404": { "$ref": "#/components/responses/NotFound" } }
      }
    },
    "/favicon/{domain}": {
      "get": {
        "tags": ["Logos by domain"],
        "operationId": "getFavicon",
        "summary": "Favicon by domain (SVG)",
        "description": "Favicon from the catalog icon. Also /favicon/{domain}.svg. Unknown domains return 404 JSON, no placeholder.",
        "parameters": [{ "$ref": "#/components/parameters/domain" }],
        "responses": { "200": { "$ref": "#/components/responses/Svg" }, "404": { "$ref": "#/components/responses/NotFound" } }
      }
    },
    "/ticker/{ticker}.svg": {
      "get": {
        "tags": ["Tickers and crypto"],
        "operationId": "getTickerSvg",
        "summary": "Square icon by stock ticker (SVG)",
        "description": "Square icon by stock or ETF ticker, case-insensitive, US listing preferred. An exchange prefix works (NASDAQ:MNDY). A coin symbol such as BTC answers the coin mark. Known tickers without a catalog icon get the company wordmark, favicon or a name tile (X-Logo-Fallback says which). Unknown ticker: 404. Also /icon/ticker/{ticker}.svg and .png.",
        "parameters": [
          { "$ref": "#/components/parameters/ticker" },
          { "name": "variant", "in": "query", "description": "full for the full logo instead of the square icon.", "schema": { "type": "string", "enum": ["full"] } },
          { "$ref": "#/components/parameters/fallback" }
        ],
        "responses": { "200": { "$ref": "#/components/responses/Svg" }, "404": { "$ref": "#/components/responses/NotFound" } }
      }
    },
    "/dark/ticker/{ticker}.svg": {
      "get": {
        "tags": ["Tickers and crypto"],
        "operationId": "getTickerDarkSvg",
        "summary": "Square icon by stock ticker, for dark backgrounds (SVG)",
        "description": "Same icon recoloured for dark backgrounds. SVG only. Also /dark/icon/ticker/{ticker}.svg.",
        "parameters": [
          { "$ref": "#/components/parameters/ticker" },
          { "name": "variant", "in": "query", "schema": { "type": "string", "enum": ["full"] } }
        ],
        "responses": { "200": { "$ref": "#/components/responses/Svg" }, "404": { "$ref": "#/components/responses/NotFound" } }
      }
    },
    "/crypto/{symbol}.svg": {
      "get": {
        "tags": ["Tickers and crypto"],
        "operationId": "getCryptoSvg",
        "summary": "Crypto coin mark by symbol (SVG)",
        "description": "Square coin mark (BTC, ETH, SOL, USDC, XRP and more). Also the bare form and .png. Unknown symbol: 404, no tile.",
        "parameters": [{ "$ref": "#/components/parameters/symbol" }],
        "responses": { "200": { "$ref": "#/components/responses/Svg" }, "404": { "$ref": "#/components/responses/NotFound" } }
      }
    },
    "/dark/crypto/{symbol}.svg": {
      "get": {
        "tags": ["Tickers and crypto"],
        "operationId": "getCryptoDarkSvg",
        "summary": "Crypto coin mark for dark backgrounds (SVG)",
        "description": "Same coin marks recoloured for dark backgrounds. SVG only. Unknown symbol: 404.",
        "parameters": [{ "$ref": "#/components/parameters/symbol" }],
        "responses": { "200": { "$ref": "#/components/responses/Svg" }, "404": { "$ref": "#/components/responses/NotFound" } }
      }
    },
    "/search": {
      "get": {
        "tags": ["Search"],
        "operationId": "searchLogos",
        "summary": "Find a logo by company name or domain",
        "description": "Matches an exact brand name, an exact domain or a close typo. Up to 8 results, best first; with tag alone, the first 48. Use it to check that a logo exists without reading the SVG.",
        "parameters": [
          { "name": "q", "in": "query", "description": "Brand name or domain, 2 to 80 characters with at least 2 letters or digits. Optional when tag is given.", "schema": { "type": "string", "minLength": 2, "maxLength": 80 }, "example": "stripe" },
          { "name": "tag", "in": "query", "description": "Exactly one sector tag.", "schema": { "type": "string", "enum": ["tech", "devtools", "finance", "retail", "media", "organizations", "health", "industry"] } },
          { "name": "page", "in": "query", "description": "Only page 1 is served; page 2 or higher is 403 page_limit.", "schema": { "type": "integer", "minimum": 1, "maximum": 1 } }
        ],
        "responses": {
          "200": {
            "description": "Matches, best first.",
            "headers": { "Access-Control-Allow-Origin": { "$ref": "#/components/headers/Cors" } },
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/SearchResponse" } } }
          },
          "400": { "description": "Bad q, more than one tag or a bad page value.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } },
          "403": { "description": "page_limit: page 2 or higher.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } },
          "429": { "description": "Search rate limit reached.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }
        }
      }
    }
  },
  "components": {
    "parameters": {
      "domain": { "name": "domain", "in": "path", "required": true, "description": "Company domain, e.g. stripe.com.", "schema": { "type": "string" }, "example": "stripe.com" },
      "ticker": { "name": "ticker", "in": "path", "required": true, "description": "Stock or ETF ticker, any case, optional exchange prefix.", "schema": { "type": "string" }, "example": "AAPL" },
      "symbol": { "name": "symbol", "in": "path", "required": true, "description": "Coin symbol, any case.", "schema": { "type": "string" }, "example": "BTC" },
      "fallback": { "name": "fallback", "in": "query", "description": "404 (or none) turns off the favicon and name-tile fallbacks: a miss returns 404.", "schema": { "type": "string", "enum": ["404", "none"] } }
    },
    "headers": {
      "Cors": { "description": "Always *.", "schema": { "type": "string" } },
      "Fallback": { "description": "Set when the response is not a catalog logo: wordmark (ticker icon routes: the company wordmark stands in), favicon (the site's own favicon) or tile (a name tile).", "schema": { "type": "string", "enum": ["wordmark", "favicon", "tile"] } },
      "Kind": { "description": "Sent on /icon/ and ticker routes: icon, wordmark or raster. A missing header does not mean icon.", "schema": { "type": "string" } },
      "Format": { "description": "png-render for PNGs rendered from SVG, png-in-svg for an SVG that wraps a PNG-only logo.", "schema": { "type": "string" } }
    },
    "responses": {
      "Svg": {
        "description": "The image. Cache-Control max-age=86400.",
        "headers": {
          "Access-Control-Allow-Origin": { "$ref": "#/components/headers/Cors" },
          "X-Logo-Fallback": { "$ref": "#/components/headers/Fallback" },
          "X-Logo-Kind": { "$ref": "#/components/headers/Kind" },
          "X-Logo-Format": { "$ref": "#/components/headers/Format" }
        },
        "content": { "image/svg+xml": { "schema": { "type": "string" } }, "image/png": { "schema": { "type": "string", "format": "binary" } } }
      },
      "Png": {
        "description": "The PNG image.",
        "headers": {
          "Access-Control-Allow-Origin": { "$ref": "#/components/headers/Cors" },
          "X-Logo-Fallback": { "$ref": "#/components/headers/Fallback" },
          "X-Logo-Format": { "$ref": "#/components/headers/Format" }
        },
        "content": { "image/png": { "schema": { "type": "string", "format": "binary" } } }
      },
      "NotFound": {
        "description": "No logo (with fallback=404 or none, an unknown ticker or coin, or raster_only on an SVG-only route).",
        "content": { "text/plain": { "schema": { "type": "string" } }, "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } }
      }
    },
    "schemas": {
      "Error": { "type": "object", "properties": { "error": { "type": "string" } }, "required": ["error"] },
      "SearchResult": {
        "type": "object",
        "required": ["domain", "name", "logo", "icon", "wordmark"],
        "properties": {
          "domain": { "type": "string" },
          "name": { "type": "string" },
          "logo": { "type": "string", "format": "uri" },
          "icon": { "type": "string", "format": "uri" },
          "format": { "type": "string", "enum": ["svg", "png"] },
          "wordmark": { "type": "boolean", "description": "true when the bare /{domain} route serves a wordmark, false when it serves an icon." },
          "score": { "type": "number", "description": "Sent on q searches, not on tag-only searches." },
          "fuzzy": { "type": "boolean", "description": "true for typo matches, ranked below exact ones." },
          "tags": { "type": "array", "items": { "type": "string" } },
          "source": { "type": "string" },
          "ticker": { "type": "string", "description": "Main listing, US first." },
          "exchange": { "type": "string" }
        }
      },
      "SearchResponse": {
        "type": "object",
        "properties": {
          "query": { "type": "string" },
          "tag": { "type": "array", "items": { "type": "string" } },
          "page": { "type": "integer" },
          "results": { "type": "array", "items": { "$ref": "#/components/schemas/SearchResult" } }
        },
        "required": ["results"]
      }
    }
  }
}
