{"openapi":"3.1.0","info":{"title":"Reqbeat API","termsOfService":"https://reqbeat.com/terms","contact":{"name":"Reqbeat support","url":"https://reqbeat.com/","email":"support@reqbeat.com"},"version":"0.1.0","x-logo":{"url":"https://reqbeat.com/assets/mcp/logo-400.png","altText":"Reqbeat"}},"servers":[{"url":"https://api.reqbeat.com"}],"paths":{"/v1/whoami":{"get":{"summary":"What your API key resolves to","description":"What the presented key resolves to. The response can only ever reflect\nthe presented key's own customer, never another's.","operationId":"whoami_v1_whoami_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WhoamiResponse"}}}},"401":{"description":"No API key was sent, or the key is not valid.","content":{"application/json":{"schema":{"type":"object","required":["detail"],"properties":{"detail":{"type":"string"}}}}}}},"security":[{"APIKeyHeader":[]}]}},"/v1/quickstart":{"post":{"summary":"Get started in five minutes","description":"5-min quickstart: curl/Python/TS/MCP/Clay snippets with the caller's\nown live key injected, plus an auto-created watch on a high-motion\ncompany on `body.webhook_url` so a webhook fires shortly after signup.\nNot billable -- getting started must never cost quota. Idempotent:\nre-opening the quickstart never mints a second watch or webhook\nendpoint.","operationId":"quickstart_v1_quickstart_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuickstartRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuickstartResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"401":{"description":"No API key was sent, or the key is not valid.","content":{"application/json":{"schema":{"type":"object","required":["detail"],"properties":{"detail":{"type":"string"}}}}}}},"security":[{"APIKeyHeader":[]}]}},"/v1/onboarding":{"get":{"summary":"Guided watch and webhook onboarding","description":"Guided watch/webhook onboarding flow: first watch -> first signed\nwebhook delivered -> the 80%-quota expansion nudge. Not billable, same\nas `/quickstart`. Idempotent: re-polling never mints a second watch or\nendpoint and never double-counts a delivery.","operationId":"onboarding_v1_onboarding_get","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"webhook_url","in":"query","required":true,"schema":{"type":"string","description":"Your HTTPS endpoint that will receive signed webhook deliveries for the watch this flow registers.","title":"Webhook Url"},"description":"Your HTTPS endpoint that will receive signed webhook deliveries for the watch this flow registers."},{"name":"domain","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Company website domain to watch, e.g. 'stripe.com'. Omit to get the onboarding steps without resolving a company.","title":"Domain"},"description":"Company website domain to watch, e.g. 'stripe.com'. Omit to get the onboarding steps without resolving a company."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OnboardingResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"401":{"description":"No API key was sent, or the key is not valid.","content":{"application/json":{"schema":{"type":"object","required":["detail"],"properties":{"detail":{"type":"string"}}}}}}}}},"/v1/keys":{"get":{"summary":"List your API keys","description":"Account-scoped key listing -- every key (active and revoked) for the\ncaller's own customer, with `last_used_at` from the usage ledger.","operationId":"list_keys_route_v1_keys_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/KeyListResponse"}}}},"401":{"description":"No API key was sent, or the key is not valid.","content":{"application/json":{"schema":{"type":"object","required":["detail"],"properties":{"detail":{"type":"string"}}}}}}},"security":[{"APIKeyHeader":[]}]},"post":{"summary":"Issue a new API key","description":"Self-serve key issuance: a developer who already holds one key can mint\nanother for their OWN account -- no operator step. `scopes` is the only\nfield the request body carries.\n\nThe new key's customer AND its tier are both taken from the AUTHENTICATED\ncaller's own key, never from the request, so a key can never be issued for\nanother tenant nor carry more entitlement than the key that authorized it.\nSending a `tier` is rejected with a 422 rather than ignored. To change your\ntier, change your plan -- the new tier then applies to every key on the\naccount.\n\nThe mint also inherits the parent key's acquisition surface, exactly as\nrotation carries it forward: an additional self-serve mint is the same\nacquisition, and the same entitlement, as the key that authorized it.","operationId":"create_key_v1_keys_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IssueKeyRequest"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IssueKeyResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"401":{"description":"No API key was sent, or the key is not valid.","content":{"application/json":{"schema":{"type":"object","required":["detail"],"properties":{"detail":{"type":"string"}}}}}}},"security":[{"APIKeyHeader":[]}]}},"/v1/keys/{key_id}":{"delete":{"summary":"Revoke an API key","description":"Self-serve key revocation, scoped to the caller's own customer --\nrevoking another tenant's key id 404s, identical to revoking one that\ndoesn't exist at all (fail-fast, no cross-tenant leak).","operationId":"delete_key_v1_keys__key_id__delete","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"key_id","in":"path","required":true,"schema":{"type":"integer","description":"The API key's id, as returned by GET /v1/keys.","title":"Key Id"},"description":"The API key's id, as returned by GET /v1/keys."}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"401":{"description":"No API key was sent, or the key is not valid.","content":{"application/json":{"schema":{"type":"object","required":["detail"],"properties":{"detail":{"type":"string"}}}}}}}}},"/v1/keys/{key_id}/rotate":{"post":{"summary":"Rotate an API key","description":"Agent-driven key rotation: mints a replacement key bound to the SAME\naccount and revokes `key_id` in one call -- an autonomous agent rotates\nits own credential without an operator or a human seat in the loop, so\nusage keeps billing to the account. Scoped to the caller's own\ncustomer; `key_id` need not be the presented key. 404 for an id that\ndoesn't exist, belongs to another tenant, or is already revoked --\nindistinguishable, same as `delete_key`.","operationId":"rotate_key_route_v1_keys__key_id__rotate_post","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"key_id","in":"path","required":true,"schema":{"type":"integer","description":"The API key's id, as returned by GET /v1/keys.","title":"Key Id"},"description":"The API key's id, as returned by GET /v1/keys."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RotateKeyRequest"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IssueKeyResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"401":{"description":"No API key was sent, or the key is not valid.","content":{"application/json":{"schema":{"type":"object","required":["detail"],"properties":{"detail":{"type":"string"}}}}}}}}},"/v1/usage":{"get":{"summary":"Your metered usage over a rolling window","description":"Metered usage for the caller's customer over a rolling window --\n`window` is hours (default 24). Aggregates across every key the\ncustomer holds, not just the one presented on this call.\n\n`keys[]` splits those same totals per key, so a customer holding one\nkey per environment (or per client) can attribute its spend. It lists\nthe keys with at least one metered event in the window, ascending by\n`key_id`; each of the five totals sums across `keys[]` to the\ncustomer-level number printed beside it.","operationId":"get_usage_v1_usage_get","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"window","in":"query","required":false,"schema":{"type":"integer","description":"Rolling look-back window in HOURS for the returned usage totals.","default":24,"title":"Window"},"description":"Rolling look-back window in HOURS for the returned usage totals."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UsageResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"401":{"description":"No API key was sent, or the key is not valid.","content":{"application/json":{"schema":{"type":"object","required":["detail"],"properties":{"detail":{"type":"string"}}}}}}}}},"/v1/usage/dashboard":{"get":{"summary":"Your usage and billing dashboard","description":"Usage & billing dashboard: per-key usage vs quota (green/amber/red),\nthe account's spend-cap status, an in-context 402 upgrade prompt when\neither is exhausted, and the 80%-quota expansion nudge -- every number\nread off the same meter enforced at request time. Not billable: reading\nthe dashboard must never itself cost quota.\n\n`free_tier` reports the free allowance and how much of it this billing\nmonth has spent (null for an account holding no free key, which neither\nfree wall can bind). `blocked_deliveries` counts the changes we DECIDED not\nto send you since that period began, per reason: `wall_blocked` is the free\nmonthly change allowance, `cap_blocked` is your own spend cap. Both are\nterminal and are never retried, so a non-zero count is why a watch has gone\nquiet -- as distinct from nobody hiring.","operationId":"usage_dashboard_v1_usage_dashboard_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UsageDashboardResponse"}}}},"401":{"description":"No API key was sent, or the key is not valid.","content":{"application/json":{"schema":{"type":"object","required":["detail"],"properties":{"detail":{"type":"string"}}}}}}},"security":[{"APIKeyHeader":[]}]}},"/v1/account/pause":{"post":{"summary":"Pause your account's metering","description":"Pause-instead-of-cancel: suspends metering for the caller's OWN account\n-- every billable route 403s with `account_paused` until resumed.\nWatches are untouched.","operationId":"pause_account_route_v1_account_pause_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AccountPauseResponse"}}}},"401":{"description":"No API key was sent, or the key is not valid.","content":{"application/json":{"schema":{"type":"object","required":["detail"],"properties":{"detail":{"type":"string"}}}}}}},"security":[{"APIKeyHeader":[]}]}},"/v1/account/resume":{"post":{"summary":"Resume a paused account","description":"Resume a paused account -- the next billable call the caller's keys\nmake is enforced normally again.","operationId":"resume_account_route_v1_account_resume_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AccountPauseResponse"}}}},"401":{"description":"No API key was sent, or the key is not valid.","content":{"application/json":{"schema":{"type":"object","required":["detail"],"properties":{"detail":{"type":"string"}}}}}}},"security":[{"APIKeyHeader":[]}]}},"/v1/companies/{company_id}/is-hiring":{"get":{"summary":"Is this company hiring?","description":"Cheap is-hiring gate -- LinkedIn-excluded (ATS tenants plus public job boards and aggregators),\nfreshness-floored: qualifies a\ncompany before an agent spends on a richer call. A free-tier account\npast its cost-to-serve cap degrades to a demand-signal-only path,\nreturning `202 {status: \"over_cap\"}` instead of a served read -- the\nsame convention as the cold-tail `202 {job_id, status: \"crawling\"}`.","operationId":"get_company_is_hiring_v1_companies__company_id__is_hiring_get","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"company_id","in":"path","required":true,"schema":{"type":"integer","description":"The plane's company id -- returned as `company_id` by /v1/reqs/search and by every company motion response.","title":"Company Id"},"description":"The plane's company id -- returned as `company_id` by /v1/reqs/search and by every company motion response."},{"name":"Idempotency-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Idempotency-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Get Company Is Hiring V1 Companies  Company Id  Is Hiring Get"}}},"headers":{"RateLimit-Limit":{"description":"Calls allowed in one 60-second window.","schema":{"type":"integer","minimum":1}},"RateLimit-Remaining":{"description":"Calls left in the current window, after this one.","schema":{"type":"integer","minimum":0}},"RateLimit-Reset":{"description":"Whole seconds until the current window ends.","schema":{"type":"integer","minimum":1}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"402":{"description":"The key is over its plan's rolling call quota, or the account is past its spend cap. `upgrade_url` and `purchase_url` are the ways out.","content":{"application/json":{"schema":{"type":"object","required":["detail"],"properties":{"detail":{"type":"object","required":["reason","endpoint"],"properties":{"reason":{"type":"string","description":"`quota_exceeded` or `spend_cap_exceeded`."},"quota":{"type":"object","properties":{"limit":{"type":"integer"},"used":{"type":"integer"},"reset":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}]}}},"upgrade_url":{"type":"string"},"purchase_url":{"type":"string"},"endpoint":{"type":"string"}}}}}}}},"429":{"description":"Too many calls in the current 60-second window. The limit is per API key, set by the key's plan, and shared by every metered REST route and MCP tool; the shared demo key is limited per IP address instead. Wait `Retry-After` seconds and retry. The `RateLimit-*` headers are absent when `reason` is `key_throttled`.","headers":{"Retry-After":{"description":"Whole seconds until the current 60-second window ends and the call can be retried. Absent when `reason` is `key_throttled`.","schema":{"type":"integer","minimum":1}},"RateLimit-Limit":{"description":"Calls allowed in one 60-second window.","schema":{"type":"integer","minimum":1}},"RateLimit-Remaining":{"description":"Calls left in the current window, after this one.","schema":{"type":"integer","minimum":0}},"RateLimit-Reset":{"description":"Whole seconds until the current window ends.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"type":"object","required":["detail"],"properties":{"detail":{"type":"object","required":["reason","endpoint"],"properties":{"reason":{"type":"string","enum":["rate_limited","key_throttled"]},"endpoint":{"type":"string"},"signup_url":{"type":"string","description":"Only on the shared demo key's limit."}}}}}}}},"401":{"description":"No API key was sent, or the key is not valid.","content":{"application/json":{"schema":{"type":"object","required":["detail"],"properties":{"detail":{"type":"string"}}}}}}}}},"/v1/companies/{company_id}/open-reqs":{"get":{"summary":"A company's open reqs, deduped across boards","description":"The company's current active reqs, deduped across boards --\nLinkedIn-excluded: ATS tenants plus public job boards and aggregators; each\nrow's `boards` names its source. Freshness-floored. The same real req posted on two\nboards appears once, with both boards listed.\n\nAn unresolvable `function` -- anything that is not a function taxonomy\nid -- is rejected with 422 instead of returning a silently-empty\nresult. `limit` is bounded: an oversized page is rejected with 422\nrather than truncated.","operationId":"get_company_open_reqs_v1_companies__company_id__open_reqs_get","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"company_id","in":"path","required":true,"schema":{"type":"integer","description":"The plane's company id -- returned as `company_id` by /v1/reqs/search and by every company motion response.","title":"Company Id"},"description":"The plane's company id -- returned as `company_id` by /v1/reqs/search and by every company motion response."},{"name":"function","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter to one function: its name as served in `function_name`, e.g. 'Software & IT', or its taxonomy id as served in `function`, e.g. '54f81306-3000-5c4a-a088-dca4350b19ff'. A name covers every function id that serves it; an id matches that one id. Anything else is rejected with 422, which lists the names.","title":"Function"},"description":"Filter to one function: its name as served in `function_name`, e.g. 'Software & IT', or its taxonomy id as served in `function`, e.g. '54f81306-3000-5c4a-a088-dca4350b19ff'. A name covers every function id that serves it; an id matches that one id. Anything else is rejected with 422, which lists the names."},{"name":"country","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter to one country by name, e.g. 'United States'. Matched against the geocoder's pinned country list.","title":"Country"},"description":"Filter to one country by name, e.g. 'United States'. Matched against the geocoder's pinned country list."},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","description":"Maximum reqs to return. An out-of-range value is rejected with 422 rather than silently truncated.","default":50,"title":"Limit"},"description":"Maximum reqs to return. An out-of-range value is rejected with 422 rather than silently truncated."},{"name":"Idempotency-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Idempotency-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpenReqsResponse"}}},"headers":{"RateLimit-Limit":{"description":"Calls allowed in one 60-second window.","schema":{"type":"integer","minimum":1}},"RateLimit-Remaining":{"description":"Calls left in the current window, after this one.","schema":{"type":"integer","minimum":0}},"RateLimit-Reset":{"description":"Whole seconds until the current window ends.","schema":{"type":"integer","minimum":1}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"402":{"description":"The key is over its plan's rolling call quota, or the account is past its spend cap. `upgrade_url` and `purchase_url` are the ways out.","content":{"application/json":{"schema":{"type":"object","required":["detail"],"properties":{"detail":{"type":"object","required":["reason","endpoint"],"properties":{"reason":{"type":"string","description":"`quota_exceeded` or `spend_cap_exceeded`."},"quota":{"type":"object","properties":{"limit":{"type":"integer"},"used":{"type":"integer"},"reset":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}]}}},"upgrade_url":{"type":"string"},"purchase_url":{"type":"string"},"endpoint":{"type":"string"}}}}}}}},"429":{"description":"Too many calls in the current 60-second window. The limit is per API key, set by the key's plan, and shared by every metered REST route and MCP tool; the shared demo key is limited per IP address instead. Wait `Retry-After` seconds and retry. The `RateLimit-*` headers are absent when `reason` is `key_throttled`.","headers":{"Retry-After":{"description":"Whole seconds until the current 60-second window ends and the call can be retried. Absent when `reason` is `key_throttled`.","schema":{"type":"integer","minimum":1}},"RateLimit-Limit":{"description":"Calls allowed in one 60-second window.","schema":{"type":"integer","minimum":1}},"RateLimit-Remaining":{"description":"Calls left in the current window, after this one.","schema":{"type":"integer","minimum":0}},"RateLimit-Reset":{"description":"Whole seconds until the current window ends.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"type":"object","required":["detail"],"properties":{"detail":{"type":"object","required":["reason","endpoint"],"properties":{"reason":{"type":"string","enum":["rate_limited","key_throttled"]},"endpoint":{"type":"string"},"signup_url":{"type":"string","description":"Only on the shared demo key's limit."}}}}}}}},"401":{"description":"No API key was sent, or the key is not valid.","content":{"application/json":{"schema":{"type":"object","required":["detail"],"properties":{"detail":{"type":"string"}}}}}}}}},"/v1/companies/{company_id}/enrichment":{"get":{"summary":"Company firmographics from ATS and job boards","description":"Basic ATS/board-derived company firmographics -- no LinkedIn-derived\nfield ever appears here by construction. Freshness-floored: `boards`\nonly reflects ATS/board sources observed at or before the floor cutoff.","operationId":"get_company_enrichment_v1_companies__company_id__enrichment_get","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"company_id","in":"path","required":true,"schema":{"type":"integer","description":"The plane's company id -- returned as `company_id` by /v1/reqs/search and by every company motion response.","title":"Company Id"},"description":"The plane's company id -- returned as `company_id` by /v1/reqs/search and by every company motion response."},{"name":"Idempotency-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Idempotency-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompanyEnrichmentResponse"}}},"headers":{"RateLimit-Limit":{"description":"Calls allowed in one 60-second window.","schema":{"type":"integer","minimum":1}},"RateLimit-Remaining":{"description":"Calls left in the current window, after this one.","schema":{"type":"integer","minimum":0}},"RateLimit-Reset":{"description":"Whole seconds until the current window ends.","schema":{"type":"integer","minimum":1}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"402":{"description":"The key is over its plan's rolling call quota, or the account is past its spend cap. `upgrade_url` and `purchase_url` are the ways out.","content":{"application/json":{"schema":{"type":"object","required":["detail"],"properties":{"detail":{"type":"object","required":["reason","endpoint"],"properties":{"reason":{"type":"string","description":"`quota_exceeded` or `spend_cap_exceeded`."},"quota":{"type":"object","properties":{"limit":{"type":"integer"},"used":{"type":"integer"},"reset":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}]}}},"upgrade_url":{"type":"string"},"purchase_url":{"type":"string"},"endpoint":{"type":"string"}}}}}}}},"429":{"description":"Too many calls in the current 60-second window. The limit is per API key, set by the key's plan, and shared by every metered REST route and MCP tool; the shared demo key is limited per IP address instead. Wait `Retry-After` seconds and retry. The `RateLimit-*` headers are absent when `reason` is `key_throttled`.","headers":{"Retry-After":{"description":"Whole seconds until the current 60-second window ends and the call can be retried. Absent when `reason` is `key_throttled`.","schema":{"type":"integer","minimum":1}},"RateLimit-Limit":{"description":"Calls allowed in one 60-second window.","schema":{"type":"integer","minimum":1}},"RateLimit-Remaining":{"description":"Calls left in the current window, after this one.","schema":{"type":"integer","minimum":0}},"RateLimit-Reset":{"description":"Whole seconds until the current window ends.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"type":"object","required":["detail"],"properties":{"detail":{"type":"object","required":["reason","endpoint"],"properties":{"reason":{"type":"string","enum":["rate_limited","key_throttled"]},"endpoint":{"type":"string"},"signup_url":{"type":"string","description":"Only on the shared demo key's limit."}}}}}}}},"401":{"description":"No API key was sent, or the key is not valid.","content":{"application/json":{"schema":{"type":"object","required":["detail"],"properties":{"detail":{"type":"string"}}}}}}}}},"/v1/companies/{company_id}/hiring-pulse":{"get":{"summary":"A company's hiring velocity and momentum","description":"A company's hiring velocity/direction/momentum in one call -- the first\npaid route, honoring `max_age` (seconds). Cold (no ATS/board data at\nall, and `max_age` demands freshness beyond nothing) returns `202\n{job_id, status: \"crawling\"}` instead of a synchronous body.","operationId":"get_company_hiring_pulse_v1_companies__company_id__hiring_pulse_get","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"company_id","in":"path","required":true,"schema":{"type":"integer","description":"The plane's company id -- returned as `company_id` by /v1/reqs/search and by every company motion response.","title":"Company Id"},"description":"The plane's company id -- returned as `company_id` by /v1/reqs/search and by every company motion response."},{"name":"max_age","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"Maximum acceptable data age in SECONDS. A company with no data fresh enough returns 202 {job_id, status: 'crawling'} instead of a pulse body.","title":"Max Age"},"description":"Maximum acceptable data age in SECONDS. A company with no data fresh enough returns 202 {job_id, status: 'crawling'} instead of a pulse body."},{"name":"Idempotency-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Idempotency-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}},"headers":{"RateLimit-Limit":{"description":"Calls allowed in one 60-second window.","schema":{"type":"integer","minimum":1}},"RateLimit-Remaining":{"description":"Calls left in the current window, after this one.","schema":{"type":"integer","minimum":0}},"RateLimit-Reset":{"description":"Whole seconds until the current window ends.","schema":{"type":"integer","minimum":1}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"402":{"description":"The key is over its plan's rolling call quota, or the account is past its spend cap. `upgrade_url` and `purchase_url` are the ways out.","content":{"application/json":{"schema":{"type":"object","required":["detail"],"properties":{"detail":{"type":"object","required":["reason","endpoint"],"properties":{"reason":{"type":"string","description":"`quota_exceeded` or `spend_cap_exceeded`."},"quota":{"type":"object","properties":{"limit":{"type":"integer"},"used":{"type":"integer"},"reset":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}]}}},"upgrade_url":{"type":"string"},"purchase_url":{"type":"string"},"endpoint":{"type":"string"}}}}}}}},"429":{"description":"Too many calls in the current 60-second window. The limit is per API key, set by the key's plan, and shared by every metered REST route and MCP tool; the shared demo key is limited per IP address instead. Wait `Retry-After` seconds and retry. The `RateLimit-*` headers are absent when `reason` is `key_throttled`.","headers":{"Retry-After":{"description":"Whole seconds until the current 60-second window ends and the call can be retried. Absent when `reason` is `key_throttled`.","schema":{"type":"integer","minimum":1}},"RateLimit-Limit":{"description":"Calls allowed in one 60-second window.","schema":{"type":"integer","minimum":1}},"RateLimit-Remaining":{"description":"Calls left in the current window, after this one.","schema":{"type":"integer","minimum":0}},"RateLimit-Reset":{"description":"Whole seconds until the current window ends.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"type":"object","required":["detail"],"properties":{"detail":{"type":"object","required":["reason","endpoint"],"properties":{"reason":{"type":"string","enum":["rate_limited","key_throttled"]},"endpoint":{"type":"string"},"signup_url":{"type":"string","description":"Only on the shared demo key's limit."}}}}}}}},"401":{"description":"No API key was sent, or the key is not valid.","content":{"application/json":{"schema":{"type":"object","required":["detail"],"properties":{"detail":{"type":"string"}}}}}}}}},"/v1/reqs/search":{"get":{"summary":"Find companies hiring for a role","description":"Reverse who's-hiring-for {role, geo}: companies with active reqs\nmatching `q` (posting title) / `geo` (country) / `since` (first-seen\nlower bound), deduped by company, each with its full hiring pulse and\nthe specific reqs that matched. LinkedIn-excluded: ATS tenants plus public job boards and aggregators; each matched req's `boards` names its\nsource. `since` and each req's `first_seen` are our first observation of\nthe req, not the employer's posting date. Freshness-floored on the\nfree tier only (by when a req was first seen), keyset-paginated via `next_cursor` (the last page's highest\n`company_id`).\n\n`q` is a full-text query over the raw posting title, not an id: type\nthe role the way a posting would spell it (`staff engineer`), every\nword must match -- plurals and other inflections included, so\n`staff engineers` is the same search -- and a title that matches nothing\ncomes back as an empty page rather than an error. `role` is its deprecated\nformer name, still accepted until its `Sunset` date. The two filters are deliberately asymmetric\n-- an unresolvable `geo` IS rejected with 422, because a country either\nis or is not in the stored vocabulary, whereas an unmatched title is an\nhonest zero result.\n\n`geo`, `industry`, `industry_terms` and `headcount_band` can each be\nrepeated: repeat a parameter to OR its values; different parameters AND.\nEvery other parameter takes one value, and repeating it is rejected with\n422. `industry`, `industry_terms` and `headcount_band` cut the corpus down\nto your ICP's companies. They are filters only -- no company facet is added to the\nresponse by passing one -- and a company whose fact we do not hold is never\nmatched, so a cut is honestly narrow rather than quietly padded.\n\n`limit` is bounded: this endpoint meters the billed `source_row` atom\noff its own serialized rows, so an unbounded page is an unbounded\ninvoice. An out-of-range `limit` is rejected with 422 rather than\nsilently truncated; page through the full set with `next_cursor`. The\nshared public demo key gets a tighter page instead -- it bills nothing,\nso no ledger-derived gate can bound it, and a full-size page would make\na world-readable credential a bulk-export window onto the fresh index.","operationId":"get_reqs_search_v1_reqs_search_get","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"q","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Full-text query over the raw posting title, e.g. 'staff engineer'. Every word must match, in any order, case-insensitively. Plurals and other inflections match, so 'engineers' finds 'engineer'. Omit to search every open req. A title that matches nothing returns an empty page rather than an error.","title":"Q"},"description":"Full-text query over the raw posting title, e.g. 'staff engineer'. Every word must match, in any order, case-insensitively. Plurals and other inflections match, so 'engineers' finds 'engineer'. Omit to search every open req. A title that matches nothing returns an empty page rather than an error."},{"name":"role","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Deprecated former name of `q`, accepted until 2026-11-09 and answered exactly as `q` would be. A call that uses it carries `Deprecation` and `Sunset` response headers. Send `q` instead; sending both is rejected with 422.","deprecated":true,"title":"Role"},"description":"Deprecated former name of `q`, accepted until 2026-11-09 and answered exactly as `q` would be. A call that uses it carries `Deprecation` and `Sunset` response headers. Send `q` instead; sending both is rejected with 422.","deprecated":true},{"name":"geo","in":"query","required":false,"schema":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}],"description":"Country name to restrict the search to, e.g. 'United States'. Repeat it to search several countries at once. Matched against the geocoder's pinned country list; a country that cannot resolve is rejected with 422 rather than answered emptily.","title":"Geo"},"description":"Country name to restrict the search to, e.g. 'United States'. Repeat it to search several countries at once. Matched against the geocoder's pinned country list; a country that cannot resolve is rejected with 422 rather than answered emptily."},{"name":"since","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"description":"ISO-8601 timestamp lower bound on `first_seen` -- our first observation of the req, not the employer's posting date -- e.g. '2026-01-01T00:00:00Z'. Omit for no lower bound.","title":"Since"},"description":"ISO-8601 timestamp lower bound on `first_seen` -- our first observation of the req, not the employer's posting date -- e.g. '2026-01-01T00:00:00Z'. Omit for no lower bound."},{"name":"source_type","in":"query","required":false,"schema":{"anyOf":[{"enum":["ats_tenant","board"],"type":"string"},{"type":"null"}],"description":"Keep only reqs read from one kind of source: 'ats_tenant' (the employer's own applicant tracking system) or 'board' (a job board or aggregator). Matches each req's `source_type`. Omit to search both, which is the default; any other value is rejected with 422.","title":"Source Type"},"description":"Keep only reqs read from one kind of source: 'ats_tenant' (the employer's own applicant tracking system) or 'board' (a job board or aggregator). Matches each req's `source_type`. Omit to search both, which is the default; any other value is rejected with 422."},{"name":"exclude_agencies","in":"query","required":false,"schema":{"type":"boolean","description":"Drop companies we have positively classified as a middleman — a staffing agency, job aggregator, subcontractor network or job board. A company whose kind we have not determined is KEPT, not dropped: this is a veto on proven intermediation, never a filter down to proven direct employers, so an unclassified company can never disappear from your results for want of a classification.","default":false,"title":"Exclude Agencies"},"description":"Drop companies we have positively classified as a middleman — a staffing agency, job aggregator, subcontractor network or job board. A company whose kind we have not determined is KEPT, not dropped: this is a veto on proven intermediation, never a filter down to proven direct employers, so an unclassified company can never disappear from your results for want of a classification."},{"name":"industry","in":"query","required":false,"schema":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}],"description":"Company industry, matched exactly (case-insensitively), e.g. 'software development'. Repeat for an OR-set. The stored vocabulary is granular -- 'software development', 'computer software' and 'it services and it consulting' are three separate labels -- so prefer `industry_terms` unless you know the exact label you want. A company whose industry we do not hold is never matched.","title":"Industry"},"description":"Company industry, matched exactly (case-insensitively), e.g. 'software development'. Repeat for an OR-set. The stored vocabulary is granular -- 'software development', 'computer software' and 'it services and it consulting' are three separate labels -- so prefer `industry_terms` unless you know the exact label you want. A company whose industry we do not hold is never matched."},{"name":"headcount_band","in":"query","required":false,"schema":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}],"description":"Company size band: one of '1-10', '11-50', '51-200', '201-500', '501-1000', '1001-5000', '5001+'. Repeat for an OR-set. A band outside that ladder is rejected with 422 rather than answered emptily; a company whose headcount we do not hold is never matched.","title":"Headcount Band"},"description":"Company size band: one of '1-10', '11-50', '51-200', '201-500', '501-1000', '1001-5000', '5001+'. Repeat for an OR-set. A band outside that ladder is rejected with 422 rather than answered emptily; a company whose headcount we do not hold is never matched."},{"name":"industry_terms","in":"query","required":false,"schema":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}],"description":"Substring of the company industry, matched case-insensitively, e.g. 'health' to reach both 'hospitals and health care' and 'health, wellness and fitness'. Repeat for an OR-set. The forgiving counterpart to `industry`, and usually the one to reach for first.","title":"Industry Terms"},"description":"Substring of the company industry, matched case-insensitively, e.g. 'health' to reach both 'hospitals and health care' and 'health, wellness and fitness'. Repeat for an OR-set. The forgiving counterpart to `industry`, and usually the one to reach for first."},{"name":"cursor","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"Keyset pagination cursor: pass the previous page's `next_cursor` to get the next page. Omit for the first page.","title":"Cursor"},"description":"Keyset pagination cursor: pass the previous page's `next_cursor` to get the next page. Omit for the first page."},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","description":"Maximum companies per page. An out-of-range value is rejected with 422 — page through the full set with `next_cursor` instead.","default":20,"title":"Limit"},"description":"Maximum companies per page. An out-of-range value is rejected with 422 — page through the full set with `next_cursor` instead."},{"name":"Idempotency-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Idempotency-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReqsSearchResponse"}}},"headers":{"RateLimit-Limit":{"description":"Calls allowed in one 60-second window.","schema":{"type":"integer","minimum":1}},"RateLimit-Remaining":{"description":"Calls left in the current window, after this one.","schema":{"type":"integer","minimum":0}},"RateLimit-Reset":{"description":"Whole seconds until the current window ends.","schema":{"type":"integer","minimum":1}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"402":{"description":"The key is over its plan's rolling call quota, or the account is past its spend cap. `upgrade_url` and `purchase_url` are the ways out.","content":{"application/json":{"schema":{"type":"object","required":["detail"],"properties":{"detail":{"type":"object","required":["reason","endpoint"],"properties":{"reason":{"type":"string","description":"`quota_exceeded` or `spend_cap_exceeded`."},"quota":{"type":"object","properties":{"limit":{"type":"integer"},"used":{"type":"integer"},"reset":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}]}}},"upgrade_url":{"type":"string"},"purchase_url":{"type":"string"},"endpoint":{"type":"string"}}}}}}}},"429":{"description":"Too many calls in the current 60-second window. The limit is per API key, set by the key's plan, and shared by every metered REST route and MCP tool; the shared demo key is limited per IP address instead. Wait `Retry-After` seconds and retry. The `RateLimit-*` headers are absent when `reason` is `key_throttled`.","headers":{"Retry-After":{"description":"Whole seconds until the current 60-second window ends and the call can be retried. Absent when `reason` is `key_throttled`.","schema":{"type":"integer","minimum":1}},"RateLimit-Limit":{"description":"Calls allowed in one 60-second window.","schema":{"type":"integer","minimum":1}},"RateLimit-Remaining":{"description":"Calls left in the current window, after this one.","schema":{"type":"integer","minimum":0}},"RateLimit-Reset":{"description":"Whole seconds until the current window ends.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"type":"object","required":["detail"],"properties":{"detail":{"type":"object","required":["reason","endpoint"],"properties":{"reason":{"type":"string","enum":["rate_limited","key_throttled"]},"endpoint":{"type":"string"},"signup_url":{"type":"string","description":"Only on the shared demo key's limit."}}}}}}}},"401":{"description":"No API key was sent, or the key is not valid.","content":{"application/json":{"schema":{"type":"object","required":["detail"],"properties":{"detail":{"type":"string"}}}}}}}}},"/v1/reqs/qualified":{"post":{"summary":"Find live reqs matching an ICP","description":"The live reqs matching a full ICP definition -- \"senior Go roles at\n51-200-person fintechs in the EU, agencies excluded\" -- as a page you pull,\nrather than a webhook you register and wait on.\n\n`criteria` is the same closed vocabulary a watch takes\n(`POST /v1/watches`), evaluated here in SQL instead of on the dispatcher's\ntick: three namespaced groups (`company`, `req`, `event`), AND across\ngroups and fields, OR within a field. A field outside the vocabulary is a\n422, and so is one this projection cannot answer -- `event.function` (a\nPython-derived taxonomy bucket, not a column; use `req.function`) and\n`event.event_type` (a ledger transition, where a row here is a live\nposting; use `/v1/events`). Never a silently-ignored filter: a dropped\ncriterion answers a wider question than the caller asked.\n\nA NULL fact never matches (fail-closed), so a criterion on a sparse facet\nis honestly narrow rather than wrong. The one exception is\n`req.q_excludes`, which vetoes and therefore does NOT fire on an absent\ntitle -- an unknown fact cannot prove an exclusion either.\n\nPOST rather than GET because criteria is a nested object; a URL-encoded\nAND-of-ORs would be an invented serialization, which is the open grammar\nthe closed vocabulary exists to refuse.\n\nRows carry the normalized req layer no other route serves -- skills,\nseniority, job family, declared **and** inferred compensation (with\n`salary_estimate_samples`, so an estimate can be judged rather than\ntrusted), the eligibility block, apply actionability, lifecycle and dedup\n-- plus `req_key`, the ledger's own identity for the req, so a page joins\nto `/v1/events`.\n\n`salary_min_usd` and `salary_max_usd` are the pay band: either alone is\nhalf-open, both together bracket one comparable yearly-USD figure per row.\nThat figure is the employer's declared salary when there is one (the\nmidpoint of a declared range) and our inferred median otherwise, and the\ninferred one qualifies only above a sample floor -- so a band is never\nsatisfied by a thinly-evidenced guess, and never half by the employer's\nnumber and half by ours. A req with no salary at all matches no band\n(fail-closed), and an inverted band is a 422 rather than a confidently\nempty page.\n\n`exclude_agencies` (default true) removes staffing agencies, aggregators\nand job boards, so a row names the employer. `live_only` (default true)\nkeeps expired and superseded postings out. Keyset-paginated: pass the\nprevious page's `next_cursor`, which is monotone, so it doubles as\n\"everything new since my last call\". `limit` is bounded -- this endpoint\nmeters the billed `source_row` atom off its own serialized rows, so an\nout-of-range page is a 422 rather than a silent truncation.\n\n`include_pulse` (default false) adds `companies`: the hiring pulse of every\ncompany on the page, keyed by `company_id` and shaped like the pulse\n`/v1/reqs/search` embeds, so a page of reqs needs no follow-up call per\ncompany. It is not billed separately; the page still bills per row.","operationId":"post_reqs_qualified_v1_reqs_qualified_post","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"Idempotency-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Idempotency-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QualifiedReqsRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/QualifiedReqsResponse"}}},"headers":{"RateLimit-Limit":{"description":"Calls allowed in one 60-second window.","schema":{"type":"integer","minimum":1}},"RateLimit-Remaining":{"description":"Calls left in the current window, after this one.","schema":{"type":"integer","minimum":0}},"RateLimit-Reset":{"description":"Whole seconds until the current window ends.","schema":{"type":"integer","minimum":1}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"402":{"description":"The key is over its plan's rolling call quota, or the account is past its spend cap. `upgrade_url` and `purchase_url` are the ways out.","content":{"application/json":{"schema":{"type":"object","required":["detail"],"properties":{"detail":{"type":"object","required":["reason","endpoint"],"properties":{"reason":{"type":"string","description":"`quota_exceeded` or `spend_cap_exceeded`."},"quota":{"type":"object","properties":{"limit":{"type":"integer"},"used":{"type":"integer"},"reset":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}]}}},"upgrade_url":{"type":"string"},"purchase_url":{"type":"string"},"endpoint":{"type":"string"}}}}}}}},"429":{"description":"Too many calls in the current 60-second window. The limit is per API key, set by the key's plan, and shared by every metered REST route and MCP tool; the shared demo key is limited per IP address instead. Wait `Retry-After` seconds and retry. The `RateLimit-*` headers are absent when `reason` is `key_throttled`.","headers":{"Retry-After":{"description":"Whole seconds until the current 60-second window ends and the call can be retried. Absent when `reason` is `key_throttled`.","schema":{"type":"integer","minimum":1}},"RateLimit-Limit":{"description":"Calls allowed in one 60-second window.","schema":{"type":"integer","minimum":1}},"RateLimit-Remaining":{"description":"Calls left in the current window, after this one.","schema":{"type":"integer","minimum":0}},"RateLimit-Reset":{"description":"Whole seconds until the current window ends.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"type":"object","required":["detail"],"properties":{"detail":{"type":"object","required":["reason","endpoint"],"properties":{"reason":{"type":"string","enum":["rate_limited","key_throttled"]},"endpoint":{"type":"string"},"signup_url":{"type":"string","description":"Only on the shared demo key's limit."}}}}}}}},"401":{"description":"No API key was sent, or the key is not valid.","content":{"application/json":{"schema":{"type":"object","required":["detail"],"properties":{"detail":{"type":"string"}}}}}}}}},"/v1/jobs/search":{"get":{"summary":"Search open roles across companies","description":"Flat, role-granular job search: the individual open roles across\ncompanies matching `function` / `geo` (country) / `since`\n(first-seen lower bound), one row per logical req. LinkedIn-excluded:\nATS tenants plus public job boards and aggregators; each row's\n`board` names its source. `since` and `first_seen` are our first\nobservation of the req, not the employer's posting date.\nFreshness-floored, PK-ordered and keyset-paginated via the opaque\n`next_cursor` (the page's last `company_id:req_key`). The\ncompany-granular reverse view is `/v1/reqs/search`; full multi-board\ndedup for one company is `/v1/companies/{company_id}/open-reqs`.\n\n`industry`, `industry_terms` and `headcount_band` cut the corpus down to\nyour ICP's companies. Repeat a parameter to OR its values; different\nparameters AND. They are filters only -- no company facet is added to a\nserved row by passing one -- and a company whose fact we do not hold is\nnever matched, so a cut is honestly narrow rather than quietly padded.\n\n`q` is free-text title search, ranked: it expands semantically to nearby\njob titles and matches them against the posting's own title, and each row\ncarries the `relevance` (0-1) it scored. `sort` picks the ordering --\n'relevance' (the default whenever `q` is given) or 'recency'. Omit both and\nthe page keeps its shipped stable order exactly. `q` is INDEPENDENT of\n`function`: pass both to search titles within one function.\n\nAn unresolvable `function` -- anything that is neither a function name\nnor a function taxonomy id -- is rejected with 422 instead of returning a\nsilently-empty result.\n`limit` is bounded: an oversized page is rejected with 422 rather than\ntruncated -- page through the full set with `next_cursor` instead of\nraising `limit`. The shared public demo key gets a tighter page instead --\nit bills nothing, so no ledger-derived gate can bound it, and a full-size\npage would make a world-readable credential a bulk-export window onto the\nfresh index. `sort='relevance'` without a `q`, and a `next_cursor`\nreplayed under a different `sort`, are 422s for the same reason: an order\nother than the one asked for reads as a measurement.","operationId":"get_jobs_search_v1_jobs_search_get","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"function","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Function to search for: its name as served in `function_name`, e.g. 'Software & IT', or its taxonomy id as served in `function`, e.g. '54f81306-3000-5c4a-a088-dca4350b19ff'. A name covers every function id that serves it; an id matches that one id. Anything else is rejected with 422, which lists the names, rather than returning a silently-empty result.","title":"Function"},"description":"Function to search for: its name as served in `function_name`, e.g. 'Software & IT', or its taxonomy id as served in `function`, e.g. '54f81306-3000-5c4a-a088-dca4350b19ff'. A name covers every function id that serves it; an id matches that one id. Anything else is rejected with 422, which lists the names, rather than returning a silently-empty result."},{"name":"geo","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Country name to restrict the search to, e.g. 'United States'. Matched against the geocoder's pinned country list.","title":"Geo"},"description":"Country name to restrict the search to, e.g. 'United States'. Matched against the geocoder's pinned country list."},{"name":"since","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"description":"ISO-8601 timestamp lower bound on `first_seen` -- our first observation of the job, not the employer's posting date -- e.g. '2026-01-01T00:00:00Z'. Omit for no lower bound.","title":"Since"},"description":"ISO-8601 timestamp lower bound on `first_seen` -- our first observation of the job, not the employer's posting date -- e.g. '2026-01-01T00:00:00Z'. Omit for no lower bound."},{"name":"q","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Free-text title search, e.g. 'senior backend engineer'. Expanded semantically to nearby job titles and matched against the posting's own title, with each row's `relevance` (0-1) reporting how well it matched. Independent of `function`: pass both to search titles WITHIN a function.","title":"Q"},"description":"Free-text title search, e.g. 'senior backend engineer'. Expanded semantically to nearby job titles and matched against the posting's own title, with each row's `relevance` (0-1) reporting how well it matched. Independent of `function`: pass both to search titles WITHIN a function."},{"name":"sort","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"'relevance' (the default when `q` is given) or 'recency' (newest `first_seen` first). Omit without a `q` for the default stable order. 'relevance' without a `q` is rejected with 422 — there is no query to be relevant to.","title":"Sort"},"description":"'relevance' (the default when `q` is given) or 'recency' (newest `first_seen` first). Omit without a `q` for the default stable order. 'relevance' without a `q` is rejected with 422 — there is no query to be relevant to."},{"name":"source_type","in":"query","required":false,"schema":{"anyOf":[{"enum":["ats_tenant","board"],"type":"string"},{"type":"null"}],"description":"Keep only reqs read from one kind of source: 'ats_tenant' (the employer's own applicant tracking system) or 'board' (a job board or aggregator). Matches each req's `source_type`. Omit to search both, which is the default; any other value is rejected with 422.","title":"Source Type"},"description":"Keep only reqs read from one kind of source: 'ats_tenant' (the employer's own applicant tracking system) or 'board' (a job board or aggregator). Matches each req's `source_type`. Omit to search both, which is the default; any other value is rejected with 422."},{"name":"exclude_agencies","in":"query","required":false,"schema":{"type":"boolean","description":"Drop reqs whose company we have positively classified as a middleman — a staffing agency, job aggregator, subcontractor network or job board. A company whose kind we have not determined is KEPT, not dropped: this is a veto on proven intermediation, never a filter down to proven direct employers, so an unclassified company can never disappear from your results for want of a classification.","default":false,"title":"Exclude Agencies"},"description":"Drop reqs whose company we have positively classified as a middleman — a staffing agency, job aggregator, subcontractor network or job board. A company whose kind we have not determined is KEPT, not dropped: this is a veto on proven intermediation, never a filter down to proven direct employers, so an unclassified company can never disappear from your results for want of a classification."},{"name":"industry","in":"query","required":false,"schema":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}],"description":"Company industry, matched exactly (case-insensitively), e.g. 'software development'. Repeat for an OR-set. The stored vocabulary is granular -- 'software development', 'computer software' and 'it services and it consulting' are three separate labels -- so prefer `industry_terms` unless you know the exact label you want. A company whose industry we do not hold is never matched.","title":"Industry"},"description":"Company industry, matched exactly (case-insensitively), e.g. 'software development'. Repeat for an OR-set. The stored vocabulary is granular -- 'software development', 'computer software' and 'it services and it consulting' are three separate labels -- so prefer `industry_terms` unless you know the exact label you want. A company whose industry we do not hold is never matched."},{"name":"headcount_band","in":"query","required":false,"schema":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}],"description":"Company size band: one of '1-10', '11-50', '51-200', '201-500', '501-1000', '1001-5000', '5001+'. Repeat for an OR-set. A band outside that ladder is rejected with 422 rather than answered emptily; a company whose headcount we do not hold is never matched.","title":"Headcount Band"},"description":"Company size band: one of '1-10', '11-50', '51-200', '201-500', '501-1000', '1001-5000', '5001+'. Repeat for an OR-set. A band outside that ladder is rejected with 422 rather than answered emptily; a company whose headcount we do not hold is never matched."},{"name":"industry_terms","in":"query","required":false,"schema":{"anyOf":[{"type":"array","items":{"type":"string"}},{"type":"null"}],"description":"Substring of the company industry, matched case-insensitively, e.g. 'health' to reach both 'hospitals and health care' and 'health, wellness and fitness'. Repeat for an OR-set. The forgiving counterpart to `industry`, and usually the one to reach for first.","title":"Industry Terms"},"description":"Substring of the company industry, matched case-insensitively, e.g. 'health' to reach both 'hospitals and health care' and 'health, wellness and fitness'. Repeat for an OR-set. The forgiving counterpart to `industry`, and usually the one to reach for first."},{"name":"cursor","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Keyset pagination cursor: pass the previous page's `next_cursor` to get the next page. Omit for the first page.","title":"Cursor"},"description":"Keyset pagination cursor: pass the previous page's `next_cursor` to get the next page. Omit for the first page."},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","description":"Maximum jobs per page. An out-of-range value is rejected with 422 — page through the full set with `next_cursor` instead.","default":20,"title":"Limit"},"description":"Maximum jobs per page. An out-of-range value is rejected with 422 — page through the full set with `next_cursor` instead."},{"name":"Idempotency-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Idempotency-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/JobsSearchResponse"}}},"headers":{"RateLimit-Limit":{"description":"Calls allowed in one 60-second window.","schema":{"type":"integer","minimum":1}},"RateLimit-Remaining":{"description":"Calls left in the current window, after this one.","schema":{"type":"integer","minimum":0}},"RateLimit-Reset":{"description":"Whole seconds until the current window ends.","schema":{"type":"integer","minimum":1}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"402":{"description":"The key is over its plan's rolling call quota, or the account is past its spend cap. `upgrade_url` and `purchase_url` are the ways out.","content":{"application/json":{"schema":{"type":"object","required":["detail"],"properties":{"detail":{"type":"object","required":["reason","endpoint"],"properties":{"reason":{"type":"string","description":"`quota_exceeded` or `spend_cap_exceeded`."},"quota":{"type":"object","properties":{"limit":{"type":"integer"},"used":{"type":"integer"},"reset":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}]}}},"upgrade_url":{"type":"string"},"purchase_url":{"type":"string"},"endpoint":{"type":"string"}}}}}}}},"429":{"description":"Too many calls in the current 60-second window. The limit is per API key, set by the key's plan, and shared by every metered REST route and MCP tool; the shared demo key is limited per IP address instead. Wait `Retry-After` seconds and retry. The `RateLimit-*` headers are absent when `reason` is `key_throttled`.","headers":{"Retry-After":{"description":"Whole seconds until the current 60-second window ends and the call can be retried. Absent when `reason` is `key_throttled`.","schema":{"type":"integer","minimum":1}},"RateLimit-Limit":{"description":"Calls allowed in one 60-second window.","schema":{"type":"integer","minimum":1}},"RateLimit-Remaining":{"description":"Calls left in the current window, after this one.","schema":{"type":"integer","minimum":0}},"RateLimit-Reset":{"description":"Whole seconds until the current window ends.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"type":"object","required":["detail"],"properties":{"detail":{"type":"object","required":["reason","endpoint"],"properties":{"reason":{"type":"string","enum":["rate_limited","key_throttled"]},"endpoint":{"type":"string"},"signup_url":{"type":"string","description":"Only on the shared demo key's limit."}}}}}}}},"401":{"description":"No API key was sent, or the key is not valid.","content":{"application/json":{"schema":{"type":"object","required":["detail"],"properties":{"detail":{"type":"string"}}}}}}}}},"/v1/jobs/role":{"get":{"summary":"One open role's detail","description":"One open role, addressed by the `(company_id, req_key)` pair every\n`/v1/jobs/search` row carries -- the follow-up call for a role you already\nhold an identifier for, instead of re-pulling the whole company through\n`/v1/companies/{company_id}/open-reqs`.\n\nScoped exactly as `/v1/jobs/search` is: LinkedIn-excluded (ATS tenants plus public job boards and aggregators) and freshness-floored, one\nrow per logical req. The body adds `raw_title` (the posting's own title) and\n`boards` -- the full, deduped list of boards reporting this req, which a\nsearch page cannot afford per row.\n\nA req that does not exist, is closed, or has not reached the freshness floor\nis a 404, never an empty 200 -- and a 404 is not metered.","operationId":"get_jobs_role_v1_jobs_role_get","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"company_id","in":"query","required":true,"schema":{"type":"integer","description":"The plane's company id -- returned as `company_id` by /v1/reqs/search and by every company motion response.","title":"Company Id"},"description":"The plane's company id -- returned as `company_id` by /v1/reqs/search and by every company motion response."},{"name":"req_key","in":"query","required":true,"schema":{"type":"string","description":"The req's own identity, as returned by `/v1/jobs/search`. Only unique WITHIN a company, so it is always spent together with `company_id`. A query parameter rather than a path segment because a board-native req id is an arbitrary string that may contain '/' or ':'.","title":"Req Key"},"description":"The req's own identity, as returned by `/v1/jobs/search`. Only unique WITHIN a company, so it is always spent together with `company_id`. A query parameter rather than a path segment because a board-native req id is an arbitrary string that may contain '/' or ':'."},{"name":"Idempotency-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Idempotency-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleResponse"}}},"headers":{"RateLimit-Limit":{"description":"Calls allowed in one 60-second window.","schema":{"type":"integer","minimum":1}},"RateLimit-Remaining":{"description":"Calls left in the current window, after this one.","schema":{"type":"integer","minimum":0}},"RateLimit-Reset":{"description":"Whole seconds until the current window ends.","schema":{"type":"integer","minimum":1}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"402":{"description":"The key is over its plan's rolling call quota, or the account is past its spend cap. `upgrade_url` and `purchase_url` are the ways out.","content":{"application/json":{"schema":{"type":"object","required":["detail"],"properties":{"detail":{"type":"object","required":["reason","endpoint"],"properties":{"reason":{"type":"string","description":"`quota_exceeded` or `spend_cap_exceeded`."},"quota":{"type":"object","properties":{"limit":{"type":"integer"},"used":{"type":"integer"},"reset":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}]}}},"upgrade_url":{"type":"string"},"purchase_url":{"type":"string"},"endpoint":{"type":"string"}}}}}}}},"429":{"description":"Too many calls in the current 60-second window. The limit is per API key, set by the key's plan, and shared by every metered REST route and MCP tool; the shared demo key is limited per IP address instead. Wait `Retry-After` seconds and retry. The `RateLimit-*` headers are absent when `reason` is `key_throttled`.","headers":{"Retry-After":{"description":"Whole seconds until the current 60-second window ends and the call can be retried. Absent when `reason` is `key_throttled`.","schema":{"type":"integer","minimum":1}},"RateLimit-Limit":{"description":"Calls allowed in one 60-second window.","schema":{"type":"integer","minimum":1}},"RateLimit-Remaining":{"description":"Calls left in the current window, after this one.","schema":{"type":"integer","minimum":0}},"RateLimit-Reset":{"description":"Whole seconds until the current window ends.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"type":"object","required":["detail"],"properties":{"detail":{"type":"object","required":["reason","endpoint"],"properties":{"reason":{"type":"string","enum":["rate_limited","key_throttled"]},"endpoint":{"type":"string"},"signup_url":{"type":"string","description":"Only on the shared demo key's limit."}}}}}}}},"401":{"description":"No API key was sent, or the key is not valid.","content":{"application/json":{"schema":{"type":"object","required":["detail"],"properties":{"detail":{"type":"string"}}}}}}}}},"/v1/companies/{company_id}/first-hire":{"get":{"summary":"A company's first hire in each function","description":"The earliest first-in-function event per function -- detects a new\nbudget line. Sourced from the role-slot recompute aggregate, not a\nspecific board posting; `source_board` says so honestly rather than\nbeing excluded outright. Free-tier reads are history-capped.\n\nAn unresolvable `function` -- anything that is not a function taxonomy\nid -- is rejected with 422 instead of returning a silently-empty\nresult.","operationId":"get_company_first_hire_v1_companies__company_id__first_hire_get","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"company_id","in":"path","required":true,"schema":{"type":"integer","description":"The plane's company id -- returned as `company_id` by /v1/reqs/search and by every company motion response.","title":"Company Id"},"description":"The plane's company id -- returned as `company_id` by /v1/reqs/search and by every company motion response."},{"name":"function","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Function whose first hire to look for: its name, e.g. 'Sales & Customer Service', or its taxonomy id, e.g. '3571b52b-ac60-58f9-b769-9affa0174f93'. Ids are the `by_function` keys this endpoint returns. A name covers every id it leads; an id matches that one id. Anything else is rejected with 422, which lists the names.","title":"Function"},"description":"Function whose first hire to look for: its name, e.g. 'Sales & Customer Service', or its taxonomy id, e.g. '3571b52b-ac60-58f9-b769-9affa0174f93'. Ids are the `by_function` keys this endpoint returns. A name covers every id it leads; an id matches that one id. Anything else is rejected with 422, which lists the names."},{"name":"Idempotency-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Idempotency-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FirstHireResponse"}}},"headers":{"RateLimit-Limit":{"description":"Calls allowed in one 60-second window.","schema":{"type":"integer","minimum":1}},"RateLimit-Remaining":{"description":"Calls left in the current window, after this one.","schema":{"type":"integer","minimum":0}},"RateLimit-Reset":{"description":"Whole seconds until the current window ends.","schema":{"type":"integer","minimum":1}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"402":{"description":"The key is over its plan's rolling call quota, or the account is past its spend cap. `upgrade_url` and `purchase_url` are the ways out.","content":{"application/json":{"schema":{"type":"object","required":["detail"],"properties":{"detail":{"type":"object","required":["reason","endpoint"],"properties":{"reason":{"type":"string","description":"`quota_exceeded` or `spend_cap_exceeded`."},"quota":{"type":"object","properties":{"limit":{"type":"integer"},"used":{"type":"integer"},"reset":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}]}}},"upgrade_url":{"type":"string"},"purchase_url":{"type":"string"},"endpoint":{"type":"string"}}}}}}}},"429":{"description":"Too many calls in the current 60-second window. The limit is per API key, set by the key's plan, and shared by every metered REST route and MCP tool; the shared demo key is limited per IP address instead. Wait `Retry-After` seconds and retry. The `RateLimit-*` headers are absent when `reason` is `key_throttled`.","headers":{"Retry-After":{"description":"Whole seconds until the current 60-second window ends and the call can be retried. Absent when `reason` is `key_throttled`.","schema":{"type":"integer","minimum":1}},"RateLimit-Limit":{"description":"Calls allowed in one 60-second window.","schema":{"type":"integer","minimum":1}},"RateLimit-Remaining":{"description":"Calls left in the current window, after this one.","schema":{"type":"integer","minimum":0}},"RateLimit-Reset":{"description":"Whole seconds until the current window ends.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"type":"object","required":["detail"],"properties":{"detail":{"type":"object","required":["reason","endpoint"],"properties":{"reason":{"type":"string","enum":["rate_limited","key_throttled"]},"endpoint":{"type":"string"},"signup_url":{"type":"string","description":"Only on the shared demo key's limit."}}}}}}}},"401":{"description":"No API key was sent, or the key is not valid.","content":{"application/json":{"schema":{"type":"object","required":["detail"],"properties":{"detail":{"type":"string"}}}}}}}}},"/v1/companies/{company_id}/repost-pain":{"get":{"summary":"A company's hardest-to-fill reqs","description":"Hard-to-fill reqs by repost count, hardest first -- LinkedIn-excluded\n(ATS tenants plus public job boards and aggregators),\nfreshness-floored. Free-tier reads are history-capped.","operationId":"get_company_repost_pain_v1_companies__company_id__repost_pain_get","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"company_id","in":"path","required":true,"schema":{"type":"integer","description":"The plane's company id -- returned as `company_id` by /v1/reqs/search and by every company motion response.","title":"Company Id"},"description":"The plane's company id -- returned as `company_id` by /v1/reqs/search and by every company motion response."},{"name":"Idempotency-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Idempotency-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RepostPainResponse"}}},"headers":{"RateLimit-Limit":{"description":"Calls allowed in one 60-second window.","schema":{"type":"integer","minimum":1}},"RateLimit-Remaining":{"description":"Calls left in the current window, after this one.","schema":{"type":"integer","minimum":0}},"RateLimit-Reset":{"description":"Whole seconds until the current window ends.","schema":{"type":"integer","minimum":1}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"402":{"description":"The key is over its plan's rolling call quota, or the account is past its spend cap. `upgrade_url` and `purchase_url` are the ways out.","content":{"application/json":{"schema":{"type":"object","required":["detail"],"properties":{"detail":{"type":"object","required":["reason","endpoint"],"properties":{"reason":{"type":"string","description":"`quota_exceeded` or `spend_cap_exceeded`."},"quota":{"type":"object","properties":{"limit":{"type":"integer"},"used":{"type":"integer"},"reset":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}]}}},"upgrade_url":{"type":"string"},"purchase_url":{"type":"string"},"endpoint":{"type":"string"}}}}}}}},"429":{"description":"Too many calls in the current 60-second window. The limit is per API key, set by the key's plan, and shared by every metered REST route and MCP tool; the shared demo key is limited per IP address instead. Wait `Retry-After` seconds and retry. The `RateLimit-*` headers are absent when `reason` is `key_throttled`.","headers":{"Retry-After":{"description":"Whole seconds until the current 60-second window ends and the call can be retried. Absent when `reason` is `key_throttled`.","schema":{"type":"integer","minimum":1}},"RateLimit-Limit":{"description":"Calls allowed in one 60-second window.","schema":{"type":"integer","minimum":1}},"RateLimit-Remaining":{"description":"Calls left in the current window, after this one.","schema":{"type":"integer","minimum":0}},"RateLimit-Reset":{"description":"Whole seconds until the current window ends.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"type":"object","required":["detail"],"properties":{"detail":{"type":"object","required":["reason","endpoint"],"properties":{"reason":{"type":"string","enum":["rate_limited","key_throttled"]},"endpoint":{"type":"string"},"signup_url":{"type":"string","description":"Only on the shared demo key's limit."}}}}}}}},"401":{"description":"No API key was sent, or the key is not valid.","content":{"application/json":{"schema":{"type":"object","required":["detail"],"properties":{"detail":{"type":"string"}}}}}}}}},"/v1/companies/{company_id}/ats-migrations":{"get":{"summary":"A company's ATS vendor switches","description":"A company's ATS-vendor switches -- ledger-backed, with a\nprovenance-wrapped `occurred_at`. No LinkedIn exclusion needed: ATS\nplatform accounts have no LinkedIn dimension.","operationId":"get_company_ats_migrations_v1_companies__company_id__ats_migrations_get","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"company_id","in":"path","required":true,"schema":{"type":"integer","description":"The plane's company id -- returned as `company_id` by /v1/reqs/search and by every company motion response.","title":"Company Id"},"description":"The plane's company id -- returned as `company_id` by /v1/reqs/search and by every company motion response."},{"name":"Idempotency-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Idempotency-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AtsMigrationsResponse"}}},"headers":{"RateLimit-Limit":{"description":"Calls allowed in one 60-second window.","schema":{"type":"integer","minimum":1}},"RateLimit-Remaining":{"description":"Calls left in the current window, after this one.","schema":{"type":"integer","minimum":0}},"RateLimit-Reset":{"description":"Whole seconds until the current window ends.","schema":{"type":"integer","minimum":1}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"402":{"description":"The key is over its plan's rolling call quota, or the account is past its spend cap. `upgrade_url` and `purchase_url` are the ways out.","content":{"application/json":{"schema":{"type":"object","required":["detail"],"properties":{"detail":{"type":"object","required":["reason","endpoint"],"properties":{"reason":{"type":"string","description":"`quota_exceeded` or `spend_cap_exceeded`."},"quota":{"type":"object","properties":{"limit":{"type":"integer"},"used":{"type":"integer"},"reset":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}]}}},"upgrade_url":{"type":"string"},"purchase_url":{"type":"string"},"endpoint":{"type":"string"}}}}}}}},"429":{"description":"Too many calls in the current 60-second window. The limit is per API key, set by the key's plan, and shared by every metered REST route and MCP tool; the shared demo key is limited per IP address instead. Wait `Retry-After` seconds and retry. The `RateLimit-*` headers are absent when `reason` is `key_throttled`.","headers":{"Retry-After":{"description":"Whole seconds until the current 60-second window ends and the call can be retried. Absent when `reason` is `key_throttled`.","schema":{"type":"integer","minimum":1}},"RateLimit-Limit":{"description":"Calls allowed in one 60-second window.","schema":{"type":"integer","minimum":1}},"RateLimit-Remaining":{"description":"Calls left in the current window, after this one.","schema":{"type":"integer","minimum":0}},"RateLimit-Reset":{"description":"Whole seconds until the current window ends.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"type":"object","required":["detail"],"properties":{"detail":{"type":"object","required":["reason","endpoint"],"properties":{"reason":{"type":"string","enum":["rate_limited","key_throttled"]},"endpoint":{"type":"string"},"signup_url":{"type":"string","description":"Only on the shared demo key's limit."}}}}}}}},"401":{"description":"No API key was sent, or the key is not valid.","content":{"application/json":{"schema":{"type":"object","required":["detail"],"properties":{"detail":{"type":"string"}}}}}}}}},"/v1/markets/role-demand":{"get":{"summary":"Market-wide demand for a role","description":"Market-wide (no single-company scope) active-req demand series for\n`function` / `geo` -- LinkedIn-excluded by construction\n(ATS tenants plus public job boards and aggregators).\n\nAn unresolvable `function` -- anything that is neither a function name\nnor a function taxonomy id -- is rejected with 422 instead of returning a\nsilently-empty result.","operationId":"get_market_role_demand_v1_markets_role_demand_get","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"function","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Function whose market demand to measure: its name as /v1/jobs/search serves it in `function_name`, e.g. 'Software & IT', or its taxonomy id as served in `function`, e.g. '54f81306-3000-5c4a-a088-dca4350b19ff'. A name covers every function id that serves it; an id matches that one id. Anything else is rejected with 422, which lists the names.","title":"Function"},"description":"Function whose market demand to measure: its name as /v1/jobs/search serves it in `function_name`, e.g. 'Software & IT', or its taxonomy id as served in `function`, e.g. '54f81306-3000-5c4a-a088-dca4350b19ff'. A name covers every function id that serves it; an id matches that one id. Anything else is rejected with 422, which lists the names."},{"name":"geo","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Country name to restrict the demand measurement to, e.g. 'United States'. Matched against the geocoder's pinned list.","title":"Geo"},"description":"Country name to restrict the demand measurement to, e.g. 'United States'. Matched against the geocoder's pinned list."},{"name":"since","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"description":"ISO-8601 timestamp lower bound on the demand window, e.g. '2026-01-01T00:00:00Z'. Omit for no lower bound.","title":"Since"},"description":"ISO-8601 timestamp lower bound on the demand window, e.g. '2026-01-01T00:00:00Z'. Omit for no lower bound."},{"name":"Idempotency-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Idempotency-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleDemandResponse"}}},"headers":{"RateLimit-Limit":{"description":"Calls allowed in one 60-second window.","schema":{"type":"integer","minimum":1}},"RateLimit-Remaining":{"description":"Calls left in the current window, after this one.","schema":{"type":"integer","minimum":0}},"RateLimit-Reset":{"description":"Whole seconds until the current window ends.","schema":{"type":"integer","minimum":1}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"402":{"description":"The key is over its plan's rolling call quota, or the account is past its spend cap. `upgrade_url` and `purchase_url` are the ways out.","content":{"application/json":{"schema":{"type":"object","required":["detail"],"properties":{"detail":{"type":"object","required":["reason","endpoint"],"properties":{"reason":{"type":"string","description":"`quota_exceeded` or `spend_cap_exceeded`."},"quota":{"type":"object","properties":{"limit":{"type":"integer"},"used":{"type":"integer"},"reset":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}]}}},"upgrade_url":{"type":"string"},"purchase_url":{"type":"string"},"endpoint":{"type":"string"}}}}}}}},"429":{"description":"Too many calls in the current 60-second window. The limit is per API key, set by the key's plan, and shared by every metered REST route and MCP tool; the shared demo key is limited per IP address instead. Wait `Retry-After` seconds and retry. The `RateLimit-*` headers are absent when `reason` is `key_throttled`.","headers":{"Retry-After":{"description":"Whole seconds until the current 60-second window ends and the call can be retried. Absent when `reason` is `key_throttled`.","schema":{"type":"integer","minimum":1}},"RateLimit-Limit":{"description":"Calls allowed in one 60-second window.","schema":{"type":"integer","minimum":1}},"RateLimit-Remaining":{"description":"Calls left in the current window, after this one.","schema":{"type":"integer","minimum":0}},"RateLimit-Reset":{"description":"Whole seconds until the current window ends.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"type":"object","required":["detail"],"properties":{"detail":{"type":"object","required":["reason","endpoint"],"properties":{"reason":{"type":"string","enum":["rate_limited","key_throttled"]},"endpoint":{"type":"string"},"signup_url":{"type":"string","description":"Only on the shared demo key's limit."}}}}}}}},"401":{"description":"No API key was sent, or the key is not valid.","content":{"application/json":{"schema":{"type":"object","required":["detail"],"properties":{"detail":{"type":"string"}}}}}}}}},"/v1/companies/{company_id}/pre-action-brief":{"get":{"summary":"A company's whole pre-action brief in one call","description":"The motion atoms + history primitives pre-joined into one bounded,\ncompact call -- an agent's whole pre-action context in one round-trip\ninstead of five. Honors `max_age` (seconds); cold returns `202 {job_id,\nstatus: \"crawling\"}`, same as hiring-pulse.","operationId":"get_company_pre_action_brief_v1_companies__company_id__pre_action_brief_get","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"company_id","in":"path","required":true,"schema":{"type":"integer","description":"The plane's company id -- returned as `company_id` by /v1/reqs/search and by every company motion response.","title":"Company Id"},"description":"The plane's company id -- returned as `company_id` by /v1/reqs/search and by every company motion response."},{"name":"max_age","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"Maximum acceptable data age in SECONDS for the underlying hiring signals the brief is assembled from.","title":"Max Age"},"description":"Maximum acceptable data age in SECONDS for the underlying hiring signals the brief is assembled from."},{"name":"Idempotency-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Idempotency-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Get Company Pre Action Brief V1 Companies  Company Id  Pre Action Brief Get"}}},"headers":{"RateLimit-Limit":{"description":"Calls allowed in one 60-second window.","schema":{"type":"integer","minimum":1}},"RateLimit-Remaining":{"description":"Calls left in the current window, after this one.","schema":{"type":"integer","minimum":0}},"RateLimit-Reset":{"description":"Whole seconds until the current window ends.","schema":{"type":"integer","minimum":1}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"402":{"description":"The key is over its plan's rolling call quota, or the account is past its spend cap. `upgrade_url` and `purchase_url` are the ways out.","content":{"application/json":{"schema":{"type":"object","required":["detail"],"properties":{"detail":{"type":"object","required":["reason","endpoint"],"properties":{"reason":{"type":"string","description":"`quota_exceeded` or `spend_cap_exceeded`."},"quota":{"type":"object","properties":{"limit":{"type":"integer"},"used":{"type":"integer"},"reset":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}]}}},"upgrade_url":{"type":"string"},"purchase_url":{"type":"string"},"endpoint":{"type":"string"}}}}}}}},"429":{"description":"Too many calls in the current 60-second window. The limit is per API key, set by the key's plan, and shared by every metered REST route and MCP tool; the shared demo key is limited per IP address instead. Wait `Retry-After` seconds and retry. The `RateLimit-*` headers are absent when `reason` is `key_throttled`.","headers":{"Retry-After":{"description":"Whole seconds until the current 60-second window ends and the call can be retried. Absent when `reason` is `key_throttled`.","schema":{"type":"integer","minimum":1}},"RateLimit-Limit":{"description":"Calls allowed in one 60-second window.","schema":{"type":"integer","minimum":1}},"RateLimit-Remaining":{"description":"Calls left in the current window, after this one.","schema":{"type":"integer","minimum":0}},"RateLimit-Reset":{"description":"Whole seconds until the current window ends.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"type":"object","required":["detail"],"properties":{"detail":{"type":"object","required":["reason","endpoint"],"properties":{"reason":{"type":"string","enum":["rate_limited","key_throttled"]},"endpoint":{"type":"string"},"signup_url":{"type":"string","description":"Only on the shared demo key's limit."}}}}}}}},"401":{"description":"No API key was sent, or the key is not valid.","content":{"application/json":{"schema":{"type":"object","required":["detail"],"properties":{"detail":{"type":"string"}}}}}}}}},"/v1/events":{"get":{"summary":"The change feed since your cursor","description":"The `since=cursor` diff feed -- ledger events with `event_seq > since`,\nordered ascending, plus a `next_cursor` an agent replays instead of\npolling or re-scraping. Meters one `change` unit per event RETURNED,\nindependent of poll count: an empty page costs nothing. A free-tier\ncaller is change-feed-gated to the same freshness floor every other\nfree atom uses. `limit` is bounded: an oversized page is rejected with\n422 rather than truncated -- replay with `next_cursor` instead of\nraising `limit`.","operationId":"get_events_v1_events_get","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"since","in":"query","required":true,"schema":{"type":"integer","description":"Cursor: return only events with `event_seq` greater than this. Start at 0, then replay the previous response's `next_cursor` instead of re-polling from the beginning.","title":"Since"},"description":"Cursor: return only events with `event_seq` greater than this. Start at 0, then replay the previous response's `next_cursor` instead of re-polling from the beginning."},{"name":"company_id","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"Return only events for this company id.","title":"Company Id"},"description":"Return only events for this company id."},{"name":"event_type","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Return only events of this type, e.g. 'opened' or 'closed'.","title":"Event Type"},"description":"Return only events of this type, e.g. 'opened' or 'closed'."},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","description":"Maximum events per page. An oversized value is rejected with 422 rather than truncated — replay with `next_cursor` instead.","default":100,"title":"Limit"},"description":"Maximum events per page. An oversized value is rejected with 422 rather than truncated — replay with `next_cursor` instead."},{"name":"Idempotency-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Idempotency-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChangeFeedResponse"}}},"headers":{"RateLimit-Limit":{"description":"Calls allowed in one 60-second window.","schema":{"type":"integer","minimum":1}},"RateLimit-Remaining":{"description":"Calls left in the current window, after this one.","schema":{"type":"integer","minimum":0}},"RateLimit-Reset":{"description":"Whole seconds until the current window ends.","schema":{"type":"integer","minimum":1}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"402":{"description":"The key is over its plan's rolling call quota, or the account is past its spend cap. `upgrade_url` and `purchase_url` are the ways out.","content":{"application/json":{"schema":{"type":"object","required":["detail"],"properties":{"detail":{"type":"object","required":["reason","endpoint"],"properties":{"reason":{"type":"string","description":"`quota_exceeded` or `spend_cap_exceeded`."},"quota":{"type":"object","properties":{"limit":{"type":"integer"},"used":{"type":"integer"},"reset":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}]}}},"upgrade_url":{"type":"string"},"purchase_url":{"type":"string"},"endpoint":{"type":"string"}}}}}}}},"429":{"description":"Too many calls in the current 60-second window. The limit is per API key, set by the key's plan, and shared by every metered REST route and MCP tool; the shared demo key is limited per IP address instead. Wait `Retry-After` seconds and retry. The `RateLimit-*` headers are absent when `reason` is `key_throttled`.","headers":{"Retry-After":{"description":"Whole seconds until the current 60-second window ends and the call can be retried. Absent when `reason` is `key_throttled`.","schema":{"type":"integer","minimum":1}},"RateLimit-Limit":{"description":"Calls allowed in one 60-second window.","schema":{"type":"integer","minimum":1}},"RateLimit-Remaining":{"description":"Calls left in the current window, after this one.","schema":{"type":"integer","minimum":0}},"RateLimit-Reset":{"description":"Whole seconds until the current window ends.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"type":"object","required":["detail"],"properties":{"detail":{"type":"object","required":["reason","endpoint"],"properties":{"reason":{"type":"string","enum":["rate_limited","key_throttled"]},"endpoint":{"type":"string"},"signup_url":{"type":"string","description":"Only on the shared demo key's limit."}}}}}}}},"401":{"description":"No API key was sent, or the key is not valid.","content":{"application/json":{"schema":{"type":"object","required":["detail"],"properties":{"detail":{"type":"string"}}}}}}}}},"/v1/webhooks":{"post":{"summary":"Register a webhook endpoint","description":"Register a webhook delivery target -- `secret` is stored as the\nendpoint's HMAC signing key, scoped to the caller's own customer, and\nnever logged.\n\nIdempotent on (customer, url): re-registering the same target returns\nthe SAME id rather than a second row, so a retrying caller ends up with\none endpoint it can hand straight to `POST /v1/watches`. Omitted\n`secret` is generated server-side.","operationId":"create_webhook_v1_webhooks_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWebhookRequest"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWebhookResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"401":{"description":"No API key was sent, or the key is not valid.","content":{"application/json":{"schema":{"type":"object","required":["detail"],"properties":{"detail":{"type":"string"}}}}}}},"security":[{"APIKeyHeader":[]}]}},"/v1/watches":{"post":{"summary":"Watch a company or a saved search","description":"Subscribe to hiring events on a registered webhook -- scoped to the\ncaller's own customer: `webhook_endpoint_id` must belong to the same\ncustomer. Meters one `watch` unit.\n\nThe watch covers one company (`company_id`) or a saved search\n(`criteria`) -- exactly one, and a criteria outside the closed\nvocabulary is a 422 raised before any row is written. So is an\n`event_types` that is empty or names anything but `opened`,\n`reobserved`, `reposted` or `closed`: such a watch could never fire,\nso it is refused rather than created and metered.\n\nA free key holds a limited number of watches AT ONCE; the one past that\nis a 402 carrying the upgrade path, checked before the watch is created,\nso a walled call leaves no subscription behind. Cancelling a watch\nreturns the slot.","operationId":"create_watch_route_v1_watches_post","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"Idempotency-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Idempotency-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWatchRequest"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateWatchResponse"}}},"headers":{"RateLimit-Limit":{"description":"Calls allowed in one 60-second window.","schema":{"type":"integer","minimum":1}},"RateLimit-Remaining":{"description":"Calls left in the current window, after this one.","schema":{"type":"integer","minimum":0}},"RateLimit-Reset":{"description":"Whole seconds until the current window ends.","schema":{"type":"integer","minimum":1}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"402":{"description":"The key is over its plan's rolling call quota, or the account is past its spend cap. `upgrade_url` and `purchase_url` are the ways out.","content":{"application/json":{"schema":{"type":"object","required":["detail"],"properties":{"detail":{"type":"object","required":["reason","endpoint"],"properties":{"reason":{"type":"string","description":"`quota_exceeded` or `spend_cap_exceeded`."},"quota":{"type":"object","properties":{"limit":{"type":"integer"},"used":{"type":"integer"},"reset":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}]}}},"upgrade_url":{"type":"string"},"purchase_url":{"type":"string"},"endpoint":{"type":"string"}}}}}}}},"429":{"description":"Too many calls in the current 60-second window. The limit is per API key, set by the key's plan, and shared by every metered REST route and MCP tool; the shared demo key is limited per IP address instead. Wait `Retry-After` seconds and retry. The `RateLimit-*` headers are absent when `reason` is `key_throttled`.","headers":{"Retry-After":{"description":"Whole seconds until the current 60-second window ends and the call can be retried. Absent when `reason` is `key_throttled`.","schema":{"type":"integer","minimum":1}},"RateLimit-Limit":{"description":"Calls allowed in one 60-second window.","schema":{"type":"integer","minimum":1}},"RateLimit-Remaining":{"description":"Calls left in the current window, after this one.","schema":{"type":"integer","minimum":0}},"RateLimit-Reset":{"description":"Whole seconds until the current window ends.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"type":"object","required":["detail"],"properties":{"detail":{"type":"object","required":["reason","endpoint"],"properties":{"reason":{"type":"string","enum":["rate_limited","key_throttled"]},"endpoint":{"type":"string"},"signup_url":{"type":"string","description":"Only on the shared demo key's limit."}}}}}}}},"401":{"description":"No API key was sent, or the key is not valid.","content":{"application/json":{"schema":{"type":"object","required":["detail"],"properties":{"detail":{"type":"string"}}}}}}}},"get":{"summary":"List your live watches","description":"The caller's own live watches -- what is currently subscribed on their\ncustomer, newest first, canceled ones excluded.\n\nA \"Watch this search\" signup lands with a watch already installed, and\nthis is where its owner confirms what it watches and which endpoint it\ndelivers to. Not billable, like the other self-serve introspection\nreads (`/webhook-deliveries`): reading your own subscriptions is\naccount management, not metered corpus access.\n\nEach watch also reports `fires_last_hour` against its declared\n`max_fires_per_hour`, and `rate_limited` when the two have met: fires past\nthat cap are DROPPED rather than queued, so this is the only place a\nsaturated watch can be told from a quiet one.\n\nAnd each reports its heartbeat -- `last_fired_at`, `fires_last_7d`,\n`fires_last_30d` and a one-word `status` -- so a watch that is silent\nbecause nobody is hiring reads differently from one that is silent because\nits criteria can never match, its plan stopped it, or its endpoint is\ndown. Absence is the customer's only evidence a watch is mis-specified,\nand for a metered product it is also the receipt for the months where the\nhonest answer is \"nothing matched\".","operationId":"list_watches_route_v1_watches_get","security":[{"APIKeyHeader":[]}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/WatchResponse"},"title":"Response List Watches Route V1 Watches Get"}}}},"401":{"description":"No API key was sent, or the key is not valid.","content":{"application/json":{"schema":{"type":"object","required":["detail"],"properties":{"detail":{"type":"string"}}}}}}}}},"/v1/watches/{watch_id}":{"delete":{"summary":"Cancel a watch","description":"Cancel a watch, scoped to the caller's own customer -- canceling\nanother tenant's watch id 404s, identical to canceling one that doesn't\nexist (fail-fast, mirrors `delete_key`). Canceling one's own\nalready-canceled watch is a 204 no-op, so the verb stays idempotent.","operationId":"delete_watch_v1_watches__watch_id__delete","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"watch_id","in":"path","required":true,"schema":{"type":"integer","description":"The watch subscription's id, as returned when the watch was created.","title":"Watch Id"},"description":"The watch subscription's id, as returned when the watch was created."}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"401":{"description":"No API key was sent, or the key is not valid.","content":{"application/json":{"schema":{"type":"object","required":["detail"],"properties":{"detail":{"type":"string"}}}}}}}}},"/v1/webhook-deliveries":{"get":{"summary":"Your webhook delivery log","description":"The caller's own self-serve webhook delivery log -- every delivery for\ntheir own customer, most recent first.\n\nEach entry carries the `idempotency_key` the delivery was sent with (also\nits `X-Plane-Idempotency-Key` header, and the id of the billed unit on your\ninvoice) plus the `response_status` your endpoint returned, so a charge can\nbe matched to the delivery that earned it without a support thread. A NULL\n`response_status` means we observed no HTTP response: the delivery has not\nbeen attempted yet, the connection failed outright, or it was mailed to a\nhosted-email endpoint.","operationId":"list_webhook_deliveries_route_v1_webhook_deliveries_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/DeliveryLogEntryResponse"},"type":"array","title":"Response List Webhook Deliveries Route V1 Webhook Deliveries Get"}}}},"401":{"description":"No API key was sent, or the key is not valid.","content":{"application/json":{"schema":{"type":"object","required":["detail"],"properties":{"detail":{"type":"string"}}}}}}},"security":[{"APIKeyHeader":[]}]}},"/v1/webhook-deliveries/{delivery_id}":{"get":{"summary":"One webhook delivery's detail","description":"One delivery's detail, scoped to the caller's own customer.","operationId":"get_webhook_delivery_route_v1_webhook_deliveries__delivery_id__get","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"delivery_id","in":"path","required":true,"schema":{"type":"integer","description":"The webhook delivery's id, as returned by GET /v1/webhook-deliveries.","title":"Delivery Id"},"description":"The webhook delivery's id, as returned by GET /v1/webhook-deliveries."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeliveryLogEntryResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"401":{"description":"No API key was sent, or the key is not valid.","content":{"application/json":{"schema":{"type":"object","required":["detail"],"properties":{"detail":{"type":"string"}}}}}}}}},"/v1/webhook-deliveries/{delivery_id}/replay":{"post":{"summary":"Replay a webhook delivery","description":"Reopens a webhook delivery for the next dispatcher tick to redeliver --\na self-serve replay debugger. Scoped to the caller's own customer,\nidempotent, and within the replay SLA window.","operationId":"replay_delivery_route_v1_webhook_deliveries__delivery_id__replay_post","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"delivery_id","in":"path","required":true,"schema":{"type":"integer","description":"The webhook delivery's id, as returned by GET /v1/webhook-deliveries.","title":"Delivery Id"},"description":"The webhook delivery's id, as returned by GET /v1/webhook-deliveries."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeliveryLogEntryResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"401":{"description":"No API key was sent, or the key is not valid.","content":{"application/json":{"schema":{"type":"object","required":["detail"],"properties":{"detail":{"type":"string"}}}}}}}}},"/v1/companies/{company_id}/outcomes":{"post":{"summary":"Report a conversion outcome","description":"Write back a conversion outcome for `company_id`. Appends to the\ncaller's own outcome labels, which are retention-protected.","operationId":"create_outcome_v1_companies__company_id__outcomes_post","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"company_id","in":"path","required":true,"schema":{"type":"integer","description":"The plane's company id -- returned as `company_id` by /v1/reqs/search and by every company motion response.","title":"Company Id"},"description":"The plane's company id -- returned as `company_id` by /v1/reqs/search and by every company motion response."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WriteOutcomeRequest"}}}},"responses":{"202":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WriteOutcomeResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"401":{"description":"No API key was sent, or the key is not valid.","content":{"application/json":{"schema":{"type":"object","required":["detail"],"properties":{"detail":{"type":"string"}}}}}}}}},"/v1/attribution":{"get":{"summary":"See which delivered signals you won","description":"\"Signal #N -> you won.\" -- the caller's own outcome labels joined back\nto the signals this plane actually delivered them.\n\nA label for a company we never signalled is deliberately absent: this\nis an attribution view, not a label dump. `attributed_14d` counts the\nones that landed in the last 14 days.","operationId":"get_attribution_v1_attribution_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AttributionResponse"}}}},"401":{"description":"No API key was sent, or the key is not valid.","content":{"application/json":{"schema":{"type":"object","required":["detail"],"properties":{"detail":{"type":"string"}}}}}}},"security":[{"APIKeyHeader":[]}]}},"/v1/companies/{company_id}/intent":{"get":{"summary":"A company's calibrated intent score","description":"The calibrated-intent score + coverage meter for `company_id` --\ncomputed live off every customer's submitted outcome labels. `score` is\n`None` below the coverage-gating minimum (never a fabricated number).","operationId":"get_calibrated_intent_v1_companies__company_id__intent_get","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"company_id","in":"path","required":true,"schema":{"type":"integer","description":"The plane's company id -- returned as `company_id` by /v1/reqs/search and by every company motion response.","title":"Company Id"},"description":"The plane's company id -- returned as `company_id` by /v1/reqs/search and by every company motion response."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CalibratedIntentResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"401":{"description":"No API key was sent, or the key is not valid.","content":{"application/json":{"schema":{"type":"object","required":["detail"],"properties":{"detail":{"type":"string"}}}}}}}}},"/v1/companies/resolve":{"get":{"summary":"Find a company's id by domain or name","description":"Turn a website or a company name into the `company_id` every\ncompany-scoped endpoint takes.\n\nPass exactly one of `domain` or `name`; both or neither is a 422 naming\nthat rule. A domain returns the companies registered at it; a name returns\nup to five candidates, each with a `match_confidence` -- 1.0 for an exact\nname, 0.8 for a match once legal suffixes are dropped.\n\nEach company carries its `country_code` and `coverage_status`, and no\nhiring signal -- ask `/v1/companies/{company_id}/is-hiring` for that.\nNothing matching is an empty array, never a 404. Not billable.","operationId":"resolve_company_route_v1_companies_resolve_get","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"domain","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"The company's website: a bare host ('stripe.com') or a full URL ('https://www.stripe.com/jobs'). Matched exactly once the scheme, path and 'www.' are dropped. Pass this or `name`, not both.","title":"Domain"},"description":"The company's website: a bare host ('stripe.com') or a full URL ('https://www.stripe.com/jobs'). Matched exactly once the scheme, path and 'www.' are dropped. Pass this or `name`, not both."},{"name":"name","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"The company's name, matched case-insensitively and then with legal suffixes dropped. Pass this or `domain`, not both.","title":"Name"},"description":"The company's name, matched case-insensitively and then with legal suffixes dropped. Pass this or `domain`, not both."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CompanyMatchResponse"},"title":"Response Resolve Company Route V1 Companies Resolve Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"401":{"description":"No API key was sent, or the key is not valid.","content":{"application/json":{"schema":{"type":"object","required":["detail"],"properties":{"detail":{"type":"string"}}}}}},"429":{"description":"Too many calls in the current 60-second window. The limit is per API key, set by the key's plan, and shared by every metered REST route and MCP tool; the shared demo key is limited per IP address instead. Wait `Retry-After` seconds and retry. The `RateLimit-*` headers are absent when `reason` is `key_throttled`.","headers":{"Retry-After":{"description":"Whole seconds until the current 60-second window ends and the call can be retried. Absent when `reason` is `key_throttled`.","schema":{"type":"integer","minimum":1}},"RateLimit-Limit":{"description":"Calls allowed in one 60-second window.","schema":{"type":"integer","minimum":1}},"RateLimit-Remaining":{"description":"Calls left in the current window, after this one.","schema":{"type":"integer","minimum":0}},"RateLimit-Reset":{"description":"Whole seconds until the current window ends.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"type":"object","required":["detail"],"properties":{"detail":{"type":"object","required":["reason","endpoint"],"properties":{"reason":{"type":"string","enum":["rate_limited","key_throttled"]},"endpoint":{"type":"string"},"signup_url":{"type":"string","description":"Only on the shared demo key's limit."}}}}}}}}}}},"/v1/clay/enrich":{"post":{"summary":"Enrich a company for a Clay column","description":"Clay HTTP-provider hiring-motion enrichment column -- entity-resolves\n`domain`/`name` to a company via the local plane cache, then composes\ncompany enrichment and hiring pulse into a flat, Clay-column-shaped\nresponse: no field beyond this declared model ever leaks, every field\nis LinkedIn-excluded (ATS tenants plus public job boards and aggregators) and provenance-backed by its own primitive. Metered to the\npresented (Clay account) key.\n\nA miss is a 200, not a 404: a 404 blanks the Clay cell, which the\ncustomer reads as \"not hiring\". It carries `coverage_status`, a\n`message`, a `checked_at` -- and NULL motion fields, never zeros. The\ncall still meters.","operationId":"clay_enrich_route_v1_clay_enrich_post","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"Idempotency-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Idempotency-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ClayEnrichRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ClayEnrichResponse"}}},"headers":{"RateLimit-Limit":{"description":"Calls allowed in one 60-second window.","schema":{"type":"integer","minimum":1}},"RateLimit-Remaining":{"description":"Calls left in the current window, after this one.","schema":{"type":"integer","minimum":0}},"RateLimit-Reset":{"description":"Whole seconds until the current window ends.","schema":{"type":"integer","minimum":1}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"402":{"description":"The key is over its plan's rolling call quota, or the account is past its spend cap. `upgrade_url` and `purchase_url` are the ways out.","content":{"application/json":{"schema":{"type":"object","required":["detail"],"properties":{"detail":{"type":"object","required":["reason","endpoint"],"properties":{"reason":{"type":"string","description":"`quota_exceeded` or `spend_cap_exceeded`."},"quota":{"type":"object","properties":{"limit":{"type":"integer"},"used":{"type":"integer"},"reset":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}]}}},"upgrade_url":{"type":"string"},"purchase_url":{"type":"string"},"endpoint":{"type":"string"}}}}}}}},"429":{"description":"Too many calls in the current 60-second window. The limit is per API key, set by the key's plan, and shared by every metered REST route and MCP tool; the shared demo key is limited per IP address instead. Wait `Retry-After` seconds and retry. The `RateLimit-*` headers are absent when `reason` is `key_throttled`.","headers":{"Retry-After":{"description":"Whole seconds until the current 60-second window ends and the call can be retried. Absent when `reason` is `key_throttled`.","schema":{"type":"integer","minimum":1}},"RateLimit-Limit":{"description":"Calls allowed in one 60-second window.","schema":{"type":"integer","minimum":1}},"RateLimit-Remaining":{"description":"Calls left in the current window, after this one.","schema":{"type":"integer","minimum":0}},"RateLimit-Reset":{"description":"Whole seconds until the current window ends.","schema":{"type":"integer","minimum":1}}},"content":{"application/json":{"schema":{"type":"object","required":["detail"],"properties":{"detail":{"type":"object","required":["reason","endpoint"],"properties":{"reason":{"type":"string","enum":["rate_limited","key_throttled"]},"endpoint":{"type":"string"},"signup_url":{"type":"string","description":"Only on the shared demo key's limit."}}}}}}}},"401":{"description":"No API key was sent, or the key is not valid.","content":{"application/json":{"schema":{"type":"object","required":["detail"],"properties":{"detail":{"type":"string"}}}}}}}}},"/v1/migration-import":{"post":{"summary":"Import a company list from your current vendor","description":"Migration import from an incumbent: a switcher's uploaded\nCoresignal/Apollo company list, resolved to the panel and enriched with\nthe hiring-motion column; every miss is routed to a real coverage\nrequest, so switching cost drops to near zero without a second \"please\ncrawl this\" mechanism. Not billable -- same convention as `/quickstart`\nand `/onboarding`.","operationId":"migration_import_route_v1_migration_import_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MigrationImportRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MigrationImportResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}},"401":{"description":"No API key was sent, or the key is not valid.","content":{"application/json":{"schema":{"type":"object","required":["detail"],"properties":{"detail":{"type":"string"}}}}}}},"security":[{"APIKeyHeader":[]}]}}},"components":{"schemas":{"AccountPauseResponse":{"properties":{"account_id":{"type":"integer","title":"Account Id"},"paused":{"type":"boolean","title":"Paused"}},"type":"object","required":["account_id","paused"],"title":"AccountPauseResponse"},"AtsMigrationsResponse":{"properties":{"migrations":{"items":{"$ref":"#/components/schemas/MigrationEventOut"},"type":"array","title":"Migrations"},"as_of":{"type":"string","format":"date-time","title":"As Of"}},"type":"object","required":["migrations","as_of"],"title":"AtsMigrationsResponse"},"AttributedOutcomeResponse":{"properties":{"event_seq":{"type":"integer","title":"Event Seq"},"company_id":{"type":"integer","title":"Company Id"},"company_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Company Name"},"req_key":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Req Key"},"title":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Title"},"outcome":{"type":"string","title":"Outcome"},"observed_at":{"type":"string","format":"date-time","title":"Observed At"}},"type":"object","required":["event_seq","company_id","company_name","req_key","title","outcome","observed_at"],"title":"AttributedOutcomeResponse"},"AttributionResponse":{"properties":{"items":{"items":{"$ref":"#/components/schemas/AttributedOutcomeResponse"},"type":"array","title":"Items"},"attributed_14d":{"type":"integer","title":"Attributed 14D"}},"type":"object","required":["items","attributed_14d"],"title":"AttributionResponse"},"BlockedDeliveriesOut":{"properties":{"wall_blocked":{"type":"integer","title":"Wall Blocked"},"cap_blocked":{"type":"integer","title":"Cap Blocked"},"since":{"type":"string","format":"date-time","title":"Since"}},"type":"object","required":["wall_blocked","cap_blocked","since"],"title":"BlockedDeliveriesOut"},"CalibratedIntentResponse":{"properties":{"company_id":{"type":"integer","title":"Company Id"},"positive_count":{"type":"integer","title":"Positive Count"},"negative_count":{"type":"integer","title":"Negative Count"},"label_count":{"type":"integer","title":"Label Count"},"coverage":{"type":"number","title":"Coverage"},"score":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Score"}},"type":"object","required":["company_id","positive_count","negative_count","label_count","coverage","score"],"title":"CalibratedIntentResponse"},"ChangeEventOut":{"properties":{"event_seq":{"type":"integer","title":"Event Seq"},"company_id":{"type":"integer","title":"Company Id"},"req_key":{"type":"string","title":"Req Key"},"board":{"type":"string","title":"Board"},"event_type":{"type":"string","title":"Event Type"},"observed_at":{"type":"string","format":"date-time","title":"Observed At"},"function":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Function"},"country":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Country"},"title":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Title"},"source_board":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Source Board","description":"The board whose posting this event was read off -- normally the same value as `board`. Null when the event carries no per-posting board label; `board` is always set."},"country_code":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Country Code","description":"The posting country's ISO-3166-1 alpha-2 code, uppercase (`DE`, `US`), derived from `country` and never stored. `null` when `country` is absent or is not a country this corpus names — never a guess. Note this is an output only: the `geo`/`country` filter still takes the name, because a bare two-letter code is ambiguous on input (`CA` is Canada to ISO and California to this column).","readOnly":true},"function_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Function Name","description":"The job function's human-readable name (`Software & IT`, `Healthcare`), derived from `function` and never stored. The `?function=` filter accepts this name as well as the opaque taxonomy id in `function`. `null` when the req carries no function attribution (`unspecified`, 10.2% of served reqs), or when it was classified from its skills alone, so its id is outside the named title-family vocabulary (16.7%) — never a guess and never the raw id. Named on 73.1% of served reqs (309,251 of 422,826, measured 2026-10-07).","readOnly":true}},"type":"object","required":["event_seq","company_id","req_key","board","event_type","observed_at","function","country","title","source_board","country_code","function_name"],"title":"ChangeEventOut"},"ChangeFeedResponse":{"properties":{"events":{"items":{"$ref":"#/components/schemas/ChangeEventOut"},"type":"array","title":"Events"},"next_cursor":{"type":"integer","title":"Next Cursor"}},"type":"object","required":["events","next_cursor"],"title":"ChangeFeedResponse"},"ClayEnrichRequest":{"properties":{"domain":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Domain"},"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"}},"type":"object","title":"ClayEnrichRequest"},"ClayEnrichResponse":{"properties":{"company_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Company Id"},"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"domain":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Domain"},"hq_country":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Hq Country"},"boards":{"items":{"type":"string"},"type":"array","title":"Boards"},"is_hiring":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Is Hiring"},"open_req_count":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Open Req Count"},"new_roles_30d":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"New Roles 30D"},"velocity":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Velocity"},"direction":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Direction"},"is_surge":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Is Surge"},"coverage_status":{"type":"string","enum":["ats_direct_hit","board_hit","no_ats_signal","unsupported_ats"],"title":"Coverage Status"},"message":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Message"},"checked_at":{"type":"string","format":"date-time","title":"Checked At"},"enrichment_as_of":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Enrichment As Of"},"motion_as_of":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Motion As Of"},"hq_country_code":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Hq Country Code","description":"The company's HQ country as an ISO-3166-1 alpha-2 code, uppercase (`DE`, `US`), derived from `hq_country` and never stored. `null` when `hq_country` is absent or is not a country this corpus names — never a guess.","readOnly":true}},"type":"object","required":["company_id","name","domain","hq_country","boards","is_hiring","open_req_count","new_roles_30d","velocity","direction","is_surge","coverage_status","message","checked_at","enrichment_as_of","motion_as_of","hq_country_code"],"title":"ClayEnrichResponse"},"CompanyEnrichmentResponse":{"properties":{"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"domain":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Domain"},"hq_country":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Hq Country"},"boards":{"items":{"type":"string"},"type":"array","title":"Boards"},"as_of":{"type":"string","format":"date-time","title":"As Of"},"coverage_status":{"type":"string","enum":["ats_direct_hit","board_hit","no_ats_signal","unsupported_ats"],"title":"Coverage Status"},"hq_country_code":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Hq Country Code","description":"The company's HQ country as an ISO-3166-1 alpha-2 code, uppercase (`DE`, `US`), derived from `hq_country` and never stored. `null` when `hq_country` is absent or is not a country this corpus names — never a guess.","readOnly":true}},"type":"object","required":["name","domain","hq_country","boards","as_of","coverage_status","hq_country_code"],"title":"CompanyEnrichmentResponse"},"CompanyMatchOut":{"properties":{"company_id":{"type":"integer","title":"Company Id"},"company_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Company Name"},"company_domain":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Company Domain"},"pulse":{"$ref":"#/components/schemas/HiringPulseResponse"},"matched_reqs":{"items":{"$ref":"#/components/schemas/MatchedReqOut"},"type":"array","title":"Matched Reqs"}},"type":"object","required":["company_id","pulse","matched_reqs"],"title":"CompanyMatchOut"},"CompanyMatchResponse":{"properties":{"company_id":{"type":"integer","title":"Company Id"},"company_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Company Name"},"company_domain":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Company Domain"},"country_code":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Country Code","description":"The posting country's ISO-3166-1 alpha-2 code, uppercase (`DE`, `US`), derived from `country` and never stored. `null` when `country` is absent or is not a country this corpus names — never a guess. Note this is an output only: the `geo`/`country` filter still takes the name, because a bare two-letter code is ambiguous on input (`CA` is Canada to ISO and California to this column)."},"coverage_status":{"type":"string","enum":["ats_direct_hit","board_hit","no_ats_signal","unsupported_ats"],"title":"Coverage Status"},"match_confidence":{"type":"number","title":"Match Confidence"}},"type":"object","required":["company_id","company_name","company_domain","country_code","coverage_status","match_confidence"],"title":"CompanyMatchResponse","description":"One company a domain or name resolved to -- identity and coverage, no\nhiring signal."},"CreateWatchRequest":{"properties":{"company_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Company Id"},"criteria":{"anyOf":[{"$ref":"#/components/schemas/Criteria"},{"type":"null"}]},"event_types":{"items":{"type":"string","enum":["opened","reobserved","reposted","closed"]},"type":"array","minItems":1,"title":"Event Types"},"webhook_endpoint_id":{"type":"integer","title":"Webhook Endpoint Id"}},"type":"object","required":["event_types","webhook_endpoint_id"],"title":"CreateWatchRequest","description":"Scope the watch with exactly one of `company_id` (one company) or\n`criteria` (a saved search).\n\n`event_types` names which hiring events fire it, at least one of:\n`opened` (a req seen for the first time), `reobserved` (a known req seen\nagain on a later day), `reposted` (a req that came back after it was\ngone) and `closed` (a req verified gone from its source). Any other value\nis a 422 and creates nothing."},"CreateWatchResponse":{"properties":{"id":{"type":"integer","title":"Id"}},"type":"object","required":["id"],"title":"CreateWatchResponse"},"CreateWebhookRequest":{"properties":{"url":{"type":"string","title":"Url"},"secret":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Secret"}},"type":"object","required":["url"],"title":"CreateWebhookRequest","description":"`secret` is optional (signalsapi-3806): an agent holding only an API\nkey has no signing key to offer, and requiring one made the watch\nsurface uncallable for exactly the caller class it exists to serve. A\ncaller that wants to verify `X-Plane-Signature` still supplies its own."},"CreateWebhookResponse":{"properties":{"id":{"type":"integer","title":"Id"},"url":{"type":"string","title":"Url"}},"type":"object","required":["id","url"],"title":"CreateWebhookResponse"},"Criteria":{"properties":{"event":{"$ref":"#/components/schemas/CriteriaEvent"},"req":{"$ref":"#/components/schemas/CriteriaReq"},"company":{"$ref":"#/components/schemas/CriteriaCompany"},"max_fires_per_hour":{"type":"integer","maximum":10000.0,"minimum":1.0,"title":"Max Fires Per Hour"},"dedup_window_days":{"type":"integer","maximum":90.0,"minimum":1.0,"title":"Dedup Window Days"}},"additionalProperties":false,"type":"object","title":"Criteria","description":"A closed AND-of-ORs over three namespaced groups. At least one field must be constrained."},"CriteriaCompany":{"properties":{"industry":{"items":{"type":"string"},"type":"array","maxItems":64,"minItems":1,"title":"Industry"},"company_kind":{"items":{"type":"string"},"type":"array","maxItems":64,"minItems":1,"title":"Company Kind"},"country":{"items":{"type":"string"},"type":"array","maxItems":64,"minItems":1,"title":"Country"},"headcount_band":{"items":{"type":"string","enum":["1-10","11-50","51-200","201-500","501-1000","1001-5000","5001+"]},"type":"array","maxItems":64,"minItems":1,"title":"Headcount Band"},"industry_terms":{"items":{"type":"string"},"type":"array","maxItems":64,"minItems":1,"title":"Industry Terms"}},"additionalProperties":false,"type":"object","title":"CriteriaCompany","description":"The `company` criteria group: AND across fields, OR within a field."},"CriteriaEvent":{"properties":{"company_id":{"items":{"type":"integer"},"type":"array","maxItems":64,"minItems":1,"title":"Company Id"},"event_type":{"items":{"type":"string"},"type":"array","maxItems":64,"minItems":1,"title":"Event Type"},"board":{"items":{"type":"string"},"type":"array","maxItems":64,"minItems":1,"title":"Board"},"source_type":{"items":{"type":"string","enum":["ats_tenant","board"]},"type":"array","maxItems":64,"minItems":1,"title":"Source Type"},"ats_vendor":{"items":{"type":"string"},"type":"array","maxItems":64,"minItems":1,"title":"Ats Vendor"},"function":{"items":{"type":"string"},"type":"array","maxItems":64,"minItems":1,"title":"Function"},"country":{"items":{"type":"string"},"type":"array","maxItems":64,"minItems":1,"title":"Country"}},"additionalProperties":false,"type":"object","title":"CriteriaEvent","description":"The `event` criteria group: AND across fields, OR within a field."},"CriteriaReq":{"properties":{"seniority_level":{"items":{"type":"string"},"type":"array","maxItems":64,"minItems":1,"title":"Seniority Level"},"function":{"items":{"type":"string"},"type":"array","maxItems":64,"minItems":1,"title":"Function"},"remote_type":{"items":{"type":"string"},"type":"array","maxItems":64,"minItems":1,"title":"Remote Type"},"skills":{"items":{"type":"string"},"type":"array","maxItems":64,"minItems":1,"title":"Skills"},"q":{"items":{"type":"string"},"type":"array","maxItems":64,"minItems":1,"title":"Q"},"location":{"items":{"type":"string"},"type":"array","maxItems":64,"minItems":1,"title":"Location"},"q_excludes":{"items":{"type":"string"},"type":"array","maxItems":64,"minItems":1,"title":"Q Excludes"}},"additionalProperties":false,"type":"object","title":"CriteriaReq","description":"The `req` criteria group: AND across fields, OR within a field."},"DeliveryLogEntryResponse":{"properties":{"id":{"type":"integer","title":"Id"},"status":{"type":"string","title":"Status"},"attempt_count":{"type":"integer","title":"Attempt Count"},"watch_id":{"type":"integer","title":"Watch Id"},"event_seq":{"type":"integer","title":"Event Seq"},"idempotency_key":{"type":"string","title":"Idempotency Key"},"event_type":{"type":"string","title":"Event Type"},"webhook_url":{"type":"string","title":"Webhook Url"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"delivered_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Delivered At"},"response_status":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Response Status"},"response_ms":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Response Ms"}},"type":"object","required":["id","status","attempt_count","watch_id","event_seq","idempotency_key","event_type","webhook_url","created_at","delivered_at","response_status","response_ms"],"title":"DeliveryLogEntryResponse"},"FirstHireResponse":{"properties":{"by_function":{"additionalProperties":{"$ref":"#/components/schemas/ProvenanceOut"},"type":"object","title":"By Function"},"as_of":{"type":"string","format":"date-time","title":"As Of"}},"type":"object","required":["by_function","as_of"],"title":"FirstHireResponse"},"FreeTierAllowanceOut":{"properties":{"watches_used":{"type":"integer","title":"Watches Used"},"watches_allowance":{"type":"integer","title":"Watches Allowance"},"changes_used":{"type":"integer","title":"Changes Used"},"changes_allowance":{"type":"integer","title":"Changes Allowance"},"changes_wall_reached":{"type":"boolean","title":"Changes Wall Reached"}},"type":"object","required":["watches_used","watches_allowance","changes_used","changes_allowance","changes_wall_reached"],"title":"FreeTierAllowanceOut"},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"HiringPulseResponse":{"properties":{"is_hiring":{"$ref":"#/components/schemas/ProvenanceOut"},"open_req_count":{"$ref":"#/components/schemas/ProvenanceOut","description":"Reqs open RIGHT NOW — a stock, counted off the hiring ledger's active reqs as of `as_of`. Its namesake inside `momentum` counts something else entirely; see that field."},"new_roles_30d":{"$ref":"#/components/schemas/ProvenanceOut"},"velocity":{"$ref":"#/components/schemas/ProvenanceOut"},"direction":{"$ref":"#/components/schemas/ProvenanceOut"},"is_surge":{"$ref":"#/components/schemas/ProvenanceOut"},"by_function":{"additionalProperties":{"type":"integer"},"type":"object","title":"By Function","description":"Open reqs per stored `function`. The key `unspecified` counts reqs that were not classified at all. A key whose leading id has no `function_name` counts reqs classified from their skills alone: a skill family, which has no readable name. The two are kept under separate keys."},"source_boards":{"items":{"type":"string"},"type":"array","title":"Source Boards","description":"Every board that reported a req the scalars above count, sorted. This is the pulse's provenance: each scalar's own `source_board` is null because one board cannot describe a value counted across several."},"momentum":{"items":{"$ref":"#/components/schemas/MomentumPointOut"},"type":"array","title":"Momentum","description":"Posting history bucketed over time (weekly), oldest bucket first. A flow, over the company's whole publication history — not a series of `open_req_count` snapshots."},"as_of":{"type":"string","format":"date-time","title":"As Of"},"coverage_status":{"type":"string","enum":["ats_direct_hit","board_hit","no_ats_signal","unsupported_ats"],"title":"Coverage Status"}},"type":"object","required":["is_hiring","open_req_count","new_roles_30d","velocity","direction","is_surge","by_function","source_boards","momentum","as_of","coverage_status"],"title":"HiringPulseResponse"},"IssueKeyRequest":{"properties":{"scopes":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Scopes"}},"additionalProperties":false,"type":"object","title":"IssueKeyRequest"},"IssueKeyResponse":{"properties":{"id":{"type":"integer","title":"Id"},"key":{"type":"string","title":"Key"},"customer_id":{"type":"string","title":"Customer Id"},"account_id":{"type":"integer","title":"Account Id"},"tier":{"type":"string","title":"Tier"},"scopes":{"items":{"type":"string"},"type":"array","title":"Scopes"}},"type":"object","required":["id","key","customer_id","account_id","tier","scopes"],"title":"IssueKeyResponse"},"JobOut":{"properties":{"req_key":{"type":"string","title":"Req Key"},"company_id":{"type":"integer","title":"Company Id"},"company_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Company Name"},"company_domain":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Company Domain"},"title":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Title"},"function":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Function"},"country":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Country"},"first_seen":{"type":"string","format":"date-time","title":"First Seen","description":"Our first observation of this req (not the employer's posting date). The `since` parameter filters on this value."},"source_posted_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Source Posted At","description":"The posting date the source itself published for this req. Null when the source gave no date, or none has been recorded yet -- `first_seen` is then the only date we hold, and it is our observation time."},"board":{"type":"string","title":"Board"},"source_type":{"anyOf":[{"type":"string","enum":["ats_tenant","board"]},{"type":"null"}],"title":"Source Type","description":"What kind of source this req was most recently read from: 'ats_tenant' (the employer's own applicant tracking system) or 'board' (a job board or aggregator). Most served reqs are 'board'; pass `source_type=ats_tenant` to keep only the ones read from the employer's own system."},"relevance":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Relevance"},"country_code":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Country Code","description":"The posting country's ISO-3166-1 alpha-2 code, uppercase (`DE`, `US`), derived from `country` and never stored. `null` when `country` is absent or is not a country this corpus names — never a guess. Note this is an output only: the `geo`/`country` filter still takes the name, because a bare two-letter code is ambiguous on input (`CA` is Canada to ISO and California to this column).","readOnly":true},"function_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Function Name","description":"The job function's human-readable name (`Software & IT`, `Healthcare`), derived from `function` and never stored. The `?function=` filter accepts this name as well as the opaque taxonomy id in `function`. `null` when the req carries no function attribution (`unspecified`, 10.2% of served reqs), or when it was classified from its skills alone, so its id is outside the named title-family vocabulary (16.7%) — never a guess and never the raw id. Named on 73.1% of served reqs (309,251 of 422,826, measured 2026-10-07).","readOnly":true}},"type":"object","required":["req_key","company_id","title","function","country","first_seen","board","country_code","function_name"],"title":"JobOut"},"JobsSearchResponse":{"properties":{"jobs":{"items":{"$ref":"#/components/schemas/JobOut"},"type":"array","title":"Jobs"},"next_cursor":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Next Cursor"},"as_of":{"type":"string","format":"date-time","title":"As Of"}},"type":"object","required":["jobs","next_cursor","as_of"],"title":"JobsSearchResponse"},"KeyListItem":{"properties":{"id":{"type":"integer","title":"Id"},"account_id":{"type":"integer","title":"Account Id"},"tier":{"type":"string","title":"Tier"},"scopes":{"items":{"type":"string"},"type":"array","title":"Scopes"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"revoked_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Revoked At"},"last_used_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Last Used At"}},"type":"object","required":["id","account_id","tier","scopes","created_at","revoked_at","last_used_at"],"title":"KeyListItem"},"KeyListResponse":{"properties":{"keys":{"items":{"$ref":"#/components/schemas/KeyListItem"},"type":"array","title":"Keys"}},"type":"object","required":["keys"],"title":"KeyListResponse"},"KeyUsageBreakdown":{"properties":{"key_id":{"type":"integer","title":"Key Id"},"calls":{"type":"integer","title":"Calls"},"changes":{"type":"integer","title":"Changes"},"watches":{"type":"integer","title":"Watches"},"forced_fresh":{"type":"integer","title":"Forced Fresh"},"by_meter_class":{"additionalProperties":{"type":"integer"},"type":"object","title":"By Meter Class"}},"type":"object","required":["key_id","calls","changes","watches","forced_fresh","by_meter_class"],"title":"KeyUsageBreakdown"},"KeyUsageOut":{"properties":{"key_id":{"type":"integer","title":"Key Id"},"tier":{"type":"string","title":"Tier"},"used":{"type":"integer","title":"Used"},"quota":{"type":"integer","title":"Quota"},"status":{"type":"string","title":"Status"}},"type":"object","required":["key_id","tier","used","quota","status"],"title":"KeyUsageOut"},"MatchedReqOut":{"properties":{"title":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Title","description":"The normalized posting title, as the crawler normalizer wrote it. OPTIONAL: present on 73.1% of served reqs (309,255 of 422,826, measured 2026-10-07). `null` means the posting's signal produced no normalized title -- it failed normalization, or normalized without one -- never that the req has no title. Read `raw_title` for a label that is always there; it is populated on every served req and is what `?q=` matches."},"raw_title":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Raw Title","description":"The posting title exactly as the board published it, and the text `?q=` full-text matches. Populated on 100% of served reqs (422,826 of 422,826, measured 2026-10-07), so this is the field to render when `title` is null."},"function":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Function"},"country":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Country"},"first_seen":{"type":"string","format":"date-time","title":"First Seen","description":"Our first observation of this req (not the employer's posting date). The `since` parameter filters on this value."},"source_posted_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Source Posted At","description":"The posting date the source itself published for this req. Null when the source gave no date, or none has been recorded yet -- `first_seen` is then the only date we hold, and it is our observation time."},"boards":{"items":{"type":"string"},"type":"array","title":"Boards"},"source_type":{"anyOf":[{"type":"string","enum":["ats_tenant","board"]},{"type":"null"}],"title":"Source Type","description":"What kind of source this req was most recently read from: 'ats_tenant' (the employer's own applicant tracking system) or 'board' (a job board or aggregator). Most served reqs are 'board'; pass `source_type=ats_tenant` to keep only the ones read from the employer's own system."},"country_code":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Country Code","description":"The posting country's ISO-3166-1 alpha-2 code, uppercase (`DE`, `US`), derived from `country` and never stored. `null` when `country` is absent or is not a country this corpus names — never a guess. Note this is an output only: the `geo`/`country` filter still takes the name, because a bare two-letter code is ambiguous on input (`CA` is Canada to ISO and California to this column).","readOnly":true},"function_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Function Name","description":"The job function's human-readable name (`Software & IT`, `Healthcare`), derived from `function` and never stored. The `?function=` filter accepts this name as well as the opaque taxonomy id in `function`. `null` when the req carries no function attribution (`unspecified`, 10.2% of served reqs), or when it was classified from its skills alone, so its id is outside the named title-family vocabulary (16.7%) — never a guess and never the raw id. Named on 73.1% of served reqs (309,251 of 422,826, measured 2026-10-07).","readOnly":true}},"type":"object","required":["title","function","country","first_seen","boards","country_code","function_name"],"title":"MatchedReqOut"},"MigrationEventOut":{"properties":{"from_vendor":{"type":"string","title":"From Vendor"},"to_vendor":{"type":"string","title":"To Vendor"},"occurred_at":{"$ref":"#/components/schemas/ProvenanceOut"}},"type":"object","required":["from_vendor","to_vendor","occurred_at"],"title":"MigrationEventOut"},"MigrationImportRequest":{"properties":{"contact_email":{"type":"string","title":"Contact Email"},"rows":{"items":{"$ref":"#/components/schemas/MigrationImportRow"},"type":"array","title":"Rows"}},"type":"object","required":["contact_email","rows"],"title":"MigrationImportRequest"},"MigrationImportResponse":{"properties":{"covered":{"type":"integer","title":"Covered"},"total":{"type":"integer","title":"Total"},"resolved":{"items":{"$ref":"#/components/schemas/ResolvedImportRow"},"type":"array","title":"Resolved"},"misses":{"items":{"$ref":"#/components/schemas/MissedImportRow"},"type":"array","title":"Misses"}},"type":"object","required":["covered","total","resolved","misses"],"title":"MigrationImportResponse"},"MigrationImportRow":{"properties":{"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"domain":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Domain"}},"type":"object","title":"MigrationImportRow"},"MissedImportRow":{"properties":{"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"domain":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Domain"}},"type":"object","required":["name","domain"],"title":"MissedImportRow"},"MomentumPointOut":{"properties":{"bucket_start":{"type":"string","format":"date-time","title":"Bucket Start","description":"Start of the bucket (weekly by default), UTC."},"open_req_count":{"type":"integer","title":"Open Req Count","description":"How many direct-ATS reqs this company POSTED in this bucket — a flow, counted off the posting history by `posted_at`, including reqs long since closed. This is NOT the number open during the bucket, and it is NOT comparable to the sibling `open_req_count` on the pulse itself, which counts reqs open right now. A bucket larger than that scalar is the ordinary case for a company that publishes more in a week than it leaves open."}},"type":"object","required":["bucket_start","open_req_count"],"title":"MomentumPointOut","description":"One momentum bucket. Its count is a flow — see the field description\nbelow."},"OnboardingResponse":{"properties":{"step":{"type":"string","title":"Step"},"company_id":{"type":"integer","title":"Company Id"},"watch_id":{"type":"integer","title":"Watch Id"},"webhook_endpoint_id":{"type":"integer","title":"Webhook Endpoint Id"},"first_webhook_delivered":{"type":"boolean","title":"First Webhook Delivered"},"expansion_nudge_triggered":{"type":"boolean","title":"Expansion Nudge Triggered"}},"type":"object","required":["step","company_id","watch_id","webhook_endpoint_id","first_webhook_delivered","expansion_nudge_triggered"],"title":"OnboardingResponse"},"OpenReqItem":{"properties":{"title":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Title","description":"The normalized posting title, as the crawler normalizer wrote it. OPTIONAL: present on 73.1% of served reqs (309,255 of 422,826, measured 2026-10-07). `null` means the posting's signal produced no normalized title -- it failed normalization, or normalized without one -- never that the req has no title. Read `raw_title` for a label that is always there; it is populated on every served req."},"raw_title":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Raw Title","description":"The posting title exactly as the board published it. Populated on 100% of served reqs (422,826 of 422,826, measured 2026-10-07), so this is the field to render when `title` is null."},"function":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Function"},"country":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Country"},"first_seen":{"type":"string","format":"date-time","title":"First Seen","description":"Our first observation of this req (not the employer's posting date). The `since` parameter filters on this value."},"source_posted_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Source Posted At","description":"The posting date the source itself published for this req. Null when the source gave no date, or none has been recorded yet -- `first_seen` is then the only date we hold, and it is our observation time."},"boards":{"items":{"type":"string"},"type":"array","title":"Boards"},"source_type":{"anyOf":[{"type":"string","enum":["ats_tenant","board"]},{"type":"null"}],"title":"Source Type","description":"What kind of source this req was most recently read from: 'ats_tenant' (the employer's own applicant tracking system) or 'board' (a job board or aggregator). Most served reqs are 'board'; pass `source_type=ats_tenant` to keep only the ones read from the employer's own system."},"country_code":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Country Code","description":"The posting country's ISO-3166-1 alpha-2 code, uppercase (`DE`, `US`), derived from `country` and never stored. `null` when `country` is absent or is not a country this corpus names — never a guess. Note this is an output only: the `geo`/`country` filter still takes the name, because a bare two-letter code is ambiguous on input (`CA` is Canada to ISO and California to this column).","readOnly":true},"function_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Function Name","description":"The job function's human-readable name (`Software & IT`, `Healthcare`), derived from `function` and never stored. The `?function=` filter accepts this name as well as the opaque taxonomy id in `function`. `null` when the req carries no function attribution (`unspecified`, 10.2% of served reqs), or when it was classified from its skills alone, so its id is outside the named title-family vocabulary (16.7%) — never a guess and never the raw id. Named on 73.1% of served reqs (309,251 of 422,826, measured 2026-10-07).","readOnly":true}},"type":"object","required":["title","function","country","first_seen","boards","country_code","function_name"],"title":"OpenReqItem"},"OpenReqsResponse":{"properties":{"reqs":{"items":{"$ref":"#/components/schemas/OpenReqItem"},"type":"array","title":"Reqs"},"as_of":{"type":"string","format":"date-time","title":"As Of"},"coverage_status":{"type":"string","enum":["ats_direct_hit","board_hit","no_ats_signal","unsupported_ats"],"title":"Coverage Status"}},"type":"object","required":["reqs","as_of","coverage_status"],"title":"OpenReqsResponse"},"ProvenanceOut":{"properties":{"value":{"title":"Value"},"source_board":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Source Board","description":"The board this value was read from. Null when the value is computed across many boards rather than read from one -- every hiring-pulse scalar is, so it is always null there; the boards behind the pulse are listed once in its `source_boards`."},"observed_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Observed At","description":"When this value was observed. For a value computed across the company's whole ledger (every hiring-pulse scalar) this is the time it was computed -- the request time, equal to the pulse's `as_of` -- not when any posting behind it was last seen."}},"type":"object","required":["value"],"title":"ProvenanceOut"},"QualifiedCriteria":{"properties":{"event":{"$ref":"#/components/schemas/QualifiedCriteriaEvent"},"req":{"$ref":"#/components/schemas/CriteriaReq"},"company":{"$ref":"#/components/schemas/CriteriaCompany"}},"additionalProperties":false,"type":"object","title":"QualifiedCriteria","description":"The watch criteria vocabulary, minus the fields a live-req page cannot answer. At least one field must be constrained."},"QualifiedCriteriaEvent":{"properties":{"company_id":{"items":{"type":"integer"},"type":"array","maxItems":64,"minItems":1,"title":"Company Id"},"board":{"items":{"type":"string"},"type":"array","maxItems":64,"minItems":1,"title":"Board"},"source_type":{"items":{"type":"string","enum":["ats_tenant","board"]},"type":"array","maxItems":64,"minItems":1,"title":"Source Type"},"ats_vendor":{"items":{"type":"string"},"type":"array","maxItems":64,"minItems":1,"title":"Ats Vendor"},"country":{"items":{"type":"string"},"type":"array","maxItems":64,"minItems":1,"title":"Country"}},"additionalProperties":false,"type":"object","title":"QualifiedCriteriaEvent","description":"The `event` criteria group as `POST /v1/reqs/qualified` answers it. Not accepted here: event.function is a Python-derived taxonomy bucket, not a stored column on this projection; filter on req.function instead; event.event_type describes a ledger transition, and a qualified req is a live posting rather than a transition; use GET /v1/events for event types."},"QualifiedReqOut":{"properties":{"req_key":{"type":"string","title":"Req Key"},"url":{"type":"string","title":"Url"},"posted_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Posted At"},"fetched_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Fetched At"},"board":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Board"},"source_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Source Type"},"ats_vendor":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Ats Vendor"},"external_reference_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"External Reference Id"},"title":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Title"},"standard_title":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Standard Title"},"seniority_level":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Seniority Level"},"job_family":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Job Family"},"skills":{"anyOf":[{"items":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"string"}]},"type":"array"},{"type":"null"}],"title":"Skills"},"country":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Country"},"location":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Location"},"remote_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Remote Type"},"remote_type_confidence":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Remote Type Confidence"},"employment_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Employment Type"},"salary_min":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Salary Min"},"salary_max":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Salary Max"},"salary_currency":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Salary Currency"},"salary_period":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Salary Period"},"yearly_salary_usd":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Yearly Salary Usd"},"salary_estimate_min":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Salary Estimate Min"},"salary_estimate_max":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Salary Estimate Max"},"salary_estimate_median":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Salary Estimate Median"},"salary_estimate_samples":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Salary Estimate Samples"},"eligibility_allowed_regions":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Eligibility Allowed Regions"},"eligibility_excluded_regions":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Eligibility Excluded Regions"},"eligibility_allowed_countries":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Eligibility Allowed Countries"},"eligibility_excluded_countries":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Eligibility Excluded Countries"},"eligibility_remote_global":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Eligibility Remote Global"},"eligibility_work_auth_required":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Eligibility Work Auth Required"},"apply_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Apply Url"},"apply_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Apply Type"},"apply_precision":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Apply Precision"},"leaves_site":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Leaves Site"},"lifecycle_status":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Lifecycle Status"},"simhash":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Simhash"},"company_id":{"type":"integer","title":"Company Id"},"company_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Company Name"},"company_domain":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Company Domain"},"company_country":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Company Country"},"country_code":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Country Code","description":"The posting country's ISO-3166-1 alpha-2 code, uppercase (`DE`, `US`), derived from `country` and never stored. `null` when `country` is absent or is not a country this corpus names — never a guess. Note this is an output only: the `geo`/`country` filter still takes the name, because a bare two-letter code is ambiguous on input (`CA` is Canada to ISO and California to this column).","readOnly":true},"posted_at_precision":{"type":"string","enum":["exact","date","unknown"],"title":"Posted At Precision","description":"How well the source knew `posted_at`: `exact` (a moment, carrying an intra-day component), `date` (a calendar day, at midnight UTC), or `unknown` (the source published no date and `posted_at` is null). Derived from `posted_at`, never stored. Note: the ingest still substitutes its own clock when a source publishes no date, so `unknown` is not yet reachable and those rows read `exact`.","readOnly":true}},"additionalProperties":false,"type":"object","required":["req_key","url","posted_at","fetched_at","board","source_type","ats_vendor","external_reference_id","title","standard_title","seniority_level","job_family","skills","country","location","remote_type","remote_type_confidence","employment_type","salary_min","salary_max","salary_currency","salary_period","yearly_salary_usd","salary_estimate_min","salary_estimate_max","salary_estimate_median","salary_estimate_samples","eligibility_allowed_regions","eligibility_excluded_regions","eligibility_allowed_countries","eligibility_excluded_countries","eligibility_remote_global","eligibility_work_auth_required","apply_url","apply_type","apply_precision","leaves_site","lifecycle_status","simhash","company_id","company_name","company_domain","company_country","country_code","posted_at_precision"],"title":"QualifiedReqOut"},"QualifiedReqsRequest":{"properties":{"criteria":{"$ref":"#/components/schemas/QualifiedCriteria"},"exclude_agencies":{"type":"boolean","title":"Exclude Agencies","default":true},"live_only":{"type":"boolean","title":"Live Only","default":true},"salary_min_usd":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Salary Min Usd"},"salary_max_usd":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Salary Max Usd"},"since":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Since"},"cursor":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Cursor"},"limit":{"type":"integer","maximum":100.0,"minimum":1.0,"title":"Limit","default":25},"include_pulse":{"type":"boolean","title":"Include Pulse","description":"Also return `companies`: the hiring pulse of each company on the page, once per company.","default":false}},"type":"object","required":["criteria"],"title":"QualifiedReqsRequest"},"QualifiedReqsResponse":{"properties":{"reqs":{"items":{"$ref":"#/components/schemas/QualifiedReqOut"},"type":"array","title":"Reqs"},"next_cursor":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Next Cursor"},"as_of":{"type":"string","format":"date-time","title":"As Of"},"companies":{"anyOf":[{"additionalProperties":{"$ref":"#/components/schemas/HiringPulseResponse"},"type":"object"},{"type":"null"}],"title":"Companies","description":"Only with `include_pulse`: each company on the page, keyed by `company_id`, with the same hiring pulse `/v1/reqs/search` embeds."}},"type":"object","required":["reqs","next_cursor","as_of"],"title":"QualifiedReqsResponse"},"QuickstartRequest":{"properties":{"webhook_url":{"type":"string","title":"Webhook Url"},"domain":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Domain"}},"type":"object","required":["webhook_url"],"title":"QuickstartRequest"},"QuickstartResponse":{"properties":{"snippets":{"additionalProperties":true,"type":"object","title":"Snippets"},"company_id":{"type":"integer","title":"Company Id"},"watch_id":{"type":"integer","title":"Watch Id"},"webhook_endpoint_id":{"type":"integer","title":"Webhook Endpoint Id"}},"type":"object","required":["snippets","company_id","watch_id","webhook_endpoint_id"],"title":"QuickstartResponse"},"RepostPainItem":{"properties":{"title":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Title"},"function":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Function"},"country":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Country"},"first_seen":{"type":"string","format":"date-time","title":"First Seen","description":"Our first observation of this req (not the employer's posting date). The `since` parameter filters on this value."},"source_posted_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Source Posted At","description":"The posting date the source itself published for this req. Null when the source gave no date, or none has been recorded yet -- `first_seen` is then the only date we hold, and it is our observation time."},"repost_count":{"$ref":"#/components/schemas/ProvenanceOut"},"country_code":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Country Code","description":"The posting country's ISO-3166-1 alpha-2 code, uppercase (`DE`, `US`), derived from `country` and never stored. `null` when `country` is absent or is not a country this corpus names — never a guess. Note this is an output only: the `geo`/`country` filter still takes the name, because a bare two-letter code is ambiguous on input (`CA` is Canada to ISO and California to this column).","readOnly":true},"function_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Function Name","description":"The job function's human-readable name (`Software & IT`, `Healthcare`), derived from `function` and never stored. The `?function=` filter accepts this name as well as the opaque taxonomy id in `function`. `null` when the req carries no function attribution (`unspecified`, 10.2% of served reqs), or when it was classified from its skills alone, so its id is outside the named title-family vocabulary (16.7%) — never a guess and never the raw id. Named on 73.1% of served reqs (309,251 of 422,826, measured 2026-10-07).","readOnly":true}},"type":"object","required":["title","function","country","first_seen","repost_count","country_code","function_name"],"title":"RepostPainItem"},"RepostPainResponse":{"properties":{"reqs":{"items":{"$ref":"#/components/schemas/RepostPainItem"},"type":"array","title":"Reqs"},"as_of":{"type":"string","format":"date-time","title":"As Of"}},"type":"object","required":["reqs","as_of"],"title":"RepostPainResponse"},"ReqsSearchResponse":{"properties":{"companies":{"items":{"$ref":"#/components/schemas/CompanyMatchOut"},"type":"array","title":"Companies"},"next_cursor":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Next Cursor"},"as_of":{"type":"string","format":"date-time","title":"As Of"}},"type":"object","required":["companies","next_cursor","as_of"],"title":"ReqsSearchResponse"},"ResolvedImportRow":{"properties":{"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"domain":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Domain"},"company_id":{"type":"integer","title":"Company Id"},"enrichment":{"additionalProperties":true,"type":"object","title":"Enrichment"}},"type":"object","required":["name","domain","company_id","enrichment"],"title":"ResolvedImportRow"},"RoleDemandPoint":{"properties":{"bucket":{"type":"string","format":"date-time","title":"Bucket"},"active_reqs":{"type":"integer","title":"Active Reqs"}},"type":"object","required":["bucket","active_reqs"],"title":"RoleDemandPoint"},"RoleDemandResponse":{"properties":{"series":{"items":{"$ref":"#/components/schemas/RoleDemandPoint"},"type":"array","title":"Series"},"as_of":{"type":"string","format":"date-time","title":"As Of"}},"type":"object","required":["series","as_of"],"title":"RoleDemandResponse"},"RoleOut":{"properties":{"req_key":{"type":"string","title":"Req Key"},"company_id":{"type":"integer","title":"Company Id"},"company_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Company Name"},"company_domain":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Company Domain"},"title":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Title"},"function":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Function"},"country":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Country"},"first_seen":{"type":"string","format":"date-time","title":"First Seen","description":"Our first observation of this req (not the employer's posting date). The `since` parameter filters on this value."},"source_posted_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Source Posted At","description":"The posting date the source itself published for this req. Null when the source gave no date, or none has been recorded yet -- `first_seen` is then the only date we hold, and it is our observation time."},"board":{"type":"string","title":"Board"},"source_type":{"anyOf":[{"type":"string","enum":["ats_tenant","board"]},{"type":"null"}],"title":"Source Type","description":"What kind of source this req was most recently read from: 'ats_tenant' (the employer's own applicant tracking system) or 'board' (a job board or aggregator). Most served reqs are 'board'; pass `source_type=ats_tenant` to keep only the ones read from the employer's own system."},"relevance":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Relevance"},"raw_title":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Raw Title"},"boards":{"items":{"type":"string"},"type":"array","title":"Boards"},"country_code":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Country Code","description":"The posting country's ISO-3166-1 alpha-2 code, uppercase (`DE`, `US`), derived from `country` and never stored. `null` when `country` is absent or is not a country this corpus names — never a guess. Note this is an output only: the `geo`/`country` filter still takes the name, because a bare two-letter code is ambiguous on input (`CA` is Canada to ISO and California to this column).","readOnly":true},"function_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Function Name","description":"The job function's human-readable name (`Software & IT`, `Healthcare`), derived from `function` and never stored. The `?function=` filter accepts this name as well as the opaque taxonomy id in `function`. `null` when the req carries no function attribution (`unspecified`, 10.2% of served reqs), or when it was classified from its skills alone, so its id is outside the named title-family vocabulary (16.7%) — never a guess and never the raw id. Named on 73.1% of served reqs (309,251 of 422,826, measured 2026-10-07).","readOnly":true}},"type":"object","required":["req_key","company_id","title","function","country","first_seen","board","raw_title","boards","country_code","function_name"],"title":"RoleOut","description":"One role's detail: the `JobOut` row `/jobs/search` serves, plus the two\nfacts a page deliberately withholds (signalsapi-4836)."},"RoleResponse":{"properties":{"role":{"$ref":"#/components/schemas/RoleOut"},"as_of":{"type":"string","format":"date-time","title":"As Of"}},"type":"object","required":["role","as_of"],"title":"RoleResponse"},"RotateKeyRequest":{"properties":{"scopes":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Scopes"}},"type":"object","title":"RotateKeyRequest"},"UpgradePromptOut":{"properties":{"reason":{"type":"string","title":"Reason"},"upgrade_url":{"type":"string","title":"Upgrade Url"}},"type":"object","required":["reason","upgrade_url"],"title":"UpgradePromptOut"},"UsageDashboardResponse":{"properties":{"keys":{"items":{"$ref":"#/components/schemas/KeyUsageOut"},"type":"array","title":"Keys"},"account_used":{"type":"integer","title":"Account Used"},"account_hard_cap":{"type":"integer","title":"Account Hard Cap"},"account_soft_cap":{"type":"integer","title":"Account Soft Cap"},"sla_credit_units":{"type":"integer","title":"Sla Credit Units"},"referral_credit_units":{"type":"integer","title":"Referral Credit Units"},"account_status":{"type":"string","title":"Account Status"},"expansion_nudge_triggered":{"type":"boolean","title":"Expansion Nudge Triggered"},"upgrade_prompt":{"anyOf":[{"$ref":"#/components/schemas/UpgradePromptOut"},{"type":"null"}]},"free_tier":{"anyOf":[{"$ref":"#/components/schemas/FreeTierAllowanceOut"},{"type":"null"}]},"blocked_deliveries":{"$ref":"#/components/schemas/BlockedDeliveriesOut"}},"type":"object","required":["keys","account_used","account_hard_cap","account_soft_cap","sla_credit_units","referral_credit_units","account_status","expansion_nudge_triggered","upgrade_prompt","free_tier","blocked_deliveries"],"title":"UsageDashboardResponse"},"UsageResponse":{"properties":{"calls":{"type":"integer","title":"Calls"},"changes":{"type":"integer","title":"Changes"},"watches":{"type":"integer","title":"Watches"},"forced_fresh":{"type":"integer","title":"Forced Fresh"},"by_meter_class":{"additionalProperties":{"type":"integer"},"type":"object","title":"By Meter Class"},"keys":{"items":{"$ref":"#/components/schemas/KeyUsageBreakdown"},"type":"array","title":"Keys"}},"type":"object","required":["calls","changes","watches","forced_fresh","by_meter_class","keys"],"title":"UsageResponse"},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"},"input":{"title":"Input"},"ctx":{"type":"object","title":"Context"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"},"WatchResponse":{"properties":{"id":{"type":"integer","title":"Id"},"company_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Company Id"},"criteria":{"anyOf":[{"$ref":"#/components/schemas/Criteria"},{"type":"null"}]},"event_types":{"items":{"type":"string"},"type":"array","title":"Event Types"},"webhook_endpoint_id":{"type":"integer","title":"Webhook Endpoint Id"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"fires_last_hour":{"type":"integer","title":"Fires Last Hour"},"max_fires_per_hour":{"type":"integer","title":"Max Fires Per Hour"},"rate_limited":{"type":"boolean","title":"Rate Limited"},"last_fired_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Last Fired At"},"fires_last_7d":{"type":"integer","title":"Fires Last 7D"},"fires_last_30d":{"type":"integer","title":"Fires Last 30D"},"status":{"type":"string","title":"Status"}},"type":"object","required":["id","event_types","webhook_endpoint_id","created_at","fires_last_hour","max_fires_per_hour","rate_limited","fires_last_7d","fires_last_30d","status"],"title":"WatchResponse","description":"One live watch, as its owner sees it (signalsapi-3963). `criteria` is\nechoed exactly as it was authored -- `watch_criteria.parse()` normalizes on\nthe read side at fan-out, so the row is the customer's own text.\n\nThe three rate fields (signalsapi-4442) are what tell a CAPPED watch from a\nquiet one: without them a watch saturating its declared\n`max_fires_per_hour` -- whose excess fires are dropped, not queued -- looked\nbyte-identical to one nobody is hiring against.\n\nThe four heartbeat fields (signalsapi-4443) answer the question one rung\nbefore that: a watch firing NOTHING was indistinguishable from one that is\nbroken, wall-blocked, or matching a criteria set that can never match.\n`last_fired_at` is when it last matched anything (`null` if never) and\n`status` is one of `watch_service.WATCH_STATUSES` -- the one-word reason,\nnever a boolean, because \"upgrade the plan\", \"raise your own cap\" and \"fix\nyour endpoint\" are three different fixes that must not render the same."},"WhoamiResponse":{"properties":{"customer_id":{"type":"string","title":"Customer Id"},"account_id":{"type":"integer","title":"Account Id"},"tier":{"type":"string","title":"Tier","description":"The id of the tier this key runs on, e.g. 'tier_1' -- the value `/v1/pricing` lists as `quota_tier`."},"tier_name":{"type":"string","title":"Tier Name","description":"The public name of that tier, e.g. 'Trial' -- the name `/v1/pricing` lists it under. It names the limits the key runs on, not what the account is billed."},"scopes":{"items":{"type":"string"},"type":"array","title":"Scopes"}},"type":"object","required":["customer_id","account_id","tier","tier_name","scopes"],"title":"WhoamiResponse"},"WriteOutcomeRequest":{"properties":{"req_key":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Req Key"},"outcome":{"type":"string","title":"Outcome"},"observed_at":{"type":"string","format":"date-time","title":"Observed At"}},"type":"object","required":["outcome","observed_at"],"title":"WriteOutcomeRequest"},"WriteOutcomeResponse":{"properties":{"id":{"type":"integer","title":"Id"}},"type":"object","required":["id"],"title":"WriteOutcomeResponse"}},"securitySchemes":{"APIKeyHeader":{"type":"apiKey","in":"header","name":"X-API-Key"}}}}