{"openapi":"3.1.1","info":{"title":"RKTAD Partner Reverse IP API","version":"1.14.2","description":"Company lookup with asynchronous enrichment. API keys belong in the Authorization header. GET polls without submitting work; POST requests enrichment on a miss. Saved results include all available company fields, even for ISP or unclassified connections. Expired results can be refreshed with POST. Response examples are illustrative; documentation IP addresses cannot be used for real lookups. Use a public IP when testing. 202 is pending, not a negative match. The error-code catalog is available in x-error-codes."},"servers":[{"url":"https://partner.rktad.com"}],"security":[{"bearerAuth":[]}],"paths":{"/v1/lookup":{"post":{"operationId":"lookupOrEnrich","summary":"Look up an IP; request enrichment if unknown","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["ip"],"additionalProperties":false,"properties":{"ip":{"type":"string","maxLength":45,"description":"Exactly one public IPv4 or global-unicast IPv6 address. IPv4-mapped IPv6 is accepted. URL-encode the value. URLs, ports, CIDRs, zone identifiers, private and reserved addresses are rejected."}}},"examples":{"ipv4":{"value":{"ip":"8.8.8.8"}},"ipv6":{"value":{"ip":"2606:4700:4700::1111"}}}}}},"responses":{"200":{"description":"Completed company, ISP or unclassified lookup","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Lookup"},"examples":{"company":{"summary":"200 · Company found","value":{"ip":"203.0.113.10","matched_ip":"203.0.113.10","status":"complete","match_type":"company","company_found":true,"enriched_at":"2026-09-18T12:00:00.000Z","stale":false,"fresh_until":"2026-10-18T12:00:00.000Z","refresh_status":"not_needed","refresh_error":null,"network":{"connection_type":"Business","audience_type":"Business","audience_group":null,"detail_level":null,"is_isp":false},"company":{"name":"Example Company","website":"example.com","brand_name":null,"linkedin_url":null,"industry":"Software","industry_subcategory":null,"employees":"120","annual_revenue":null,"revenue_band":null,"naics_code":"541511","sic_code":null,"city":"London","region":null,"postal_code":null,"country_code":"GB","country_name":"United Kingdom"},"request_id":"00000000-0000-4000-8000-000000000001"}},"isp":{"summary":"200 · ISP","value":{"ip":"203.0.113.10","matched_ip":"203.0.113.10","status":"complete","match_type":"isp","company_found":false,"enriched_at":"2026-09-18T12:00:00.000Z","stale":false,"fresh_until":"2026-09-25T12:00:00.000Z","refresh_status":"not_needed","refresh_error":null,"network":{"connection_type":"Business","audience_type":"Business","audience_group":null,"detail_level":null,"is_isp":true},"company":{"name":"Example Company","website":"example.com","brand_name":null,"linkedin_url":null,"industry":"Software","industry_subcategory":null,"employees":"120","annual_revenue":null,"revenue_band":null,"naics_code":"541511","sic_code":null,"city":"London","region":null,"postal_code":null,"country_code":"GB","country_name":"United Kingdom"},"request_id":"00000000-0000-4000-8000-000000000001"}},"unclassified":{"summary":"200 · Unclassified","value":{"ip":"203.0.113.10","matched_ip":"203.0.113.10","status":"complete","match_type":"unclassified","company_found":false,"enriched_at":"2026-09-18T12:00:00.000Z","stale":false,"fresh_until":"2026-09-25T12:00:00.000Z","refresh_status":"not_needed","refresh_error":null,"network":{"connection_type":"Business","audience_type":"Business","audience_group":null,"detail_level":null,"is_isp":null},"company":null,"request_id":"00000000-0000-4000-8000-000000000001"}},"refreshing":{"summary":"200 · Saved data, refreshing","value":{"ip":"203.0.113.10","matched_ip":"203.0.113.10","status":"complete","match_type":"company","company_found":true,"enriched_at":"2026-08-01T12:00:00.000Z","stale":true,"fresh_until":"2026-08-31T12:00:00.000Z","refresh_status":"pending","refresh_error":null,"network":{"connection_type":"Business","audience_type":"Business","audience_group":null,"detail_level":null,"is_isp":false},"company":{"name":"Example Company","website":"example.com","brand_name":null,"linkedin_url":null,"industry":"Software","industry_subcategory":null,"employees":"120","annual_revenue":null,"revenue_band":null,"naics_code":"541511","sic_code":null,"city":"London","region":null,"postal_code":null,"country_code":"GB","country_name":"United Kingdom"},"request_id":"00000000-0000-4000-8000-000000000001"}},"additional_pending":{"summary":"200 · Saved ISP, company lookup pending","value":{"ip":"203.0.113.10","matched_ip":"203.0.113.10","status":"complete","match_type":"isp","company_found":false,"enriched_at":"2026-09-18T12:00:00.000Z","stale":false,"fresh_until":"2026-09-25T12:00:00.000Z","refresh_status":"pending","refresh_error":null,"network":{"connection_type":"Business","audience_type":"Business","audience_group":null,"detail_level":null,"is_isp":true},"company":null,"request_id":"00000000-0000-4000-8000-000000000001"}},"refresh_deferred":{"summary":"200 · Saved data, refresh deferred","value":{"ip":"203.0.113.10","matched_ip":"203.0.113.10","status":"complete","match_type":"company","company_found":true,"enriched_at":"2026-08-01T12:00:00.000Z","stale":true,"fresh_until":"2026-08-31T12:00:00.000Z","refresh_status":"deferred","refresh_error":"pending_limit","network":{"connection_type":"Business","audience_type":"Business","audience_group":null,"detail_level":null,"is_isp":false},"company":{"name":"Example Company","website":"example.com","brand_name":null,"linkedin_url":null,"industry":"Software","industry_subcategory":null,"employees":"120","annual_revenue":null,"revenue_band":null,"naics_code":"541511","sic_code":null,"city":"London","region":null,"postal_code":null,"country_code":"GB","country_name":"United Kingdom"},"request_id":"00000000-0000-4000-8000-000000000001"}},"company_clues":{"summary":"200 · With company clues","value":{"ip":"203.0.113.10","matched_ip":"203.0.113.10","status":"complete","match_type":"company","company_found":true,"enriched_at":"2026-09-18T12:00:00.000Z","stale":false,"fresh_until":"2026-10-18T12:00:00.000Z","refresh_status":"not_needed","refresh_error":null,"network":{"connection_type":"Business","audience_type":"Business","audience_group":null,"detail_level":null,"is_isp":false},"company":{"name":"Example Company","website":"example.com","brand_name":null,"linkedin_url":null,"industry":"Software","industry_subcategory":null,"employees":"120","annual_revenue":null,"revenue_band":null,"naics_code":"541511","sic_code":null,"city":"London","region":null,"postal_code":null,"country_code":"GB","country_name":"United Kingdom"},"request_id":"00000000-0000-4000-8000-000000000001","company_signals":{"status":"available","window_days":30,"truncated":false,"candidates":[{"domain":"example-business.org","company":null,"verified":false,"evidence":"field_only","first_seen_at":"2026-09-18T11:00:00.000Z","last_seen_at":"2026-09-18T12:00:00.000Z","observations":2,"submitted_observations":0,"observed_visits":1,"sites":1,"flags":["field_only","differs_from_lookup","unmatched_domain"]}]}}}}}},"headers":{"X-Request-ID":{"description":"Request identifier to share with support","schema":{"type":"string","format":"uuid"}},"Retry-After":{"schema":{"type":"integer"},"description":"Minimum delay before polling pending work or retrying deferred work."}}},"202":{"description":"Durably submitted; processing or retrying. No completion deadline is promised.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Pending"},"examples":{"pending":{"summary":"202 · Pending","value":{"ip":"203.0.113.10","lookup_ip":"203.0.113.10","status":"pending","company_found":null,"company":null,"submitted_at":"2026-09-18T12:00:00.000Z","attempts":0,"next_retry_at":null,"last_error":null,"status_url":"/v1/lookup?ip=203.0.113.10","poll_after_seconds":15,"request_id":"00000000-0000-4000-8000-000000000001"}},"retrying":{"summary":"202 · Retrying","value":{"ip":"203.0.113.10","lookup_ip":"203.0.113.10","status":"retrying","company_found":null,"company":null,"submitted_at":"2026-09-18T12:00:00.000Z","attempts":2,"next_retry_at":"2026-09-18T12:30:00.000Z","last_error":"lookup_failed","status_url":"/v1/lookup?ip=203.0.113.10","poll_after_seconds":15,"request_id":"00000000-0000-4000-8000-000000000001"}}}}},"headers":{"Location":{"schema":{"type":"string"}},"Retry-After":{"schema":{"type":"integer"},"description":"Suggested polling interval in seconds"},"X-Request-ID":{"description":"Request identifier to share with support","schema":{"type":"string","format":"uuid"}}},"links":{"pollLookup":{"operationId":"getLookup","parameters":{"ip":"$response.body#/lookup_ip"},"description":"Wait at least Retry-After seconds before polling with the same Bearer key."}}},"400":{"description":"Invalid input","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"invalid_ip":{"summary":"The IP is missing, malformed, private or reserved.","description":"Send one public IPv4 or IPv6 address, without a port, CIDR suffix or zone ID.","value":{"error":{"code":"invalid_ip","message":"The IP is missing, malformed, private or reserved."},"request_id":"00000000-0000-4000-8000-000000000001"}},"invalid_query":{"summary":"The query parameters do not match the endpoint.","description":"GET lookup needs exactly one ip parameter. POST lookup takes JSON, with no query string.","value":{"error":{"code":"invalid_query","message":"The query parameters do not match the endpoint."},"request_id":"00000000-0000-4000-8000-000000000001"}},"invalid_json":{"summary":"The request body is not valid JSON.","description":"Send valid JSON such as {\"ip\":\"8.8.8.8\"}.","value":{"error":{"code":"invalid_json","message":"The request body is not valid JSON."},"request_id":"00000000-0000-4000-8000-000000000001"}},"invalid_body":{"summary":"The JSON body has the wrong shape or extra fields.","description":"Send an object containing only ip. A missing or invalid ip returns invalid_ip.","value":{"error":{"code":"invalid_body","message":"The JSON body has the wrong shape or extra fields."},"request_id":"00000000-0000-4000-8000-000000000001"}}}}},"headers":{"X-Request-ID":{"description":"Request identifier to share with support","schema":{"type":"string","format":"uuid"}}}},"401":{"description":"Missing, invalid, expired or revoked API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"unauthorized":{"summary":"The key is missing, malformed, invalid, expired or revoked.","description":"Send exactly one Authorization: Bearer header with an active key. Contact your API administrator for a replacement.","value":{"error":{"code":"unauthorized","message":"The key is missing, malformed, invalid, expired or revoked."},"request_id":"00000000-0000-4000-8000-000000000001"}}}}},"headers":{"X-Request-ID":{"description":"Request identifier to share with support","schema":{"type":"string","format":"uuid"}},"WWW-Authenticate":{"schema":{"type":"string"},"example":"Bearer realm=\"partner\""}}},"413":{"description":"Body exceeds 1024 bytes","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"body_too_large":{"summary":"The request body exceeds 1,024 bytes.","description":"Submit one IP per request in a small JSON object.","value":{"error":{"code":"body_too_large","message":"The request body exceeds 1,024 bytes."},"request_id":"00000000-0000-4000-8000-000000000001"}}}}},"headers":{"X-Request-ID":{"description":"Request identifier to share with support","schema":{"type":"string","format":"uuid"}}}},"414":{"description":"Request URL exceeds 512 characters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"uri_too_long":{"summary":"The request URL exceeds 512 characters.","description":"Shorten the path and query. Never put your API key in the URL.","value":{"error":{"code":"uri_too_long","message":"The request URL exceeds 512 characters."},"request_id":"00000000-0000-4000-8000-000000000001"}}}}},"headers":{"X-Request-ID":{"description":"Request identifier to share with support","schema":{"type":"string","format":"uuid"}}}},"415":{"description":"Use uncompressed application/json","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"unsupported_media_type":{"summary":"The POST Content-Type is not application/json.","description":"Set Content-Type: application/json.","value":{"error":{"code":"unsupported_media_type","message":"The POST Content-Type is not application/json."},"request_id":"00000000-0000-4000-8000-000000000001"}},"unsupported_encoding":{"summary":"The request has a Content-Encoding header.","description":"Send uncompressed JSON without Content-Encoding.","value":{"error":{"code":"unsupported_encoding","message":"The request has a Content-Encoding header."},"request_id":"00000000-0000-4000-8000-000000000001"}}}}},"headers":{"X-Request-ID":{"description":"Request identifier to share with support","schema":{"type":"string","format":"uuid"}}}},"429":{"description":"Rate, enrichment allowance or capacity limit; retry later","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"rate_limit":{"summary":"This key has exceeded its request rate.","description":"Wait at least Retry-After seconds, then reduce concurrency. View your key limits with GET /v1/usage.","value":{"error":{"code":"rate_limit","message":"This key has exceeded its request rate."},"request_id":"00000000-0000-4000-8000-000000000001"}},"api_rate_limit":{"summary":"The API has reached its shared request capacity.","description":"Honor Retry-After, add jitter and retry with lower concurrency.","value":{"error":{"code":"api_rate_limit","message":"The API has reached its shared request capacity."},"request_id":"00000000-0000-4000-8000-000000000001"}},"lookup_capacity":{"summary":"Too many distinct IP lookups are in flight.","description":"Honor Retry-After and retry with fewer simultaneous lookups.","value":{"error":{"code":"lookup_capacity","message":"Too many distinct IP lookups are in flight."},"request_id":"00000000-0000-4000-8000-000000000001"}},"pending_limit":{"summary":"Your partner has reached its limit for unfinished enrichments.","description":"Wait for existing lookups to finish before submitting new IPs. View enrichment and limits in GET /v1/usage. Repeating an accepted IP is allowed.","value":{"error":{"code":"pending_limit","message":"Your partner has reached its limit for unfinished enrichments."},"request_id":"00000000-0000-4000-8000-000000000001"}},"enrichment_limit":{"summary":"This key has used its daily allowance for new enrichment reservations.","description":"Wait until the next UTC day or ask for a higher allowance. Existing saved lookups remain available; retrying every 15 seconds will not reset the allowance.","value":{"error":{"code":"enrichment_limit","message":"This key has used its daily allowance for new enrichment reservations."},"request_id":"00000000-0000-4000-8000-000000000001"}},"enrichment_capacity":{"summary":"The shared enrichment intake or outstanding-work limit is full.","description":"Honor Retry-After and use backoff. Repeated submissions do not speed up the lookup.","value":{"error":{"code":"enrichment_capacity","message":"The shared enrichment intake or outstanding-work limit is full."},"request_id":"00000000-0000-4000-8000-000000000001"}}}}},"headers":{"Retry-After":{"description":"Minimum retry delay in seconds. Daily allowances may require waiting until the next UTC day.","schema":{"type":"integer"}},"X-Request-ID":{"description":"Request identifier to share with support","schema":{"type":"string","format":"uuid"}}}},"503":{"description":"Lookup, usage reporting or enrichment temporarily unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"api_busy":{"summary":"The API is temporarily busy.","description":"Honor Retry-After (normally 5 seconds for this code) and retry with backoff.","value":{"error":{"code":"api_busy","message":"Service temporarily unavailable; retry later"},"request_id":"00000000-0000-4000-8000-000000000001"}},"backend_unavailable":{"summary":"The lookup or enrichment request could not be completed.","description":"Retry with backoff. A failed POST response does not prove submission failed; repeating the same POST is safe.","value":{"error":{"code":"backend_unavailable","message":"Service temporarily unavailable; retry later"},"request_id":"00000000-0000-4000-8000-000000000001"}},"backend_timeout":{"summary":"The request took too long to complete.","description":"Retry with backoff. Do not interpret a timeout as a no-company result.","value":{"error":{"code":"backend_timeout","message":"Service temporarily unavailable; retry later"},"request_id":"00000000-0000-4000-8000-000000000001"}},"submission_unconfirmed":{"summary":"An enrichment reservation exists, but acceptance was not confirmed.","description":"Repeat POST for the same IP to confirm submission, then poll with GET.","value":{"error":{"code":"submission_unconfirmed","message":"Service temporarily unavailable; retry later"},"request_id":"00000000-0000-4000-8000-000000000001"}},"lookup_reconciliation_required":{"summary":"Work is marked complete, but the saved lookup is unavailable.","description":"Retry later; if persistent, share request_id with your API administrator.","value":{"error":{"code":"lookup_reconciliation_required","message":"Service temporarily unavailable; retry later"},"request_id":"00000000-0000-4000-8000-000000000001"}},"usage_unavailable":{"summary":"Usage reporting is temporarily unavailable.","description":"Retry with backoff. A POST may already have been submitted; repeating the same IP is safe.","value":{"error":{"code":"usage_unavailable","message":"Service temporarily unavailable; retry later"},"request_id":"00000000-0000-4000-8000-000000000001"}},"service_unavailable":{"summary":"An unexpected temporary service failure occurred.","description":"Honor Retry-After and retry with backoff; share request_id if the error persists.","value":{"error":{"code":"service_unavailable","message":"Service temporarily unavailable; retry later"},"request_id":"00000000-0000-4000-8000-000000000001"}}}}},"headers":{"X-Request-ID":{"description":"Request identifier to share with support","schema":{"type":"string","format":"uuid"}},"Retry-After":{"description":"Minimum retry delay in seconds. Daily allowances may require waiting until the next UTC day.","schema":{"type":"integer"}}}},"default":{"description":"Unexpected application error; inspect HTTP status and error.code. Proxy/network failures can be non-JSON.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"headers":{"X-Request-ID":{"description":"Request identifier to share with support","schema":{"type":"string","format":"uuid"}}}}},"tags":["Lookups"],"description":"Submit exactly one public IP as JSON with no additional fields or query parameters. If a successful saved result exists, return HTTP 200 with all available fields. If the saved result needs refreshing or additional company enrichment, POST requests that work within existing limits: refresh_status=pending confirms acceptance, deferred means inspect refresh_error and retry POST later. GET never starts a refresh. Use fresh_until for result expiry, based on enrichment time rather than API reads. Poll GET on the same IP every Retry-After seconds until stale=false and refresh_status=not_needed; use a caller-defined overall deadline. Otherwise acknowledge durable enrichment submission with HTTP 202. Repeating POST for the same IP does not request duplicate enrichment. After 202, poll getLookup using status_url and wait at least Retry-After seconds. Completion time is not guaranteed. A timeout or 503 does not prove submission failed; repeat the same POST to confirm. New and refresh reservations consume a daily budget only when one is set; reading saved results does not. limits.new_enrichments_per_day=null means no daily cap; 0 disables new reservations. Shared intake and pending-work limits still apply."},"get":{"operationId":"getLookup","summary":"Read a saved lookup or poll a pending request","parameters":[{"name":"ip","in":"query","required":true,"schema":{"type":"string","maxLength":45},"example":"8.8.8.8","description":"Exactly one public IPv4 or global-unicast IPv6 address. IPv4-mapped IPv6 is accepted. URL-encode the value. URLs, ports, CIDRs, zone identifiers, private and reserved addresses are rejected."}],"responses":{"200":{"description":"Completed company, ISP or unclassified lookup","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Lookup"},"examples":{"company":{"summary":"200 · Company found","value":{"ip":"203.0.113.10","matched_ip":"203.0.113.10","status":"complete","match_type":"company","company_found":true,"enriched_at":"2026-09-18T12:00:00.000Z","stale":false,"fresh_until":"2026-10-18T12:00:00.000Z","refresh_status":"not_needed","refresh_error":null,"network":{"connection_type":"Business","audience_type":"Business","audience_group":null,"detail_level":null,"is_isp":false},"company":{"name":"Example Company","website":"example.com","brand_name":null,"linkedin_url":null,"industry":"Software","industry_subcategory":null,"employees":"120","annual_revenue":null,"revenue_band":null,"naics_code":"541511","sic_code":null,"city":"London","region":null,"postal_code":null,"country_code":"GB","country_name":"United Kingdom"},"request_id":"00000000-0000-4000-8000-000000000001"}},"isp":{"summary":"200 · ISP","value":{"ip":"203.0.113.10","matched_ip":"203.0.113.10","status":"complete","match_type":"isp","company_found":false,"enriched_at":"2026-09-18T12:00:00.000Z","stale":false,"fresh_until":"2026-09-25T12:00:00.000Z","refresh_status":"not_needed","refresh_error":null,"network":{"connection_type":"Business","audience_type":"Business","audience_group":null,"detail_level":null,"is_isp":true},"company":{"name":"Example Company","website":"example.com","brand_name":null,"linkedin_url":null,"industry":"Software","industry_subcategory":null,"employees":"120","annual_revenue":null,"revenue_band":null,"naics_code":"541511","sic_code":null,"city":"London","region":null,"postal_code":null,"country_code":"GB","country_name":"United Kingdom"},"request_id":"00000000-0000-4000-8000-000000000001"}},"unclassified":{"summary":"200 · Unclassified","value":{"ip":"203.0.113.10","matched_ip":"203.0.113.10","status":"complete","match_type":"unclassified","company_found":false,"enriched_at":"2026-09-18T12:00:00.000Z","stale":false,"fresh_until":"2026-09-25T12:00:00.000Z","refresh_status":"not_needed","refresh_error":null,"network":{"connection_type":"Business","audience_type":"Business","audience_group":null,"detail_level":null,"is_isp":null},"company":null,"request_id":"00000000-0000-4000-8000-000000000001"}},"refreshing":{"summary":"200 · Saved data, refreshing","value":{"ip":"203.0.113.10","matched_ip":"203.0.113.10","status":"complete","match_type":"company","company_found":true,"enriched_at":"2026-08-01T12:00:00.000Z","stale":true,"fresh_until":"2026-08-31T12:00:00.000Z","refresh_status":"pending","refresh_error":null,"network":{"connection_type":"Business","audience_type":"Business","audience_group":null,"detail_level":null,"is_isp":false},"company":{"name":"Example Company","website":"example.com","brand_name":null,"linkedin_url":null,"industry":"Software","industry_subcategory":null,"employees":"120","annual_revenue":null,"revenue_band":null,"naics_code":"541511","sic_code":null,"city":"London","region":null,"postal_code":null,"country_code":"GB","country_name":"United Kingdom"},"request_id":"00000000-0000-4000-8000-000000000001"}},"additional_pending":{"summary":"200 · Saved ISP, company lookup pending","value":{"ip":"203.0.113.10","matched_ip":"203.0.113.10","status":"complete","match_type":"isp","company_found":false,"enriched_at":"2026-09-18T12:00:00.000Z","stale":false,"fresh_until":"2026-09-25T12:00:00.000Z","refresh_status":"pending","refresh_error":null,"network":{"connection_type":"Business","audience_type":"Business","audience_group":null,"detail_level":null,"is_isp":true},"company":null,"request_id":"00000000-0000-4000-8000-000000000001"}},"refresh_deferred":{"summary":"200 · Saved data, refresh deferred","value":{"ip":"203.0.113.10","matched_ip":"203.0.113.10","status":"complete","match_type":"company","company_found":true,"enriched_at":"2026-08-01T12:00:00.000Z","stale":true,"fresh_until":"2026-08-31T12:00:00.000Z","refresh_status":"deferred","refresh_error":"pending_limit","network":{"connection_type":"Business","audience_type":"Business","audience_group":null,"detail_level":null,"is_isp":false},"company":{"name":"Example Company","website":"example.com","brand_name":null,"linkedin_url":null,"industry":"Software","industry_subcategory":null,"employees":"120","annual_revenue":null,"revenue_band":null,"naics_code":"541511","sic_code":null,"city":"London","region":null,"postal_code":null,"country_code":"GB","country_name":"United Kingdom"},"request_id":"00000000-0000-4000-8000-000000000001"}},"company_clues":{"summary":"200 · With company clues","value":{"ip":"203.0.113.10","matched_ip":"203.0.113.10","status":"complete","match_type":"company","company_found":true,"enriched_at":"2026-09-18T12:00:00.000Z","stale":false,"fresh_until":"2026-10-18T12:00:00.000Z","refresh_status":"not_needed","refresh_error":null,"network":{"connection_type":"Business","audience_type":"Business","audience_group":null,"detail_level":null,"is_isp":false},"company":{"name":"Example Company","website":"example.com","brand_name":null,"linkedin_url":null,"industry":"Software","industry_subcategory":null,"employees":"120","annual_revenue":null,"revenue_band":null,"naics_code":"541511","sic_code":null,"city":"London","region":null,"postal_code":null,"country_code":"GB","country_name":"United Kingdom"},"request_id":"00000000-0000-4000-8000-000000000001","company_signals":{"status":"available","window_days":30,"truncated":false,"candidates":[{"domain":"example-business.org","company":null,"verified":false,"evidence":"field_only","first_seen_at":"2026-09-18T11:00:00.000Z","last_seen_at":"2026-09-18T12:00:00.000Z","observations":2,"submitted_observations":0,"observed_visits":1,"sites":1,"flags":["field_only","differs_from_lookup","unmatched_domain"]}]}}}}}},"headers":{"X-Request-ID":{"description":"Request identifier to share with support","schema":{"type":"string","format":"uuid"}},"Retry-After":{"schema":{"type":"integer"},"description":"Minimum delay before polling pending work or retrying deferred work."}}},"202":{"description":"Durably submitted; processing or retrying. No completion deadline is promised.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Pending"},"examples":{"pending":{"summary":"202 · Pending","value":{"ip":"203.0.113.10","lookup_ip":"203.0.113.10","status":"pending","company_found":null,"company":null,"submitted_at":"2026-09-18T12:00:00.000Z","attempts":0,"next_retry_at":null,"last_error":null,"status_url":"/v1/lookup?ip=203.0.113.10","poll_after_seconds":15,"request_id":"00000000-0000-4000-8000-000000000001"}},"retrying":{"summary":"202 · Retrying","value":{"ip":"203.0.113.10","lookup_ip":"203.0.113.10","status":"retrying","company_found":null,"company":null,"submitted_at":"2026-09-18T12:00:00.000Z","attempts":2,"next_retry_at":"2026-09-18T12:30:00.000Z","last_error":"lookup_failed","status_url":"/v1/lookup?ip=203.0.113.10","poll_after_seconds":15,"request_id":"00000000-0000-4000-8000-000000000001"}}}}},"headers":{"Location":{"schema":{"type":"string"}},"Retry-After":{"schema":{"type":"integer"},"description":"Suggested polling interval in seconds"},"X-Request-ID":{"description":"Request identifier to share with support","schema":{"type":"string","format":"uuid"}}}},"400":{"description":"Invalid input","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"invalid_ip":{"summary":"The IP is missing, malformed, private or reserved.","description":"Send one public IPv4 or IPv6 address, without a port, CIDR suffix or zone ID.","value":{"error":{"code":"invalid_ip","message":"The IP is missing, malformed, private or reserved."},"request_id":"00000000-0000-4000-8000-000000000001"}},"invalid_query":{"summary":"The query parameters do not match the endpoint.","description":"GET lookup needs exactly one ip parameter. POST lookup takes JSON, with no query string.","value":{"error":{"code":"invalid_query","message":"The query parameters do not match the endpoint."},"request_id":"00000000-0000-4000-8000-000000000001"}}}}},"headers":{"X-Request-ID":{"description":"Request identifier to share with support","schema":{"type":"string","format":"uuid"}}}},"401":{"description":"Missing, invalid, expired or revoked API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"unauthorized":{"summary":"The key is missing, malformed, invalid, expired or revoked.","description":"Send exactly one Authorization: Bearer header with an active key. Contact your API administrator for a replacement.","value":{"error":{"code":"unauthorized","message":"The key is missing, malformed, invalid, expired or revoked."},"request_id":"00000000-0000-4000-8000-000000000001"}}}}},"headers":{"X-Request-ID":{"description":"Request identifier to share with support","schema":{"type":"string","format":"uuid"}},"WWW-Authenticate":{"schema":{"type":"string"},"example":"Bearer realm=\"partner\""}}},"404":{"description":"No saved result or API submission; use POST to request enrichment","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"not_requested":{"summary":"GET found no saved result and no API enrichment submission.","description":"POST the same IP to request enrichment, then poll with GET. This is not a confirmed no-company result.","value":{"error":{"code":"not_requested","message":"GET found no saved result and no API enrichment submission."},"request_id":"00000000-0000-4000-8000-000000000001"}}}}},"headers":{"X-Request-ID":{"description":"Request identifier to share with support","schema":{"type":"string","format":"uuid"}}}},"414":{"description":"Request URL exceeds 512 characters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"uri_too_long":{"summary":"The request URL exceeds 512 characters.","description":"Shorten the path and query. Never put your API key in the URL.","value":{"error":{"code":"uri_too_long","message":"The request URL exceeds 512 characters."},"request_id":"00000000-0000-4000-8000-000000000001"}}}}},"headers":{"X-Request-ID":{"description":"Request identifier to share with support","schema":{"type":"string","format":"uuid"}}}},"429":{"description":"Rate, enrichment allowance or capacity limit; retry later","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"rate_limit":{"summary":"This key has exceeded its request rate.","description":"Wait at least Retry-After seconds, then reduce concurrency. View your key limits with GET /v1/usage.","value":{"error":{"code":"rate_limit","message":"This key has exceeded its request rate."},"request_id":"00000000-0000-4000-8000-000000000001"}},"api_rate_limit":{"summary":"The API has reached its shared request capacity.","description":"Honor Retry-After, add jitter and retry with lower concurrency.","value":{"error":{"code":"api_rate_limit","message":"The API has reached its shared request capacity."},"request_id":"00000000-0000-4000-8000-000000000001"}},"lookup_capacity":{"summary":"Too many distinct IP lookups are in flight.","description":"Honor Retry-After and retry with fewer simultaneous lookups.","value":{"error":{"code":"lookup_capacity","message":"Too many distinct IP lookups are in flight."},"request_id":"00000000-0000-4000-8000-000000000001"}}}}},"headers":{"Retry-After":{"description":"Minimum retry delay in seconds. Daily allowances may require waiting until the next UTC day.","schema":{"type":"integer"}},"X-Request-ID":{"description":"Request identifier to share with support","schema":{"type":"string","format":"uuid"}}}},"503":{"description":"Lookup, usage reporting or enrichment temporarily unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"api_busy":{"summary":"The API is temporarily busy.","description":"Honor Retry-After (normally 5 seconds for this code) and retry with backoff.","value":{"error":{"code":"api_busy","message":"Service temporarily unavailable; retry later"},"request_id":"00000000-0000-4000-8000-000000000001"}},"backend_unavailable":{"summary":"The lookup or enrichment request could not be completed.","description":"Retry with backoff. A failed POST response does not prove submission failed; repeating the same POST is safe.","value":{"error":{"code":"backend_unavailable","message":"Service temporarily unavailable; retry later"},"request_id":"00000000-0000-4000-8000-000000000001"}},"backend_timeout":{"summary":"The request took too long to complete.","description":"Retry with backoff. Do not interpret a timeout as a no-company result.","value":{"error":{"code":"backend_timeout","message":"Service temporarily unavailable; retry later"},"request_id":"00000000-0000-4000-8000-000000000001"}},"submission_unconfirmed":{"summary":"An enrichment reservation exists, but acceptance was not confirmed.","description":"Repeat POST for the same IP to confirm submission, then poll with GET.","value":{"error":{"code":"submission_unconfirmed","message":"Service temporarily unavailable; retry later"},"request_id":"00000000-0000-4000-8000-000000000001"}},"lookup_reconciliation_required":{"summary":"Work is marked complete, but the saved lookup is unavailable.","description":"Retry later; if persistent, share request_id with your API administrator.","value":{"error":{"code":"lookup_reconciliation_required","message":"Service temporarily unavailable; retry later"},"request_id":"00000000-0000-4000-8000-000000000001"}},"usage_unavailable":{"summary":"Usage reporting is temporarily unavailable.","description":"Retry with backoff. A POST may already have been submitted; repeating the same IP is safe.","value":{"error":{"code":"usage_unavailable","message":"Service temporarily unavailable; retry later"},"request_id":"00000000-0000-4000-8000-000000000001"}},"service_unavailable":{"summary":"An unexpected temporary service failure occurred.","description":"Honor Retry-After and retry with backoff; share request_id if the error persists.","value":{"error":{"code":"service_unavailable","message":"Service temporarily unavailable; retry later"},"request_id":"00000000-0000-4000-8000-000000000001"}}}}},"headers":{"X-Request-ID":{"description":"Request identifier to share with support","schema":{"type":"string","format":"uuid"}},"Retry-After":{"description":"Minimum retry delay in seconds. Daily allowances may require waiting until the next UTC day.","schema":{"type":"integer"}}}},"default":{"description":"Unexpected application error; inspect HTTP status and error.code. Proxy/network failures can be non-JSON.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"headers":{"X-Request-ID":{"description":"Request identifier to share with support","schema":{"type":"string","format":"uuid"}}}}},"tags":["Lookups"],"description":"Read a saved result or poll an API-submitted IP. This operation never starts enrichment. HTTP 200 is complete: company_found=true and match_type=company indicate a non-ISP company classification. The company object contains all available company fields regardless of classification, and is null only when none are available. HTTP 202 is pending or retrying, not a negative match. HTTP 404 not_requested means no saved result or API submission exists; call lookupOrEnrich if enrichment is wanted. Transport and application errors must never be interpreted as company_found=false."}},"/v1/usage":{"get":{"operationId":"getOwnUsage","summary":"Usage belonging only to the calling API key","description":"UTC hourly counters. Maximum 31-day range. Default: today. Only authenticated lookup responses count, including GET polls, invalid lookup requests and per-key rate limits. Usage/docs/health calls and invalid keys do not count. Counters are committed before responding; they measure server responses prepared, not guaranteed client receipt. Enrichment status is a current snapshot shared by keys belonging to the same partner. Historical usage counters remain exclusive to the calling key.","parameters":[{"name":"from","in":"query","schema":{"type":"string","format":"date"},"description":"Inclusive UTC date"},{"name":"to","in":"query","schema":{"type":"string","format":"date"},"description":"Exclusive UTC date"}],"responses":{"200":{"description":"Usage for the current key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Usage"},"examples":{"usage":{"summary":"200 · Usage","value":{"key_id":"example-key-id","name":"Example partner","from":"2026-09-18T00:00:00Z","to":"2026-09-19T00:00:00Z","timezone":"UTC","limits":{"requests_per_second":1100,"new_enrichments_per_day":null,"pending_enrichments":500},"totals":{"requests":2,"cache_hits":1,"average_processing_ms":12.5},"outcomes":{"company":2},"hourly":[{"hour":"2026-09-18T12:00:00Z","outcome":"company","requests":2,"cache_hits":1,"duration_ms":25}],"enrichment":{"pending":0,"submission_unconfirmed":0,"retrying":0,"oldest_pending_at":null,"oldest_checked_at":null,"completed_observed_last_minute":0},"accounting":"Authenticated lookup responses, including errors and polling. Usage/docs/health and invalid keys excluded. Recorded before sending; client receipt is not guaranteed."}}}}},"headers":{"X-Request-ID":{"description":"Request identifier to share with support","schema":{"type":"string","format":"uuid"}}}},"400":{"description":"Invalid input","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"invalid_range":{"summary":"The usage dates or query parameters are invalid.","description":"Use real UTC dates, from < to, at most 31 days, with no duplicate or extra parameters.","value":{"error":{"code":"invalid_range","message":"The usage dates or query parameters are invalid."},"request_id":"00000000-0000-4000-8000-000000000001"}}}}},"headers":{"X-Request-ID":{"description":"Request identifier to share with support","schema":{"type":"string","format":"uuid"}}}},"401":{"description":"Missing, invalid, expired or revoked API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"unauthorized":{"summary":"The key is missing, malformed, invalid, expired or revoked.","description":"Send exactly one Authorization: Bearer header with an active key. Contact your API administrator for a replacement.","value":{"error":{"code":"unauthorized","message":"The key is missing, malformed, invalid, expired or revoked."},"request_id":"00000000-0000-4000-8000-000000000001"}}}}},"headers":{"X-Request-ID":{"description":"Request identifier to share with support","schema":{"type":"string","format":"uuid"}},"WWW-Authenticate":{"schema":{"type":"string"},"example":"Bearer realm=\"partner\""}}},"414":{"description":"Request URL exceeds 512 characters","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"uri_too_long":{"summary":"The request URL exceeds 512 characters.","description":"Shorten the path and query. Never put your API key in the URL.","value":{"error":{"code":"uri_too_long","message":"The request URL exceeds 512 characters."},"request_id":"00000000-0000-4000-8000-000000000001"}}}}},"headers":{"X-Request-ID":{"description":"Request identifier to share with support","schema":{"type":"string","format":"uuid"}}}},"429":{"description":"Rate, enrichment allowance or capacity limit; retry later","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"rate_limit":{"summary":"This key has exceeded its request rate.","description":"Wait at least Retry-After seconds, then reduce concurrency. View your key limits with GET /v1/usage.","value":{"error":{"code":"rate_limit","message":"This key has exceeded its request rate."},"request_id":"00000000-0000-4000-8000-000000000001"}},"api_rate_limit":{"summary":"The API has reached its shared request capacity.","description":"Honor Retry-After, add jitter and retry with lower concurrency.","value":{"error":{"code":"api_rate_limit","message":"The API has reached its shared request capacity."},"request_id":"00000000-0000-4000-8000-000000000001"}}}}},"headers":{"Retry-After":{"description":"Minimum retry delay in seconds. Daily allowances may require waiting until the next UTC day.","schema":{"type":"integer"}},"X-Request-ID":{"description":"Request identifier to share with support","schema":{"type":"string","format":"uuid"}}}},"503":{"description":"Lookup, usage reporting or enrichment temporarily unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"examples":{"api_busy":{"summary":"The API is temporarily busy.","description":"Honor Retry-After (normally 5 seconds for this code) and retry with backoff.","value":{"error":{"code":"api_busy","message":"Service temporarily unavailable; retry later"},"request_id":"00000000-0000-4000-8000-000000000001"}},"usage_unavailable":{"summary":"Usage reporting is temporarily unavailable.","description":"Retry with backoff. A POST may already have been submitted; repeating the same IP is safe.","value":{"error":{"code":"usage_unavailable","message":"Service temporarily unavailable; retry later"},"request_id":"00000000-0000-4000-8000-000000000001"}},"service_unavailable":{"summary":"An unexpected temporary service failure occurred.","description":"Honor Retry-After and retry with backoff; share request_id if the error persists.","value":{"error":{"code":"service_unavailable","message":"Service temporarily unavailable; retry later"},"request_id":"00000000-0000-4000-8000-000000000001"}}}}},"headers":{"X-Request-ID":{"description":"Request identifier to share with support","schema":{"type":"string","format":"uuid"}},"Retry-After":{"description":"Minimum retry delay in seconds. Daily allowances may require waiting until the next UTC day.","schema":{"type":"integer"}}}},"default":{"description":"Unexpected application error; inspect HTTP status and error.code. Proxy/network failures can be non-JSON.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"headers":{"X-Request-ID":{"description":"Request identifier to share with support","schema":{"type":"string","format":"uuid"}}}}},"tags":["Usage"]}},"/healthz":{"get":{"operationId":"health","summary":"Service health (does not guarantee lookup availability)","security":[],"responses":{"200":{"description":"Service is running","headers":{"X-Request-ID":{"description":"Request identifier to share with support","schema":{"type":"string","format":"uuid"}}},"content":{"application/json":{"schema":{"type":"object","required":["status"],"properties":{"status":{"const":"ok"}}},"example":{"status":"ok"}}}},"503":{"description":"Service temporarily unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"tags":["Health"]}},"/v1/trackers":{"get":{"operationId":"listTrackers","summary":"List your website trackers","description":"Scoped to the calling partner. Disabled trackers are included. Permanently deleted trackers are excluded.","tags":["Website tracking"],"responses":{"200":{"description":"List your website trackers","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TrackerList"}}}},"400":{"description":"invalid_range, invalid_origin, invalid_tracker, invalid_capture, invalid_custom_parameters, invalid_cursor, invalid_idempotency_key, invalid_query, invalid_json, invalid_body, invalid_ip","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"untrusted_collector, tracker_origin_denied","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"tracker_not_found, session_not_found, reveal_not_found, not_found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"idempotency_conflict, tracker_disabled","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"410":{"description":"tracker_deleted, session_expired, reveal_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"body_too_large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"414":{"description":"uri_too_long","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"415":{"description":"unsupported_media_type","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"tracking_capacity, tracker_limit, rate_limit, api_rate_limit, pending_limit, enrichment_limit, enrichment_capacity, lookup_capacity","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"headers":{"Retry-After":{"schema":{"type":"integer"}}}},"503":{"description":"api_busy, backend_timeout, submission_unconfirmed, tracking_unavailable, reveal_unconfirmed, usage_unavailable, backend_unavailable, service_unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"headers":{"Retry-After":{"schema":{"type":"integer"}}}}}},"post":{"operationId":"createTracker","summary":"Create a website tracker","description":"Creates a public tracker ID for one customer website. Install the returned snippet. Maximum 1,000 non-deleted trackers per partner. Tracker IDs are public, never API keys.","tags":["Website tracking"],"responses":{"201":{"description":"Create a website tracker","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Tracker"}}}},"400":{"description":"invalid_range, invalid_origin, invalid_tracker, invalid_capture, invalid_custom_parameters, invalid_cursor, invalid_idempotency_key, invalid_query, invalid_json, invalid_body, invalid_ip","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"untrusted_collector, tracker_origin_denied","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"tracker_not_found, session_not_found, reveal_not_found, not_found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"idempotency_conflict, tracker_disabled","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"410":{"description":"tracker_deleted, session_expired, reveal_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"body_too_large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"414":{"description":"uri_too_long","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"415":{"description":"unsupported_media_type","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"tracking_capacity, tracker_limit, rate_limit, api_rate_limit, pending_limit, enrichment_limit, enrichment_capacity, lookup_capacity","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"headers":{"Retry-After":{"schema":{"type":"integer"}}}},"503":{"description":"api_busy, backend_timeout, submission_unconfirmed, tracking_unavailable, reveal_unconfirmed, usage_unavailable, backend_unavailable, service_unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"headers":{"Retry-After":{"schema":{"type":"integer"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TrackerCreate"}}}}}},"/v1/trackers/{tracker_id}":{"delete":{"operationId":"disableTracker","summary":"Disable a tracker","description":"Stops new collection and new reveals for this tracker. Retains existing receipts and usage. Repeated DELETE is safe.","tags":["Website tracking"],"responses":{"200":{"description":"Disable a tracker","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Tracker"}}}},"400":{"description":"invalid_range, invalid_origin, invalid_tracker, invalid_capture, invalid_custom_parameters, invalid_cursor, invalid_idempotency_key, invalid_query, invalid_json, invalid_body, invalid_ip","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"untrusted_collector, tracker_origin_denied","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"tracker_not_found, session_not_found, reveal_not_found, not_found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"idempotency_conflict, tracker_disabled","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"410":{"description":"tracker_deleted, session_expired, reveal_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"body_too_large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"414":{"description":"uri_too_long","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"415":{"description":"unsupported_media_type","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"tracking_capacity, tracker_limit, rate_limit, api_rate_limit, pending_limit, enrichment_limit, enrichment_capacity, lookup_capacity","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"headers":{"Retry-After":{"schema":{"type":"integer"}}}},"503":{"description":"api_busy, backend_timeout, submission_unconfirmed, tracking_unavailable, reveal_unconfirmed, usage_unavailable, backend_unavailable, service_unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"headers":{"Retry-After":{"schema":{"type":"integer"}}}}},"parameters":[{"name":"tracker_id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}]}},"/v1/trackers/{tracker_id}/delete":{"post":{"operationId":"deleteTracker","summary":"Permanently delete a tracker","description":"Removes the tracker from lists, stops new collection and new reveal creation, and frees its tracker slot. Cannot be enabled again; install a new tracker if needed. Repeated delete returns the original deleted_at. Keeps account usage and billing. Existing session previews, per-tracker usage and reveal receipts remain readable under their normal retention; previously created reveals may still complete and bill once. This is not a personal-data erasure endpoint. DELETE on the bare tracker path continues to mean reversible disable.","tags":["Website tracking"],"responses":{"200":{"description":"Permanently delete a tracker","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TrackerDeleted"}}}},"400":{"description":"invalid_range, invalid_origin, invalid_tracker, invalid_capture, invalid_custom_parameters, invalid_cursor, invalid_idempotency_key, invalid_query, invalid_json, invalid_body, invalid_ip","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"untrusted_collector, tracker_origin_denied","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"tracker_not_found, session_not_found, reveal_not_found, not_found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"idempotency_conflict, tracker_disabled","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"410":{"description":"tracker_deleted, session_expired, reveal_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"body_too_large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"414":{"description":"uri_too_long","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"415":{"description":"unsupported_media_type","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"tracking_capacity, tracker_limit, rate_limit, api_rate_limit, pending_limit, enrichment_limit, enrichment_capacity, lookup_capacity","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"headers":{"Retry-After":{"schema":{"type":"integer"}}}},"503":{"description":"api_busy, backend_timeout, submission_unconfirmed, tracking_unavailable, reveal_unconfirmed, usage_unavailable, backend_unavailable, service_unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"headers":{"Retry-After":{"schema":{"type":"integer"}}}}},"parameters":[{"name":"tracker_id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{},"required":[]}}}}}},"/v1/trackers/{tracker_id}/enable":{"post":{"operationId":"enableTracker","summary":"Enable a tracker","description":"Returns 410 tracker_deleted for a permanently deleted tracker. Resumes collection and new reveals using the same tracker ID, allowed origins and installation snippet. Repeated enable is safe. Existing history and reveal billing are preserved.","tags":["Website tracking"],"responses":{"200":{"description":"Enable a tracker","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Tracker"}}}},"400":{"description":"invalid_range, invalid_origin, invalid_tracker, invalid_capture, invalid_custom_parameters, invalid_cursor, invalid_idempotency_key, invalid_query, invalid_json, invalid_body, invalid_ip","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"untrusted_collector, tracker_origin_denied","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"tracker_not_found, session_not_found, reveal_not_found, not_found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"idempotency_conflict, tracker_disabled","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"410":{"description":"tracker_deleted, session_expired, reveal_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"body_too_large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"414":{"description":"uri_too_long","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"415":{"description":"unsupported_media_type","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"tracking_capacity, tracker_limit, rate_limit, api_rate_limit, pending_limit, enrichment_limit, enrichment_capacity, lookup_capacity","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"headers":{"Retry-After":{"schema":{"type":"integer"}}}},"503":{"description":"api_busy, backend_timeout, submission_unconfirmed, tracking_unavailable, reveal_unconfirmed, usage_unavailable, backend_unavailable, service_unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"headers":{"Retry-After":{"schema":{"type":"integer"}}}}},"parameters":[{"name":"tracker_id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{},"required":[]}}}}}},"/v1/trackers/{tracker_id}/usage":{"get":{"operationId":"getTrackerUsage","summary":"Read usage for one tracker","description":"Partner-scoped durable hourly counters. Capture requests include retries, not unique visits. Sessions count new tracker sessions. API requests count successful calls attributed to this tracker, including 202s and repeated receipt reads; completed responses exclude 202, company responses count every returned company result. New/completed/company reveals count receipts, not unique companies. Failed calls, list-all, usage and dashboard calls are excluded. Billable reveals keep per-reveal semantics. Pending is current state. Capture/API counters begin at metrics_started_at; earlier session/reveal history is limited to retained records and expired classifications may be unknown. partial_history warns that earlier zeros are not proof of no activity. This read does not add request usage or reveal units.","tags":["Website tracking"],"responses":{"200":{"description":"Read usage for one tracker","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TrackerUsage"}}}},"400":{"description":"invalid_range, invalid_origin, invalid_tracker, invalid_capture, invalid_custom_parameters, invalid_cursor, invalid_idempotency_key, invalid_query, invalid_json, invalid_body, invalid_ip","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"untrusted_collector, tracker_origin_denied","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"tracker_not_found, session_not_found, reveal_not_found, not_found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"idempotency_conflict, tracker_disabled","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"410":{"description":"tracker_deleted, session_expired, reveal_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"body_too_large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"414":{"description":"uri_too_long","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"415":{"description":"unsupported_media_type","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"tracking_capacity, tracker_limit, rate_limit, api_rate_limit, pending_limit, enrichment_limit, enrichment_capacity, lookup_capacity","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"headers":{"Retry-After":{"schema":{"type":"integer"}}}},"503":{"description":"api_busy, backend_timeout, submission_unconfirmed, tracking_unavailable, reveal_unconfirmed, usage_unavailable, backend_unavailable, service_unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"headers":{"Retry-After":{"schema":{"type":"integer"}}}}},"parameters":[{"name":"tracker_id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"from","in":"query","schema":{"type":"string","format":"date"},"description":"Inclusive UTC date. Defaults to today."},{"name":"to","in":"query","schema":{"type":"string","format":"date"},"description":"Exclusive UTC date. Defaults to tomorrow. Range must be 1–31 days."}]}},"/v1/sessions":{"get":{"operationId":"listSessions","summary":"Preview new sessions and visitor countries","description":"No company lookup, enrichment or billable reveal. Poll with the last next_cursor; process every page while has_more=true. Sessions arrive in stable creation order. Cursor feed reports new sessions, not every page view. Read a session separately for its latest last_seen_at. Country may be null. Retention is 30 days.","tags":["Website tracking"],"responses":{"200":{"description":"Preview new sessions and visitor countries","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SessionFeed"}}}},"400":{"description":"invalid_range, invalid_origin, invalid_tracker, invalid_capture, invalid_custom_parameters, invalid_cursor, invalid_idempotency_key, invalid_query, invalid_json, invalid_body, invalid_ip","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"untrusted_collector, tracker_origin_denied","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"tracker_not_found, session_not_found, reveal_not_found, not_found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"idempotency_conflict, tracker_disabled","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"410":{"description":"tracker_deleted, session_expired, reveal_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"body_too_large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"414":{"description":"uri_too_long","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"415":{"description":"unsupported_media_type","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"tracking_capacity, tracker_limit, rate_limit, api_rate_limit, pending_limit, enrichment_limit, enrichment_capacity, lookup_capacity","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"headers":{"Retry-After":{"schema":{"type":"integer"}}}},"503":{"description":"api_busy, backend_timeout, submission_unconfirmed, tracking_unavailable, reveal_unconfirmed, usage_unavailable, backend_unavailable, service_unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"headers":{"Retry-After":{"schema":{"type":"integer"}}}}},"parameters":[{"name":"tracker_id","in":"query","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"cursor","in":"query","schema":{"type":"string","pattern":"^[0-9]+$","default":"0"}}]}},"/v1/sessions/{session_id}":{"get":{"operationId":"getSessionPreview","summary":"Read a session preview","description":"Returns visitor country, tracker/customer references and custom parameters captured on the first accepted visit. Never reveals company data or exposes the IP. Access is partner-scoped.","tags":["Website tracking"],"responses":{"200":{"description":"Read a session preview","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SessionPreview"}}}},"400":{"description":"invalid_range, invalid_origin, invalid_tracker, invalid_capture, invalid_custom_parameters, invalid_cursor, invalid_idempotency_key, invalid_query, invalid_json, invalid_body, invalid_ip","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"untrusted_collector, tracker_origin_denied","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"tracker_not_found, session_not_found, reveal_not_found, not_found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"idempotency_conflict, tracker_disabled","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"410":{"description":"tracker_deleted, session_expired, reveal_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"body_too_large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"414":{"description":"uri_too_long","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"415":{"description":"unsupported_media_type","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"tracking_capacity, tracker_limit, rate_limit, api_rate_limit, pending_limit, enrichment_limit, enrichment_capacity, lookup_capacity","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"headers":{"Retry-After":{"schema":{"type":"integer"}}}},"503":{"description":"api_busy, backend_timeout, submission_unconfirmed, tracking_unavailable, reveal_unconfirmed, usage_unavailable, backend_unavailable, service_unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"headers":{"Retry-After":{"schema":{"type":"integer"}}}}},"parameters":[{"name":"session_id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}]}},"/v1/sessions/{session_id}/reveal":{"post":{"operationId":"revealSession","summary":"Reveal company or network information","description":"Every new Idempotency-Key creates a separate reveal, even for the same session or cached IP. A completed result containing ANY company or network value consumes one unit, including ISP and unclassified data. No classification filter. Empty results, pending and errors consume zero units. Retry a timed-out POST with the SAME key to recover its receipt; a different key creates another potentially billable reveal. Existing per-key enrichment allowances and shared capacity apply on a miss. A saved stale result is returned with stale=true; this endpoint does not refresh an already available result.","tags":["Website tracking"],"responses":{"200":{"description":"Reveal company or network information","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Reveal"}}}},"202":{"description":"Accepted enrichment; wait at least 15 seconds, then GET status_url. No completion deadline.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Reveal"}}},"headers":{"Retry-After":{"schema":{"type":"integer","const":15}},"Location":{"schema":{"type":"string"}}}},"400":{"description":"invalid_range, invalid_origin, invalid_tracker, invalid_capture, invalid_custom_parameters, invalid_cursor, invalid_idempotency_key, invalid_query, invalid_json, invalid_body, invalid_ip","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"untrusted_collector, tracker_origin_denied","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"tracker_not_found, session_not_found, reveal_not_found, not_found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"idempotency_conflict, tracker_disabled","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"410":{"description":"tracker_deleted, session_expired, reveal_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"body_too_large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"414":{"description":"uri_too_long","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"415":{"description":"unsupported_media_type","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"tracking_capacity, tracker_limit, rate_limit, api_rate_limit, pending_limit, enrichment_limit, enrichment_capacity, lookup_capacity","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"headers":{"Retry-After":{"schema":{"type":"integer"}}}},"503":{"description":"api_busy, backend_timeout, submission_unconfirmed, tracking_unavailable, reveal_unconfirmed, usage_unavailable, backend_unavailable, service_unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"headers":{"Retry-After":{"schema":{"type":"integer"}}}}},"parameters":[{"name":"session_id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","format":"uuid"},"description":"UUID v4. New reveal = new UUID. Retry of that reveal = same UUID. Scope is partner-wide; reusing it for another session returns 409."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{},"required":[]}}}}}},"/v1/reveals/{reveal_id}":{"get":{"operationId":"getReveal","summary":"Read or poll an existing reveal","description":"Never creates another reveal or submits new enrichment. When the accepted work produces data, its first returned result and one billable unit are committed together. Later reads return that frozen receipt without another charge. A pending reveal does not bill until a completed response is prepared. Server commits do not prove the client received the response; retry the same receipt after a network failure.","tags":["Website tracking"],"responses":{"200":{"description":"Reveal company or network information","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Reveal"}}}},"202":{"description":"Accepted enrichment; wait at least 15 seconds, then GET status_url. No completion deadline.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Reveal"}}},"headers":{"Retry-After":{"schema":{"type":"integer","const":15}},"Location":{"schema":{"type":"string"}}}},"400":{"description":"invalid_range, invalid_origin, invalid_tracker, invalid_capture, invalid_custom_parameters, invalid_cursor, invalid_idempotency_key, invalid_query, invalid_json, invalid_body, invalid_ip","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"untrusted_collector, tracker_origin_denied","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"tracker_not_found, session_not_found, reveal_not_found, not_found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"idempotency_conflict, tracker_disabled","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"410":{"description":"tracker_deleted, session_expired, reveal_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"body_too_large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"414":{"description":"uri_too_long","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"415":{"description":"unsupported_media_type","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"tracking_capacity, tracker_limit, rate_limit, api_rate_limit, pending_limit, enrichment_limit, enrichment_capacity, lookup_capacity","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"headers":{"Retry-After":{"schema":{"type":"integer"}}}},"503":{"description":"api_busy, backend_timeout, submission_unconfirmed, tracking_unavailable, reveal_unconfirmed, usage_unavailable, backend_unavailable, service_unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"headers":{"Retry-After":{"schema":{"type":"integer"}}}}},"parameters":[{"name":"reveal_id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}]}},"/tracking/a.js":{"get":{"operationId":"loadTrackerScript","summary":"Load the public website pixel","tags":["Website tracking"],"security":[],"description":"Install the returned tracker snippet once per page. Optional data-custom attribute is a flat JSON object; see CustomParameters. Invalid attributes log a warning and do not send a visit. API keys never belong in this script URL. Uses session storage, not cookies.","parameters":[{"name":"tracker_id","in":"query","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Browser JavaScript","content":{"application/javascript":{"schema":{"type":"string"}}}}}}},"/v1/webhooks":{"get":{"operationId":"listWebhooks","summary":"List your webhook endpoints","description":"","tags":["Webhooks"],"responses":{"200":{"description":"List your webhook endpoints","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookList"}}}},"400":{"description":"invalid_webhook, invalid_webhook_url, invalid_webhook_query, invalid_body, invalid_json","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"webhook_not_found, webhook_delivery_not_found, tracker_not_found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"405":{"description":"method_not_allowed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"webhook_disabled, webhook_rotation_pending","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"410":{"description":"webhook_event_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"body_too_large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"415":{"description":"unsupported_media_type","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"webhook_limit, webhook_management_limit, rate_limit, api_rate_limit","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"webhook_queue_full, webhooks_unavailable, api_busy, service_unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"operationId":"createWebhook","summary":"Create a webhook endpoint","description":"Subscribe to new events only; no historical backfill. Maximum five endpoints per partner. URL is immutable. Creation does not prove delivery: send a test and inspect its delivery. Secret is shown once; if the response is lost, list endpoints and rotate its secret. Management has a separate120/minute budget and does not add lookup requests or reveal units.","tags":["Webhooks"],"responses":{"201":{"description":"Create a webhook endpoint","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookSecret"}}}},"400":{"description":"invalid_webhook, invalid_webhook_url, invalid_webhook_query, invalid_body, invalid_json","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"webhook_not_found, webhook_delivery_not_found, tracker_not_found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"405":{"description":"method_not_allowed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"webhook_disabled, webhook_rotation_pending","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"410":{"description":"webhook_event_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"body_too_large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"415":{"description":"unsupported_media_type","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"webhook_limit, webhook_management_limit, rate_limit, api_rate_limit","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"webhook_queue_full, webhooks_unavailable, api_busy, service_unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookCreate"}}}}}},"/v1/webhooks/{webhook_id}":{"get":{"operationId":"getWebhook","summary":"Read webhook settings and delivery totals","description":"","tags":["Webhooks"],"responses":{"200":{"description":"Read webhook settings and delivery totals","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Webhook"}}}},"400":{"description":"invalid_webhook, invalid_webhook_url, invalid_webhook_query, invalid_body, invalid_json","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"webhook_not_found, webhook_delivery_not_found, tracker_not_found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"405":{"description":"method_not_allowed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"webhook_disabled, webhook_rotation_pending","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"410":{"description":"webhook_event_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"body_too_large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"415":{"description":"unsupported_media_type","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"webhook_limit, webhook_management_limit, rate_limit, api_rate_limit","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"webhook_queue_full, webhooks_unavailable, api_busy, service_unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"parameters":[{"name":"webhook_id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}]},"patch":{"operationId":"updateWebhook","summary":"Update or pause a webhook","description":"enabled=false pauses pending deliveries and stops capturing new events for this endpoint; no catch-up for events created during pause. In-flight requests may still arrive. Resume with enabled=true. You may change name/events; existing queued events keep their subscription snapshot.","tags":["Webhooks"],"responses":{"200":{"description":"Update or pause a webhook","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Webhook"}}}},"400":{"description":"invalid_webhook, invalid_webhook_url, invalid_webhook_query, invalid_body, invalid_json","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"webhook_not_found, webhook_delivery_not_found, tracker_not_found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"405":{"description":"method_not_allowed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"webhook_disabled, webhook_rotation_pending","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"410":{"description":"webhook_event_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"body_too_large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"415":{"description":"unsupported_media_type","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"webhook_limit, webhook_management_limit, rate_limit, api_rate_limit","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"webhook_queue_full, webhooks_unavailable, api_busy, service_unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"parameters":[{"name":"webhook_id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookUpdate"}}}}},"delete":{"operationId":"deleteWebhook","summary":"Delete a webhook and cancel pending deliveries","description":"Idempotent. In-flight delivery may arrive. Delivery history stays readable by ID until retention expires. A deleted endpoint cannot be enabled or replayed.","tags":["Webhooks"],"responses":{"200":{"description":"Delete a webhook and cancel pending deliveries","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookDeleted"}}}},"400":{"description":"invalid_webhook, invalid_webhook_url, invalid_webhook_query, invalid_body, invalid_json","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"webhook_not_found, webhook_delivery_not_found, tracker_not_found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"405":{"description":"method_not_allowed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"webhook_disabled, webhook_rotation_pending","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"410":{"description":"webhook_event_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"body_too_large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"415":{"description":"unsupported_media_type","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"webhook_limit, webhook_management_limit, rate_limit, api_rate_limit","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"webhook_queue_full, webhooks_unavailable, api_busy, service_unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"parameters":[{"name":"webhook_id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}]}},"/v1/webhooks/{webhook_id}/rotate-secret":{"post":{"operationId":"rotateWebhookSecret","summary":"Rotate the signing secret","description":"Both old and new signatures are sent for24hours; install the new secret immediately. Rotation again during overlap returns409. Secrets are never returned by GET.","tags":["Webhooks"],"responses":{"200":{"description":"Rotate the signing secret","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookSecret"}}}},"400":{"description":"invalid_webhook, invalid_webhook_url, invalid_webhook_query, invalid_body, invalid_json","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"webhook_not_found, webhook_delivery_not_found, tracker_not_found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"405":{"description":"method_not_allowed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"webhook_disabled, webhook_rotation_pending","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"410":{"description":"webhook_event_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"body_too_large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"415":{"description":"unsupported_media_type","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"webhook_limit, webhook_management_limit, rate_limit, api_rate_limit","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"webhook_queue_full, webhooks_unavailable, api_busy, service_unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"parameters":[{"name":"webhook_id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{},"required":[]}}}}}},"/v1/webhooks/{webhook_id}/test":{"post":{"operationId":"testWebhook","summary":"Queue a synthetic test event","description":"202 means durable acceptance, not receiver delivery. Inspect deliveries to see the HTTP result.","tags":["Webhooks"],"responses":{"202":{"description":"Queue a synthetic test event","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookTest"}}}},"400":{"description":"invalid_webhook, invalid_webhook_url, invalid_webhook_query, invalid_body, invalid_json","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"webhook_not_found, webhook_delivery_not_found, tracker_not_found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"405":{"description":"method_not_allowed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"webhook_disabled, webhook_rotation_pending","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"410":{"description":"webhook_event_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"body_too_large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"415":{"description":"unsupported_media_type","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"webhook_limit, webhook_management_limit, rate_limit, api_rate_limit","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"webhook_queue_full, webhooks_unavailable, api_busy, service_unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"parameters":[{"name":"webhook_id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{},"required":[]}}}}}},"/v1/webhooks/{webhook_id}/deliveries":{"get":{"operationId":"listWebhookDeliveries","summary":"List recent deliveries","description":"Newest first,50 per page. Save next_cursor while has_more=true. Pending includes retrying or paused work. Failed deliveries remain visible; manual redelivery is allowed before source expiry.","tags":["Webhooks"],"responses":{"200":{"description":"List recent deliveries","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookDeliveryList"}}}},"400":{"description":"invalid_webhook, invalid_webhook_url, invalid_webhook_query, invalid_body, invalid_json","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"webhook_not_found, webhook_delivery_not_found, tracker_not_found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"405":{"description":"method_not_allowed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"webhook_disabled, webhook_rotation_pending","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"410":{"description":"webhook_event_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"body_too_large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"415":{"description":"unsupported_media_type","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"webhook_limit, webhook_management_limit, rate_limit, api_rate_limit","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"webhook_queue_full, webhooks_unavailable, api_busy, service_unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"parameters":[{"name":"webhook_id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"cursor","in":"query","schema":{"type":"string","pattern":"^[0-9]+$"}},{"name":"status","in":"query","schema":{"enum":["pending","delivered","failed","cancelled","expired"]}}]}},"/v1/webhooks/{webhook_id}/deliveries/{delivery_id}":{"get":{"operationId":"getWebhookDelivery","summary":"Inspect a delivery and its event","description":"","tags":["Webhooks"],"responses":{"200":{"description":"Inspect a delivery and its event","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookDeliveryDetail"}}}},"400":{"description":"invalid_webhook, invalid_webhook_url, invalid_webhook_query, invalid_body, invalid_json","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"webhook_not_found, webhook_delivery_not_found, tracker_not_found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"405":{"description":"method_not_allowed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"webhook_disabled, webhook_rotation_pending","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"410":{"description":"webhook_event_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"body_too_large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"415":{"description":"unsupported_media_type","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"webhook_limit, webhook_management_limit, rate_limit, api_rate_limit","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"webhook_queue_full, webhooks_unavailable, api_busy, service_unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"parameters":[{"name":"webhook_id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"delivery_id","in":"path","required":true,"schema":{"type":"string","pattern":"^del_[a-f0-9]{32}$"}}]}},"/v1/webhooks/{webhook_id}/deliveries/{delivery_id}/retry":{"post":{"operationId":"retryWebhookDelivery","summary":"Redeliver an event with its original event ID","description":"A pending event is not duplicated. Terminal events start a new retry cycle. Does not reveal again or charge a reveal unit. Payload must still be retained and the endpoint enabled.","tags":["Webhooks"],"responses":{"200":{"description":"Redeliver an event with its original event ID","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookDeliveryDetail"}}}},"400":{"description":"invalid_webhook, invalid_webhook_url, invalid_webhook_query, invalid_body, invalid_json","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"webhook_not_found, webhook_delivery_not_found, tracker_not_found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"405":{"description":"method_not_allowed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"webhook_disabled, webhook_rotation_pending","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"410":{"description":"webhook_event_expired","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"body_too_large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"415":{"description":"unsupported_media_type","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"webhook_limit, webhook_management_limit, rate_limit, api_rate_limit","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"webhook_queue_full, webhooks_unavailable, api_busy, service_unavailable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"parameters":[{"name":"webhook_id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"delivery_id","in":"path","required":true,"schema":{"type":"string","pattern":"^del_[a-f0-9]{32}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{},"required":[]}}}}}}},"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"API key"}},"schemas":{"Error":{"type":"object","required":["error","request_id"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Machine-readable application error. See x-error-codes for known codes; clients should also handle unknown codes and non-JSON proxy errors.","examples":["invalid_ip","invalid_query","invalid_json","invalid_body","invalid_range","unauthorized","not_requested","not_found","method_not_allowed","body_too_large","uri_too_long","unsupported_media_type","unsupported_encoding","rate_limit","api_rate_limit","lookup_capacity","pending_limit","enrichment_limit","enrichment_capacity","api_busy","backend_unavailable","backend_timeout","submission_unconfirmed","lookup_reconciliation_required","usage_unavailable","service_unavailable"]},"message":{"type":"string"}}},"request_id":{"type":"string","format":"uuid"},"company_signals":{"$ref":"#/components/schemas/CompanySignals"}}},"Company":{"type":"object","additionalProperties":false,"properties":{"name":{"type":["string","null"],"description":"Company field; null when unavailable."},"website":{"type":["string","null"],"description":"Company field; null when unavailable."},"brand_name":{"type":["string","null"],"description":"Marketing or alternate company name; not necessarily a registered brand."},"linkedin_url":{"type":["string","null"],"description":"Company field; null when unavailable."},"industry":{"type":["string","null"],"description":"Company field; null when unavailable."},"industry_subcategory":{"type":["string","null"],"description":"Company field; null when unavailable."},"revenue_band":{"type":["string","null"],"description":"Company field; null when unavailable."},"naics_code":{"type":["string","null"],"description":"Company field; null when unavailable."},"sic_code":{"type":["string","null"],"description":"Company field; null when unavailable."},"city":{"type":["string","null"],"description":"Company field; null when unavailable."},"region":{"type":["string","null"],"description":"Company field; null when unavailable."},"postal_code":{"type":["string","null"],"description":"Company field; null when unavailable."},"country_code":{"type":["string","null"],"description":"Company field; null when unavailable."},"country_name":{"type":["string","null"],"description":"Company field; null when unavailable."},"employees":{"type":["string","integer","null"],"description":"Reported employee count or range. Preserve strings; ranges are not exact headcounts and large counts may be decimal strings."},"annual_revenue":{"type":["string","integer","null"],"description":"Annual sales value; currency and reporting period are unspecified. May be a decimal string to preserve precision."}},"required":["name","website","brand_name","linkedin_url","industry","industry_subcategory","revenue_band","naics_code","sic_code","city","region","postal_code","country_code","country_name","employees","annual_revenue"]},"Lookup":{"type":"object","additionalProperties":false,"required":["ip","matched_ip","status","match_type","company_found","company","network","enriched_at","request_id","stale","fresh_until","refresh_status","refresh_error"],"properties":{"ip":{"type":"string"},"matched_ip":{"type":"string","description":"Exact spelling of the IP address that matched"},"status":{"const":"complete"},"match_type":{"enum":["company","isp","unclassified"],"description":"company: company information found; isp: internet service provider; unclassified: insufficient evidence to classify. Unclassified is not proof that the IP is not a business."},"company_found":{"type":"boolean","description":"True only when match_type is company. False for complete ISP/unclassified results. Pending responses instead use null."},"enriched_at":{"type":["string","null"],"format":"date-time","description":"UTC timestamp of the saved enrichment, not the current API request time."},"company":{"anyOf":[{"$ref":"#/components/schemas/Company"},{"type":"null"}],"description":"All available company fields, including ISP/unclassified records; null only when every public company field is unavailable. Presence does not override network.is_isp or establish a non-ISP business match."},"network":{"type":"object","additionalProperties":false,"required":["connection_type","audience_type","audience_group","detail_level","is_isp"],"properties":{"connection_type":{"type":["string","null"]},"audience_type":{"type":["string","null"]},"audience_group":{"type":["string","null"]},"detail_level":{"type":["string","null"]},"is_isp":{"type":["boolean","null"],"description":"True: internet service provider. False: non-ISP. Null: unspecified. False alone does not establish a company match; use company_found and match_type."}}},"request_id":{"type":"string","format":"uuid"},"stale":{"type":"boolean","description":"Whether this saved result is due for refresh. Expiry does not remove available fields."},"fresh_until":{"type":["string","null"],"format":"date-time","description":"Expiry of this saved result. Use this timestamp rather than assuming a fixed lifetime. Most company results last 30 days; some last 7 days. Null if no usable timestamp."},"refresh_status":{"enum":["not_needed","not_requested","pending","deferred"],"description":"not_needed: no additional work needed; not_requested: this GET started no work (another request may have done so); pending: unfinished enrichment has been accepted; deferred: POST could not confirm or admit work, so retry POST after Retry-After. A saved ISP/unclassified result may be fresh while additional company enrichment is pending."},"refresh_error":{"enum":[null,"pending_limit","enrichment_limit","enrichment_capacity","submission_unconfirmed","lookup_failed"],"description":"Reason for deferred refresh. Existing data is still returned with HTTP 200. Apply daily/pending limits or temporary-error retry guidance. Unknown acknowledgement: repeat the same POST; do not assume no job exists."},"company_signals":{"$ref":"#/components/schemas/CompanySignals"}}},"Pending":{"type":"object","required":["ip","lookup_ip","status","company_found","company","submitted_at","attempts","next_retry_at","last_error","status_url","poll_after_seconds","request_id"],"properties":{"ip":{"type":"string"},"lookup_ip":{"type":"string"},"status":{"enum":["pending","retrying"]},"company_found":{"type":"null"},"company":{"type":"null"},"submitted_at":{"type":"string","format":"date-time"},"attempts":{"type":"integer","minimum":0},"next_retry_at":{"type":["string","null"],"format":"date-time","description":"Next scheduled retry in UTC, or null. Not a completion estimate."},"last_error":{"enum":[null,"lookup_failed"]},"status_url":{"type":"string","description":"Relative same-origin URL for getLookup. Send the same Bearer authentication; do not follow arbitrary external URLs."},"poll_after_seconds":{"type":"integer","description":"Suggested minimum delay before the next GET poll; also provided by Retry-After."},"request_id":{"type":"string","format":"uuid"},"company_signals":{"$ref":"#/components/schemas/CompanySignals"}}},"Usage":{"type":"object","required":["key_id","name","from","to","timezone","limits","totals","outcomes","hourly","accounting","enrichment"],"properties":{"key_id":{"type":"string"},"name":{"type":"string"},"from":{"type":"string","format":"date-time"},"to":{"type":"string","format":"date-time"},"timezone":{"const":"UTC"},"limits":{"type":"object","properties":{"requests_per_second":{"type":"integer"},"new_enrichments_per_day":{"type":["integer","null"],"minimum":0,"description":"Optional daily budget for new reservations. null = no daily cap; 0 = saved-IP lookups only. A set budget resets at 00:00 UTC. Request-rate, pending-work and shared intake limits still apply."},"pending_enrichments":{"type":"integer","minimum":0,"description":"Maximum unfinished enrichments started by this partner, shared across its keys."}}},"totals":{"type":"object","properties":{"requests":{"type":"integer"},"cache_hits":{"type":"integer"},"average_processing_ms":{"type":"number"}}},"outcomes":{"type":"object","additionalProperties":{"type":"integer"}},"hourly":{"type":"array","items":{"type":"object","properties":{"hour":{"type":"string"},"outcome":{"type":"string"},"requests":{"type":"integer"},"cache_hits":{"type":"integer"},"duration_ms":{"type":"number"}}}},"accounting":{"type":"string"},"enrichment":{"$ref":"#/components/schemas/EnrichmentStatus","description":"Current enrichment status for the partner that owns this key; no IP list or other partners are exposed."},"reveals":{"$ref":"#/components/schemas/RevealUsage"}}},"EnrichmentStatus":{"type":"object","additionalProperties":false,"required":["pending","submission_unconfirmed","retrying","oldest_pending_at","oldest_checked_at","completed_observed_last_minute"],"properties":{"pending":{"type":"integer","minimum":0,"description":"Unfinished unique enrichments started by this partner, shared across its keys. Current snapshot, independent of usage date range."},"submission_unconfirmed":{"type":"integer","minimum":0,"description":"Pending requests whose acceptance is not confirmed. Repeat the original POST to confirm."},"retrying":{"type":"integer","minimum":0,"description":"Pending IPs with at least one observed unsuccessful attempt. Updates periodically."},"oldest_pending_at":{"type":["string","null"],"format":"date-time","description":"Submission time of the oldest unfinished request, or null."},"oldest_checked_at":{"type":["string","null"],"format":"date-time","description":"Oldest status-check time among pending requests; null if none or any are not checked yet. Status updates can lag."},"completed_observed_last_minute":{"type":"integer","minimum":0,"description":"Requests observed to finish during the last minute; not a guaranteed completion rate."}}},"CompanySignals":{"type":"object","additionalProperties":false,"required":["status","window_days","candidates","truncated"],"description":"Optional supplementary company clues for enabled API keys. Never proof of employment, IP ownership, email ownership or a completed enrichment. No email addresses, visited pages or installation identifiers are returned.","properties":{"status":{"enum":["available","unavailable"],"description":"unavailable means the clues could not be checked. An empty available list means no eligible recent clues were found."},"window_days":{"const":30},"truncated":{"type":"boolean","description":"More evidence may exist than the bounded response includes."},"candidates":{"type":"array","maxItems":5,"items":{"$ref":"#/components/schemas/CompanyCandidate"}}}},"CompanyCandidate":{"type":"object","additionalProperties":false,"required":["domain","company","verified","evidence","first_seen_at","last_seen_at","observations","submitted_observations","observed_visits","sites","flags"],"properties":{"domain":{"type":"string","description":"Observed email domain, with common personal and reserved test domains excluded. Unlisted personal/disposable domains can still appear."},"company":{"anyOf":[{"$ref":"#/components/schemas/Company"},{"type":"null"}],"description":"Profile matched by exact website hostname, ignoring www. Null if unmatched or multiple profiles share the domain. Subdomains are not guessed."},"verified":{"const":false},"evidence":{"enum":["submitted","field_only"],"description":"submitted records a browser submit event, not confirmed form acceptance. field_only means an email field was observed."},"first_seen_at":{"type":"string","format":"date-time","description":"First qualifying observation within the rolling 30-day window."},"last_seen_at":{"type":"string","format":"date-time"},"observations":{"type":"integer","minimum":1,"description":"Distinct captured events. Retries/replay are deduplicated; blur and submit can be separate events."},"submitted_observations":{"type":"integer","minimum":0},"observed_visits":{"type":"integer","minimum":0,"description":"Distinct known page-run identifiers; 0 means none were recorded. Not a person or session count."},"sites":{"type":"integer","minimum":1,"description":"Number of distinct website/installation combinations; their identities are private."},"flags":{"type":"array","uniqueItems":true,"items":{"enum":["field_only","multiple_domains","differs_from_lookup","bot_associated","shared_connection","ambiguous_profile","unmatched_domain","older_than_7_days"]},"description":"Reasons to treat a candidate cautiously. An empty list is not verification. Bot/connection flags describe the current IP classification, not necessarily its classification at observation time."}}},"CustomParameters":{"type":"object","maxProperties":32,"propertyNames":{"pattern":"^[A-Za-z][A-Za-z0-9_.-]{0,63}$","not":{"enum":["constructor","prototype"]}},"additionalProperties":{"anyOf":[{"type":"string","maxLength":512},{"type":"number"},{"type":"boolean"},{"type":"null"}]},"description":"Installer-supplied, untrusted labels. Flat JSON object, at most 2048 UTF-8 bytes after JSON serialization. First accepted visit freezes custom for that session. Missing/legacy custom is {}. Never use these values for authorization or billing.","example":{"account_id":"acme","campaign":"autumn","plan":"pro"}},"TrackerCreate":{"type":"object","additionalProperties":false,"properties":{"name":{"type":"string","minLength":1,"maxLength":100},"origins":{"type":"array","minItems":1,"maxItems":10,"uniqueItems":true,"items":{"type":"string","format":"uri","description":"Exact HTTPS website origin, such as https://www.example.com. No paths, credentials, ports or wildcards."}},"customer_reference":{"type":["string","null"],"maxLength":128}},"required":["name","origins"]},"Tracker":{"type":"object","additionalProperties":false,"properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"origins":{"type":"array","items":{"type":"string"}},"customer_reference":{"type":["string","null"]},"created_at":{"type":"string","format":"date-time"},"disabled_at":{"type":["string","null"],"format":"date-time"},"snippet":{"type":"string"},"request_id":{"type":"string","format":"uuid"}},"required":["id","name","origins","customer_reference","created_at","disabled_at","snippet"]},"TrackerDeleted":{"type":"object","additionalProperties":false,"properties":{"id":{"type":"string","format":"uuid"},"deleted":{"const":true},"deleted_at":{"type":"string","format":"date-time"},"request_id":{"type":"string","format":"uuid"}},"required":["id","deleted","deleted_at","request_id"]},"TrackerList":{"type":"object","additionalProperties":false,"properties":{"trackers":{"type":"array","maxItems":1000,"items":{"$ref":"#/components/schemas/Tracker"}},"request_id":{"type":"string","format":"uuid"}},"required":["trackers","request_id"]},"TrackerUsage":{"type":"object","additionalProperties":false,"properties":{"tracker_id":{"type":"string","format":"uuid"},"from":{"type":"string","format":"date-time"},"to":{"type":"string","format":"date-time"},"timezone":{"const":"UTC"},"totals":{"type":"object","additionalProperties":false,"properties":{"capture_requests":{"type":"integer","minimum":0,"description":"Accepted pixel capture calls; repeats and retries count."},"sessions_created":{"type":"integer","minimum":0,"description":"New tracker sessions; not unique people. Earlier counts include retained sessions only."},"api_requests":{"type":"integer","minimum":0,"description":"Successful API calls attributable to this tracker, including 202 and repeated receipt reads."},"api_completed_responses":{"type":"integer","minimum":0,"description":"Attributed successful API responses with status 200 or 201; excludes pending 202."},"api_company_responses":{"type":"integer","minimum":0,"description":"Attributed responses with result.company_found=true; repeated reads count again."},"new_reveals":{"type":"integer","minimum":0,"description":"New reveal receipts created, counted at creation time; idempotent retries do not create another."},"completed_reveals":{"type":"integer","minimum":0,"description":"Reveal receipts completed in the selected period."},"company_reveals":{"type":"integer","minimum":0,"description":"Completed receipts classified company; not unique companies."},"isp_reveals":{"type":"integer","minimum":0,"description":"Completed receipts classified ISP."},"unclassified_reveals":{"type":"integer","minimum":0,"description":"Completed receipts classified unclassified."},"billable_reveals":{"type":"integer","minimum":0,"description":"Durable billed units at completion time, including cached, ISP and unclassified data."},"unknown_reveal_results":{"type":"integer","minimum":0,"description":"Completed receipts whose result classification was unavailable during historical recovery."}},"required":["capture_requests","sessions_created","api_requests","api_completed_responses","api_company_responses","new_reveals","completed_reveals","company_reveals","isp_reveals","unclassified_reveals","billable_reveals","unknown_reveal_results"]},"hourly":{"type":"array","maxItems":744,"items":{"type":"object","additionalProperties":false,"properties":{"hour":{"type":"string","format":"date-time"},"capture_requests":{"type":"integer","minimum":0,"description":"Accepted pixel capture calls; repeats and retries count."},"sessions_created":{"type":"integer","minimum":0,"description":"New tracker sessions; not unique people. Earlier counts include retained sessions only."},"api_requests":{"type":"integer","minimum":0,"description":"Successful API calls attributable to this tracker, including 202 and repeated receipt reads."},"api_completed_responses":{"type":"integer","minimum":0,"description":"Attributed successful API responses with status 200 or 201; excludes pending 202."},"api_company_responses":{"type":"integer","minimum":0,"description":"Attributed responses with result.company_found=true; repeated reads count again."},"new_reveals":{"type":"integer","minimum":0,"description":"New reveal receipts created, counted at creation time; idempotent retries do not create another."},"completed_reveals":{"type":"integer","minimum":0,"description":"Reveal receipts completed in the selected period."},"company_reveals":{"type":"integer","minimum":0,"description":"Completed receipts classified company; not unique companies."},"isp_reveals":{"type":"integer","minimum":0,"description":"Completed receipts classified ISP."},"unclassified_reveals":{"type":"integer","minimum":0,"description":"Completed receipts classified unclassified."},"billable_reveals":{"type":"integer","minimum":0,"description":"Durable billed units at completion time, including cached, ISP and unclassified data."},"unknown_reveal_results":{"type":"integer","minimum":0,"description":"Completed receipts whose result classification was unavailable during historical recovery."}},"required":["hour","capture_requests","sessions_created","api_requests","api_completed_responses","api_company_responses","new_reveals","completed_reveals","company_reveals","isp_reveals","unclassified_reveals","billable_reveals","unknown_reveal_results"]}},"pending_reveals":{"type":"integer","minimum":0},"metrics_started_at":{"type":"string","format":"date-time"},"partial_history":{"type":"boolean","description":"True if this tracker existed before full counters started and the range includes that earlier time. Earlier sessions and reveals include retained records only; zero may represent missing history."},"accounting":{"type":"string"},"request_id":{"type":"string","format":"uuid"}},"required":["tracker_id","from","to","timezone","totals","hourly","pending_reveals","metrics_started_at","partial_history","accounting"]},"SessionPreview":{"type":"object","additionalProperties":false,"properties":{"session_id":{"type":"string","format":"uuid"},"tracker_id":{"type":"string","format":"uuid"},"customer_reference":{"type":["string","null"]},"custom":{"$ref":"#/components/schemas/CustomParameters"},"visitor_country":{"type":["string","null"],"pattern":"^[A-Z]{2}$","description":"Estimated visitor IP country, not company headquarters. null means unknown. VPNs can affect location."},"first_seen_at":{"type":"string","format":"date-time"},"last_seen_at":{"type":"string","format":"date-time"},"expires_at":{"type":"string","format":"date-time"},"request_id":{"type":"string","format":"uuid"}},"required":["session_id","tracker_id","customer_reference","visitor_country","first_seen_at","last_seen_at","expires_at"],"example":{"session_id":"00000000-0000-4000-8000-000000000001","tracker_id":"00000000-0000-4000-8000-000000000002","customer_reference":"acme","custom":{"account_id":"acme","campaign":"autumn","plan":"pro"},"visitor_country":"GB","first_seen_at":"2026-09-25T12:00:00.000Z","last_seen_at":"2026-09-25T12:00:00.000Z","expires_at":"2026-10-25T12:00:00.000Z"}},"SessionFeed":{"type":"object","additionalProperties":false,"properties":{"sessions":{"type":"array","maxItems":100,"items":{"$ref":"#/components/schemas/SessionPreview"}},"next_cursor":{"type":"string","pattern":"^[0-9]+$"},"has_more":{"type":"boolean"},"request_id":{"type":"string","format":"uuid"}},"required":["sessions","next_cursor","has_more","request_id"]},"RevealResult":{"type":"object","additionalProperties":false,"properties":{"status":{"const":"complete"},"match_type":{"enum":["company","isp","unclassified"],"description":"company: company information found; isp: internet service provider; unclassified: insufficient evidence to classify. Unclassified is not proof that the IP is not a business."},"company_found":{"type":"boolean","description":"True only when match_type is company. False for complete ISP/unclassified results. Pending responses instead use null."},"enriched_at":{"type":["string","null"],"format":"date-time","description":"UTC timestamp of the saved enrichment, not the current API request time."},"company":{"anyOf":[{"$ref":"#/components/schemas/Company"},{"type":"null"}],"description":"All available company fields, including ISP/unclassified records; null only when every public company field is unavailable. Presence does not override network.is_isp or establish a non-ISP business match."},"network":{"type":"object","additionalProperties":false,"required":["connection_type","audience_type","audience_group","detail_level","is_isp"],"properties":{"connection_type":{"type":["string","null"]},"audience_type":{"type":["string","null"]},"audience_group":{"type":["string","null"]},"detail_level":{"type":["string","null"]},"is_isp":{"type":["boolean","null"],"description":"True: internet service provider. False: non-ISP. Null: unspecified. False alone does not establish a company match; use company_found and match_type."}}},"stale":{"type":"boolean","description":"Whether this saved result is due for refresh. Expiry does not remove available fields."},"fresh_until":{"type":["string","null"],"format":"date-time","description":"Expiry of this saved result. Use this timestamp rather than assuming a fixed lifetime. Most company results last 30 days; some last 7 days. Null if no usable timestamp."},"refresh_status":{"enum":["not_needed","not_requested","pending","deferred"],"description":"not_needed: no additional work needed; not_requested: this GET started no work (another request may have done so); pending: unfinished enrichment has been accepted; deferred: POST could not confirm or admit work, so retry POST after Retry-After. A saved ISP/unclassified result may be fresh while additional company enrichment is pending."},"refresh_error":{"enum":[null,"pending_limit","enrichment_limit","enrichment_capacity","submission_unconfirmed","lookup_failed"],"description":"Reason for deferred refresh. Existing data is still returned with HTTP 200. Apply daily/pending limits or temporary-error retry guidance. Unknown acknowledgement: repeat the same POST; do not assume no job exists."}},"required":["status","match_type","company_found","enriched_at","company","network","stale","fresh_until","refresh_status","refresh_error"]},"Reveal":{"type":"object","additionalProperties":false,"properties":{"reveal_id":{"type":"string","format":"uuid"},"session_id":{"type":"string","format":"uuid"},"tracker_id":{"type":"string","format":"uuid"},"custom":{"$ref":"#/components/schemas/CustomParameters"},"status":{"enum":["pending","complete"]},"billable":{"type":"boolean","description":"True when this reveal has one recorded billable unit. Re-reading this receipt does not charge again."},"billable_units":{"type":"integer","enum":[0,1]},"created_at":{"type":"string","format":"date-time"},"completed_at":{"type":["string","null"],"format":"date-time"},"expires_at":{"type":"string","format":"date-time"},"result":{"anyOf":[{"$ref":"#/components/schemas/RevealResult"},{"type":"null"}]},"status_url":{"type":"string"},"request_id":{"type":"string","format":"uuid"}},"required":["reveal_id","session_id","tracker_id","status","billable","billable_units","created_at","completed_at","expires_at","result","status_url","request_id"],"example":{"reveal_id":"00000000-0000-4000-8000-000000000003","session_id":"00000000-0000-4000-8000-000000000001","tracker_id":"00000000-0000-4000-8000-000000000002","custom":{"account_id":"acme","campaign":"autumn","plan":"pro"},"status":"complete","billable":true,"billable_units":1,"created_at":"2026-09-25T12:00:00.000Z","completed_at":"2026-09-25T12:00:00.000Z","expires_at":"2026-10-25T12:00:00.000Z","result":{"status":"complete","match_type":"company","company_found":true,"enriched_at":"2026-09-18T12:00:00.000Z","stale":false,"fresh_until":"2026-10-18T12:00:00.000Z","refresh_status":"not_needed","refresh_error":null,"network":{"connection_type":"Business","audience_type":"Business","audience_group":null,"detail_level":null,"is_isp":false},"company":{"name":"Example Company","website":"example.com","brand_name":null,"linkedin_url":null,"industry":"Software","industry_subcategory":null,"employees":"120","annual_revenue":null,"revenue_band":null,"naics_code":"541511","sic_code":null,"city":"London","region":null,"postal_code":null,"country_code":"GB","country_name":"United Kingdom"}},"status_url":"/v1/reveals/00000000-0000-4000-8000-000000000003","request_id":"00000000-0000-4000-8000-000000000004"}},"RevealUsage":{"type":"object","additionalProperties":false,"properties":{"billable_reveals":{"type":"integer","minimum":0},"completed_reveals":{"type":"integer","minimum":0},"hourly":{"type":"array","items":{"type":"object","additionalProperties":false,"properties":{"hour":{"type":"string","format":"date-time"},"completed":{"type":"integer"},"billable_reveals":{"type":"integer"}},"required":["hour","completed","billable_reveals"]}},"accounting":{"type":"string"}},"required":["billable_reveals","completed_reveals","hourly","accounting"]},"WebhookCreate":{"type":"object","additionalProperties":false,"properties":{"name":{"type":"string","minLength":1,"maxLength":100},"url":{"type":"string","format":"uri","maxLength":1024,"description":"Public HTTPS on port443; no credentials, fragment, private addresses or redirects. Immutable; create a new endpoint to change it."},"events":{"type":"array","items":{"enum":["session.created","reveal.completed"]},"minItems":1,"maxItems":2,"uniqueItems":true},"tracker_id":{"type":["string","null"],"format":"uuid","description":"Omit or null for all trackers owned by this partner."}},"required":["name","url","events"]},"WebhookUpdate":{"type":"object","additionalProperties":false,"properties":{"name":{"type":"string","minLength":1,"maxLength":100},"events":{"type":"array","items":{"enum":["session.created","reveal.completed"]},"minItems":1,"maxItems":2,"uniqueItems":true},"enabled":{"type":"boolean"}},"required":[]},"Webhook":{"type":"object","additionalProperties":false,"properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"url":{"type":"string"},"events":{"type":"array","items":{"enum":["session.created","reveal.completed"]},"minItems":1,"maxItems":2,"uniqueItems":true},"tracker_id":{"type":["string","null"]},"enabled":{"type":"boolean"},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"},"deleted_at":{"type":["string","null"]},"secret_rotation_until":{"type":["string","null"]},"deliveries":{"type":"object","additionalProperties":false,"properties":{"pending":{"type":"integer","minimum":0},"delivered":{"type":"integer","minimum":0},"failed":{"type":"integer","minimum":0},"cancelled":{"type":"integer","minimum":0},"expired":{"type":"integer","minimum":0}},"required":["pending","delivered","failed","cancelled","expired"]},"request_id":{"type":"string","format":"uuid"}},"required":["id","name","url","events","tracker_id","enabled","created_at","updated_at","deleted_at","secret_rotation_until","deliveries"]},"WebhookSecret":{"type":"object","additionalProperties":false,"properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"url":{"type":"string"},"events":{"type":"array","items":{"enum":["session.created","reveal.completed"]},"minItems":1,"maxItems":2,"uniqueItems":true},"tracker_id":{"type":["string","null"]},"enabled":{"type":"boolean"},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"},"deleted_at":{"type":["string","null"]},"secret_rotation_until":{"type":["string","null"]},"deliveries":{"type":"object","additionalProperties":false,"properties":{"pending":{"type":"integer","minimum":0},"delivered":{"type":"integer","minimum":0},"failed":{"type":"integer","minimum":0},"cancelled":{"type":"integer","minimum":0},"expired":{"type":"integer","minimum":0}},"required":["pending","delivered","failed","cancelled","expired"]},"request_id":{"type":"string","format":"uuid"},"signing_secret":{"type":"string","pattern":"^whsec_","description":"Shown once on creation/rotation. Verify HMAC SHA-256 signatures server-side. Never send this secret to a browser installation snippet."}},"required":["id","name","url","events","tracker_id","enabled","created_at","updated_at","deleted_at","secret_rotation_until","deliveries","signing_secret"]},"WebhookList":{"type":"object","additionalProperties":false,"properties":{"webhooks":{"type":"array","items":{"$ref":"#/components/schemas/Webhook"}},"limits":{"type":"object","additionalProperties":false,"properties":{"endpoints":{"const":5},"pending_deliveries":{"const":2500000}},"required":["endpoints","pending_deliveries"]},"worker":{"type":"object","additionalProperties":false,"properties":{"status":{"enum":["running","unavailable"]},"checked_at":{"type":["string","null"]}},"required":["status","checked_at"]},"request_id":{"type":"string","format":"uuid"}},"required":["webhooks","limits","worker"]},"WebhookDeleted":{"type":"object","additionalProperties":false,"properties":{"id":{"type":"string","format":"uuid"},"deleted":{"const":true},"deleted_at":{"type":"string","format":"date-time"},"request_id":{"type":"string","format":"uuid"}},"required":["id","deleted","deleted_at"]},"WebhookTest":{"type":"object","additionalProperties":false,"properties":{"delivery_id":{"type":"string"},"event_id":{"type":"string"},"status":{"const":"pending"},"request_id":{"type":"string","format":"uuid"}},"required":["delivery_id","event_id","status"]},"WebhookRevealReceipt":{"type":"object","additionalProperties":false,"properties":{"reveal_id":{"type":"string","format":"uuid"},"session_id":{"type":"string","format":"uuid"},"tracker_id":{"type":"string","format":"uuid"},"custom":{"$ref":"#/components/schemas/CustomParameters"},"status":{"enum":["pending","complete"]},"billable":{"type":"boolean","description":"True when this reveal has one recorded billable unit. Re-reading this receipt does not charge again."},"billable_units":{"type":"integer","enum":[0,1]},"created_at":{"type":"string","format":"date-time"},"completed_at":{"type":["string","null"],"format":"date-time"},"expires_at":{"type":"string","format":"date-time"},"result":{"anyOf":[{"$ref":"#/components/schemas/RevealResult"},{"type":"null"}]},"status_url":{"type":"string"}},"required":["reveal_id","session_id","tracker_id","status","billable","billable_units","created_at","completed_at","expires_at","result","status_url"],"example":{"reveal_id":"00000000-0000-4000-8000-000000000003","session_id":"00000000-0000-4000-8000-000000000001","tracker_id":"00000000-0000-4000-8000-000000000002","custom":{"account_id":"acme","campaign":"autumn","plan":"pro"},"status":"complete","billable":true,"billable_units":1,"created_at":"2026-09-25T12:00:00.000Z","completed_at":"2026-09-25T12:00:00.000Z","expires_at":"2026-10-25T12:00:00.000Z","result":{"status":"complete","match_type":"company","company_found":true,"enriched_at":"2026-09-18T12:00:00.000Z","stale":false,"fresh_until":"2026-10-18T12:00:00.000Z","refresh_status":"not_needed","refresh_error":null,"network":{"connection_type":"Business","audience_type":"Business","audience_group":null,"detail_level":null,"is_isp":false},"company":{"name":"Example Company","website":"example.com","brand_name":null,"linkedin_url":null,"industry":"Software","industry_subcategory":null,"employees":"120","annual_revenue":null,"revenue_band":null,"naics_code":"541511","sic_code":null,"city":"London","region":null,"postal_code":null,"country_code":"GB","country_name":"United Kingdom"}},"status_url":"/v1/reveals/00000000-0000-4000-8000-000000000003"}},"WebhookEvent":{"oneOf":[{"type":"object","additionalProperties":false,"properties":{"id":{"type":"string"},"type":{"const":"session.created"},"schema_version":{"const":1},"created_at":{"type":"string","format":"date-time"},"data":{"$ref":"#/components/schemas/SessionPreview"}},"required":["id","type","schema_version","created_at","data"]},{"type":"object","additionalProperties":false,"properties":{"id":{"type":"string"},"type":{"const":"reveal.completed"},"schema_version":{"const":1},"created_at":{"type":"string","format":"date-time"},"data":{"$ref":"#/components/schemas/WebhookRevealReceipt"}},"required":["id","type","schema_version","created_at","data"]},{"type":"object","additionalProperties":false,"properties":{"id":{"type":"string"},"type":{"const":"webhook.test"},"schema_version":{"const":1},"created_at":{"type":"string","format":"date-time"},"data":{"type":"object","additionalProperties":false,"properties":{"message":{"type":"string"}},"required":["message"]}},"required":["id","type","schema_version","created_at","data"]}],"examples":[{"id":"evt_session_00000000-0000-4000-8000-000000000001","type":"session.created","schema_version":1,"created_at":"2026-09-25T12:00:00.000Z","data":{"session_id":"00000000-0000-4000-8000-000000000001","tracker_id":"00000000-0000-4000-8000-000000000002","customer_reference":"acme","custom":{"account_id":"acme","campaign":"autumn","plan":"pro"},"visitor_country":"GB","first_seen_at":"2026-09-25T12:00:00.000Z","last_seen_at":"2026-09-25T12:00:00.000Z","expires_at":"2026-10-25T12:00:00.000Z"}},{"id":"evt_reveal_00000000-0000-4000-8000-000000000003","type":"reveal.completed","schema_version":1,"created_at":"2026-09-25T12:00:00.000Z","data":{"reveal_id":"00000000-0000-4000-8000-000000000003","session_id":"00000000-0000-4000-8000-000000000001","tracker_id":"00000000-0000-4000-8000-000000000002","custom":{"account_id":"acme","campaign":"autumn","plan":"pro"},"status":"complete","billable":true,"billable_units":1,"created_at":"2026-09-25T12:00:00.000Z","completed_at":"2026-09-25T12:00:00.000Z","expires_at":"2026-10-25T12:00:00.000Z","result":{"status":"complete","match_type":"company","company_found":true,"enriched_at":"2026-09-18T12:00:00.000Z","stale":false,"fresh_until":"2026-10-18T12:00:00.000Z","refresh_status":"not_needed","refresh_error":null,"network":{"connection_type":"Business","audience_type":"Business","audience_group":null,"detail_level":null,"is_isp":false},"company":{"name":"Example Company","website":"example.com","brand_name":null,"linkedin_url":null,"industry":"Software","industry_subcategory":null,"employees":"120","annual_revenue":null,"revenue_band":null,"naics_code":"541511","sic_code":null,"city":"London","region":null,"postal_code":null,"country_code":"GB","country_name":"United Kingdom"}},"status_url":"/v1/reveals/00000000-0000-4000-8000-000000000003"}}]},"WebhookDelivery":{"type":"object","additionalProperties":false,"properties":{"id":{"type":"string"},"event_id":{"type":"string"},"type":{"enum":["session.created","reveal.completed","webhook.test"]},"state":{"enum":["pending","delivered","failed","cancelled","expired"]},"attempts":{"type":"integer","minimum":0},"created_at":{"type":"string","format":"date-time"},"last_attempt_at":{"type":["string","null"]},"delivered_at":{"type":["string","null"]},"next_attempt_at":{"type":["string","null"]},"http_status":{"type":["integer","null"]},"error":{"type":["string","null"]}},"required":["id","event_id","type","state","attempts","created_at","last_attempt_at","delivered_at","next_attempt_at","http_status","error"]},"WebhookDeliveryDetail":{"type":"object","additionalProperties":false,"properties":{"id":{"type":"string"},"event_id":{"type":"string"},"type":{"enum":["session.created","reveal.completed","webhook.test"]},"state":{"enum":["pending","delivered","failed","cancelled","expired"]},"attempts":{"type":"integer","minimum":0},"created_at":{"type":"string","format":"date-time"},"last_attempt_at":{"type":["string","null"]},"delivered_at":{"type":["string","null"]},"next_attempt_at":{"type":["string","null"]},"http_status":{"type":["integer","null"]},"error":{"type":["string","null"]},"event":{"anyOf":[{"$ref":"#/components/schemas/WebhookEvent"},{"type":"null"}]},"request_id":{"type":"string","format":"uuid"}},"required":["id","event_id","type","state","attempts","created_at","last_attempt_at","delivered_at","next_attempt_at","http_status","error","event"]},"WebhookDeliveryList":{"type":"object","additionalProperties":false,"properties":{"deliveries":{"type":"array","items":{"$ref":"#/components/schemas/WebhookDelivery"}},"has_more":{"type":"boolean"},"next_cursor":{"type":"string"},"request_id":{"type":"string","format":"uuid"}},"required":["deliveries","has_more","next_cursor"]}}},"x-error-codes":[{"status":400,"code":"invalid_ip","meaning":"The IP is missing, malformed, private or reserved.","action":"Send one public IPv4 or IPv6 address, without a port, CIDR suffix or zone ID."},{"status":400,"code":"invalid_query","meaning":"The query parameters do not match the endpoint.","action":"GET lookup needs exactly one ip parameter. POST lookup takes JSON, with no query string."},{"status":400,"code":"invalid_json","meaning":"The request body is not valid JSON.","action":"Send valid JSON such as {\"ip\":\"8.8.8.8\"}."},{"status":400,"code":"invalid_body","meaning":"The JSON body has the wrong shape or extra fields.","action":"Send an object containing only ip. A missing or invalid ip returns invalid_ip."},{"status":400,"code":"invalid_range","meaning":"The usage dates or query parameters are invalid.","action":"Use real UTC dates, from < to, at most 31 days, with no duplicate or extra parameters."},{"status":401,"code":"unauthorized","meaning":"The key is missing, malformed, invalid, expired or revoked.","action":"Send exactly one Authorization: Bearer header with an active key. Contact your API administrator for a replacement."},{"status":404,"code":"not_requested","meaning":"GET found no saved result and no API enrichment submission.","action":"POST the same IP to request enrichment, then poll with GET. This is not a confirmed no-company result."},{"status":404,"code":"not_found","meaning":"The endpoint does not exist.","action":"Check the path. Use /v1/lookup or /v1/usage."},{"status":405,"code":"method_not_allowed","meaning":"The lookup endpoint does not accept this HTTP method.","action":"Use GET or POST; the Allow response header lists the accepted methods."},{"status":413,"code":"body_too_large","meaning":"The request body exceeds 1,024 bytes.","action":"Submit one IP per request in a small JSON object."},{"status":414,"code":"uri_too_long","meaning":"The request URL exceeds 512 characters.","action":"Shorten the path and query. Never put your API key in the URL."},{"status":415,"code":"unsupported_media_type","meaning":"The POST Content-Type is not application/json.","action":"Set Content-Type: application/json."},{"status":415,"code":"unsupported_encoding","meaning":"The request has a Content-Encoding header.","action":"Send uncompressed JSON without Content-Encoding."},{"status":429,"code":"rate_limit","meaning":"This key has exceeded its request rate.","action":"Wait at least Retry-After seconds, then reduce concurrency. View your key limits with GET /v1/usage."},{"status":429,"code":"api_rate_limit","meaning":"The API has reached its shared request capacity.","action":"Honor Retry-After, add jitter and retry with lower concurrency."},{"status":429,"code":"lookup_capacity","meaning":"Too many distinct IP lookups are in flight.","action":"Honor Retry-After and retry with fewer simultaneous lookups."},{"status":429,"code":"pending_limit","meaning":"Your partner has reached its limit for unfinished enrichments.","action":"Wait for existing lookups to finish before submitting new IPs. View enrichment and limits in GET /v1/usage. Repeating an accepted IP is allowed."},{"status":429,"code":"enrichment_limit","meaning":"This key has used its daily allowance for new enrichment reservations.","action":"Wait until the next UTC day or ask for a higher allowance. Existing saved lookups remain available; retrying every 15 seconds will not reset the allowance."},{"status":429,"code":"enrichment_capacity","meaning":"The shared enrichment intake or outstanding-work limit is full.","action":"Honor Retry-After and use backoff. Repeated submissions do not speed up the lookup."},{"status":503,"code":"api_busy","meaning":"The API is temporarily busy.","action":"Honor Retry-After (normally 5 seconds for this code) and retry with backoff."},{"status":503,"code":"backend_unavailable","meaning":"The lookup or enrichment request could not be completed.","action":"Retry with backoff. A failed POST response does not prove submission failed; repeating the same POST is safe."},{"status":503,"code":"backend_timeout","meaning":"The request took too long to complete.","action":"Retry with backoff. Do not interpret a timeout as a no-company result."},{"status":503,"code":"submission_unconfirmed","meaning":"An enrichment reservation exists, but acceptance was not confirmed.","action":"Repeat POST for the same IP to confirm submission, then poll with GET."},{"status":503,"code":"lookup_reconciliation_required","meaning":"Work is marked complete, but the saved lookup is unavailable.","action":"Retry later; if persistent, share request_id with your API administrator."},{"status":503,"code":"usage_unavailable","meaning":"Usage reporting is temporarily unavailable.","action":"Retry with backoff. A POST may already have been submitted; repeating the same IP is safe."},{"status":503,"code":"service_unavailable","meaning":"An unexpected temporary service failure occurred.","action":"Honor Retry-After and retry with backoff; share request_id if the error persists."}],"tags":[{"name":"Lookups","description":"Read saved company information or request enrichment."},{"name":"Usage","description":"Usage and limits for your own API key."},{"name":"Health","description":"Basic service health only."}],"x-client-guidance":{"authentication":"Authorization: Bearer <API key>. Keep keys server-side; never place them in URLs.","polling":"After HTTP 202, GET status_url with the same key after Retry-After seconds. Apply a caller-defined overall deadline; no completion SLA is guaranteed. HTTP 200 may return saved data while additional enrichment is pending. Inspect refresh_status as well as stale; stop when refresh_status=not_needed and stale=false, or when your own deadline expires.","errors":"Branch on HTTP status and error.code, not error.message. Handle unknown codes and non-JSON edge responses. Save request_id or CF-Ray for diagnostics.","retries":"Honor Retry-After for 429/503 and use exponential backoff with jitter. enrichment_limit requires the next UTC day or a higher allowance. Never retry invalid input or credentials unchanged. pending_limit requires waiting for existing enrichments to finish; saved lookups and polls remain available.","data":"Nullable fields are unknown. Preserve employees/annual_revenue strings without lossy number conversion. Employees can be a range rather than an exact count. company_id is not exposed. Inspect company for available data, and network.is_isp/match_type for classification. company_found=false does not mean company is null. POST refreshes stale data; GET only reads. HTTP 200 with stale=true is an old saved result, not evidence a refresh has completed. Enabled keys also receive company_signals on 200/202 and 404 not_requested. These unverified candidates never change company, company_found, match_type or enrichment state. Clues cover the last 30 days, can lag by up to 60 seconds, and include at most five domains. Inspect flags. Do not identify a person or assert employment from an IP/domain association.","accounting":"Authenticated lookup responses, including polls and errors, count toward usage. GET /v1/usage reports the calling key’s usage counters; enrichment status is shared by keys assigned to the same partner. Successful tracker/session/reveal endpoint calls also count as requests, except usage reads; rejected calls are not included. Reveal units are separate under usage.reveals. Preview and polling requests do not create extra reveal units.","tracking":"Create a tracker, install its snippet, poll new session previews, compare visitor_country with your own allowed countries, and POST reveal only for selected sessions. Never put API keys in browsers. GET session is preview only; GET reveal_id retrieves the paid receipt. Polling adds no new reveal unit. Totals are caller-key-only; partner keys share authorized sessions. Billing attribution stays with the key that created the reveal.","webhooks":"Use session.created for country previews, then explicitly POST a reveal for chosen sessions. reveal.completed reports the frozen receipt after source data becomes available, including ISP/unclassified/empty results. Previously accepted pending reveals with an active subscription can complete and bill without a GET poll. Webhooks never create new reveals. Verify webhook-id, webhook-timestamp and webhook-signature against the exact raw request body; reject timestamps outside5minutes and deduplicate by event ID. Durably save before returning2xx. At-least-once and unordered delivery;12 attempts or7days per cycle, Retry-After respected up to24h. Payload expires with source, at most30days; metadata90days. Queue full rejects the source transaction with503. Management operations and redelivery do not add reveal units. Standard IP /v1/lookup requests do not emit webhook events."},"x-pixel-custom-parameters":{"attribute":"data-custom","schema":{"$ref":"#/components/schemas/CustomParameters"},"snapshot":"First accepted visit in a session; subsequent visits do not overwrite it.","outputs":["SessionPreview.custom","Reveal.custom","session.created.data.custom","reveal.completed.data.custom"]},"x-tracking-error-codes":{"400":["invalid_range","invalid_origin","invalid_tracker","invalid_capture","invalid_custom_parameters","invalid_cursor","invalid_idempotency_key","invalid_query","invalid_json","invalid_body","invalid_ip"],"401":["unauthorized"],"403":["untrusted_collector","tracker_origin_denied"],"404":["tracker_not_found","session_not_found","reveal_not_found","not_found"],"409":["idempotency_conflict","tracker_disabled"],"410":["tracker_deleted","session_expired","reveal_expired"],"413":["body_too_large"],"414":["uri_too_long"],"415":["unsupported_media_type"],"429":["tracking_capacity","tracker_limit","rate_limit","api_rate_limit","pending_limit","enrichment_limit","enrichment_capacity","lookup_capacity"],"503":["api_busy","backend_timeout","submission_unconfirmed","tracking_unavailable","reveal_unconfirmed","usage_unavailable","backend_unavailable","service_unavailable"]},"externalDocs":{"description":"Agent integration guide and documentation index","url":"https://partner.rktad.com/llms.txt"},"x-webhook-error-codes":{"400":"invalid_webhook, invalid_webhook_url, invalid_webhook_query, invalid_body, invalid_json","401":"unauthorized","404":"webhook_not_found, webhook_delivery_not_found, tracker_not_found","405":"method_not_allowed","409":"webhook_disabled, webhook_rotation_pending","410":"webhook_event_expired","413":"body_too_large","415":"unsupported_media_type","429":"webhook_limit, webhook_management_limit, rate_limit, api_rate_limit","503":"webhook_queue_full, webhooks_unavailable, api_busy, service_unavailable"}}