{
  "openapi": "3.1.0",
  "info": {
    "title": "HappyFetch API",
    "version": "1.0.0",
    "description": "Company data and search, fetched live or served from our cache, with every credit traceable.\n\nAuthenticate with `Authorization: Bearer <key>` (or `X-Api-Key`). Every response carries `X-Request-Id`. Failures that aren't your input are refunded automatically.",
    "contact": {
      "name": "HappyFetch",
      "url": "https://happyfetch.net/docs"
    }
  },
  "servers": [
    {
      "url": "https://api.happyfetch.net"
    }
  ],
  "security": [
    {
      "bearerAuth": []
    },
    {
      "apiKeyHeader": []
    }
  ],
  "tags": [
    {
      "name": "Company",
      "description": "Company profiles."
    },
    {
      "name": "Person",
      "description": "A person's public mini profile."
    },
    {
      "name": "Search",
      "description": "Web search results as JSON."
    },
    {
      "name": "Cache",
      "description": "What we hold in our cache, for free."
    },
    {
      "name": "Meta",
      "description": "Public, unauthenticated endpoints."
    }
  ],
  "paths": {
    "/v1/company": {
      "post": {
        "operationId": "getCompany",
        "tags": [
          "Company"
        ],
        "summary": "Look up a company",
        "description": "Returns a company profile for any LinkedIn company reference. Served from our cache when a fresh enough copy exists (see `max_age`); otherwise fetched now. Every input form of a known company (URL variants, case, old slug, numeric id, URN) is a cache hit.",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "Any unique string (for example a UUID) per logical request. A retry with the same key within 24 hours replays the stored response instead of running, and charging, again.",
            "schema": {
              "type": "string",
              "maxLength": 255
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CompanyRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The company.",
            "headers": {
              "X-Request-Id": {
                "description": "Correlation id for this request. Quote it to support; it ties the call to its charge and the data it returned.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Limit": {
                "description": "Requests per minute allowed for this API key.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until the budget is fully restored.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Credits-Charged": {
                "description": "Credits charged for this call (0 when refunded or not billable).",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Credits-Remaining": {
                "description": "Workspace balance after this call.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Cache": {
                "description": "HIT, MISS or REFRESH.",
                "schema": {
                  "type": "string"
                }
              },
              "Age": {
                "description": "Seconds since the data was fetched.",
                "schema": {
                  "type": "integer"
                }
              },
              "Idempotent-Replayed": {
                "description": "`true` when this response is a stored replay of an earlier request with the same Idempotency-Key.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CompanyResponse"
                }
              }
            }
          },
          "400": {
            "description": "`invalid_request`: The body isn't valid JSON or doesn't match the schema. `details` names each field.\n\n`invalid_company_reference`: `url` isn't a LinkedIn company reference (for example a /in/ profile, a school page, or free text).",
            "headers": {
              "X-Request-Id": {
                "description": "Correlation id for this request. Quote it to support; it ties the call to its charge and the data it returned.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Limit": {
                "description": "Requests per minute allowed for this API key.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until the budget is fully restored.",
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "`unauthorized`: The API key is missing, malformed or revoked. Send it as `Authorization: Bearer <key>` or `X-Api-Key`.",
            "headers": {
              "X-Request-Id": {
                "description": "Correlation id for this request. Quote it to support; it ties the call to its charge and the data it returned.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Limit": {
                "description": "Requests per minute allowed for this API key.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until the budget is fully restored.",
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "`insufficient_credits`: The workspace balance doesn't cover this call. Top up in the console; nothing was charged.",
            "headers": {
              "X-Request-Id": {
                "description": "Correlation id for this request. Quote it to support; it ties the call to its charge and the data it returned.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Limit": {
                "description": "Requests per minute allowed for this API key.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until the budget is fully restored.",
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "`not_found`: Nothing exists for this lookup: no company behind the reference or the domain, or no profile at that name. A definitive answer, charged at the lookup's not-found price (see GET /v1/pricing); free when it comes from the cache. `error.reason` says which answer it is where there's more than one.\n\n`unresolvable_id`: No public company page could be found for this numeric id. Charged at the not-found price (see GET /v1/pricing); free when the answer comes from the cache.",
            "headers": {
              "X-Request-Id": {
                "description": "Correlation id for this request. Quote it to support; it ties the call to its charge and the data it returned.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Limit": {
                "description": "Requests per minute allowed for this API key.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until the budget is fully restored.",
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "`idempotency_key_in_use`: A request with this Idempotency-Key is still running. Retry shortly to get its stored response.",
            "headers": {
              "X-Request-Id": {
                "description": "Correlation id for this request. Quote it to support; it ties the call to its charge and the data it returned.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Limit": {
                "description": "Requests per minute allowed for this API key.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until the budget is fully restored.",
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "`idempotency_key_reused`: This Idempotency-Key was already used with a different endpoint or body.",
            "headers": {
              "X-Request-Id": {
                "description": "Correlation id for this request. Quote it to support; it ties the call to its charge and the data it returned.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Limit": {
                "description": "Requests per minute allowed for this API key.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until the budget is fully restored.",
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "`rate_limited`: Too many requests for this API key. Wait for Retry-After; RateLimit-* headers show the budget.\n\n`concurrency_limited`: Too many of this workspace's lookups are in flight. Retry after Retry-After.",
            "headers": {
              "X-Request-Id": {
                "description": "Correlation id for this request. Quote it to support; it ties the call to its charge and the data it returned.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Limit": {
                "description": "Requests per minute allowed for this API key.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until the budget is fully restored.",
                "schema": {
                  "type": "integer"
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "`internal_error`: Something failed on our side. Any charge was refunded; the request id helps us find it.",
            "headers": {
              "X-Request-Id": {
                "description": "Correlation id for this request. Quote it to support; it ties the call to its charge and the data it returned.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Limit": {
                "description": "Requests per minute allowed for this API key.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until the budget is fully restored.",
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "502": {
            "description": "`upstream_error`: The data couldn't be fetched because of an unexpected error. Refunded automatically.\n\n`parse_error`: The data was fetched but couldn't be read. We're alerted; refunded automatically.",
            "headers": {
              "X-Request-Id": {
                "description": "Correlation id for this request. Quote it to support; it ties the call to its charge and the data it returned.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Limit": {
                "description": "Requests per minute allowed for this API key.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until the budget is fully restored.",
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "`blocked`: The data couldn't be fetched right now. Refunded automatically; retry after Retry-After.\n\n`source_rate_limited`: Fetching is being slowed down right now. Refunded automatically; retry after Retry-After.\n\n`no_capacity`: We can't take new lookups right now. Rejected before charging.",
            "headers": {
              "X-Request-Id": {
                "description": "Correlation id for this request. Quote it to support; it ties the call to its charge and the data it returned.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Limit": {
                "description": "Requests per minute allowed for this API key.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until the budget is fully restored.",
                "schema": {
                  "type": "integer"
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "504": {
            "description": "`timeout`: No definitive answer arrived in time. Refunded automatically.",
            "headers": {
              "X-Request-Id": {
                "description": "Correlation id for this request. Quote it to support; it ties the call to its charge and the data it returned.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Limit": {
                "description": "Requests per minute allowed for this API key.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until the budget is fully restored.",
                "schema": {
                  "type": "integer"
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "cURL",
            "source": "curl https://api.happyfetch.net/v1/company --max-time 120 \\\n  -H \"Authorization: Bearer $HAPPYFETCH_API_KEY\" \\\n  -H \"Idempotency-Key: $(uuidgen)\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"url\":\"https://www.linkedin.com/company/stripe\"}'"
          },
          {
            "lang": "javascript",
            "label": "JavaScript",
            "source": "const res = await fetch(\"https://api.happyfetch.net/v1/company\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.HAPPYFETCH_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n    \"Idempotency-Key\": crypto.randomUUID(), // send the same key when you retry this call\n  },\n  body: JSON.stringify({\n    \"url\": \"https://www.linkedin.com/company/stripe\"\n  }),\n  signal: AbortSignal.timeout(120_000),\n});\nconst { data, meta, error } = await res.json();\nif (!res.ok) throw new Error(`${error.code}: ${error.message}`);\nconsole.log(meta.request_id, meta.cache.status, data);"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "import os, uuid, requests\n\nres = requests.post(\n    \"https://api.happyfetch.net/v1/company\",\n    headers={\n        \"Authorization\": f\"Bearer {os.environ['HAPPYFETCH_API_KEY']}\",\n        \"Idempotency-Key\": str(uuid.uuid4()),  # send the same key when you retry this call\n    },\n    json={\n      \"url\": \"https://www.linkedin.com/company/stripe\"\n    },\n    timeout=120,\n)\nbody = res.json()\nif not res.ok:\n    raise RuntimeError(f\"{body['error']['code']}: {body['error']['message']}\")\nprint(body[\"meta\"][\"request_id\"], body[\"meta\"][\"cache\"][\"status\"])"
          }
        ]
      }
    },
    "/v1/domain": {
      "post": {
        "operationId": "getCompanyByDomain",
        "tags": [
          "Company"
        ],
        "summary": "Look up a company by its website",
        "description": "Returns the company profile for a website domain, in the same shape as POST /v1/company. Any page or subdomain of a site is the same lookup (the registrable domain). Served from our cache when a fresh enough copy exists (see `max_age`); otherwise found now. `meta.resolved` says which domain was resolved and whether the company's own website field confirms it.",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "Any unique string (for example a UUID) per logical request. A retry with the same key within 24 hours replays the stored response instead of running, and charging, again.",
            "schema": {
              "type": "string",
              "maxLength": 255
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DomainRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The company behind the domain.",
            "headers": {
              "X-Request-Id": {
                "description": "Correlation id for this request. Quote it to support; it ties the call to its charge and the data it returned.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Limit": {
                "description": "Requests per minute allowed for this API key.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until the budget is fully restored.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Credits-Charged": {
                "description": "Credits charged for this call (0 when refunded or not billable).",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Credits-Remaining": {
                "description": "Workspace balance after this call.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Cache": {
                "description": "HIT, MISS or REFRESH.",
                "schema": {
                  "type": "string"
                }
              },
              "Age": {
                "description": "Seconds since the data was fetched.",
                "schema": {
                  "type": "integer"
                }
              },
              "Idempotent-Replayed": {
                "description": "`true` when this response is a stored replay of an earlier request with the same Idempotency-Key.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CompanyResponse"
                }
              }
            }
          },
          "400": {
            "description": "`invalid_request`: The body isn't valid JSON or doesn't match the schema. `details` names each field.\n\n`invalid_domain`: `domain` isn't a website on a public domain. Company page URLs and slugs go to POST /v1/company.",
            "headers": {
              "X-Request-Id": {
                "description": "Correlation id for this request. Quote it to support; it ties the call to its charge and the data it returned.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Limit": {
                "description": "Requests per minute allowed for this API key.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until the budget is fully restored.",
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "`unauthorized`: The API key is missing, malformed or revoked. Send it as `Authorization: Bearer <key>` or `X-Api-Key`.",
            "headers": {
              "X-Request-Id": {
                "description": "Correlation id for this request. Quote it to support; it ties the call to its charge and the data it returned.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Limit": {
                "description": "Requests per minute allowed for this API key.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until the budget is fully restored.",
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "`insufficient_credits`: The workspace balance doesn't cover this call. Top up in the console; nothing was charged.",
            "headers": {
              "X-Request-Id": {
                "description": "Correlation id for this request. Quote it to support; it ties the call to its charge and the data it returned.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Limit": {
                "description": "Requests per minute allowed for this API key.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until the budget is fully restored.",
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "`not_found`: Nothing exists for this lookup: no company behind the reference or the domain, or no profile at that name. A definitive answer, charged at the lookup's not-found price (see GET /v1/pricing); free when it comes from the cache. `error.reason` says which answer it is where there's more than one.",
            "headers": {
              "X-Request-Id": {
                "description": "Correlation id for this request. Quote it to support; it ties the call to its charge and the data it returned.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Limit": {
                "description": "Requests per minute allowed for this API key.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until the budget is fully restored.",
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "`idempotency_key_in_use`: A request with this Idempotency-Key is still running. Retry shortly to get its stored response.",
            "headers": {
              "X-Request-Id": {
                "description": "Correlation id for this request. Quote it to support; it ties the call to its charge and the data it returned.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Limit": {
                "description": "Requests per minute allowed for this API key.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until the budget is fully restored.",
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "`idempotency_key_reused`: This Idempotency-Key was already used with a different endpoint or body.",
            "headers": {
              "X-Request-Id": {
                "description": "Correlation id for this request. Quote it to support; it ties the call to its charge and the data it returned.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Limit": {
                "description": "Requests per minute allowed for this API key.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until the budget is fully restored.",
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "`rate_limited`: Too many requests for this API key. Wait for Retry-After; RateLimit-* headers show the budget.\n\n`concurrency_limited`: Too many of this workspace's lookups are in flight. Retry after Retry-After.",
            "headers": {
              "X-Request-Id": {
                "description": "Correlation id for this request. Quote it to support; it ties the call to its charge and the data it returned.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Limit": {
                "description": "Requests per minute allowed for this API key.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until the budget is fully restored.",
                "schema": {
                  "type": "integer"
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "`internal_error`: Something failed on our side. Any charge was refunded; the request id helps us find it.",
            "headers": {
              "X-Request-Id": {
                "description": "Correlation id for this request. Quote it to support; it ties the call to its charge and the data it returned.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Limit": {
                "description": "Requests per minute allowed for this API key.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until the budget is fully restored.",
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "502": {
            "description": "`upstream_error`: The data couldn't be fetched because of an unexpected error. Refunded automatically.\n\n`parse_error`: The data was fetched but couldn't be read. We're alerted; refunded automatically.",
            "headers": {
              "X-Request-Id": {
                "description": "Correlation id for this request. Quote it to support; it ties the call to its charge and the data it returned.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Limit": {
                "description": "Requests per minute allowed for this API key.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until the budget is fully restored.",
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "`blocked`: The data couldn't be fetched right now. Refunded automatically; retry after Retry-After.\n\n`source_rate_limited`: Fetching is being slowed down right now. Refunded automatically; retry after Retry-After.\n\n`no_capacity`: We can't take new lookups right now. Rejected before charging.",
            "headers": {
              "X-Request-Id": {
                "description": "Correlation id for this request. Quote it to support; it ties the call to its charge and the data it returned.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Limit": {
                "description": "Requests per minute allowed for this API key.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until the budget is fully restored.",
                "schema": {
                  "type": "integer"
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "504": {
            "description": "`timeout`: No definitive answer arrived in time. Refunded automatically.",
            "headers": {
              "X-Request-Id": {
                "description": "Correlation id for this request. Quote it to support; it ties the call to its charge and the data it returned.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Limit": {
                "description": "Requests per minute allowed for this API key.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until the budget is fully restored.",
                "schema": {
                  "type": "integer"
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "cURL",
            "source": "curl https://api.happyfetch.net/v1/domain --max-time 120 \\\n  -H \"Authorization: Bearer $HAPPYFETCH_API_KEY\" \\\n  -H \"Idempotency-Key: $(uuidgen)\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"domain\":\"stripe.com\"}'"
          },
          {
            "lang": "javascript",
            "label": "JavaScript",
            "source": "const res = await fetch(\"https://api.happyfetch.net/v1/domain\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.HAPPYFETCH_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n    \"Idempotency-Key\": crypto.randomUUID(), // send the same key when you retry this call\n  },\n  body: JSON.stringify({\n    \"domain\": \"stripe.com\"\n  }),\n  signal: AbortSignal.timeout(120_000),\n});\nconst { data, meta, error } = await res.json();\nif (!res.ok) throw new Error(`${error.code}: ${error.message}`);\nconsole.log(meta.request_id, meta.cache.status, data);"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "import os, uuid, requests\n\nres = requests.post(\n    \"https://api.happyfetch.net/v1/domain\",\n    headers={\n        \"Authorization\": f\"Bearer {os.environ['HAPPYFETCH_API_KEY']}\",\n        \"Idempotency-Key\": str(uuid.uuid4()),  # send the same key when you retry this call\n    },\n    json={\n      \"domain\": \"stripe.com\"\n    },\n    timeout=120,\n)\nbody = res.json()\nif not res.ok:\n    raise RuntimeError(f\"{body['error']['code']}: {body['error']['message']}\")\nprint(body[\"meta\"][\"request_id\"], body[\"meta\"][\"cache\"][\"status\"])"
          }
        ]
      }
    },
    "/v1/person": {
      "post": {
        "operationId": "getPerson",
        "tags": [
          "Person"
        ],
        "summary": "Look up a person",
        "description": "Returns a person's public mini profile from their LinkedIn profile URL or name: name, location, the start of the About text, employers (current first), schools and follower count. Served from our cache when a fresh enough copy exists (see `max_age`); otherwise fetched now. `meta.content_hash` covers `data`, so an unchanged profile keeps its hash: compare hashes to watch people for changes.",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "Any unique string (for example a UUID) per logical request. A retry with the same key within 24 hours replays the stored response instead of running, and charging, again.",
            "schema": {
              "type": "string",
              "maxLength": 255
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PersonRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The person.",
            "headers": {
              "X-Request-Id": {
                "description": "Correlation id for this request. Quote it to support; it ties the call to its charge and the data it returned.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Limit": {
                "description": "Requests per minute allowed for this API key.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until the budget is fully restored.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Credits-Charged": {
                "description": "Credits charged for this call (0 when refunded or not billable).",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Credits-Remaining": {
                "description": "Workspace balance after this call.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Cache": {
                "description": "HIT, MISS or REFRESH.",
                "schema": {
                  "type": "string"
                }
              },
              "Age": {
                "description": "Seconds since the data was fetched.",
                "schema": {
                  "type": "integer"
                }
              },
              "Idempotent-Replayed": {
                "description": "`true` when this response is a stored replay of an earlier request with the same Idempotency-Key.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PersonResponse"
                }
              }
            }
          },
          "400": {
            "description": "`invalid_request`: The body isn't valid JSON or doesn't match the schema. `details` names each field.\n\n`invalid_person_reference`: `url` isn't a LinkedIn profile: send its URL (linkedin.com/in/<name>) or the name. Member ids (ACoAA…) aren't accepted.",
            "headers": {
              "X-Request-Id": {
                "description": "Correlation id for this request. Quote it to support; it ties the call to its charge and the data it returned.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Limit": {
                "description": "Requests per minute allowed for this API key.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until the budget is fully restored.",
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "`unauthorized`: The API key is missing, malformed or revoked. Send it as `Authorization: Bearer <key>` or `X-Api-Key`.",
            "headers": {
              "X-Request-Id": {
                "description": "Correlation id for this request. Quote it to support; it ties the call to its charge and the data it returned.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Limit": {
                "description": "Requests per minute allowed for this API key.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until the budget is fully restored.",
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "`insufficient_credits`: The workspace balance doesn't cover this call. Top up in the console; nothing was charged.",
            "headers": {
              "X-Request-Id": {
                "description": "Correlation id for this request. Quote it to support; it ties the call to its charge and the data it returned.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Limit": {
                "description": "Requests per minute allowed for this API key.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until the budget is fully restored.",
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "`not_found`: Nothing exists for this lookup: no company behind the reference or the domain, or no profile at that name. A definitive answer, charged at the lookup's not-found price (see GET /v1/pricing); free when it comes from the cache. `error.reason` says which answer it is where there's more than one.",
            "headers": {
              "X-Request-Id": {
                "description": "Correlation id for this request. Quote it to support; it ties the call to its charge and the data it returned.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Limit": {
                "description": "Requests per minute allowed for this API key.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until the budget is fully restored.",
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "`idempotency_key_in_use`: A request with this Idempotency-Key is still running. Retry shortly to get its stored response.",
            "headers": {
              "X-Request-Id": {
                "description": "Correlation id for this request. Quote it to support; it ties the call to its charge and the data it returned.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Limit": {
                "description": "Requests per minute allowed for this API key.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until the budget is fully restored.",
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "`idempotency_key_reused`: This Idempotency-Key was already used with a different endpoint or body.",
            "headers": {
              "X-Request-Id": {
                "description": "Correlation id for this request. Quote it to support; it ties the call to its charge and the data it returned.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Limit": {
                "description": "Requests per minute allowed for this API key.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until the budget is fully restored.",
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "`rate_limited`: Too many requests for this API key. Wait for Retry-After; RateLimit-* headers show the budget.\n\n`concurrency_limited`: Too many of this workspace's lookups are in flight. Retry after Retry-After.",
            "headers": {
              "X-Request-Id": {
                "description": "Correlation id for this request. Quote it to support; it ties the call to its charge and the data it returned.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Limit": {
                "description": "Requests per minute allowed for this API key.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until the budget is fully restored.",
                "schema": {
                  "type": "integer"
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "`internal_error`: Something failed on our side. Any charge was refunded; the request id helps us find it.",
            "headers": {
              "X-Request-Id": {
                "description": "Correlation id for this request. Quote it to support; it ties the call to its charge and the data it returned.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Limit": {
                "description": "Requests per minute allowed for this API key.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until the budget is fully restored.",
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "502": {
            "description": "`upstream_error`: The data couldn't be fetched because of an unexpected error. Refunded automatically.\n\n`parse_error`: The data was fetched but couldn't be read. We're alerted; refunded automatically.",
            "headers": {
              "X-Request-Id": {
                "description": "Correlation id for this request. Quote it to support; it ties the call to its charge and the data it returned.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Limit": {
                "description": "Requests per minute allowed for this API key.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until the budget is fully restored.",
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "`blocked`: The data couldn't be fetched right now. Refunded automatically; retry after Retry-After.\n\n`source_rate_limited`: Fetching is being slowed down right now. Refunded automatically; retry after Retry-After.\n\n`no_capacity`: We can't take new lookups right now. Rejected before charging.",
            "headers": {
              "X-Request-Id": {
                "description": "Correlation id for this request. Quote it to support; it ties the call to its charge and the data it returned.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Limit": {
                "description": "Requests per minute allowed for this API key.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until the budget is fully restored.",
                "schema": {
                  "type": "integer"
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "504": {
            "description": "`timeout`: No definitive answer arrived in time. Refunded automatically.",
            "headers": {
              "X-Request-Id": {
                "description": "Correlation id for this request. Quote it to support; it ties the call to its charge and the data it returned.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Limit": {
                "description": "Requests per minute allowed for this API key.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until the budget is fully restored.",
                "schema": {
                  "type": "integer"
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "cURL",
            "source": "curl https://api.happyfetch.net/v1/person --max-time 120 \\\n  -H \"Authorization: Bearer $HAPPYFETCH_API_KEY\" \\\n  -H \"Idempotency-Key: $(uuidgen)\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"url\":\"https://www.linkedin.com/in/jane-example\"}'"
          },
          {
            "lang": "javascript",
            "label": "JavaScript",
            "source": "const res = await fetch(\"https://api.happyfetch.net/v1/person\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.HAPPYFETCH_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n    \"Idempotency-Key\": crypto.randomUUID(), // send the same key when you retry this call\n  },\n  body: JSON.stringify({\n    \"url\": \"https://www.linkedin.com/in/jane-example\"\n  }),\n  signal: AbortSignal.timeout(120_000),\n});\nconst { data, meta, error } = await res.json();\nif (!res.ok) throw new Error(`${error.code}: ${error.message}`);\nconsole.log(meta.request_id, meta.cache.status, data);"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "import os, uuid, requests\n\nres = requests.post(\n    \"https://api.happyfetch.net/v1/person\",\n    headers={\n        \"Authorization\": f\"Bearer {os.environ['HAPPYFETCH_API_KEY']}\",\n        \"Idempotency-Key\": str(uuid.uuid4()),  # send the same key when you retry this call\n    },\n    json={\n      \"url\": \"https://www.linkedin.com/in/jane-example\"\n    },\n    timeout=120,\n)\nbody = res.json()\nif not res.ok:\n    raise RuntimeError(f\"{body['error']['code']}: {body['error']['message']}\")\nprint(body[\"meta\"][\"request_id\"], body[\"meta\"][\"cache\"][\"status\"])"
          }
        ]
      }
    },
    "/v1/search": {
      "post": {
        "operationId": "search",
        "tags": [
          "Search"
        ],
        "summary": "Search the web",
        "description": "Runs a web search and returns the results as JSON. An empty result list is a completed search and is billed. Results are cached; see `max_age`.",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "Any unique string (for example a UUID) per logical request. A retry with the same key within 24 hours replays the stored response instead of running, and charging, again.",
            "schema": {
              "type": "string",
              "maxLength": 255
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SearchRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Search results.",
            "headers": {
              "X-Request-Id": {
                "description": "Correlation id for this request. Quote it to support; it ties the call to its charge and the data it returned.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Limit": {
                "description": "Requests per minute allowed for this API key.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until the budget is fully restored.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Credits-Charged": {
                "description": "Credits charged for this call (0 when refunded or not billable).",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Credits-Remaining": {
                "description": "Workspace balance after this call.",
                "schema": {
                  "type": "integer"
                }
              },
              "X-Cache": {
                "description": "HIT, MISS or REFRESH.",
                "schema": {
                  "type": "string"
                }
              },
              "Age": {
                "description": "Seconds since the data was fetched.",
                "schema": {
                  "type": "integer"
                }
              },
              "Idempotent-Replayed": {
                "description": "`true` when this response is a stored replay of an earlier request with the same Idempotency-Key.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SearchResponse"
                }
              }
            }
          },
          "400": {
            "description": "`invalid_request`: The body isn't valid JSON or doesn't match the schema. `details` names each field.",
            "headers": {
              "X-Request-Id": {
                "description": "Correlation id for this request. Quote it to support; it ties the call to its charge and the data it returned.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Limit": {
                "description": "Requests per minute allowed for this API key.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until the budget is fully restored.",
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "`unauthorized`: The API key is missing, malformed or revoked. Send it as `Authorization: Bearer <key>` or `X-Api-Key`.",
            "headers": {
              "X-Request-Id": {
                "description": "Correlation id for this request. Quote it to support; it ties the call to its charge and the data it returned.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Limit": {
                "description": "Requests per minute allowed for this API key.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until the budget is fully restored.",
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "`insufficient_credits`: The workspace balance doesn't cover this call. Top up in the console; nothing was charged.",
            "headers": {
              "X-Request-Id": {
                "description": "Correlation id for this request. Quote it to support; it ties the call to its charge and the data it returned.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Limit": {
                "description": "Requests per minute allowed for this API key.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until the budget is fully restored.",
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "`idempotency_key_in_use`: A request with this Idempotency-Key is still running. Retry shortly to get its stored response.",
            "headers": {
              "X-Request-Id": {
                "description": "Correlation id for this request. Quote it to support; it ties the call to its charge and the data it returned.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Limit": {
                "description": "Requests per minute allowed for this API key.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until the budget is fully restored.",
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "`idempotency_key_reused`: This Idempotency-Key was already used with a different endpoint or body.",
            "headers": {
              "X-Request-Id": {
                "description": "Correlation id for this request. Quote it to support; it ties the call to its charge and the data it returned.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Limit": {
                "description": "Requests per minute allowed for this API key.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until the budget is fully restored.",
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "`rate_limited`: Too many requests for this API key. Wait for Retry-After; RateLimit-* headers show the budget.\n\n`concurrency_limited`: Too many of this workspace's lookups are in flight. Retry after Retry-After.",
            "headers": {
              "X-Request-Id": {
                "description": "Correlation id for this request. Quote it to support; it ties the call to its charge and the data it returned.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Limit": {
                "description": "Requests per minute allowed for this API key.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until the budget is fully restored.",
                "schema": {
                  "type": "integer"
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "`internal_error`: Something failed on our side. Any charge was refunded; the request id helps us find it.",
            "headers": {
              "X-Request-Id": {
                "description": "Correlation id for this request. Quote it to support; it ties the call to its charge and the data it returned.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Limit": {
                "description": "Requests per minute allowed for this API key.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until the budget is fully restored.",
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "502": {
            "description": "`upstream_error`: The data couldn't be fetched because of an unexpected error. Refunded automatically.",
            "headers": {
              "X-Request-Id": {
                "description": "Correlation id for this request. Quote it to support; it ties the call to its charge and the data it returned.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Limit": {
                "description": "Requests per minute allowed for this API key.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until the budget is fully restored.",
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "`blocked`: The data couldn't be fetched right now. Refunded automatically; retry after Retry-After.\n\n`source_rate_limited`: Fetching is being slowed down right now. Refunded automatically; retry after Retry-After.\n\n`no_capacity`: We can't take new lookups right now. Rejected before charging.",
            "headers": {
              "X-Request-Id": {
                "description": "Correlation id for this request. Quote it to support; it ties the call to its charge and the data it returned.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Limit": {
                "description": "Requests per minute allowed for this API key.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until the budget is fully restored.",
                "schema": {
                  "type": "integer"
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "504": {
            "description": "`timeout`: No definitive answer arrived in time. Refunded automatically.",
            "headers": {
              "X-Request-Id": {
                "description": "Correlation id for this request. Quote it to support; it ties the call to its charge and the data it returned.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Limit": {
                "description": "Requests per minute allowed for this API key.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until the budget is fully restored.",
                "schema": {
                  "type": "integer"
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "cURL",
            "source": "curl https://api.happyfetch.net/v1/search --max-time 120 \\\n  -H \"Authorization: Bearer $HAPPYFETCH_API_KEY\" \\\n  -H \"Idempotency-Key: $(uuidgen)\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"query\":\"stripe\",\"max_results\":5}'"
          },
          {
            "lang": "javascript",
            "label": "JavaScript",
            "source": "const res = await fetch(\"https://api.happyfetch.net/v1/search\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.HAPPYFETCH_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n    \"Idempotency-Key\": crypto.randomUUID(), // send the same key when you retry this call\n  },\n  body: JSON.stringify({\n    \"query\": \"stripe\",\n    \"max_results\": 5\n  }),\n  signal: AbortSignal.timeout(120_000),\n});\nconst { data, meta, error } = await res.json();\nif (!res.ok) throw new Error(`${error.code}: ${error.message}`);\nconsole.log(meta.request_id, meta.cache.status, data);"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "import os, uuid, requests\n\nres = requests.post(\n    \"https://api.happyfetch.net/v1/search\",\n    headers={\n        \"Authorization\": f\"Bearer {os.environ['HAPPYFETCH_API_KEY']}\",\n        \"Idempotency-Key\": str(uuid.uuid4()),  # send the same key when you retry this call\n    },\n    json={\n      \"query\": \"stripe\",\n      \"max_results\": 5\n    },\n    timeout=120,\n)\nbody = res.json()\nif not res.ok:\n    raise RuntimeError(f\"{body['error']['code']}: {body['error']['message']}\")\nprint(body[\"meta\"][\"request_id\"], body[\"meta\"][\"cache\"][\"status\"])"
          }
        ]
      }
    },
    "/v1/cache": {
      "post": {
        "operationId": "checkCache",
        "tags": [
          "Cache"
        ],
        "summary": "Check how old our copy is (free)",
        "description": "Free. Send the body you'd send to POST /v1/company (`url`) or POST /v1/domain (`domain`), with your `max_age` if you use one. The answer says whether we hold an answer for that lookup, how old it is, whether the lookup would be served from our cache, and what it would cost from cache and fetched fresh. Nothing is charged, and no data is returned.",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "Any unique string (for example a UUID) per logical request. A retry with the same key within 24 hours replays the stored response instead of running, and charging, again.",
            "schema": {
              "type": "string",
              "maxLength": 255
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CacheCheckRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "What we hold for that lookup.",
            "headers": {
              "X-Request-Id": {
                "description": "Correlation id for this request. Quote it to support; it ties the call to its charge and the data it returned.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Limit": {
                "description": "Requests per minute allowed for this API key.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until the budget is fully restored.",
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CacheCheckResponse"
                }
              }
            }
          },
          "400": {
            "description": "`invalid_request`: The body isn't valid JSON or doesn't match the schema. `details` names each field.\n\n`invalid_company_reference`: `url` isn't a LinkedIn company reference (for example a /in/ profile, a school page, or free text).\n\n`invalid_domain`: `domain` isn't a website on a public domain. Company page URLs and slugs go to POST /v1/company.",
            "headers": {
              "X-Request-Id": {
                "description": "Correlation id for this request. Quote it to support; it ties the call to its charge and the data it returned.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Limit": {
                "description": "Requests per minute allowed for this API key.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until the budget is fully restored.",
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "`unauthorized`: The API key is missing, malformed or revoked. Send it as `Authorization: Bearer <key>` or `X-Api-Key`.",
            "headers": {
              "X-Request-Id": {
                "description": "Correlation id for this request. Quote it to support; it ties the call to its charge and the data it returned.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Limit": {
                "description": "Requests per minute allowed for this API key.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until the budget is fully restored.",
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "`idempotency_key_in_use`: A request with this Idempotency-Key is still running. Retry shortly to get its stored response.",
            "headers": {
              "X-Request-Id": {
                "description": "Correlation id for this request. Quote it to support; it ties the call to its charge and the data it returned.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Limit": {
                "description": "Requests per minute allowed for this API key.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until the budget is fully restored.",
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "`idempotency_key_reused`: This Idempotency-Key was already used with a different endpoint or body.",
            "headers": {
              "X-Request-Id": {
                "description": "Correlation id for this request. Quote it to support; it ties the call to its charge and the data it returned.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Limit": {
                "description": "Requests per minute allowed for this API key.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until the budget is fully restored.",
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "`rate_limited`: Too many requests for this API key. Wait for Retry-After; RateLimit-* headers show the budget.",
            "headers": {
              "X-Request-Id": {
                "description": "Correlation id for this request. Quote it to support; it ties the call to its charge and the data it returned.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Limit": {
                "description": "Requests per minute allowed for this API key.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until the budget is fully restored.",
                "schema": {
                  "type": "integer"
                }
              },
              "Retry-After": {
                "description": "Seconds to wait before retrying.",
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "`internal_error`: Something failed on our side. Any charge was refunded; the request id helps us find it.",
            "headers": {
              "X-Request-Id": {
                "description": "Correlation id for this request. Quote it to support; it ties the call to its charge and the data it returned.",
                "schema": {
                  "type": "string"
                }
              },
              "RateLimit-Limit": {
                "description": "Requests per minute allowed for this API key.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Remaining": {
                "description": "Requests left in the current window.",
                "schema": {
                  "type": "integer"
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until the budget is fully restored.",
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "cURL",
            "source": "curl https://api.happyfetch.net/v1/cache --max-time 120 \\\n  -H \"Authorization: Bearer $HAPPYFETCH_API_KEY\" \\\n  -H \"Idempotency-Key: $(uuidgen)\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"url\":\"https://www.linkedin.com/company/stripe\"}'"
          },
          {
            "lang": "javascript",
            "label": "JavaScript",
            "source": "const res = await fetch(\"https://api.happyfetch.net/v1/cache\", {\n  method: \"POST\",\n  headers: {\n    Authorization: `Bearer ${process.env.HAPPYFETCH_API_KEY}`,\n    \"Content-Type\": \"application/json\",\n    \"Idempotency-Key\": crypto.randomUUID(), // send the same key when you retry this call\n  },\n  body: JSON.stringify({\n    \"url\": \"https://www.linkedin.com/company/stripe\"\n  }),\n  signal: AbortSignal.timeout(120_000),\n});\nconst { data, meta, error } = await res.json();\nif (!res.ok) throw new Error(`${error.code}: ${error.message}`);\nconsole.log(data.from_cache, data.price_credits, data.age_seconds);"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "import os, uuid, requests\n\nres = requests.post(\n    \"https://api.happyfetch.net/v1/cache\",\n    headers={\n        \"Authorization\": f\"Bearer {os.environ['HAPPYFETCH_API_KEY']}\",\n        \"Idempotency-Key\": str(uuid.uuid4()),  # send the same key when you retry this call\n    },\n    json={\n      \"url\": \"https://www.linkedin.com/company/stripe\"\n    },\n    timeout=120,\n)\nbody = res.json()\nif not res.ok:\n    raise RuntimeError(f\"{body['error']['code']}: {body['error']['message']}\")\nprint(body[\"data\"][\"from_cache\"], body[\"data\"][\"price_credits\"], body[\"data\"][\"age_seconds\"])"
          }
        ]
      }
    },
    "/v1/pricing": {
      "get": {
        "operationId": "getPricing",
        "tags": [
          "Meta"
        ],
        "summary": "Current prices",
        "description": "Per-call prices and credit packs, straight from the database. No authentication.",
        "security": [],
        "responses": {
          "200": {
            "description": "Prices.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    },
    "/v1/site": {
      "get": {
        "operationId": "getSite",
        "tags": [
          "Meta"
        ],
        "summary": "Website settings",
        "description": "What the website reads when it is built, next to the prices: the PostHog project key it counts page views with (cookieless), or null while analytics is off. Only public values. No authentication; cacheable for 60 seconds.",
        "security": [],
        "responses": {
          "200": {
            "description": "Website settings.",
            "headers": {
              "Cache-Control": {
                "description": "public, max-age=60",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "analytics"
                  ],
                  "additionalProperties": false,
                  "properties": {
                    "analytics": {
                      "type": [
                        "object",
                        "null"
                      ],
                      "description": "null while analytics is off.",
                      "required": [
                        "posthog_key",
                        "posthog_host"
                      ],
                      "additionalProperties": false,
                      "properties": {
                        "posthog_key": {
                          "type": "string",
                          "description": "A PostHog project API key (public, write-only).",
                          "examples": [
                            "phc_8f2Kq0abcdefghijklmnop"
                          ]
                        },
                        "posthog_host": {
                          "type": "string",
                          "format": "uri",
                          "examples": [
                            "https://eu.i.posthog.com"
                          ]
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "description": "Your API key, e.g. `hf_live_…`."
      },
      "apiKeyHeader": {
        "type": "apiKey",
        "in": "header",
        "name": "X-Api-Key"
      }
    },
    "schemas": {
      "CompanyRequest": {
        "type": "object",
        "properties": {
          "url": {
            "type": "string",
            "minLength": 1,
            "maxLength": 2048,
            "description": "Any LinkedIn company reference: a company URL (any linkedin.com subdomain, scheme optional, `/about/` and tracking parameters ignored), `company/<slug>`, a bare slug, a numeric company id, or `urn:li:organization:<id>`.",
            "examples": [
              "https://www.linkedin.com/company/stripe/",
              "stripe",
              "2135371",
              "urn:li:organization:2135371"
            ]
          },
          "max_age": {
            "type": "integer",
            "minimum": 0,
            "description": "Oldest cached result you accept, in seconds, with no upper limit: a copy of any age we still hold is served. `0` forces a fresh fetch. Defaults to the endpoint's cache TTL, listed at GET /v1/pricing."
          }
        },
        "required": [
          "url"
        ],
        "additionalProperties": false
      },
      "DomainRequest": {
        "type": "object",
        "properties": {
          "domain": {
            "type": "string",
            "minLength": 1,
            "maxLength": 2048,
            "description": "A company's website: a domain (`stripe.com`, `www.stripe.com`) or any URL on it (`https://stripe.com/pricing`). The company is looked up by the registrable domain, so every page and subdomain of one site is the same lookup.",
            "examples": [
              "stripe.com",
              "https://www.stripe.com/pricing",
              "careers.booking.com"
            ]
          },
          "max_age": {
            "type": "integer",
            "minimum": 0,
            "description": "Oldest cached result you accept, in seconds, with no upper limit: a copy of any age we still hold is served. `0` forces a fresh fetch. Defaults to the endpoint's cache TTL, listed at GET /v1/pricing."
          }
        },
        "required": [
          "domain"
        ],
        "additionalProperties": false
      },
      "PersonRequest": {
        "type": "object",
        "properties": {
          "url": {
            "type": "string",
            "minLength": 1,
            "maxLength": 2048,
            "description": "A person's LinkedIn profile: its URL on any LinkedIn host (scheme optional, query ignored), `in/<name>`, or the bare name. Member ids (`ACoAA…`) aren't accepted.",
            "examples": [
              "https://www.linkedin.com/in/jane-example",
              "jane-example"
            ]
          },
          "max_age": {
            "type": "integer",
            "minimum": 0,
            "description": "Oldest cached result you accept, in seconds, with no upper limit: a copy of any age we still hold is served. `0` forces a fresh fetch. Defaults to the endpoint's cache TTL, listed at GET /v1/pricing."
          }
        },
        "required": [
          "url"
        ],
        "additionalProperties": false
      },
      "CacheCheckRequest": {
        "type": "object",
        "properties": {
          "url": {
            "description": "A company reference, exactly as you'd send it to POST /v1/company. Send this or `domain`.",
            "examples": [
              "https://www.linkedin.com/company/stripe/",
              "2135371"
            ],
            "type": "string",
            "minLength": 1,
            "maxLength": 2048
          },
          "domain": {
            "description": "A website, exactly as you'd send it to POST /v1/domain. Send this or `url`.",
            "examples": [
              "stripe.com"
            ],
            "type": "string",
            "minLength": 1,
            "maxLength": 2048
          },
          "max_age": {
            "description": "The max_age you'd send with the lookup. Defaults to that endpoint's cache TTL.",
            "type": "integer",
            "minimum": 0
          }
        },
        "additionalProperties": false
      },
      "SearchRequest": {
        "type": "object",
        "properties": {
          "query": {
            "type": "string",
            "minLength": 1,
            "maxLength": 500,
            "description": "What to search for, as you would type it into a search engine.",
            "examples": [
              "stripe payments"
            ]
          },
          "max_results": {
            "default": 10,
            "description": "Maximum number of results (1–50).",
            "type": "integer",
            "minimum": 1,
            "maximum": 50
          },
          "region": {
            "default": "",
            "description": "Search region, like `us-en` or `nl-nl`. Leave it empty for no region.",
            "type": "string",
            "pattern": "^([a-z]{2}-[a-z]{2})?$"
          },
          "scope": {
            "default": "web",
            "type": "string",
            "enum": [
              "web",
              "linkedin_companies"
            ],
            "description": "Which results to return. Defaults to `web`."
          },
          "max_age": {
            "type": "integer",
            "minimum": 0,
            "description": "Oldest cached result you accept, in seconds, with no upper limit: a copy of any age we still hold is served. `0` forces a fresh fetch. Defaults to the endpoint's cache TTL, listed at GET /v1/pricing."
          }
        },
        "required": [
          "query"
        ],
        "additionalProperties": false
      },
      "Address": {
        "type": "object",
        "properties": {
          "city": {
            "type": [
              "string",
              "null"
            ]
          },
          "country": {
            "type": [
              "string",
              "null"
            ]
          },
          "geographicArea": {
            "type": [
              "string",
              "null"
            ]
          },
          "postalCode": {
            "type": [
              "string",
              "null"
            ]
          },
          "street1": {
            "type": [
              "string",
              "null"
            ]
          },
          "street2": {
            "type": [
              "string",
              "null"
            ]
          }
        },
        "required": [
          "city",
          "country",
          "geographicArea",
          "postalCode",
          "street1",
          "street2"
        ],
        "additionalProperties": false
      },
      "Location": {
        "type": "object",
        "properties": {
          "city": {
            "type": [
              "string",
              "null"
            ]
          },
          "country": {
            "type": [
              "string",
              "null"
            ]
          },
          "postalCode": {
            "type": [
              "string",
              "null"
            ]
          },
          "state": {
            "type": [
              "string",
              "null"
            ]
          },
          "street1": {
            "type": [
              "string",
              "null"
            ]
          },
          "street2": {
            "type": [
              "string",
              "null"
            ]
          }
        },
        "required": [
          "city",
          "country",
          "postalCode",
          "state",
          "street1",
          "street2"
        ],
        "additionalProperties": false
      },
      "Company": {
        "type": "object",
        "properties": {
          "name": {
            "type": [
              "string",
              "null"
            ]
          },
          "tagline": {
            "type": [
              "string",
              "null"
            ]
          },
          "description": {
            "type": [
              "string",
              "null"
            ]
          },
          "industry": {
            "type": [
              "string",
              "null"
            ]
          },
          "websiteUrl": {
            "type": [
              "string",
              "null"
            ]
          },
          "phone": {
            "type": [
              "string",
              "null"
            ]
          },
          "logo": {
            "type": [
              "string",
              "null"
            ]
          },
          "backgroundUrl": {
            "type": [
              "string",
              "null"
            ]
          },
          "followerCount": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ]
          },
          "employeeCount": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "Exact headcount, when available."
          },
          "employeeCountRange": {
            "anyOf": [
              {
                "type": "object",
                "properties": {
                  "start": {
                    "anyOf": [
                      {
                        "type": "integer"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  },
                  "end": {
                    "anyOf": [
                      {
                        "type": "integer"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  }
                },
                "required": [
                  "start",
                  "end"
                ],
                "additionalProperties": false
              },
              {
                "type": "null"
              }
            ]
          },
          "foundedOn": {
            "anyOf": [
              {
                "type": "object",
                "properties": {
                  "year": {
                    "anyOf": [
                      {
                        "type": "integer"
                      },
                      {
                        "type": "null"
                      }
                    ]
                  }
                },
                "required": [
                  "year"
                ],
                "additionalProperties": false
              },
              {
                "type": "null"
              }
            ]
          },
          "headquarter": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/Address"
              },
              {
                "type": "null"
              }
            ]
          },
          "locations": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Location"
            }
          },
          "specialities": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "universalName": {
            "description": "The company's canonical slug.",
            "type": [
              "string",
              "null"
            ]
          },
          "linkedInUrl": {
            "type": [
              "string",
              "null"
            ]
          },
          "linkedInId": {
            "description": "Numeric organization id, as a string.",
            "type": [
              "string",
              "null"
            ]
          }
        },
        "required": [
          "name",
          "tagline",
          "description",
          "industry",
          "websiteUrl",
          "phone",
          "logo",
          "backgroundUrl",
          "followerCount",
          "employeeCount",
          "employeeCountRange",
          "foundedOn",
          "headquarter",
          "locations",
          "specialities",
          "universalName",
          "linkedInUrl",
          "linkedInId"
        ],
        "additionalProperties": false,
        "description": "Every key is always present; a value is null when it isn't available."
      },
      "SearchResult": {
        "type": "object",
        "properties": {
          "title": {
            "type": "string"
          },
          "href": {
            "type": "string",
            "description": "The result URL."
          },
          "body": {
            "type": "string",
            "description": "The snippet."
          },
          "company": {
            "description": "Only with scope=linkedin_companies.",
            "type": "object",
            "properties": {
              "kind": {
                "type": "string",
                "enum": [
                  "slug",
                  "id"
                ]
              },
              "ref": {
                "type": "string",
                "description": "Pass this as `url` to POST /v1/company."
              },
              "url": {
                "type": "string"
              }
            },
            "required": [
              "kind",
              "ref",
              "url"
            ],
            "additionalProperties": false
          }
        },
        "required": [
          "title",
          "href",
          "body"
        ],
        "additionalProperties": false
      },
      "SearchResults": {
        "type": "object",
        "properties": {
          "results": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SearchResult"
            }
          }
        },
        "required": [
          "results"
        ],
        "additionalProperties": false
      },
      "CacheInfo": {
        "type": "object",
        "properties": {
          "status": {
            "type": "string",
            "enum": [
              "hit",
              "miss",
              "refresh"
            ],
            "description": "`hit`: served from our database. `miss`: nothing usable was cached, fetched now. `refresh`: a cached copy existed but was older than max_age, fetched now."
          },
          "age_seconds": {
            "type": "integer",
            "description": "Seconds since the data was fetched."
          },
          "fetched_at": {
            "type": "string",
            "description": "When the data was fetched (ISO 8601)."
          },
          "max_age_seconds": {
            "type": "integer",
            "description": "The freshness window that applied to this request."
          }
        },
        "required": [
          "status",
          "age_seconds",
          "fetched_at",
          "max_age_seconds"
        ],
        "additionalProperties": false
      },
      "ResponseMeta": {
        "type": "object",
        "properties": {
          "request_id": {
            "type": "string",
            "description": "Correlation id. It is also in the X-Request-Id header; support can trace everything from it."
          },
          "endpoint": {
            "type": "string",
            "enum": [
              "company",
              "search",
              "domain",
              "person"
            ]
          },
          "credits_charged": {
            "type": "integer"
          },
          "credits_remaining": {
            "type": "integer"
          },
          "cache": {
            "$ref": "#/components/schemas/CacheInfo"
          },
          "content_hash": {
            "type": "string",
            "description": "sha256 of `data`; unchanged data keeps the same hash."
          },
          "canonical": {
            "description": "Company and domain only: the canonical slug and numeric id.",
            "type": "object",
            "properties": {
              "slug": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "id": {
                "type": [
                  "string",
                  "null"
                ]
              }
            },
            "required": [
              "slug",
              "id"
            ],
            "additionalProperties": false
          },
          "resolved": {
            "description": "Domain only: which domain was resolved and whether the match is verified.",
            "type": "object",
            "properties": {
              "domain": {
                "type": "string",
                "description": "The registrable domain that was looked up, e.g. `booking.com` for `careers.booking.com`."
              },
              "verified": {
                "type": "boolean",
                "description": "`true` when the website on the company's profile is on this domain, or on the domain the site redirects to. `false` when the company was matched to this domain but its profile lists another website, such as a careers site or a parent company's."
              }
            },
            "required": [
              "domain",
              "verified"
            ],
            "additionalProperties": false
          }
        },
        "required": [
          "request_id",
          "endpoint",
          "credits_charged",
          "credits_remaining",
          "cache",
          "content_hash"
        ],
        "additionalProperties": false
      },
      "CompanyResponse": {
        "type": "object",
        "properties": {
          "data": {
            "$ref": "#/components/schemas/Company"
          },
          "meta": {
            "$ref": "#/components/schemas/ResponseMeta"
          }
        },
        "required": [
          "data",
          "meta"
        ],
        "additionalProperties": false
      },
      "Person": {
        "type": "object",
        "properties": {
          "vanityName": {
            "type": "string",
            "description": "The profile's name in its URL: `jane-example` for linkedin.com/in/jane-example."
          },
          "url": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "location": {
            "anyOf": [
              {
                "type": "object",
                "properties": {
                  "locality": {
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "country": {
                    "type": [
                      "string",
                      "null"
                    ]
                  }
                },
                "required": [
                  "locality",
                  "country"
                ],
                "additionalProperties": false
              },
              {
                "type": "null"
              }
            ]
          },
          "about": {
            "description": "The start of the About text. The headline isn't included.",
            "type": [
              "string",
              "null"
            ]
          },
          "currentEmployer": {
            "anyOf": [
              {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string"
                  },
                  "slug": {
                    "description": "The LinkedIn page's slug, or `null` when it has no page.",
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "linkedInUrl": {
                    "type": [
                      "string",
                      "null"
                    ]
                  }
                },
                "required": [
                  "name",
                  "slug",
                  "linkedInUrl"
                ],
                "additionalProperties": false
              },
              {
                "type": "null"
              }
            ],
            "description": "The first listed employer: the current job, or the latest one when none is current. `null` when there's none, or when LinkedIn masks it for anonymous visitors."
          },
          "employers": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "name": {
                  "type": "string"
                },
                "slug": {
                  "description": "The LinkedIn page's slug, or `null` when it has no page.",
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "linkedInUrl": {
                  "type": [
                    "string",
                    "null"
                  ]
                }
              },
              "required": [
                "name",
                "slug",
                "linkedInUrl"
              ],
              "additionalProperties": false
            },
            "description": "The employers LinkedIn shows anonymous visitors, in its order. Masked ones and job titles and dates aren't included: LinkedIn hides them."
          },
          "employerCount": {
            "type": "integer",
            "description": "How many employers the profile lists, masked ones included."
          },
          "education": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "name": {
                  "type": "string"
                },
                "slug": {
                  "description": "The LinkedIn page's slug, or `null` when it has no page.",
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "linkedInUrl": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "startYear": {
                  "anyOf": [
                    {
                      "type": "integer"
                    },
                    {
                      "type": "null"
                    }
                  ]
                },
                "endYear": {
                  "anyOf": [
                    {
                      "type": "integer"
                    },
                    {
                      "type": "null"
                    }
                  ]
                }
              },
              "required": [
                "name",
                "slug",
                "linkedInUrl",
                "startYear",
                "endYear"
              ],
              "additionalProperties": false
            }
          },
          "schoolCount": {
            "type": "integer",
            "description": "How many schools the profile lists, masked ones included."
          },
          "followers": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ]
          }
        },
        "required": [
          "vanityName",
          "url",
          "name",
          "location",
          "about",
          "currentEmployer",
          "employers",
          "employerCount",
          "education",
          "schoolCount",
          "followers"
        ],
        "additionalProperties": false
      },
      "PersonResponse": {
        "type": "object",
        "properties": {
          "data": {
            "$ref": "#/components/schemas/Person"
          },
          "meta": {
            "$ref": "#/components/schemas/ResponseMeta"
          }
        },
        "required": [
          "data",
          "meta"
        ],
        "additionalProperties": false
      },
      "CacheCheck": {
        "type": "object",
        "properties": {
          "lookup": {
            "type": "string",
            "enum": [
              "company",
              "domain"
            ],
            "description": "The lookup this is about: POST /v1/company (`url`) or POST /v1/domain (`domain`)."
          },
          "cached": {
            "type": "boolean",
            "description": "Whether we hold an answer for it."
          },
          "answer": {
            "anyOf": [
              {
                "type": "string",
                "enum": [
                  "company",
                  "not_found"
                ]
              },
              {
                "type": "null"
              }
            ],
            "description": "What we hold: a company profile, or the answer that there is none. `null` when nothing is cached."
          },
          "fetched_at": {
            "description": "When that answer was fetched (ISO 8601), or `null`.",
            "type": [
              "string",
              "null"
            ]
          },
          "age_seconds": {
            "anyOf": [
              {
                "type": "integer"
              },
              {
                "type": "null"
              }
            ],
            "description": "How old that answer is, in seconds (86400 is a day), or `null`."
          },
          "max_age_seconds": {
            "type": "integer",
            "description": "The oldest answer the lookup accepts: your `max_age`, or its default cache TTL."
          },
          "from_cache": {
            "type": "boolean",
            "description": "Whether the lookup, sent now with this body, would be answered from our cache."
          },
          "price_credits": {
            "type": "integer",
            "description": "What that lookup costs now: the cache price, `0` for a not-found from the cache, or the fetch price (a not-found found then costs the not-found price)."
          },
          "fetch_price_credits": {
            "type": "integer",
            "description": "What the lookup costs fetched fresh, with `max_age: 0`."
          }
        },
        "required": [
          "lookup",
          "cached",
          "answer",
          "fetched_at",
          "age_seconds",
          "max_age_seconds",
          "from_cache",
          "price_credits",
          "fetch_price_credits"
        ],
        "additionalProperties": false
      },
      "FreeMeta": {
        "type": "object",
        "properties": {
          "request_id": {
            "type": "string",
            "description": "Correlation id, also in the X-Request-Id header."
          },
          "endpoint": {
            "type": "string",
            "enum": [
              "cache"
            ]
          },
          "credits_charged": {
            "type": "integer",
            "description": "Always `0`: this endpoint is free."
          },
          "credits_remaining": {
            "type": "integer"
          }
        },
        "required": [
          "request_id",
          "endpoint",
          "credits_charged",
          "credits_remaining"
        ],
        "additionalProperties": false
      },
      "CacheCheckResponse": {
        "type": "object",
        "properties": {
          "data": {
            "$ref": "#/components/schemas/CacheCheck"
          },
          "meta": {
            "$ref": "#/components/schemas/FreeMeta"
          }
        },
        "required": [
          "data",
          "meta"
        ],
        "additionalProperties": false
      },
      "SearchResponse": {
        "type": "object",
        "properties": {
          "data": {
            "$ref": "#/components/schemas/SearchResults"
          },
          "meta": {
            "$ref": "#/components/schemas/ResponseMeta"
          }
        },
        "required": [
          "data",
          "meta"
        ],
        "additionalProperties": false
      },
      "Error": {
        "type": "object",
        "properties": {
          "error": {
            "type": "object",
            "properties": {
              "type": {
                "type": "string",
                "enum": [
                  "invalid_request_error",
                  "authentication_error",
                  "billing_error",
                  "not_found_error",
                  "idempotency_error",
                  "rate_limit_error",
                  "upstream_error",
                  "api_error"
                ]
              },
              "code": {
                "type": "string",
                "enum": [
                  "invalid_request",
                  "invalid_person_reference",
                  "invalid_domain",
                  "invalid_company_reference",
                  "unauthorized",
                  "insufficient_credits",
                  "not_found",
                  "unresolvable_id",
                  "route_not_found",
                  "idempotency_key_in_use",
                  "idempotency_key_reused",
                  "rate_limited",
                  "concurrency_limited",
                  "upstream_error",
                  "parse_error",
                  "blocked",
                  "source_rate_limited",
                  "no_capacity",
                  "timeout",
                  "internal_error"
                ]
              },
              "message": {
                "type": "string"
              },
              "retryable": {
                "type": "boolean"
              },
              "doc_url": {
                "type": "string"
              },
              "retry_after_seconds": {
                "type": "integer"
              },
              "reason": {
                "description": "POST /v1/domain `not_found` only: `no_website` when no website answers at the domain and no company page lists it (often a mistyped domain), `no_linkedin_page` when the website exists but has no company page.",
                "type": "string",
                "enum": [
                  "no_website",
                  "no_linkedin_page"
                ]
              },
              "details": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "field": {
                      "type": "string"
                    },
                    "message": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "field",
                    "message"
                  ],
                  "additionalProperties": false
                }
              }
            },
            "required": [
              "type",
              "code",
              "message",
              "retryable",
              "doc_url"
            ],
            "additionalProperties": false
          },
          "meta": {
            "type": "object",
            "properties": {
              "request_id": {
                "type": "string"
              },
              "credits_charged": {
                "type": "integer"
              },
              "credits_remaining": {
                "anyOf": [
                  {
                    "type": "integer"
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "cache": {
                "$ref": "#/components/schemas/CacheInfo"
              }
            },
            "required": [
              "request_id",
              "credits_charged",
              "credits_remaining"
            ],
            "additionalProperties": false
          }
        },
        "required": [
          "error",
          "meta"
        ],
        "additionalProperties": false
      }
    }
  }
}