{"components":{"schemas":{"ValidationErrorResponse":{"properties":{"error":{"properties":{"code":{"type":"string"},"details":{"items":{"additionalProperties":true,"properties":{"field":{"type":"string"},"issue":{"type":"string"}},"type":"object"},"type":"array"},"message":{"type":"string"},"request_id":{"type":"string"}},"required":["code","message","details","request_id"],"type":"object"},"meta":{"properties":{"credits_charged":{"const":0,"type":"number"}},"type":"object"},"ok":{"const":false,"type":"boolean"}},"required":["ok","error","meta"],"type":"object"},"WritingDryRun":{"properties":{"dry_run":{"const":true,"type":"boolean"},"estimated_credits":{"type":"number"},"job_created":{"const":false,"type":"boolean"},"prose_generated":{"const":false,"type":"boolean"},"resolved_context":{"additionalProperties":true,"type":"object"}},"required":["dry_run","job_created","prose_generated","estimated_credits","resolved_context"],"type":"object"},"WritingEmailOutput":{"additionalProperties":false,"properties":{"ai_costs":{"additionalProperties":true,"type":"object"},"body":{"description":"Portable LF-only plain text.","type":"string"},"body_html":{"description":"HTML representation semantically equivalent to body.","type":"string"},"channel":{"const":"email","type":"string"},"resolved_context":{"additionalProperties":true,"type":"object"},"subject":{"type":"string"}},"required":["channel","subject","body","body_html","resolved_context"],"type":"object"},"WritingJob":{"additionalProperties":false,"properties":{"billing":{"additionalProperties":false,"properties":{"credits_charged":{"type":"number"},"credits_refunded":{"const":0,"deprecated":true,"type":"number"},"credits_released":{"type":"number"},"credits_reserved":{"type":"number"}},"required":["credits_reserved","credits_refunded","credits_charged"],"type":"object"},"channel":{"enum":["email","linkedin"],"type":"string"},"created_at":{"format":"date-time","type":["string","null"]},"done":{"type":"boolean"},"error":{"oneOf":[{"type":"string"},{"additionalProperties":true,"type":"object"},{"type":"null"}]},"eventCount":{"minimum":0,"type":"integer"},"events":{"items":{"$ref":"#/components/schemas/WritingJobEvent"},"type":"array"},"id":{"type":"string"},"jobSuccess":{"type":["boolean","null"]},"kind":{"type":["string","null"]},"label":{"type":"string"},"linkedin_type":{"enum":["message","connection_request",null],"type":["string","null"]},"output":{"oneOf":[{"$ref":"#/components/schemas/WritingEmailOutput"},{"$ref":"#/components/schemas/WritingLinkedInOutput"},{"type":"null"}]},"progress":{"maximum":100,"minimum":0,"type":"integer"},"resolved_context":{"additionalProperties":true,"type":["object","null"]},"status":{"enum":["queued","running","completed","failed"],"type":"string"},"success":{"description":"Null before completion, true on completed delivery, and false on terminal failure.","type":["boolean","null"]},"updated_at":{"format":"date-time","type":["string","null"]}},"required":["id","kind","success","status","progress","label","events","done","jobSuccess","error","eventCount","created_at","updated_at","channel","linkedin_type","output","resolved_context","billing"],"type":"object"},"WritingJobEvent":{"additionalProperties":false,"properties":{"label":{"type":"string"},"progress":{"maximum":100,"minimum":0,"type":"integer"},"ts":{"description":"Event time in Unix milliseconds.","type":"integer"}},"required":["progress","label","ts"],"type":"object"},"WritingJobResponse":{"properties":{"data":{"oneOf":[{"$ref":"#/components/schemas/WritingJob"},{"$ref":"#/components/schemas/WritingDryRun"}]},"meta":{"properties":{"credits_charged":{"type":"number"},"credits_reserved":{"type":"number"},"dry_run":{"type":"boolean"},"idempotency_reused":{"type":"boolean"}},"type":"object"},"ok":{"const":true,"type":"boolean"}},"required":["ok","data","meta"],"type":"object"},"WritingLinkedInOutput":{"additionalProperties":false,"properties":{"ai_costs":{"additionalProperties":true,"type":"object"},"channel":{"const":"linkedin","type":"string"},"content":{"type":"string"},"linkedin_type":{"enum":["message","connection_request"],"type":"string"},"resolved_context":{"additionalProperties":true,"type":"object"}},"required":["channel","linkedin_type","content","resolved_context"],"type":"object"}},"securitySchemes":{"BearerAuth":{"bearerFormat":"API key or JWT","description":"Enter your token only. Swagger UI will add the Bearer prefix.","scheme":"bearer","type":"http"}}},"info":{"description":"Internal phase API. Responses may include internal_phase markers, count_pending: true while totals are still being computed, and broad-filter gating rules for overly broad queries. Sandbox/test API keys are limited to read-only companies, personnel, broker-offices, and brokers endpoints plus filter options, whoami, and health; use a production API key for tags, credits, key management, reports, and other endpoints.\n\n## Campaign tags (filtering)\n\nList endpoints for `companies`, `brokers`, `broker-offices`, and `personnel` accept a `tags` query parameter to return only entities tagged by the authenticated API user.\n\n- **User-scoped:** Only tags created by the authenticated user (or the user linked to an API key) are considered. Tags from other users never match.\n- **AND semantics:** Pass multiple tag names comma-separated (for example `tags=q1-outreach,high-priority`). An entity must have **all** listed tags to match.\n- **Entity-specific:** Tags are stored per entity type. A tag on a company does not match broker, broker-office, or personnel queries.\n- **Normalization:** Tag names are normalized on write and filter (leading `#` is stripped and casing is folded).\n- **Combines with other filters:** `tags` can be used together with geography, search, signals, and other list filters.\n\nTag management endpoints:\n- `GET /tags` lists tag assignments for the authenticated user.\n- `GET /tags/entities` lists entity IDs that have a given tag.\n- `POST /tags` and `POST /tags/bulk` assign tags to entities.\n- `DELETE /tags` and `DELETE /tags/{id}` remove tags.\n","title":"Hillwinds Segment Studio API","version":"1.0.0-internal-phase-1"},"openapi":"3.1.0","paths":{"/api-keys":{"get":{"description":"Requires an API key with keys:read scope. Returns root and child keys in the current credit account, each enriched with all-time usage (credits_used, rows_returned, queries) for the per-key usage board. The full secret is never returned here.","parameters":[],"responses":{"200":{"description":"Successful response"},"400":{"description":"Validation error"},"401":{"description":"Missing or invalid authorization"},"403":{"description":"Forbidden"},"404":{"description":"Not found"}},"summary":"List API keys"},"post":{"description":"Requires a root API key with keys:write scope. Child keys share the same organization credit pool as the parent key and can only receive data-read scopes allowed by the parent. Field-tier templates and per-entity tier choices are copied from the parent key. The full key secret is returned only in this response.","parameters":[],"requestBody":{"content":{"application/json":{"example":{"field_tier":"advanced","key_type":"live","name":"Partner data pull","scopes":["read:companies","read:personnel"]},"schema":{"properties":{"entity_field_tiers":{"additionalProperties":{"enum":["basic","advanced"],"type":"string"},"description":"Per-entity Basic/Advanced tier choices copied from the parent key.","readOnly":true,"type":"object"},"field_tier":{"enum":["basic","advanced"],"type":"string"},"field_tiers":{"description":"Per-entity basic/advanced field lists copied from the parent key.","readOnly":true,"type":"object"},"key_type":{"enum":["live","test"],"type":"string"},"name":{"description":"Display name for the child key.","type":"string"},"scopes":{"description":"Data-read scopes only, for example read:companies or read:personnel.","items":{"type":"string"},"type":"array"}},"required":["scopes"],"type":"object"}}},"required":true},"responses":{"201":{"description":"Successful response"},"400":{"description":"Validation error"},"401":{"description":"Missing or invalid authorization"},"403":{"description":"Forbidden"},"404":{"description":"Not found"}},"summary":"Create child API key"}},"/api-keys/{key_id}":{"delete":{"description":"Requires keys:write scope. Revokes a key in the current credit account; revoked keys can no longer call /v1 endpoints.","parameters":[{"description":"Resource identifier.","in":"path","name":"key_id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response"},"400":{"description":"Validation error"},"401":{"description":"Missing or invalid authorization"},"403":{"description":"Forbidden"},"404":{"description":"Not found"}},"summary":"Revoke API key"}},"/api-keys/{key_id}/rotate":{"post":{"description":"Requires keys:write scope. Invalidates the old secret immediately and returns the new full secret only in this response.","parameters":[{"description":"Resource identifier.","in":"path","name":"key_id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response"},"400":{"description":"Validation error"},"401":{"description":"Missing or invalid authorization"},"403":{"description":"Forbidden"},"404":{"description":"Not found"}},"summary":"Rotate API key"}},"/broker-offices":{"get":{"description":"List broker offices with pagination, sorting, and filters. Use the `tags` query parameter to return only entities that have the authenticated user's campaign tags (AND semantics when multiple tags are provided).","parameters":[{"description":"Comma-separated broker IDs.","in":"query","name":"broker_ids","required":false,"schema":{"type":"string"}},{"description":"Broker office name or UUID across broker office relationships.","in":"query","name":"broker_office","required":false,"schema":{"type":"string"}},{"description":"Comma-separated brokerage classes.","in":"query","name":"brokerage_class","required":false,"schema":{"enum":["national player","regional player","local broker"],"type":"string"}},{"description":"Carrier name substring.","in":"query","name":"carrier_search","required":false,"schema":{"type":"string"}},{"description":"Comma-separated client count bands.","in":"query","name":"client_count_bands","required":false,"schema":{"type":"string"}},{"description":"Comma-separated commission tiers.","in":"query","name":"commission_tiers","required":false,"schema":{"type":"string"}},{"description":"Return only the total count and no rows.","in":"query","name":"count_only","required":false,"schema":{"type":"boolean"}},{"description":"CRM match status. Requires an API key owned by a user with CRM context.","in":"query","name":"crm_status","required":false,"schema":{"enum":["in_hubspot","in_salesforce","in_both","not_in_crm"],"type":"string"}},{"description":"Comma-separated DMA names.","in":"query","name":"dmas","required":false,"schema":{"type":"string"}},{"description":"Estimate the rows and credits for one page without returning rows. The response also reports estimated_total_matches; estimated_rows is page-bounded.","in":"query","name":"dry_run","required":false,"schema":{"type":"boolean"}},{"description":"Employee-size distribution of broker office clients.","in":"query","name":"employee_coverage","required":false,"schema":{"type":"string"}},{"description":"Comma-separated response fields. id is always included.","in":"query","name":"fields","required":false,"schema":{"type":"string"}},{"description":"Filing year or latest.","in":"query","name":"filing_year","required":false,"schema":{"type":"string"}},{"description":"Response format.","in":"query","name":"format","required":false,"schema":{"enum":["json","flat"],"type":"string"}},{"description":"Geographic filter mode.","in":"query","name":"geo_mode","required":false,"schema":{"enum":["state","dma"],"type":"string"}},{"description":"Include total_count in response metadata.","in":"query","name":"include_count","required":false,"schema":{"type":"boolean"}},{"description":"Industry distribution of broker office clients.","in":"query","name":"industry_coverage","required":false,"schema":{"type":"string"}},{"description":"Filter long-tail records.","in":"query","name":"long_tail","required":false,"schema":{"type":"boolean"}},{"description":"Response field tier.","in":"query","name":"mode","required":false,"schema":{"enum":["basic","full","light"],"type":"string"}},{"description":"Zero-indexed page number.","in":"query","name":"page","required":false,"schema":{"minimum":0,"type":"integer"}},{"description":"Rows per page. Maximum 500. Values above 25 require at least one filter.","in":"query","name":"page_size","required":false,"schema":{"maximum":500,"minimum":1,"type":"integer"}},{"description":"Resource-specific fuzzy search.","in":"query","name":"search","required":false,"schema":{"type":"string"}},{"description":"Signal match mode. all requires every requested signal and is echoed in meta.applied_filters.","in":"query","name":"signal_match","required":false,"schema":{"enum":["any","all"],"type":"string"}},{"description":"Comma-separated signal names.","in":"query","name":"signals","required":false,"schema":{"type":"string"}},{"description":"Sort field from the resource allowlist.","in":"query","name":"sort_by","required":false,"schema":{"type":"string"}},{"description":"Sort direction.","in":"query","name":"sort_dir","required":false,"schema":{"enum":["asc","desc"],"type":"string"}},{"description":"Comma-separated two-letter USPS state codes. Lowercase codes are normalized; invalid codes or full state names return 400 with the supported values.","in":"query","name":"states","required":false,"schema":{"type":"string"}},{"description":"Comma-separated campaign tag names. User-scoped: only tags owned by the authenticated API user apply. AND semantics: when multiple tags are provided, the entity must have all of them. Supported on GET /companies, /brokers, /broker-offices, and /personnel (including export.csv). Example: q1-outreach,high-priority","in":"query","name":"tags","required":false,"schema":{"type":"string"}},{"description":"Column filter. Replace `column` with the column key, e.g. `cf[total_number_of_employees]=gte:300,lte:500` or `cf[company_name]=acme`. Numeric columns support `gte:`, `gt:`, `lte:`, and `lt:` bounds. Percentage columns such as `participant_growth`, `commission_growth`, and `broker_commission_growth_pct` interpret numeric thresholds as percent values and scale them to stored ratios internally (`gte:1` means at least 1%). Multiple filters can be provided by comma-separating values.","in":"query","name":"cf[column]","required":false,"schema":{"type":"string"}},{"description":"Exclude rows where the named column is blank.","in":"query","name":"eb[column]","required":false,"schema":{"type":"boolean"}}],"responses":{"200":{"description":"Successful response"},"400":{"description":"Validation error"},"401":{"description":"Missing or invalid authorization"},"403":{"description":"Forbidden"},"404":{"description":"Not found"}},"summary":"List broker offices"}},"/broker-offices/autocomplete":{"get":{"parameters":[{"description":"column","in":"query","name":"column","required":false,"schema":{"type":"string"}},{"description":"query","in":"query","name":"query","required":false,"schema":{"type":"string"}},{"description":"Resource-specific fuzzy search.","in":"query","name":"search","required":false,"schema":{"type":"string"}},{"description":"limit","in":"query","name":"limit","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response"},"400":{"description":"Validation error"},"401":{"description":"Missing or invalid authorization"},"403":{"description":"Forbidden"},"404":{"description":"Not found"}},"summary":"Autocomplete broker offices"}},"/broker-offices/export.csv":{"get":{"description":"List broker offices with pagination, sorting, and filters. Use the `tags` query parameter to return only entities that have the authenticated user's campaign tags (AND semantics when multiple tags are provided).","parameters":[{"description":"Comma-separated broker IDs.","in":"query","name":"broker_ids","required":false,"schema":{"type":"string"}},{"description":"Broker office name or UUID across broker office relationships.","in":"query","name":"broker_office","required":false,"schema":{"type":"string"}},{"description":"Comma-separated brokerage classes.","in":"query","name":"brokerage_class","required":false,"schema":{"enum":["national player","regional player","local broker"],"type":"string"}},{"description":"Carrier name substring.","in":"query","name":"carrier_search","required":false,"schema":{"type":"string"}},{"description":"Comma-separated client count bands.","in":"query","name":"client_count_bands","required":false,"schema":{"type":"string"}},{"description":"Comma-separated commission tiers.","in":"query","name":"commission_tiers","required":false,"schema":{"type":"string"}},{"description":"Return only the total count and no rows.","in":"query","name":"count_only","required":false,"schema":{"type":"boolean"}},{"description":"CRM match status. Requires an API key owned by a user with CRM context.","in":"query","name":"crm_status","required":false,"schema":{"enum":["in_hubspot","in_salesforce","in_both","not_in_crm"],"type":"string"}},{"description":"Comma-separated DMA names.","in":"query","name":"dmas","required":false,"schema":{"type":"string"}},{"description":"Estimate the rows and credits for one page without returning rows. The response also reports estimated_total_matches; estimated_rows is page-bounded.","in":"query","name":"dry_run","required":false,"schema":{"type":"boolean"}},{"description":"Employee-size distribution of broker office clients.","in":"query","name":"employee_coverage","required":false,"schema":{"type":"string"}},{"description":"Comma-separated response fields. id is always included.","in":"query","name":"fields","required":false,"schema":{"type":"string"}},{"description":"Filing year or latest.","in":"query","name":"filing_year","required":false,"schema":{"type":"string"}},{"description":"Response format.","in":"query","name":"format","required":false,"schema":{"enum":["json","flat"],"type":"string"}},{"description":"Geographic filter mode.","in":"query","name":"geo_mode","required":false,"schema":{"enum":["state","dma"],"type":"string"}},{"description":"Include total_count in response metadata.","in":"query","name":"include_count","required":false,"schema":{"type":"boolean"}},{"description":"Industry distribution of broker office clients.","in":"query","name":"industry_coverage","required":false,"schema":{"type":"string"}},{"description":"Filter long-tail records.","in":"query","name":"long_tail","required":false,"schema":{"type":"boolean"}},{"description":"Response field tier.","in":"query","name":"mode","required":false,"schema":{"enum":["basic","full","light"],"type":"string"}},{"description":"Zero-indexed page number.","in":"query","name":"page","required":false,"schema":{"minimum":0,"type":"integer"}},{"description":"Rows per page. Maximum 500. Values above 25 require at least one filter.","in":"query","name":"page_size","required":false,"schema":{"maximum":500,"minimum":1,"type":"integer"}},{"description":"Resource-specific fuzzy search.","in":"query","name":"search","required":false,"schema":{"type":"string"}},{"description":"Signal match mode. all requires every requested signal and is echoed in meta.applied_filters.","in":"query","name":"signal_match","required":false,"schema":{"enum":["any","all"],"type":"string"}},{"description":"Comma-separated signal names.","in":"query","name":"signals","required":false,"schema":{"type":"string"}},{"description":"Sort field from the resource allowlist.","in":"query","name":"sort_by","required":false,"schema":{"type":"string"}},{"description":"Sort direction.","in":"query","name":"sort_dir","required":false,"schema":{"enum":["asc","desc"],"type":"string"}},{"description":"Comma-separated two-letter USPS state codes. Lowercase codes are normalized; invalid codes or full state names return 400 with the supported values.","in":"query","name":"states","required":false,"schema":{"type":"string"}},{"description":"Comma-separated campaign tag names. User-scoped: only tags owned by the authenticated API user apply. AND semantics: when multiple tags are provided, the entity must have all of them. Supported on GET /companies, /brokers, /broker-offices, and /personnel (including export.csv). Example: q1-outreach,high-priority","in":"query","name":"tags","required":false,"schema":{"type":"string"}},{"description":"Column filter. Replace `column` with the column key, e.g. `cf[total_number_of_employees]=gte:300,lte:500` or `cf[company_name]=acme`. Numeric columns support `gte:`, `gt:`, `lte:`, and `lt:` bounds. Percentage columns such as `participant_growth`, `commission_growth`, and `broker_commission_growth_pct` interpret numeric thresholds as percent values and scale them to stored ratios internally (`gte:1` means at least 1%). Multiple filters can be provided by comma-separating values.","in":"query","name":"cf[column]","required":false,"schema":{"type":"string"}},{"description":"Exclude rows where the named column is blank.","in":"query","name":"eb[column]","required":false,"schema":{"type":"boolean"}}],"responses":{"200":{"description":"Successful response"},"400":{"description":"Validation error"},"401":{"description":"Missing or invalid authorization"},"403":{"description":"Forbidden"},"404":{"description":"Not found"}},"summary":"Export broker offices CSV"}},"/broker-offices/{id}":{"get":{"parameters":[{"description":"Resource identifier.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response"},"400":{"description":"Validation error"},"401":{"description":"Missing or invalid authorization"},"403":{"description":"Forbidden"},"404":{"description":"Not found"}},"summary":"Get broker office"}},"/broker-offices/{id}/tags":{"get":{"description":"List user-scoped tags attached to one broker office for the authenticated API user.","parameters":[{"description":"Resource identifier.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response"},"400":{"description":"Validation error"},"401":{"description":"Missing or invalid authorization"},"403":{"description":"Forbidden"},"404":{"description":"Not found"}},"summary":"List broker office tags"}},"/brokers":{"get":{"description":"List brokers with pagination, sorting, and filters. Use the `tags` query parameter to return only entities that have the authenticated user's campaign tags (AND semantics when multiple tags are provided).","parameters":[{"description":"Comma-separated brokerage classes.","in":"query","name":"brokerage_class","required":false,"schema":{"enum":["national player","regional player","local broker"],"type":"string"}},{"description":"Comma-separated client count bands.","in":"query","name":"client_count_bands","required":false,"schema":{"type":"string"}},{"description":"Return only the total count and no rows.","in":"query","name":"count_only","required":false,"schema":{"type":"boolean"}},{"description":"CRM match status. Requires an API key owned by a user with CRM context.","in":"query","name":"crm_status","required":false,"schema":{"enum":["in_hubspot","in_salesforce","in_both","not_in_crm"],"type":"string"}},{"description":"Comma-separated DMA names.","in":"query","name":"dmas","required":false,"schema":{"type":"string"}},{"description":"Estimate the rows and credits for one page without returning rows. The response also reports estimated_total_matches; estimated_rows is page-bounded.","in":"query","name":"dry_run","required":false,"schema":{"type":"boolean"}},{"description":"Comma-separated response fields. id is always included.","in":"query","name":"fields","required":false,"schema":{"type":"string"}},{"description":"Filing year or latest.","in":"query","name":"filing_year","required":false,"schema":{"type":"string"}},{"description":"Response format.","in":"query","name":"format","required":false,"schema":{"enum":["json","flat"],"type":"string"}},{"description":"Geographic filter mode.","in":"query","name":"geo_mode","required":false,"schema":{"enum":["state","dma"],"type":"string"}},{"description":"Include total_count in response metadata.","in":"query","name":"include_count","required":false,"schema":{"type":"boolean"}},{"description":"Filter long-tail records.","in":"query","name":"long_tail","required":false,"schema":{"type":"boolean"}},{"description":"Response field tier.","in":"query","name":"mode","required":false,"schema":{"enum":["basic","full","light"],"type":"string"}},{"description":"Zero-indexed page number.","in":"query","name":"page","required":false,"schema":{"minimum":0,"type":"integer"}},{"description":"Rows per page. Maximum 500. Values above 25 require at least one filter.","in":"query","name":"page_size","required":false,"schema":{"maximum":500,"minimum":1,"type":"integer"}},{"description":"Resource-specific fuzzy search.","in":"query","name":"search","required":false,"schema":{"type":"string"}},{"description":"Signal match mode. all requires every requested signal and is echoed in meta.applied_filters.","in":"query","name":"signal_match","required":false,"schema":{"enum":["any","all"],"type":"string"}},{"description":"Comma-separated signal names.","in":"query","name":"signals","required":false,"schema":{"type":"string"}},{"description":"Sort field from the resource allowlist.","in":"query","name":"sort_by","required":false,"schema":{"type":"string"}},{"description":"Sort direction.","in":"query","name":"sort_dir","required":false,"schema":{"enum":["asc","desc"],"type":"string"}},{"description":"Comma-separated two-letter USPS state codes. Lowercase codes are normalized; invalid codes or full state names return 400 with the supported values.","in":"query","name":"states","required":false,"schema":{"type":"string"}},{"description":"Comma-separated campaign tag names. User-scoped: only tags owned by the authenticated API user apply. AND semantics: when multiple tags are provided, the entity must have all of them. Supported on GET /companies, /brokers, /broker-offices, and /personnel (including export.csv). Example: q1-outreach,high-priority","in":"query","name":"tags","required":false,"schema":{"type":"string"}},{"description":"Column filter. Replace `column` with the column key, e.g. `cf[total_number_of_employees]=gte:300,lte:500` or `cf[company_name]=acme`. Numeric columns support `gte:`, `gt:`, `lte:`, and `lt:` bounds. Percentage columns such as `participant_growth`, `commission_growth`, and `broker_commission_growth_pct` interpret numeric thresholds as percent values and scale them to stored ratios internally (`gte:1` means at least 1%). Multiple filters can be provided by comma-separating values.","in":"query","name":"cf[column]","required":false,"schema":{"type":"string"}},{"description":"Exclude rows where the named column is blank.","in":"query","name":"eb[column]","required":false,"schema":{"type":"boolean"}}],"responses":{"200":{"description":"Successful response"},"400":{"description":"Validation error"},"401":{"description":"Missing or invalid authorization"},"403":{"description":"Forbidden"},"404":{"description":"Not found"}},"summary":"List brokers"}},"/brokers/autocomplete":{"get":{"parameters":[{"description":"column","in":"query","name":"column","required":false,"schema":{"type":"string"}},{"description":"query","in":"query","name":"query","required":false,"schema":{"type":"string"}},{"description":"Resource-specific fuzzy search.","in":"query","name":"search","required":false,"schema":{"type":"string"}},{"description":"limit","in":"query","name":"limit","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response"},"400":{"description":"Validation error"},"401":{"description":"Missing or invalid authorization"},"403":{"description":"Forbidden"},"404":{"description":"Not found"}},"summary":"Autocomplete brokers"}},"/brokers/export.csv":{"get":{"description":"List brokers with pagination, sorting, and filters. Use the `tags` query parameter to return only entities that have the authenticated user's campaign tags (AND semantics when multiple tags are provided).","parameters":[{"description":"Comma-separated brokerage classes.","in":"query","name":"brokerage_class","required":false,"schema":{"enum":["national player","regional player","local broker"],"type":"string"}},{"description":"Comma-separated client count bands.","in":"query","name":"client_count_bands","required":false,"schema":{"type":"string"}},{"description":"Return only the total count and no rows.","in":"query","name":"count_only","required":false,"schema":{"type":"boolean"}},{"description":"CRM match status. Requires an API key owned by a user with CRM context.","in":"query","name":"crm_status","required":false,"schema":{"enum":["in_hubspot","in_salesforce","in_both","not_in_crm"],"type":"string"}},{"description":"Comma-separated DMA names.","in":"query","name":"dmas","required":false,"schema":{"type":"string"}},{"description":"Estimate the rows and credits for one page without returning rows. The response also reports estimated_total_matches; estimated_rows is page-bounded.","in":"query","name":"dry_run","required":false,"schema":{"type":"boolean"}},{"description":"Comma-separated response fields. id is always included.","in":"query","name":"fields","required":false,"schema":{"type":"string"}},{"description":"Filing year or latest.","in":"query","name":"filing_year","required":false,"schema":{"type":"string"}},{"description":"Response format.","in":"query","name":"format","required":false,"schema":{"enum":["json","flat"],"type":"string"}},{"description":"Geographic filter mode.","in":"query","name":"geo_mode","required":false,"schema":{"enum":["state","dma"],"type":"string"}},{"description":"Include total_count in response metadata.","in":"query","name":"include_count","required":false,"schema":{"type":"boolean"}},{"description":"Filter long-tail records.","in":"query","name":"long_tail","required":false,"schema":{"type":"boolean"}},{"description":"Response field tier.","in":"query","name":"mode","required":false,"schema":{"enum":["basic","full","light"],"type":"string"}},{"description":"Zero-indexed page number.","in":"query","name":"page","required":false,"schema":{"minimum":0,"type":"integer"}},{"description":"Rows per page. Maximum 500. Values above 25 require at least one filter.","in":"query","name":"page_size","required":false,"schema":{"maximum":500,"minimum":1,"type":"integer"}},{"description":"Resource-specific fuzzy search.","in":"query","name":"search","required":false,"schema":{"type":"string"}},{"description":"Signal match mode. all requires every requested signal and is echoed in meta.applied_filters.","in":"query","name":"signal_match","required":false,"schema":{"enum":["any","all"],"type":"string"}},{"description":"Comma-separated signal names.","in":"query","name":"signals","required":false,"schema":{"type":"string"}},{"description":"Sort field from the resource allowlist.","in":"query","name":"sort_by","required":false,"schema":{"type":"string"}},{"description":"Sort direction.","in":"query","name":"sort_dir","required":false,"schema":{"enum":["asc","desc"],"type":"string"}},{"description":"Comma-separated two-letter USPS state codes. Lowercase codes are normalized; invalid codes or full state names return 400 with the supported values.","in":"query","name":"states","required":false,"schema":{"type":"string"}},{"description":"Comma-separated campaign tag names. User-scoped: only tags owned by the authenticated API user apply. AND semantics: when multiple tags are provided, the entity must have all of them. Supported on GET /companies, /brokers, /broker-offices, and /personnel (including export.csv). Example: q1-outreach,high-priority","in":"query","name":"tags","required":false,"schema":{"type":"string"}},{"description":"Column filter. Replace `column` with the column key, e.g. `cf[total_number_of_employees]=gte:300,lte:500` or `cf[company_name]=acme`. Numeric columns support `gte:`, `gt:`, `lte:`, and `lt:` bounds. Percentage columns such as `participant_growth`, `commission_growth`, and `broker_commission_growth_pct` interpret numeric thresholds as percent values and scale them to stored ratios internally (`gte:1` means at least 1%). Multiple filters can be provided by comma-separating values.","in":"query","name":"cf[column]","required":false,"schema":{"type":"string"}},{"description":"Exclude rows where the named column is blank.","in":"query","name":"eb[column]","required":false,"schema":{"type":"boolean"}}],"responses":{"200":{"description":"Successful response"},"400":{"description":"Validation error"},"401":{"description":"Missing or invalid authorization"},"403":{"description":"Forbidden"},"404":{"description":"Not found"}},"summary":"Export brokers CSV"}},"/brokers/lookup":{"get":{"parameters":[{"description":"name","in":"query","name":"name","required":true,"schema":{"type":"string"}},{"description":"Response field tier.","in":"query","name":"mode","required":false,"schema":{"enum":["basic","full","light"],"type":"string"}},{"description":"Comma-separated response fields. id is always included.","in":"query","name":"fields","required":false,"schema":{"type":"string"}},{"description":"Response format.","in":"query","name":"format","required":false,"schema":{"enum":["json","flat"],"type":"string"}}],"responses":{"200":{"description":"Successful response"},"400":{"description":"Validation error"},"401":{"description":"Missing or invalid authorization"},"403":{"description":"Forbidden"},"404":{"description":"Not found"}},"summary":"Lookup broker"}},"/brokers/{id}":{"get":{"parameters":[{"description":"Resource identifier.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response"},"400":{"description":"Validation error"},"401":{"description":"Missing or invalid authorization"},"403":{"description":"Forbidden"},"404":{"description":"Not found"}},"summary":"Get broker"}},"/brokers/{id}/tags":{"get":{"description":"List user-scoped tags attached to one broker record for the authenticated API user.","parameters":[{"description":"Resource identifier.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response"},"400":{"description":"Validation error"},"401":{"description":"Missing or invalid authorization"},"403":{"description":"Forbidden"},"404":{"description":"Not found"}},"summary":"List broker tags"}},"/companies":{"get":{"description":"List companies with pagination, sorting, and filters. Use the `tags` query parameter to return only entities that have the authenticated user's campaign tags (AND semantics when multiple tags are provided).","parameters":[{"description":"Comma-separated 401K asset tiers.","in":"query","name":"asset_tiers_401k","required":false,"schema":{"type":"string"}},{"description":"Insurance line filter.","in":"query","name":"benefit_type","required":false,"schema":{"type":"string"}},{"description":"Broker name substring across broker relationships.","in":"query","name":"broker","required":false,"schema":{"type":"string"}},{"description":"Broker office name or UUID across broker office relationships.","in":"query","name":"broker_office","required":false,"schema":{"type":"string"}},{"description":"Comma-separated broker office IDs.","in":"query","name":"broker_office_ids","required":false,"schema":{"type":"string"}},{"description":"Carrier name substring across carrier relationships.","in":"query","name":"carrier","required":false,"schema":{"type":"string"}},{"description":"Return only the total count and no rows.","in":"query","name":"count_only","required":false,"schema":{"type":"boolean"}},{"description":"CRM match status. Requires an API key owned by a user with CRM context.","in":"query","name":"crm_status","required":false,"schema":{"enum":["in_hubspot","in_salesforce","in_both","not_in_crm"],"type":"string"}},{"description":"Comma-separated DMA names.","in":"query","name":"dmas","required":false,"schema":{"type":"string"}},{"description":"Exact company domain (equality on the normalized domain).","in":"query","name":"domain","required":false,"schema":{"type":"string"}},{"description":"Substring match on the company website column.","in":"query","name":"domain_contains","required":false,"schema":{"type":"string"}},{"description":"Estimate the rows and credits for one page without returning rows. The response also reports estimated_total_matches; estimated_rows is page-bounded.","in":"query","name":"dry_run","required":false,"schema":{"type":"boolean"}},{"description":"Comma-separated employee bands.","in":"query","name":"employee_bands","required":false,"schema":{"type":"string"}},{"description":"Comma-separated response fields. id is always included.","in":"query","name":"fields","required":false,"schema":{"type":"string"}},{"description":"Filing year or latest.","in":"query","name":"filing_year","required":false,"schema":{"type":"string"}},{"description":"Response format.","in":"query","name":"format","required":false,"schema":{"enum":["json","flat"],"type":"string"}},{"description":"Self-Funded or Fully Insured.","in":"query","name":"funding_status","required":false,"schema":{"type":"string"}},{"description":"Geographic filter mode.","in":"query","name":"geo_mode","required":false,"schema":{"enum":["state","dma"],"type":"string"}},{"description":"Include total_count in response metadata.","in":"query","name":"include_count","required":false,"schema":{"type":"boolean"}},{"description":"Comma-separated industry labels. Each label expands across its industry_search_term category hierarchy, so returned company_industry values can be adjacent industries. Use cf[company_industry] for the stricter substring match on the returned field.","in":"query","name":"industries","required":false,"schema":{"type":"string"}},{"description":"Filter long-tail records.","in":"query","name":"long_tail","required":false,"schema":{"type":"boolean"}},{"description":"Filter long-tail broker records.","in":"query","name":"long_tail_brokers","required":false,"schema":{"type":"boolean"}},{"description":"Response field tier.","in":"query","name":"mode","required":false,"schema":{"enum":["basic","full","light"],"type":"string"}},{"description":"Zero-indexed page number.","in":"query","name":"page","required":false,"schema":{"minimum":0,"type":"integer"}},{"description":"Rows per page. Maximum 500. Values above 25 require at least one filter.","in":"query","name":"page_size","required":false,"schema":{"maximum":500,"minimum":1,"type":"integer"}},{"description":"Comma-separated premium tiers.","in":"query","name":"premium_tiers","required":false,"schema":{"type":"string"}},{"description":"Primary broker name.","in":"query","name":"primary_broker","required":false,"schema":{"type":"string"}},{"description":"primary_broker_office","in":"query","name":"primary_broker_office","required":false,"schema":{"type":"string"}},{"description":"Comma-separated relationship-density bands.","in":"query","name":"relationship_density","required":false,"schema":{"type":"string"}},{"description":"Renewal month name.","in":"query","name":"renewal_month","required":false,"schema":{"type":"string"}},{"description":"Resource-specific fuzzy search.","in":"query","name":"search","required":false,"schema":{"type":"string"}},{"description":"Filter short-form filings.","in":"query","name":"short_form","required":false,"schema":{"type":"boolean"}},{"description":"Signal match mode. all requires every requested signal and is echoed in meta.applied_filters.","in":"query","name":"signal_match","required":false,"schema":{"enum":["any","all"],"type":"string"}},{"description":"Comma-separated signal names.","in":"query","name":"signals","required":false,"schema":{"type":"string"}},{"description":"Sort field from the resource allowlist.","in":"query","name":"sort_by","required":false,"schema":{"type":"string"}},{"description":"Sort direction.","in":"query","name":"sort_dir","required":false,"schema":{"enum":["asc","desc"],"type":"string"}},{"description":"Comma-separated two-letter USPS state codes. Lowercase codes are normalized; invalid codes or full state names return 400 with the supported values.","in":"query","name":"states","required":false,"schema":{"type":"string"}},{"description":"Comma-separated campaign tag names. User-scoped: only tags owned by the authenticated API user apply. AND semantics: when multiple tags are provided, the entity must have all of them. Supported on GET /companies, /brokers, /broker-offices, and /personnel (including export.csv). Example: q1-outreach,high-priority","in":"query","name":"tags","required":false,"schema":{"type":"string"}},{"description":"Column filter. Replace `column` with the column key, e.g. `cf[total_number_of_employees]=gte:300,lte:500` or `cf[company_name]=acme`. Numeric columns support `gte:`, `gt:`, `lte:`, and `lt:` bounds. Percentage columns such as `participant_growth`, `commission_growth`, and `broker_commission_growth_pct` interpret numeric thresholds as percent values and scale them to stored ratios internally (`gte:1` means at least 1%). Multiple filters can be provided by comma-separating values.","in":"query","name":"cf[column]","required":false,"schema":{"type":"string"}},{"description":"Exclude rows where the named column is blank.","in":"query","name":"eb[column]","required":false,"schema":{"type":"boolean"}}],"responses":{"200":{"description":"Successful response"},"400":{"description":"Validation error"},"401":{"description":"Missing or invalid authorization"},"403":{"description":"Forbidden"},"404":{"description":"Not found"}},"summary":"List companies"}},"/companies/autocomplete":{"get":{"parameters":[{"description":"column","in":"query","name":"column","required":false,"schema":{"type":"string"}},{"description":"query","in":"query","name":"query","required":false,"schema":{"type":"string"}},{"description":"Resource-specific fuzzy search.","in":"query","name":"search","required":false,"schema":{"type":"string"}},{"description":"limit","in":"query","name":"limit","required":false,"schema":{"type":"string"}},{"description":"Comma-separated response fields. id is always included.","in":"query","name":"fields","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response"},"400":{"description":"Validation error"},"401":{"description":"Missing or invalid authorization"},"403":{"description":"Forbidden"},"404":{"description":"Not found"}},"summary":"Autocomplete companies"}},"/companies/batch":{"post":{"description":"Provide domains or EINs, but not both. Domains use the same normalized exact-domain matcher and best-record selection as GET /companies/lookup. For a shared exact domain, a company-name/domain-brand ownership match takes precedence over employee count. Each miss is returned in data.unmatched using the original input string; data.not_found is a compatibility alias. Fuzzy or substring website matches are not returned or billed.","parameters":[{"description":"Response field tier.","in":"query","name":"mode","required":false,"schema":{"enum":["basic","full","light"],"type":"string"}},{"description":"Comma-separated response fields. id is always included.","in":"query","name":"fields","required":false,"schema":{"type":"string"}},{"description":"Response format.","in":"query","name":"format","required":false,"schema":{"enum":["json","flat"],"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"domains":{"items":{"type":"string"},"maxItems":100,"type":"array"},"eins":{"items":{"type":"string"},"maxItems":100,"type":"array"}},"type":"object"}}},"required":false},"responses":{"200":{"description":"Successful response"},"400":{"description":"Validation error"},"401":{"description":"Missing or invalid authorization"},"403":{"description":"Forbidden"},"404":{"description":"Not found"}},"summary":"Batch lookup companies"}},"/companies/export.csv":{"get":{"description":"List companies with pagination, sorting, and filters. Use the `tags` query parameter to return only entities that have the authenticated user's campaign tags (AND semantics when multiple tags are provided).","parameters":[{"description":"Comma-separated 401K asset tiers.","in":"query","name":"asset_tiers_401k","required":false,"schema":{"type":"string"}},{"description":"Insurance line filter.","in":"query","name":"benefit_type","required":false,"schema":{"type":"string"}},{"description":"Broker name substring across broker relationships.","in":"query","name":"broker","required":false,"schema":{"type":"string"}},{"description":"Broker office name or UUID across broker office relationships.","in":"query","name":"broker_office","required":false,"schema":{"type":"string"}},{"description":"Comma-separated broker office IDs.","in":"query","name":"broker_office_ids","required":false,"schema":{"type":"string"}},{"description":"Carrier name substring across carrier relationships.","in":"query","name":"carrier","required":false,"schema":{"type":"string"}},{"description":"Return only the total count and no rows.","in":"query","name":"count_only","required":false,"schema":{"type":"boolean"}},{"description":"CRM match status. Requires an API key owned by a user with CRM context.","in":"query","name":"crm_status","required":false,"schema":{"enum":["in_hubspot","in_salesforce","in_both","not_in_crm"],"type":"string"}},{"description":"Comma-separated DMA names.","in":"query","name":"dmas","required":false,"schema":{"type":"string"}},{"description":"Exact company domain (equality on the normalized domain).","in":"query","name":"domain","required":false,"schema":{"type":"string"}},{"description":"Substring match on the company website column.","in":"query","name":"domain_contains","required":false,"schema":{"type":"string"}},{"description":"Estimate the rows and credits for one page without returning rows. The response also reports estimated_total_matches; estimated_rows is page-bounded.","in":"query","name":"dry_run","required":false,"schema":{"type":"boolean"}},{"description":"Comma-separated employee bands.","in":"query","name":"employee_bands","required":false,"schema":{"type":"string"}},{"description":"Comma-separated response fields. id is always included.","in":"query","name":"fields","required":false,"schema":{"type":"string"}},{"description":"Filing year or latest.","in":"query","name":"filing_year","required":false,"schema":{"type":"string"}},{"description":"Response format.","in":"query","name":"format","required":false,"schema":{"enum":["json","flat"],"type":"string"}},{"description":"Self-Funded or Fully Insured.","in":"query","name":"funding_status","required":false,"schema":{"type":"string"}},{"description":"Geographic filter mode.","in":"query","name":"geo_mode","required":false,"schema":{"enum":["state","dma"],"type":"string"}},{"description":"Include total_count in response metadata.","in":"query","name":"include_count","required":false,"schema":{"type":"boolean"}},{"description":"Comma-separated industry labels. Each label expands across its industry_search_term category hierarchy, so returned company_industry values can be adjacent industries. Use cf[company_industry] for the stricter substring match on the returned field.","in":"query","name":"industries","required":false,"schema":{"type":"string"}},{"description":"Filter long-tail records.","in":"query","name":"long_tail","required":false,"schema":{"type":"boolean"}},{"description":"Filter long-tail broker records.","in":"query","name":"long_tail_brokers","required":false,"schema":{"type":"boolean"}},{"description":"Response field tier.","in":"query","name":"mode","required":false,"schema":{"enum":["basic","full","light"],"type":"string"}},{"description":"Zero-indexed page number.","in":"query","name":"page","required":false,"schema":{"minimum":0,"type":"integer"}},{"description":"Rows per page. Maximum 500. Values above 25 require at least one filter.","in":"query","name":"page_size","required":false,"schema":{"maximum":500,"minimum":1,"type":"integer"}},{"description":"Comma-separated premium tiers.","in":"query","name":"premium_tiers","required":false,"schema":{"type":"string"}},{"description":"Primary broker name.","in":"query","name":"primary_broker","required":false,"schema":{"type":"string"}},{"description":"primary_broker_office","in":"query","name":"primary_broker_office","required":false,"schema":{"type":"string"}},{"description":"Comma-separated relationship-density bands.","in":"query","name":"relationship_density","required":false,"schema":{"type":"string"}},{"description":"Renewal month name.","in":"query","name":"renewal_month","required":false,"schema":{"type":"string"}},{"description":"Resource-specific fuzzy search.","in":"query","name":"search","required":false,"schema":{"type":"string"}},{"description":"Filter short-form filings.","in":"query","name":"short_form","required":false,"schema":{"type":"boolean"}},{"description":"Signal match mode. all requires every requested signal and is echoed in meta.applied_filters.","in":"query","name":"signal_match","required":false,"schema":{"enum":["any","all"],"type":"string"}},{"description":"Comma-separated signal names.","in":"query","name":"signals","required":false,"schema":{"type":"string"}},{"description":"Sort field from the resource allowlist.","in":"query","name":"sort_by","required":false,"schema":{"type":"string"}},{"description":"Sort direction.","in":"query","name":"sort_dir","required":false,"schema":{"enum":["asc","desc"],"type":"string"}},{"description":"Comma-separated two-letter USPS state codes. Lowercase codes are normalized; invalid codes or full state names return 400 with the supported values.","in":"query","name":"states","required":false,"schema":{"type":"string"}},{"description":"Comma-separated campaign tag names. User-scoped: only tags owned by the authenticated API user apply. AND semantics: when multiple tags are provided, the entity must have all of them. Supported on GET /companies, /brokers, /broker-offices, and /personnel (including export.csv). Example: q1-outreach,high-priority","in":"query","name":"tags","required":false,"schema":{"type":"string"}},{"description":"Column filter. Replace `column` with the column key, e.g. `cf[total_number_of_employees]=gte:300,lte:500` or `cf[company_name]=acme`. Numeric columns support `gte:`, `gt:`, `lte:`, and `lt:` bounds. Percentage columns such as `participant_growth`, `commission_growth`, and `broker_commission_growth_pct` interpret numeric thresholds as percent values and scale them to stored ratios internally (`gte:1` means at least 1%). Multiple filters can be provided by comma-separating values.","in":"query","name":"cf[column]","required":false,"schema":{"type":"string"}},{"description":"Exclude rows where the named column is blank.","in":"query","name":"eb[column]","required":false,"schema":{"type":"boolean"}}],"responses":{"200":{"description":"Successful response"},"400":{"description":"Validation error"},"401":{"description":"Missing or invalid authorization"},"403":{"description":"Forbidden"},"404":{"description":"Not found"}},"summary":"Export companies CSV"}},"/companies/lookup":{"get":{"description":"Provide exactly one of domain, name, or ein. Name returns 200 only for one exact stored-name match, 400 with suggestions when ambiguous, and 404 on a miss. Domain 404 does not prove the company is absent because website coverage can be incomplete; use /companies/autocomplete by company_name before concluding a miss.","parameters":[{"description":"Exact company domain (equality on the normalized domain).","in":"query","name":"domain","required":false,"schema":{"type":"string"}},{"description":"name","in":"query","name":"name","required":false,"schema":{"type":"string"}},{"description":"ein","in":"query","name":"ein","required":false,"schema":{"type":"string"}},{"description":"Response field tier.","in":"query","name":"mode","required":false,"schema":{"enum":["basic","full","light"],"type":"string"}},{"description":"Comma-separated response fields. id is always included.","in":"query","name":"fields","required":false,"schema":{"type":"string"}},{"description":"Response format.","in":"query","name":"format","required":false,"schema":{"enum":["json","flat"],"type":"string"}}],"responses":{"200":{"description":"Successful response"},"400":{"description":"Validation error"},"401":{"description":"Missing or invalid authorization"},"403":{"description":"Forbidden"},"404":{"description":"Not found"}},"summary":"Lookup company"}},"/companies/{id}":{"get":{"parameters":[{"description":"Resource identifier.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response"},"400":{"description":"Validation error"},"401":{"description":"Missing or invalid authorization"},"403":{"description":"Forbidden"},"404":{"description":"Not found"}},"summary":"Get company"}},"/companies/{id}/tags":{"get":{"description":"List user-scoped tags attached to one company record for the authenticated API user.","parameters":[{"description":"Resource identifier.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response"},"400":{"description":"Validation error"},"401":{"description":"Missing or invalid authorization"},"403":{"description":"Forbidden"},"404":{"description":"Not found"}},"summary":"List company tags"}},"/credits":{"get":{"description":"Requires credits:read scope. Returns remaining pooled credits, active grants with expiration dates, overage allowance, and rolling usage.","parameters":[],"responses":{"200":{"description":"Successful response"},"400":{"description":"Validation error"},"401":{"description":"Missing or invalid authorization"},"403":{"description":"Forbidden"},"404":{"description":"Not found"}},"summary":"Check credit balance"}},"/credits/usage":{"get":{"description":"Requires usage:read scope. Returns usage for the current credit account. Use group_by=api_key to see usage attributed to each key, including child keys.","parameters":[{"description":"Inclusive usage start date or timestamp.","in":"query","name":"from","required":false,"schema":{"type":"string"}},{"description":"Inclusive usage end date or timestamp.","in":"query","name":"to","required":false,"schema":{"type":"string"}},{"description":"Usage grouping. One of day, endpoint, or api_key.","in":"query","name":"group_by","required":false,"schema":{"enum":["day","endpoint","api_key"],"type":"string"}}],"responses":{"200":{"description":"Successful response"},"400":{"description":"Validation error"},"401":{"description":"Missing or invalid authorization"},"403":{"description":"Forbidden"},"404":{"description":"Not found"}},"summary":"Credit usage history"}},"/credits/usage/by-endpoint":{"get":{"description":"Requires usage:read scope. Canonical nested alias for endpoint usage rollups. Writing-job status polls report zero credits under /writing-jobs/{job_id}; finalized generation charges are attributed to /writing-jobs.","parameters":[{"description":"Inclusive usage start date or timestamp.","in":"query","name":"from","required":false,"schema":{"type":"string"}},{"description":"Inclusive usage end date or timestamp.","in":"query","name":"to","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response"},"400":{"description":"Validation error"},"401":{"description":"Missing or invalid authorization"},"403":{"description":"Forbidden"},"404":{"description":"Not found"}},"summary":"Credit usage grouped by endpoint"}},"/credits/usage/by-key":{"get":{"description":"Requires usage:read scope. Canonical nested alias for API-key usage rollups.","parameters":[{"description":"Inclusive usage start date or timestamp.","in":"query","name":"from","required":false,"schema":{"type":"string"}},{"description":"Inclusive usage end date or timestamp.","in":"query","name":"to","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response"},"400":{"description":"Validation error"},"401":{"description":"Missing or invalid authorization"},"403":{"description":"Forbidden"},"404":{"description":"Not found"}},"summary":"Credit usage grouped by API key"}},"/data-flags":{"get":{"parameters":[{"description":"status","in":"query","name":"status","required":false,"schema":{"type":"string"}},{"description":"Entity type for tag operations. Accepts API resource names (`companies`, `brokers`, `broker-offices`, `personnel`) or singular aliases (`company`, `broker`, `broker-office`, `personnel`).","in":"query","name":"entity_type","required":false,"schema":{"type":"string"}},{"description":"Zero-indexed page number.","in":"query","name":"page","required":false,"schema":{"minimum":0,"type":"integer"}},{"description":"Rows per page. Maximum 500. Values above 25 require at least one filter.","in":"query","name":"page_size","required":false,"schema":{"maximum":500,"minimum":1,"type":"integer"}}],"responses":{"200":{"description":"Successful response"},"400":{"description":"Validation error"},"401":{"description":"Missing or invalid authorization"},"403":{"description":"Forbidden"},"404":{"description":"Not found"}},"summary":"List data quality flags"},"post":{"parameters":[],"requestBody":{"content":{"application/json":{"schema":{"properties":{"corrections":{"items":{"type":"object"},"type":"array"},"entity_id":{"type":"string"},"entity_name":{"type":"string"},"entity_type":{"type":"string"},"field":{"type":"string"},"field_key":{"type":"string"},"issue":{"type":"string"},"reason":{"type":"string"},"resource":{"type":"string"},"suggested_value":{"type":"string"}},"required":["entity_id"],"type":"object"}}},"required":true},"responses":{"201":{"description":"Successful response"},"400":{"description":"Validation error"},"401":{"description":"Missing or invalid authorization"},"403":{"description":"Forbidden"},"404":{"description":"Not found"}},"summary":"Create data quality flag"}},"/data-flags/bulk":{"patch":{"parameters":[],"responses":{"200":{"description":"Successful response"},"400":{"description":"Validation error"},"401":{"description":"Missing or invalid authorization"},"403":{"description":"Forbidden"},"404":{"description":"Not found"}},"summary":"Internal reviewer: bulk approve or reject data quality flags"}},"/data-flags/{id}":{"delete":{"parameters":[{"description":"Resource identifier.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response"},"400":{"description":"Validation error"},"401":{"description":"Missing or invalid authorization"},"403":{"description":"Forbidden"},"404":{"description":"Not found"}},"summary":"Internal reviewer: delete data quality flag"},"patch":{"parameters":[{"description":"Resource identifier.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response"},"400":{"description":"Validation error"},"401":{"description":"Missing or invalid authorization"},"403":{"description":"Forbidden"},"404":{"description":"Not found"}},"summary":"Internal reviewer: approve or reject data quality flag"}},"/dynamic-tags":{"get":{"parameters":[{"description":"Zero-indexed page number.","in":"query","name":"page","required":false,"schema":{"minimum":0,"type":"integer"}},{"description":"Rows per page. Maximum 500. Values above 25 require at least one filter.","in":"query","name":"page_size","required":false,"schema":{"maximum":500,"minimum":1,"type":"integer"}},{"description":"Resource-specific fuzzy search.","in":"query","name":"search","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response"},"400":{"description":"Validation error"},"401":{"description":"Missing or invalid authorization"},"403":{"description":"Forbidden"},"404":{"description":"Not found"}},"summary":"List saved dynamic tags"},"post":{"parameters":[],"requestBody":{"content":{"application/json":{"schema":{"properties":{"color_index":{"type":"integer"},"entity_type":{"enum":["company","broker","personnel"],"type":"string"},"filter_def":{"additionalProperties":true,"type":"object"},"name":{"type":"string"}},"required":["name","entity_type","filter_def"],"type":"object"}}},"required":true},"responses":{"201":{"description":"Successful response"},"400":{"description":"Validation error"},"401":{"description":"Missing or invalid authorization"},"403":{"description":"Forbidden"},"404":{"description":"Not found"}},"summary":"Create a saved dynamic tag"}},"/dynamic-tags/{id}":{"delete":{"parameters":[{"description":"Resource identifier.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response"},"400":{"description":"Validation error"},"401":{"description":"Missing or invalid authorization"},"403":{"description":"Forbidden"},"404":{"description":"Not found"}},"summary":"Delete a saved dynamic tag"},"get":{"parameters":[{"description":"Resource identifier.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response"},"400":{"description":"Validation error"},"401":{"description":"Missing or invalid authorization"},"403":{"description":"Forbidden"},"404":{"description":"Not found"}},"summary":"Get a saved dynamic tag"},"patch":{"parameters":[{"description":"Resource identifier.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"color_index":{"type":"integer"},"entity_type":{"enum":["company","broker","personnel"],"type":"string"},"filter_def":{"additionalProperties":true,"type":"object"},"name":{"type":"string"}},"type":"object"}}},"required":false},"responses":{"200":{"description":"Successful response"},"400":{"description":"Validation error"},"401":{"description":"Missing or invalid authorization"},"403":{"description":"Forbidden"},"404":{"description":"Not found"}},"summary":"Edit a saved dynamic tag"}},"/filter-options":{"get":{"description":"Returns the filter discovery manifest. Enumerated values live under `data.enums`; `data.enums.top_brokers` contains the top 50 brokers, each with `broker_id` and `broker_name`.","parameters":[],"responses":{"200":{"content":{"application/json":{"example":{"data":{"enums":{"top_brokers":[{"broker_id":"161b6b3f7c962d10e894c461ca4d55f5","broker_name":"Gallagher"}]},"resources":{}},"meta":{"credits_charged":0},"ok":true},"schema":{"properties":{"data":{"properties":{"enums":{"properties":{"top_brokers":{"items":{"properties":{"broker_id":{"type":"string"},"broker_name":{"type":"string"}},"required":["broker_id","broker_name"],"type":"object"},"maxItems":50,"type":"array"}},"type":"object"},"resources":{"type":"object"}},"type":"object"},"meta":{"type":"object"},"ok":{"type":"boolean"}},"type":"object"}}},"description":"Successful response"},"400":{"description":"Validation error"},"401":{"description":"Missing or invalid authorization"},"403":{"description":"Forbidden"},"404":{"description":"Not found"}},"summary":"List filter options"}},"/filter-options/broker-offices":{"get":{"parameters":[],"responses":{"200":{"description":"Successful response"},"400":{"description":"Validation error"},"401":{"description":"Missing or invalid authorization"},"403":{"description":"Forbidden"},"404":{"description":"Not found"}},"summary":"Get broker office filter details"}},"/filter-options/brokers":{"get":{"parameters":[],"responses":{"200":{"description":"Successful response"},"400":{"description":"Validation error"},"401":{"description":"Missing or invalid authorization"},"403":{"description":"Forbidden"},"404":{"description":"Not found"}},"summary":"Get broker filter details"}},"/filter-options/companies":{"get":{"parameters":[],"responses":{"200":{"description":"Successful response"},"400":{"description":"Validation error"},"401":{"description":"Missing or invalid authorization"},"403":{"description":"Forbidden"},"404":{"description":"Not found"}},"summary":"Get company filter details"}},"/filter-options/personnel":{"get":{"parameters":[],"responses":{"200":{"description":"Successful response"},"400":{"description":"Validation error"},"401":{"description":"Missing or invalid authorization"},"403":{"description":"Forbidden"},"404":{"description":"Not found"}},"summary":"Get personnel filter details"}},"/filter-options/top_brokers":{"get":{"parameters":[],"responses":{"200":{"description":"Successful response"},"400":{"description":"Validation error"},"401":{"description":"Missing or invalid authorization"},"403":{"description":"Forbidden"},"404":{"description":"Not found"}},"summary":"Get top broker filter values"}},"/filter-options/{key}":{"get":{"parameters":[{"description":"Filter option key, such as employee_bands, crm_status, brokerage_class, or filing_year.","in":"path","name":"key","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response"},"400":{"description":"Validation error"},"401":{"description":"Missing or invalid authorization"},"403":{"description":"Forbidden"},"404":{"description":"Not found"}},"summary":"Get filter option values"}},"/filter-options/{resource}/{filter}":{"get":{"parameters":[{"description":"Alias for `entity_type` on tag endpoints.","in":"path","name":"resource","required":true,"schema":{"type":"string"}},{"description":"Resource identifier.","in":"path","name":"filter","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response"},"400":{"description":"Validation error"},"401":{"description":"Missing or invalid authorization"},"403":{"description":"Forbidden"},"404":{"description":"Not found"}},"summary":"Get resource filter values"}},"/identities":{"get":{"description":"List the authenticated user's saved marketing identity versions. Summary fields use the same casing as identity detail responses, including companyName and versionName.","parameters":[],"responses":{"200":{"description":"Successful response"},"400":{"description":"Validation error"},"401":{"description":"Missing or invalid authorization"},"403":{"description":"Forbidden"},"404":{"description":"Not found"}},"summary":"List marketing identities"},"post":{"description":"With url alone, queue website and AI processing and return 202 with a job_id. With url and identity, skip crawling, persist the supplied identity JSON, and return 201.","parameters":[],"requestBody":{"content":{"application/json":{"example":{"url":"https://example.com"},"schema":{"properties":{"identity":{"additionalProperties":true,"type":"object"},"outreach_context":{"type":"string"},"url":{"format":"uri","type":"string"}},"required":["url"],"type":"object"}}},"required":true},"responses":{"201":{"description":"Successful response"},"202":{"description":"Successful response"},"400":{"description":"Validation error"},"401":{"description":"Missing or invalid authorization"},"403":{"description":"Forbidden"},"404":{"description":"Not found"}},"summary":"Create a marketing identity"}},"/identities/schema":{"get":{"description":"Return the schema and example accepted by POST /identities in its manual creation mode.","parameters":[],"responses":{"200":{"description":"Successful response"},"400":{"description":"Validation error"},"401":{"description":"Missing or invalid authorization"},"403":{"description":"Forbidden"},"404":{"description":"Not found"}},"summary":"Get the marketing identity JSON structure"}},"/identities/{id}":{"delete":{"parameters":[{"description":"Resource identifier.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response"},"400":{"description":"Validation error"},"401":{"description":"Missing or invalid authorization"},"403":{"description":"Forbidden"},"404":{"description":"Not found"}},"summary":"Delete a marketing identity"},"get":{"parameters":[{"description":"Resource identifier.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response"},"400":{"description":"Validation error"},"401":{"description":"Missing or invalid authorization"},"403":{"description":"Forbidden"},"404":{"description":"Not found"}},"summary":"Get a marketing identity"},"patch":{"description":"Merge the supplied identity fields into the saved full identity JSON.","parameters":[{"description":"Resource identifier.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"data":{"additionalProperties":true,"type":"object"}},"required":["data"],"type":"object"}}},"required":true},"responses":{"200":{"description":"Successful response"},"400":{"description":"Validation error"},"401":{"description":"Missing or invalid authorization"},"403":{"description":"Forbidden"},"404":{"description":"Not found"}},"summary":"Edit a marketing identity"}},"/identities/{id}/duplicate":{"post":{"parameters":[{"description":"Resource identifier.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"201":{"description":"Successful response"},"400":{"description":"Validation error"},"401":{"description":"Missing or invalid authorization"},"403":{"description":"Forbidden"},"404":{"description":"Not found"}},"summary":"Duplicate a marketing identity"}},"/identities/{id}/share":{"post":{"description":"Return a stable public read link for this exact identity version.","parameters":[{"description":"Resource identifier.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response"},"400":{"description":"Validation error"},"401":{"description":"Missing or invalid authorization"},"403":{"description":"Forbidden"},"404":{"description":"Not found"}},"summary":"Create or retrieve an identity share link"}},"/identity-generation-jobs/{job_id}":{"get":{"description":"Returns queued, running, completed, or failed. A completed response includes the full persisted identity. For bounded long polling, pass wait_ms from 0 through 5000; out-of-range values are rejected. Optionally pass the last observed last_event_count so the response returns when the event count changes or the timeout elapses.","parameters":[{"description":"Resource identifier.","in":"path","name":"job_id","required":true,"schema":{"type":"string"}},{"description":"Bounded long-poll duration in milliseconds, from 0 through 5000. Out-of-range values are rejected.","in":"query","name":"wait_ms","required":false,"schema":{"maximum":5000,"minimum":0,"type":"integer"}},{"description":"Known progress-event count; return when the count changes or wait_ms elapses.","in":"query","name":"last_event_count","required":false,"schema":{"minimum":0,"type":"integer"}}],"responses":{"200":{"description":"Successful response"},"400":{"description":"Validation error"},"401":{"description":"Missing or invalid authorization"},"403":{"description":"Forbidden"},"404":{"description":"Not found"}},"summary":"Get marketing identity generation status"}},"/identity-shares/{token}":{"get":{"description":"Publicly resolve an active share token to the complete identity JSON.","parameters":[{"description":"Resource identifier.","in":"path","name":"token","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response"},"400":{"description":"Validation error"},"401":{"description":"Missing or invalid authorization"},"403":{"description":"Forbidden"},"404":{"description":"Not found"}},"summary":"Get a shared marketing identity"}},"/llms-full.txt":{"get":{"parameters":[],"responses":{"200":{"description":"Successful response"},"400":{"description":"Validation error"},"401":{"description":"Missing or invalid authorization"},"403":{"description":"Forbidden"},"404":{"description":"Not found"}},"summary":"Read the complete plain-text API reference"}},"/llms.txt":{"get":{"parameters":[],"responses":{"200":{"description":"Successful response"},"400":{"description":"Validation error"},"401":{"description":"Missing or invalid authorization"},"403":{"description":"Forbidden"},"404":{"description":"Not found"}},"summary":"List machine-readable API discovery links and core endpoints"}},"/lookalikes":{"post":{"description":"Return up to 50 company, broker-office, or email-eligible personnel lookalikes from 1\u20135 seed IDs. Optional category weights are normalized before ranking. Optional standard resource filters constrain the result population before final ranking. The canonical broker value is broker_office because ranking and results are office-level. A key with the matching read scope is required. Test keys return deterministic sandbox entities and are never charged. Successful production-key searches cost exactly 1 credit per returned entity; validation, authorization, missing-seed, no-match, timeout, and internal failures cost zero. Set dry_run=true to validate seed eligibility without ranking or charge; INVALID_SEED details identify each unavailable seed in received. Personnel requests may set exclude_seed_company=true to remove coworkers before final ranking and billing. weights_mode=override preserves legacy replacement behavior; weights_mode=adjust nudges adaptive weights and returns the final vector in meta.applied_weights.","parameters":[],"requestBody":{"content":{"application/json":{"example":{"dry_run":false,"entity_type":"company","exclude_seed_company":false,"filters":{"states":["TX"]},"limit":25,"seed_ids":["123456789"],"weights":{"geo":1,"industry":2},"weights_mode":"override"},"schema":{"additionalProperties":false,"allOf":[{"oneOf":[{"properties":{"entity_type":{"const":"company"},"weights":{"additionalProperties":false,"minProperties":1,"properties":{"all_carriers":{"minimum":0,"type":"number"},"all_providers_carriers":{"minimum":0,"type":"number"},"carrier_premiums":{"minimum":0,"type":"number"},"company_profile":{"minimum":0,"type":"number"},"employee_count_bucket":{"minimum":0,"type":"number"},"geo":{"minimum":0,"type":"number"},"industry":{"minimum":0,"type":"number"},"medical_broker_relationship":{"minimum":0,"type":"number"},"premium_relationship_summary":{"minimum":0,"type":"number"},"total_premiums":{"minimum":0,"type":"number"},"total_relationships":{"minimum":0,"type":"number"}},"type":"object"}},"title":"company lookalike request"},{"properties":{"entity_type":{"const":"broker_office"},"weights":{"additionalProperties":false,"minProperties":1,"properties":{"broker":{"minimum":0,"type":"number"},"broker_carrier":{"minimum":0,"type":"number"},"broker_office_commissions":{"minimum":0,"type":"number"},"client_count_bucket":{"minimum":0,"type":"number"},"employee_coverage":{"minimum":0,"type":"number"},"general":{"minimum":0,"type":"number"},"geo":{"minimum":0,"type":"number"},"industry":{"minimum":0,"type":"number"}},"type":"object"}},"title":"broker_office lookalike request"},{"properties":{"entity_type":{"const":"personnel"},"weights":{"additionalProperties":false,"minProperties":1,"properties":{"broker_office":{"minimum":0,"type":"number"},"company_industry":{"minimum":0,"type":"number"},"company_name":{"minimum":0,"type":"number"},"geo":{"minimum":0,"type":"number"},"job_description":{"minimum":0,"type":"number"},"seniority":{"minimum":0,"type":"number"},"title":{"minimum":0,"type":"number"}},"type":"object"}},"title":"personnel lookalike request"}]}],"properties":{"dry_run":{"default":false,"description":"Validate V3 seed eligibility without ranking candidates or charging credits. Successful probes return one eligibility row per seed.","type":"boolean"},"entity_type":{"enum":["company","broker_office","personnel"],"type":"string"},"exclude_seed_company":{"default":false,"description":"Personnel only. Exclude candidates whose company EIN matches any seed's company before ranking and billing.","type":"boolean"},"filters":{"additionalProperties":true,"description":"Standard filters for the selected result resource, applied to the candidate population before final ranking. Use the same top-level names as the resource list endpoint; custom-column filters may be supplied under cf. Query parameters are rejected.","minProperties":1,"type":"object"},"limit":{"default":25,"maximum":50,"minimum":1,"type":"integer"},"seed_ids":{"items":{"minLength":1,"type":"string"},"maxItems":5,"minItems":1,"type":"array","uniqueItems":true},"weights":{"additionalProperties":{"minimum":0,"type":"number"},"description":"Entity-specific public category weights. Select only fields documented for the requested entity_type. Unknown fields, negative/non-finite values, and all-zero sets are rejected.","minProperties":1,"type":"object"},"weights_mode":{"default":"override","description":"override normalizes only supplied categories and assigns omitted categories zero weight. adjust multiplies adaptive weights by supplied ratios and preserves omitted dimensions.","enum":["override","adjust"],"type":"string"}},"required":["entity_type","seed_ids"],"type":"object"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"data":{"items":{"properties":{"id":{"type":"string"},"rank":{"minimum":1,"type":"integer"}},"required":["id","rank"],"type":"object"},"type":"array"},"meta":{"properties":{"applied_weights":{"additionalProperties":{"minimum":0,"type":"number"},"type":"object"},"base_credits":{"minimum":1,"type":"number"},"billable_rows":{"minimum":1,"type":"integer"},"cached_rows":{"const":0,"type":"integer"},"credit_balance_after":{"type":"number"},"credit_balance_before":{"type":"number"},"credits_charged":{"minimum":1,"type":"number"},"entity_type":{"enum":["company","broker_office","personnel"],"type":"string"},"lookalike_version":{"type":"string"},"overage_credits_charged":{"minimum":0,"type":"number"},"returned":{"minimum":1,"type":"integer"},"signal_credits":{"const":0,"type":"number"}},"required":["returned","entity_type","lookalike_version","credits_charged","base_credits","signal_credits","billable_rows","cached_rows"],"type":"object"},"ok":{"const":true,"type":"boolean"}},"required":["ok","data","meta"],"type":"object"}}},"description":"Successful response"},"400":{"content":{"application/json":{"schema":{"properties":{"error":{"properties":{"code":{"const":"VALIDATION_ERROR","type":"string"},"details":{"items":{"additionalProperties":true,"type":"object"},"type":"array"},"message":{"type":"string"},"request_id":{"type":"string"}},"required":["code","message","details","request_id"],"type":"object"},"meta":{"properties":{"credits_charged":{"const":0,"type":"number"}},"required":["credits_charged"],"type":"object"},"ok":{"const":false,"type":"boolean"}},"required":["ok","error","meta"],"type":"object"}}},"description":"Invalid request"},"401":{"content":{"application/json":{"schema":{"properties":{"error":{"properties":{"code":{"const":"UNAUTHORIZED","type":"string"},"details":{"items":{"additionalProperties":true,"type":"object"},"type":"array"},"message":{"type":"string"},"request_id":{"type":"string"}},"required":["code","message","details","request_id"],"type":"object"},"meta":{"properties":{"credits_charged":{"const":0,"type":"number"}},"required":["credits_charged"],"type":"object"},"ok":{"const":false,"type":"boolean"}},"required":["ok","error","meta"],"type":"object"}}},"description":"Missing or invalid authorization"},"403":{"content":{"application/json":{"schema":{"properties":{"error":{"properties":{"code":{"const":"FORBIDDEN","type":"string"},"details":{"items":{"additionalProperties":true,"type":"object"},"type":"array"},"message":{"type":"string"},"request_id":{"type":"string"}},"required":["code","message","details","request_id"],"type":"object"},"meta":{"properties":{"credits_charged":{"const":0,"type":"number"}},"required":["credits_charged"],"type":"object"},"ok":{"const":false,"type":"boolean"}},"required":["ok","error","meta"],"type":"object"}}},"description":"The production key lacks the required read scope"},"404":{"content":{"application/json":{"schema":{"properties":{"error":{"properties":{"code":{"const":"NO_MATCHES","type":"string"},"details":{"items":{"additionalProperties":true,"type":"object"},"type":"array"},"message":{"type":"string"},"request_id":{"type":"string"}},"required":["code","message","details","request_id"],"type":"object"},"meta":{"properties":{"credits_charged":{"const":0,"type":"number"}},"required":["credits_charged"],"type":"object"},"ok":{"const":false,"type":"boolean"}},"required":["ok","error","meta"],"type":"object"}}},"description":"Valid seeds produced no matches"},"422":{"content":{"application/json":{"schema":{"properties":{"error":{"properties":{"code":{"const":"INVALID_SEED","type":"string"},"details":{"items":{"additionalProperties":true,"type":"object"},"type":"array"},"message":{"type":"string"},"request_id":{"type":"string"}},"required":["code","message","details","request_id"],"type":"object"},"meta":{"properties":{"credits_charged":{"const":0,"type":"number"}},"required":["credits_charged"],"type":"object"},"ok":{"const":false,"type":"boolean"}},"required":["ok","error","meta"],"type":"object"}}},"description":"At least one seed is unavailable in the selected V3 population"},"500":{"content":{"application/json":{"schema":{"properties":{"error":{"properties":{"code":{"const":"LOOKALIKE_FAILED","type":"string"},"details":{"items":{"additionalProperties":true,"type":"object"},"type":"array"},"message":{"type":"string"},"request_id":{"type":"string"}},"required":["code","message","details","request_id"],"type":"object"},"meta":{"properties":{"credits_charged":{"const":0,"type":"number"}},"required":["credits_charged"],"type":"object"},"ok":{"const":false,"type":"boolean"}},"required":["ok","error","meta"],"type":"object"}}},"description":"The ranking operation failed"},"504":{"content":{"application/json":{"schema":{"properties":{"error":{"properties":{"code":{"const":"LOOKALIKE_TIMEOUT","type":"string"},"details":{"items":{"additionalProperties":true,"type":"object"},"type":"array"},"message":{"type":"string"},"request_id":{"type":"string"}},"required":["code","message","details","request_id"],"type":"object"},"meta":{"properties":{"credits_charged":{"const":0,"type":"number"}},"required":["credits_charged"],"type":"object"},"ok":{"const":false,"type":"boolean"}},"required":["ok","error","meta"],"type":"object"}}},"description":"The ranking query exceeded its deadline"}},"summary":"Find similar entities"}},"/personnel":{"get":{"description":"List personnel with pagination, sorting, and filters. Use the `tags` query parameter to return only entities that have the authenticated user's campaign tags (AND semantics when multiple tags are provided).","parameters":[{"description":"Insurance line filter.","in":"query","name":"benefit_type","required":false,"schema":{"type":"string"}},{"description":"Broker name substring across broker relationships.","in":"query","name":"broker","required":false,"schema":{"type":"string"}},{"description":"Comma-separated broker IDs.","in":"query","name":"broker_ids","required":false,"schema":{"type":"string"}},{"description":"Broker office name or UUID across broker office relationships.","in":"query","name":"broker_office","required":false,"schema":{"type":"string"}},{"description":"Comma-separated broker office IDs.","in":"query","name":"broker_office_ids","required":false,"schema":{"type":"string"}},{"description":"Carrier name substring across carrier relationships.","in":"query","name":"carrier","required":false,"schema":{"type":"string"}},{"description":"Comma-separated company EINs.","in":"query","name":"company_eins","required":false,"schema":{"type":"string"}},{"description":"Return only the total count and no rows.","in":"query","name":"count_only","required":false,"schema":{"type":"boolean"}},{"description":"CRM match status. Requires an API key owned by a user with CRM context.","in":"query","name":"crm_status","required":false,"schema":{"enum":["in_hubspot","in_salesforce","in_both","not_in_crm"],"type":"string"}},{"description":"Comma-separated DMA names.","in":"query","name":"dmas","required":false,"schema":{"type":"string"}},{"description":"Estimate the rows and credits for one page without returning rows. The response also reports estimated_total_matches; estimated_rows is page-bounded.","in":"query","name":"dry_run","required":false,"schema":{"type":"boolean"}},{"description":"Comma-separated employee bands.","in":"query","name":"employee_bands","required":false,"schema":{"type":"string"}},{"description":"Comma-separated response fields. id is always included.","in":"query","name":"fields","required":false,"schema":{"type":"string"}},{"description":"Filing year or latest.","in":"query","name":"filing_year","required":false,"schema":{"type":"string"}},{"description":"Comma-separated Form 5500 roles.","in":"query","name":"form5500_role","required":false,"schema":{"type":"string"}},{"description":"Response format.","in":"query","name":"format","required":false,"schema":{"enum":["json","flat"],"type":"string"}},{"description":"Self-Funded or Fully Insured.","in":"query","name":"funding_status","required":false,"schema":{"type":"string"}},{"description":"Geographic filter mode.","in":"query","name":"geo_mode","required":false,"schema":{"enum":["state","dma"],"type":"string"}},{"description":"Only contacts with email.","in":"query","name":"has_email","required":false,"schema":{"type":"boolean"}},{"description":"Only contacts with LinkedIn.","in":"query","name":"has_linkedin","required":false,"schema":{"type":"boolean"}},{"description":"Only contacts with phone.","in":"query","name":"has_phone","required":false,"schema":{"type":"boolean"}},{"description":"Include total_count in response metadata.","in":"query","name":"include_count","required":false,"schema":{"type":"boolean"}},{"description":"Comma-separated industry labels. Each label expands across its industry_search_term category hierarchy, so returned company_industry values can be adjacent industries. Use cf[company_industry] for the stricter substring match on the returned field.","in":"query","name":"industries","required":false,"schema":{"type":"string"}},{"description":"Comma-separated job function buckets.","in":"query","name":"job_function","required":false,"schema":{"type":"string"}},{"description":"Job title substring.","in":"query","name":"job_title","required":false,"schema":{"type":"string"}},{"description":"Personnel contact type. Required for personnel.","in":"query","name":"lead_type","required":true,"schema":{"enum":["company","broker"],"type":"string"}},{"description":"Filter long-tail records.","in":"query","name":"long_tail","required":false,"schema":{"type":"boolean"}},{"description":"Filter long-tail broker records.","in":"query","name":"long_tail_brokers","required":false,"schema":{"type":"boolean"}},{"description":"Response field tier.","in":"query","name":"mode","required":false,"schema":{"enum":["basic","full","light"],"type":"string"}},{"description":"Zero-indexed page number.","in":"query","name":"page","required":false,"schema":{"minimum":0,"type":"integer"}},{"description":"Rows per page. Maximum 500. Values above 25 require at least one filter.","in":"query","name":"page_size","required":false,"schema":{"maximum":500,"minimum":1,"type":"integer"}},{"description":"Comma-separated person-level DMA names.","in":"query","name":"person_dmas","required":false,"schema":{"type":"string"}},{"description":"Person-level geographic filter mode.","in":"query","name":"person_geo_mode","required":false,"schema":{"enum":["state","dma"],"type":"string"}},{"description":"Comma-separated person-level state codes.","in":"query","name":"person_states","required":false,"schema":{"type":"string"}},{"description":"Renewal month name.","in":"query","name":"renewal_month","required":false,"schema":{"type":"string"}},{"description":"Resource-specific fuzzy search.","in":"query","name":"search","required":false,"schema":{"type":"string"}},{"description":"Comma-separated seniority levels.","in":"query","name":"seniority","required":false,"schema":{"type":"string"}},{"description":"Filter short-form filings.","in":"query","name":"short_form","required":false,"schema":{"type":"boolean"}},{"description":"Signal match mode. all requires every requested signal and is echoed in meta.applied_filters.","in":"query","name":"signal_match","required":false,"schema":{"enum":["any","all"],"type":"string"}},{"description":"Comma-separated signal names.","in":"query","name":"signals","required":false,"schema":{"type":"string"}},{"description":"Sort field from the resource allowlist.","in":"query","name":"sort_by","required":false,"schema":{"type":"string"}},{"description":"Sort direction.","in":"query","name":"sort_dir","required":false,"schema":{"enum":["asc","desc"],"type":"string"}},{"description":"Comma-separated two-letter USPS state codes. Lowercase codes are normalized; invalid codes or full state names return 400 with the supported values.","in":"query","name":"states","required":false,"schema":{"type":"string"}},{"description":"Comma-separated campaign tag names. User-scoped: only tags owned by the authenticated API user apply. AND semantics: when multiple tags are provided, the entity must have all of them. Supported on GET /companies, /brokers, /broker-offices, and /personnel (including export.csv). Example: q1-outreach,high-priority","in":"query","name":"tags","required":false,"schema":{"type":"string"}},{"description":"Column filter. Replace `column` with the column key, e.g. `cf[total_number_of_employees]=gte:300,lte:500` or `cf[company_name]=acme`. Numeric columns support `gte:`, `gt:`, `lte:`, and `lt:` bounds. Percentage columns such as `participant_growth`, `commission_growth`, and `broker_commission_growth_pct` interpret numeric thresholds as percent values and scale them to stored ratios internally (`gte:1` means at least 1%). Multiple filters can be provided by comma-separating values.","in":"query","name":"cf[column]","required":false,"schema":{"type":"string"}},{"description":"Exclude rows where the named column is blank.","in":"query","name":"eb[column]","required":false,"schema":{"type":"boolean"}}],"responses":{"200":{"description":"Successful response"},"400":{"description":"Validation error"},"401":{"description":"Missing or invalid authorization"},"403":{"description":"Forbidden"},"404":{"description":"Not found"}},"summary":"List personnel"}},"/personnel/autocomplete":{"get":{"parameters":[{"description":"column","in":"query","name":"column","required":false,"schema":{"type":"string"}},{"description":"query","in":"query","name":"query","required":false,"schema":{"type":"string"}},{"description":"Resource-specific fuzzy search.","in":"query","name":"search","required":false,"schema":{"type":"string"}},{"description":"limit","in":"query","name":"limit","required":false,"schema":{"type":"string"}},{"description":"Personnel contact type. Required for personnel.","in":"query","name":"lead_type","required":false,"schema":{"enum":["company","broker"],"type":"string"}}],"responses":{"200":{"description":"Successful response"},"400":{"description":"Validation error"},"401":{"description":"Missing or invalid authorization"},"403":{"description":"Forbidden"},"404":{"description":"Not found"}},"summary":"Autocomplete personnel"}},"/personnel/batch":{"post":{"parameters":[{"description":"Personnel contact type. Required for personnel.","in":"query","name":"lead_type","required":false,"schema":{"enum":["company","broker"],"type":"string"}},{"description":"Response field tier.","in":"query","name":"mode","required":false,"schema":{"enum":["basic","full","light"],"type":"string"}},{"description":"Comma-separated response fields. id is always included.","in":"query","name":"fields","required":false,"schema":{"type":"string"}},{"description":"Response format.","in":"query","name":"format","required":false,"schema":{"enum":["json","flat"],"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"company_eins":{"items":{"type":"string"},"type":"array"},"ids":{"items":{"type":"string"},"type":"array"},"lead_type":{"type":"string"},"page_size":{"type":"integer"}},"type":"object"}}},"required":false},"responses":{"200":{"description":"Successful response"},"400":{"description":"Validation error"},"401":{"description":"Missing or invalid authorization"},"403":{"description":"Forbidden"},"404":{"description":"Not found"}},"summary":"Batch enrich personnel by company EIN or personnel id"}},"/personnel/export.csv":{"get":{"description":"List personnel with pagination, sorting, and filters. Use the `tags` query parameter to return only entities that have the authenticated user's campaign tags (AND semantics when multiple tags are provided).","parameters":[{"description":"Insurance line filter.","in":"query","name":"benefit_type","required":false,"schema":{"type":"string"}},{"description":"Broker name substring across broker relationships.","in":"query","name":"broker","required":false,"schema":{"type":"string"}},{"description":"Comma-separated broker IDs.","in":"query","name":"broker_ids","required":false,"schema":{"type":"string"}},{"description":"Broker office name or UUID across broker office relationships.","in":"query","name":"broker_office","required":false,"schema":{"type":"string"}},{"description":"Comma-separated broker office IDs.","in":"query","name":"broker_office_ids","required":false,"schema":{"type":"string"}},{"description":"Carrier name substring across carrier relationships.","in":"query","name":"carrier","required":false,"schema":{"type":"string"}},{"description":"Comma-separated company EINs.","in":"query","name":"company_eins","required":false,"schema":{"type":"string"}},{"description":"Return only the total count and no rows.","in":"query","name":"count_only","required":false,"schema":{"type":"boolean"}},{"description":"CRM match status. Requires an API key owned by a user with CRM context.","in":"query","name":"crm_status","required":false,"schema":{"enum":["in_hubspot","in_salesforce","in_both","not_in_crm"],"type":"string"}},{"description":"Comma-separated DMA names.","in":"query","name":"dmas","required":false,"schema":{"type":"string"}},{"description":"Estimate the rows and credits for one page without returning rows. The response also reports estimated_total_matches; estimated_rows is page-bounded.","in":"query","name":"dry_run","required":false,"schema":{"type":"boolean"}},{"description":"Comma-separated employee bands.","in":"query","name":"employee_bands","required":false,"schema":{"type":"string"}},{"description":"Comma-separated response fields. id is always included.","in":"query","name":"fields","required":false,"schema":{"type":"string"}},{"description":"Filing year or latest.","in":"query","name":"filing_year","required":false,"schema":{"type":"string"}},{"description":"Comma-separated Form 5500 roles.","in":"query","name":"form5500_role","required":false,"schema":{"type":"string"}},{"description":"Response format.","in":"query","name":"format","required":false,"schema":{"enum":["json","flat"],"type":"string"}},{"description":"Self-Funded or Fully Insured.","in":"query","name":"funding_status","required":false,"schema":{"type":"string"}},{"description":"Geographic filter mode.","in":"query","name":"geo_mode","required":false,"schema":{"enum":["state","dma"],"type":"string"}},{"description":"Only contacts with email.","in":"query","name":"has_email","required":false,"schema":{"type":"boolean"}},{"description":"Only contacts with LinkedIn.","in":"query","name":"has_linkedin","required":false,"schema":{"type":"boolean"}},{"description":"Only contacts with phone.","in":"query","name":"has_phone","required":false,"schema":{"type":"boolean"}},{"description":"Include total_count in response metadata.","in":"query","name":"include_count","required":false,"schema":{"type":"boolean"}},{"description":"Comma-separated industry labels. Each label expands across its industry_search_term category hierarchy, so returned company_industry values can be adjacent industries. Use cf[company_industry] for the stricter substring match on the returned field.","in":"query","name":"industries","required":false,"schema":{"type":"string"}},{"description":"Comma-separated job function buckets.","in":"query","name":"job_function","required":false,"schema":{"type":"string"}},{"description":"Job title substring.","in":"query","name":"job_title","required":false,"schema":{"type":"string"}},{"description":"Personnel contact type. Required for personnel.","in":"query","name":"lead_type","required":true,"schema":{"enum":["company","broker"],"type":"string"}},{"description":"Filter long-tail records.","in":"query","name":"long_tail","required":false,"schema":{"type":"boolean"}},{"description":"Filter long-tail broker records.","in":"query","name":"long_tail_brokers","required":false,"schema":{"type":"boolean"}},{"description":"Response field tier.","in":"query","name":"mode","required":false,"schema":{"enum":["basic","full","light"],"type":"string"}},{"description":"Zero-indexed page number.","in":"query","name":"page","required":false,"schema":{"minimum":0,"type":"integer"}},{"description":"Rows per page. Maximum 500. Values above 25 require at least one filter.","in":"query","name":"page_size","required":false,"schema":{"maximum":500,"minimum":1,"type":"integer"}},{"description":"Comma-separated person-level DMA names.","in":"query","name":"person_dmas","required":false,"schema":{"type":"string"}},{"description":"Person-level geographic filter mode.","in":"query","name":"person_geo_mode","required":false,"schema":{"enum":["state","dma"],"type":"string"}},{"description":"Comma-separated person-level state codes.","in":"query","name":"person_states","required":false,"schema":{"type":"string"}},{"description":"Renewal month name.","in":"query","name":"renewal_month","required":false,"schema":{"type":"string"}},{"description":"Resource-specific fuzzy search.","in":"query","name":"search","required":false,"schema":{"type":"string"}},{"description":"Comma-separated seniority levels.","in":"query","name":"seniority","required":false,"schema":{"type":"string"}},{"description":"Filter short-form filings.","in":"query","name":"short_form","required":false,"schema":{"type":"boolean"}},{"description":"Signal match mode. all requires every requested signal and is echoed in meta.applied_filters.","in":"query","name":"signal_match","required":false,"schema":{"enum":["any","all"],"type":"string"}},{"description":"Comma-separated signal names.","in":"query","name":"signals","required":false,"schema":{"type":"string"}},{"description":"Sort field from the resource allowlist.","in":"query","name":"sort_by","required":false,"schema":{"type":"string"}},{"description":"Sort direction.","in":"query","name":"sort_dir","required":false,"schema":{"enum":["asc","desc"],"type":"string"}},{"description":"Comma-separated two-letter USPS state codes. Lowercase codes are normalized; invalid codes or full state names return 400 with the supported values.","in":"query","name":"states","required":false,"schema":{"type":"string"}},{"description":"Comma-separated campaign tag names. User-scoped: only tags owned by the authenticated API user apply. AND semantics: when multiple tags are provided, the entity must have all of them. Supported on GET /companies, /brokers, /broker-offices, and /personnel (including export.csv). Example: q1-outreach,high-priority","in":"query","name":"tags","required":false,"schema":{"type":"string"}},{"description":"Column filter. Replace `column` with the column key, e.g. `cf[total_number_of_employees]=gte:300,lte:500` or `cf[company_name]=acme`. Numeric columns support `gte:`, `gt:`, `lte:`, and `lt:` bounds. Percentage columns such as `participant_growth`, `commission_growth`, and `broker_commission_growth_pct` interpret numeric thresholds as percent values and scale them to stored ratios internally (`gte:1` means at least 1%). Multiple filters can be provided by comma-separating values.","in":"query","name":"cf[column]","required":false,"schema":{"type":"string"}},{"description":"Exclude rows where the named column is blank.","in":"query","name":"eb[column]","required":false,"schema":{"type":"boolean"}}],"responses":{"200":{"description":"Successful response"},"400":{"description":"Validation error"},"401":{"description":"Missing or invalid authorization"},"403":{"description":"Forbidden"},"404":{"description":"Not found"}},"summary":"Export personnel CSV"}},"/personnel/{id}":{"get":{"parameters":[{"description":"Resource identifier.","in":"path","name":"id","required":true,"schema":{"type":"string"}},{"description":"Personnel contact type. Required for personnel.","in":"query","name":"lead_type","required":false,"schema":{"enum":["company","broker"],"type":"string"}},{"description":"Response field tier.","in":"query","name":"mode","required":false,"schema":{"enum":["basic","full","light"],"type":"string"}},{"description":"Comma-separated response fields. id is always included.","in":"query","name":"fields","required":false,"schema":{"type":"string"}},{"description":"Response format.","in":"query","name":"format","required":false,"schema":{"enum":["json","flat"],"type":"string"}}],"responses":{"200":{"description":"Successful response"},"400":{"description":"Validation error"},"401":{"description":"Missing or invalid authorization"},"403":{"description":"Forbidden"},"404":{"description":"Not found"}},"summary":"Get personnel"}},"/personnel/{id}/tags":{"get":{"description":"List user-scoped tags attached to one personnel record for the authenticated API user.","parameters":[{"description":"Resource identifier.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response"},"400":{"description":"Validation error"},"401":{"description":"Missing or invalid authorization"},"403":{"description":"Forbidden"},"404":{"description":"Not found"}},"summary":"List personnel tags"}},"/reports":{"post":{"parameters":[],"requestBody":{"content":{"application/json":{"schema":{"properties":{"description":{"type":"string"},"endpoint":{"type":"string"},"logs":{"type":"object"},"severity":{"type":"string"},"title":{"type":"string"}},"required":["title","description"],"type":"object"}}},"required":true},"responses":{"201":{"description":"Successful response"},"400":{"description":"Validation error"},"401":{"description":"Missing or invalid authorization"},"403":{"description":"Forbidden"},"404":{"description":"Not found"}},"summary":"Create API bug report"}},"/review-flags":{"get":{"parameters":[{"description":"status","in":"query","name":"status","required":false,"schema":{"type":"string"}},{"description":"Entity type for tag operations. Accepts API resource names (`companies`, `brokers`, `broker-offices`, `personnel`) or singular aliases (`company`, `broker`, `broker-office`, `personnel`).","in":"query","name":"entity_type","required":false,"schema":{"type":"string"}},{"description":"Zero-indexed page number.","in":"query","name":"page","required":false,"schema":{"minimum":0,"type":"integer"}},{"description":"Rows per page. Maximum 500. Values above 25 require at least one filter.","in":"query","name":"page_size","required":false,"schema":{"maximum":500,"minimum":1,"type":"integer"}}],"responses":{"200":{"description":"Successful response"},"400":{"description":"Validation error"},"401":{"description":"Missing or invalid authorization"},"403":{"description":"Forbidden"},"404":{"description":"Not found"}},"summary":"List review flags"},"post":{"parameters":[],"requestBody":{"content":{"application/json":{"schema":{"properties":{"corrections":{"items":{"type":"object"},"type":"array"},"entity_id":{"type":"string"},"entity_name":{"type":"string"},"entity_type":{"type":"string"},"field":{"type":"string"},"field_key":{"type":"string"},"issue":{"type":"string"},"reason":{"type":"string"},"resource":{"type":"string"},"suggested_value":{"type":"string"}},"required":["entity_id"],"type":"object"}}},"required":true},"responses":{"201":{"description":"Successful response"},"400":{"description":"Validation error"},"401":{"description":"Missing or invalid authorization"},"403":{"description":"Forbidden"},"404":{"description":"Not found"}},"summary":"Create review flag (alias of data-flags)"}},"/review-flags/bulk":{"patch":{"parameters":[],"responses":{"200":{"description":"Successful response"},"400":{"description":"Validation error"},"401":{"description":"Missing or invalid authorization"},"403":{"description":"Forbidden"},"404":{"description":"Not found"}},"summary":"Internal reviewer: bulk approve or reject review flags"}},"/review-flags/{id}":{"delete":{"parameters":[{"description":"Resource identifier.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response"},"400":{"description":"Validation error"},"401":{"description":"Missing or invalid authorization"},"403":{"description":"Forbidden"},"404":{"description":"Not found"}},"summary":"Internal reviewer: delete review flag"},"patch":{"parameters":[{"description":"Resource identifier.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response"},"400":{"description":"Validation error"},"401":{"description":"Missing or invalid authorization"},"403":{"description":"Forbidden"},"404":{"description":"Not found"}},"summary":"Internal reviewer: approve or reject review flag"}},"/tags":{"delete":{"description":"Remove a campaign tag from one entity for the authenticated API user.","parameters":[],"responses":{"200":{"description":"Successful response"},"400":{"description":"Validation error"},"401":{"description":"Missing or invalid authorization"},"403":{"description":"Forbidden"},"404":{"description":"Not found"}},"summary":"Delete tag by entity id and tag"},"get":{"description":"List campaign tag assignments owned by the authenticated API user. Optionally filter by `tag`, `entity_type`, or `resource`.","parameters":[{"description":"Campaign tag name. Normalized on write (leading `#` stripped, casing folded). Required for `GET /tags/entities` unless `tag_id` is provided.","in":"query","name":"tag","required":false,"schema":{"type":"string"}},{"description":"Entity type for tag operations. Accepts API resource names (`companies`, `brokers`, `broker-offices`, `personnel`) or singular aliases (`company`, `broker`, `broker-office`, `personnel`).","in":"query","name":"entity_type","required":false,"schema":{"type":"string"}},{"description":"Alias for `entity_type` on tag endpoints.","in":"query","name":"resource","required":false,"schema":{"type":"string"}},{"description":"Zero-indexed page number.","in":"query","name":"page","required":false,"schema":{"minimum":0,"type":"integer"}},{"description":"Rows per page. Maximum 500. Values above 25 require at least one filter.","in":"query","name":"page_size","required":false,"schema":{"maximum":500,"minimum":1,"type":"integer"}}],"responses":{"200":{"description":"Successful response"},"400":{"description":"Validation error"},"401":{"description":"Missing or invalid authorization"},"403":{"description":"Forbidden"},"404":{"description":"Not found"}},"summary":"List tags"},"post":{"description":"Assign one campaign tag to one entity. Tags are user-scoped and can later be used to filter list endpoints via the `tags` query parameter.","parameters":[],"requestBody":{"content":{"application/json":{"schema":{"properties":{"entity_id":{"type":"string"},"entity_type":{"type":"string"},"resource":{"type":"string"},"tag":{"type":"string"}},"required":["entity_id","tag"],"type":"object"}}},"required":true},"responses":{"201":{"description":"Successful response"},"400":{"description":"Validation error"},"401":{"description":"Missing or invalid authorization"},"403":{"description":"Forbidden"},"404":{"description":"Not found"}},"summary":"Create tag"}},"/tags/bulk":{"post":{"description":"Assign the same campaign tag to up to 100 entities of one `entity_type`. Tags are user-scoped.","parameters":[],"requestBody":{"content":{"application/json":{"schema":{"properties":{"entity_ids":{"items":{"type":"string"},"type":"array"},"entity_type":{"type":"string"},"tag":{"type":"string"}},"required":["entity_ids","entity_type","tag"],"type":"object"}}},"required":true},"responses":{"201":{"description":"Successful response"},"400":{"description":"Validation error"},"401":{"description":"Missing or invalid authorization"},"403":{"description":"Forbidden"},"404":{"description":"Not found"}},"summary":"Bulk create tags"}},"/tags/entities":{"get":{"description":"List entity IDs that have a given campaign tag for the authenticated API user. Provide `tag` or `tag_id`. Optionally filter by `entity_type` or `resource`.","parameters":[{"description":"Campaign tag name. Normalized on write (leading `#` stripped, casing folded). Required for `GET /tags/entities` unless `tag_id` is provided.","in":"query","name":"tag","required":false,"schema":{"type":"string"}},{"description":"Tag record UUID from `GET /tags`, or an entity ID fallback when resolving `GET /tags/entities`.","in":"query","name":"tag_id","required":false,"schema":{"type":"string"}},{"description":"Entity type for tag operations. Accepts API resource names (`companies`, `brokers`, `broker-offices`, `personnel`) or singular aliases (`company`, `broker`, `broker-office`, `personnel`).","in":"query","name":"entity_type","required":false,"schema":{"type":"string"}},{"description":"Alias for `entity_type` on tag endpoints.","in":"query","name":"resource","required":false,"schema":{"type":"string"}},{"description":"Zero-indexed page number.","in":"query","name":"page","required":false,"schema":{"minimum":0,"type":"integer"}},{"description":"Rows per page. Maximum 500. Values above 25 require at least one filter.","in":"query","name":"page_size","required":false,"schema":{"maximum":500,"minimum":1,"type":"integer"}}],"responses":{"200":{"description":"Successful response"},"400":{"description":"Validation error"},"401":{"description":"Missing or invalid authorization"},"403":{"description":"Forbidden"},"404":{"description":"Not found"}},"summary":"List entities for tag"}},"/tags/{id}":{"delete":{"parameters":[{"description":"Resource identifier.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response"},"400":{"description":"Validation error"},"401":{"description":"Missing or invalid authorization"},"403":{"description":"Forbidden"},"404":{"description":"Not found"}},"summary":"Delete tag"}},"/usage/ai-costs":{"get":{"description":"Internal test access only.","parameters":[{"description":"Inclusive usage start date or timestamp.","in":"query","name":"from","required":false,"schema":{"type":"string"}},{"description":"Inclusive usage end date or timestamp.","in":"query","name":"to","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response"},"400":{"description":"Validation error"},"401":{"description":"Missing or invalid authorization"},"403":{"description":"Forbidden"},"404":{"description":"Not found"}},"summary":"Report internal writing AI costs"}},"/usage/by-endpoint":{"get":{"description":"Requires usage:read scope. Returns usage for the current credit account rolled up per endpoint (credits_used, rows_returned, queries), for the endpoint breakdown of the usage board. Writing-job status polls report zero credits under /writing-jobs/{job_id}; finalized generation charges are attributed to /writing-jobs. Also available at /credits/by-endpoint. Accepts optional from/to date bounds.","parameters":[{"description":"Inclusive usage start date or timestamp.","in":"query","name":"from","required":false,"schema":{"type":"string"}},{"description":"Inclusive usage end date or timestamp.","in":"query","name":"to","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response"},"400":{"description":"Validation error"},"401":{"description":"Missing or invalid authorization"},"403":{"description":"Forbidden"},"404":{"description":"Not found"}},"summary":"Credit usage grouped by endpoint"}},"/usage/by-key":{"get":{"description":"Requires usage:read scope. Returns usage for the current credit account rolled up per API key (credits_used, rows_returned, queries), including child keys. Also available at /credits/by-key. Accepts optional from/to date bounds.","parameters":[{"description":"Inclusive usage start date or timestamp.","in":"query","name":"from","required":false,"schema":{"type":"string"}},{"description":"Inclusive usage end date or timestamp.","in":"query","name":"to","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response"},"400":{"description":"Validation error"},"401":{"description":"Missing or invalid authorization"},"403":{"description":"Forbidden"},"404":{"description":"Not found"}},"summary":"Credit usage grouped by API key"}},"/usage/writing":{"get":{"parameters":[{"description":"Inclusive usage start date or timestamp.","in":"query","name":"from","required":false,"schema":{"type":"string"}},{"description":"Inclusive usage end date or timestamp.","in":"query","name":"to","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response"},"400":{"description":"Validation error"},"401":{"description":"Missing or invalid authorization"},"403":{"description":"Forbidden"},"404":{"description":"Not found"}},"summary":"Report writing API usage"}},"/whoami":{"get":{"description":"Returns the authenticated caller context for the bearer token used on this request. API keys return account/key metadata, linked email, org name, scopes, and field-tier settings; internal and JWT bearer tokens return their auth type and user context. Costs 0 credits.","parameters":[],"responses":{"200":{"description":"Successful response"},"400":{"description":"Validation error"},"401":{"description":"Missing or invalid authorization"},"403":{"description":"Forbidden"},"404":{"description":"Not found"}},"summary":"Inspect current caller"}},"/writing-ctas":{"get":{"parameters":[{"description":"Zero-indexed page number.","in":"query","name":"page","required":false,"schema":{"minimum":0,"type":"integer"}},{"description":"Rows per page. Maximum 500. Values above 25 require at least one filter.","in":"query","name":"page_size","required":false,"schema":{"maximum":500,"minimum":1,"type":"integer"}},{"description":"Resource-specific fuzzy search.","in":"query","name":"search","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response"},"400":{"description":"Validation error"},"401":{"description":"Missing or invalid authorization"},"403":{"description":"Forbidden"},"404":{"description":"Not found"}},"summary":"List personal writing CTAs"},"post":{"parameters":[],"requestBody":{"content":{"application/json":{"schema":{"properties":{"body":{"type":"string"},"name":{"type":"string"}},"required":["name","body"],"type":"object"}}},"required":true},"responses":{"201":{"description":"Successful response"},"400":{"description":"Validation error"},"401":{"description":"Missing or invalid authorization"},"403":{"description":"Forbidden"},"404":{"description":"Not found"}},"summary":"Create a personal writing CTA"}},"/writing-ctas/{id}":{"delete":{"parameters":[{"description":"Resource identifier.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response"},"400":{"description":"Validation error"},"401":{"description":"Missing or invalid authorization"},"403":{"description":"Forbidden"},"404":{"description":"Not found"}},"summary":"Delete a personal writing CTA"},"get":{"parameters":[{"description":"Resource identifier.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response"},"400":{"description":"Validation error"},"401":{"description":"Missing or invalid authorization"},"403":{"description":"Forbidden"},"404":{"description":"Not found"}},"summary":"Get a personal writing CTA"},"patch":{"parameters":[{"description":"Resource identifier.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"body":{"type":"string"},"name":{"type":"string"}},"type":"object"}}},"required":false},"responses":{"200":{"description":"Successful response"},"400":{"description":"Validation error"},"401":{"description":"Missing or invalid authorization"},"403":{"description":"Forbidden"},"404":{"description":"Not found"}},"summary":"Edit a personal writing CTA"}},"/writing-jobs":{"get":{"description":"Requires writing:read. Returns owned jobs with terminal output, resolved context, and billing reconciliation.","parameters":[{"description":"status","in":"query","name":"status","required":false,"schema":{"type":"string"}},{"description":"channel","in":"query","name":"channel","required":false,"schema":{"type":"string"}},{"description":"Zero-indexed page number.","in":"query","name":"page","required":false,"schema":{"minimum":0,"type":"integer"}},{"description":"Rows per page. Maximum 500. Values above 25 require at least one filter.","in":"query","name":"page_size","required":false,"schema":{"maximum":500,"minimum":1,"type":"integer"}}],"responses":{"200":{"description":"Successful response"},"400":{"description":"Validation error"},"401":{"description":"Missing or invalid authorization"},"403":{"description":"Forbidden"},"404":{"description":"Not found"}},"summary":"List writing generation jobs"},"post":{"description":"Requires writing:generate. Generate from saved resources, fully inline data, or saved resources with inline overrides. Field names are case-sensitive. Unknown fields are rejected synchronously before job creation, model execution, or billing. A valid explicit sender overrides the account default. Email costs 5 credits and LinkedIn costs 3 credits by default; rejected requests cost 0. Accepted jobs reserve the configured amount, report zero charged credits while queued or running, and finalize the charge only after successful completion. Terminal non-success releases the reservation. Set dry_run=true to resolve the complete context without creating a job, calling a model, or charging credits. Idempotency-Key is scoped to the credit account and canonical JSON payload: an identical retry returns the original job without another charge, while reuse with a different payload returns 409.","parameters":[{"description":"Account-scoped idempotency key retained with the job for 30 days.","in":"header","name":"Idempotency-Key","required":false,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"example":{"channel":"email","identity_id":"identity-id","sender":{"company_name":"Acme Bennies","full_name":"Dana Whitfield","title":"Head of Sales"},"source_mode":"saved","target":{"company_name":"Marsh McLennan Agency","first_name":"Jordan"},"writing":{"case_study_id":"none","content_angle_id":"auto","personal_play_id":"play-id","play_source":"personal","value_prop_id":"auto"}},"schema":{"additionalProperties":false,"properties":{"channel":{"enum":["email","linkedin"],"type":"string"},"cta_id":{"description":"Top-level saved CTA selector.","type":"string"},"dry_run":{"description":"Resolve and return generation context without creating a job, invoking a model, or charging credits.","type":"boolean"},"force_failure":{"description":"Internal test access only. Force a terminal generation failure to verify refund accounting.","type":"boolean"},"identity":{"additionalProperties":true,"description":"Inline identity using the existing /identities/schema casing.","type":"object"},"identity_id":{"type":"string"},"include_ai_costs":{"description":"Internal test access only.","type":"boolean"},"linkedin_type":{"enum":["message","connection_request"],"type":"string"},"play_id":{"description":"Top-level saved personal-play selector.","type":"string"},"selected_icp_id":{"type":"string"},"sender":{"additionalProperties":false,"anyOf":[{"required":["full_name"]},{"required":["name"]}],"properties":{"company":{"deprecated":true,"description":"Legacy alias for company_name.","type":"string"},"company_name":{"type":"string"},"full_name":{"type":"string"},"name":{"deprecated":true,"description":"Legacy alias for full_name.","type":"string"},"signature":{"type":"string"},"title":{"type":"string"}},"type":"object"},"source_mode":{"enum":["saved","inline","hybrid"],"type":"string"},"subject_id":{"description":"Top-level saved subject selector.","type":"string"},"target":{"additionalProperties":false,"properties":{"company":{"additionalProperties":false,"properties":{"address":{"type":"string"},"channel_type":{"type":"string"},"city":{"type":"string"},"company_type":{"type":"string"},"country":{"type":"string"},"employee_count":{"type":["integer","string"]},"geo":{"type":"string"},"industry":{"type":"string"},"location":{"type":"string"},"name":{"type":"string"},"signal":{"type":"string"},"size":{"type":["integer","string"]},"state":{"type":"string"},"type":{"type":"string"},"website":{"type":"string"}},"type":"object"},"company_geo":{"type":"string"},"company_name":{"type":"string"},"company_size":{"type":["integer","string"]},"employee_count":{"type":["integer","string"]},"first_name":{"type":"string"},"last_name":{"type":"string"},"linkedin":{"type":"string"},"linkedin_url":{"type":"string"},"location":{"type":"string"},"person":{"additionalProperties":false,"properties":{"first_name":{"type":"string"},"last_name":{"type":"string"},"linkedin":{"type":"string"},"linkedin_url":{"type":"string"},"title":{"type":"string"}},"type":"object"},"title":{"type":"string"}},"type":"object"},"writing":{"additionalProperties":false,"properties":{"brand_voice":{"oneOf":[{"type":"string"},{"type":"object"}]},"broker_language_preference":{"type":"string"},"case_studies":{"items":{"type":"object"},"type":"array"},"case_study_id":{"description":"A specific ID, auto, or none.","type":"string"},"case_study_selection":{"additionalProperties":false,"description":"Mutually exclusive with case_study_id.","properties":{"selected_ids":{"items":{"type":"string"},"type":"array"},"selection":{"enum":["auto","specific","none"],"type":"string"}},"type":"object"},"content_angle_id":{"description":"A specific ID, auto, or none.","type":"string"},"content_angle_selection":{"additionalProperties":false,"description":"Mutually exclusive with content_angle_id.","properties":{"selected_ids":{"items":{"type":"string"},"type":"array"},"selection":{"enum":["auto","specific","none"],"type":"string"}},"type":"object"},"content_angles":{"items":{"type":"object"},"type":"array"},"content_mode":{"enum":["personalization","contextualization"],"type":"string"},"cta":{"oneOf":[{"type":"string"},{"additionalProperties":false,"properties":{"body":{"type":"string"},"id":{"type":"string"},"instruction":{"type":"string"},"name":{"type":"string"}},"type":"object"}]},"cta_id":{"type":"string"},"differentiators":{"items":{"type":"object"},"type":"array"},"icps":{"items":{"type":"object"},"type":"array"},"instructions":{"maxLength":4000,"type":"string"},"pain_point_selection":{"additionalProperties":false,"properties":{"selected_ids":{"items":{"type":"string"},"type":"array"},"selection":{"enum":["auto","specific","none"],"type":"string"}},"type":"object"},"pain_points":{"items":{"type":"object"},"type":"array"},"personal_play_id":{"type":"string"},"play":{"additionalProperties":false,"properties":{"body":{"type":"string"},"example":{"type":"string"},"id":{"type":"string"},"instructions":{"type":"string"},"name":{"type":"string"},"subject":{"type":"string"}},"type":"object"},"play_source":{"enum":["template","personal"],"type":"string"},"selected_icp_id":{"type":"string"},"subject":{"additionalProperties":false,"properties":{"instructions":{"type":"string"},"mode":{"enum":["auto","specific"],"type":"string"},"text":{"type":"string"}},"type":"object"},"subject_id":{"type":"string"},"technique":{"additionalProperties":false,"properties":{"description":{"type":"string"},"example":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"prompt_instruction":{"type":"string"}},"type":"object"},"value_prop_id":{"description":"A specific ID, auto, or none.","type":"string"},"value_proposition_selection":{"additionalProperties":false,"description":"Mutually exclusive with value_prop_id.","properties":{"selected_ids":{"items":{"type":"string"},"type":"array"},"selection":{"enum":["auto","specific","none"],"type":"string"}},"type":"object"},"value_propositions":{"items":{"type":"object"},"type":"array"},"variant_objective":{"type":"string"}},"type":"object"}},"required":["source_mode","channel"],"type":"object"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WritingJobResponse"}}},"description":"Successful response"},"202":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WritingJobResponse"}}},"description":"Successful response"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationErrorResponse"}}},"description":"Validation error"},"401":{"description":"Missing or invalid authorization"},"403":{"description":"Forbidden"},"404":{"description":"Not found"},"409":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationErrorResponse"}}},"description":"Idempotency-Key was reused with a different canonical payload"}},"summary":"Start email or LinkedIn generation"}},"/writing-jobs/batch":{"post":{"description":"Validates each target independently. All-valid batches return 202; mixed valid and invalid targets return 207 with per-item data or error envelopes; all-invalid batches return 400. Only accepted targets reserve credits. A batch Idempotency-Key is deterministically scoped to each target index and canonical item payload.","parameters":[{"in":"header","name":"Idempotency-Key","required":false,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"additionalProperties":false,"properties":{"channel":{"enum":["email","linkedin"],"type":"string"},"cta_id":{"description":"Top-level saved CTA selector.","type":"string"},"dry_run":{"description":"Resolve and return generation context without creating a job, invoking a model, or charging credits.","type":"boolean"},"force_failure":{"description":"Internal test access only. Force a terminal generation failure to verify refund accounting.","type":"boolean"},"identity":{"additionalProperties":true,"description":"Inline identity using the existing /identities/schema casing.","type":"object"},"identity_id":{"type":"string"},"include_ai_costs":{"description":"Internal test access only.","type":"boolean"},"linkedin_type":{"enum":["message","connection_request"],"type":"string"},"play_id":{"description":"Top-level saved personal-play selector.","type":"string"},"selected_icp_id":{"type":"string"},"sender":{"additionalProperties":false,"anyOf":[{"required":["full_name"]},{"required":["name"]}],"properties":{"company":{"deprecated":true,"description":"Legacy alias for company_name.","type":"string"},"company_name":{"type":"string"},"full_name":{"type":"string"},"name":{"deprecated":true,"description":"Legacy alias for full_name.","type":"string"},"signature":{"type":"string"},"title":{"type":"string"}},"type":"object"},"source_mode":{"enum":["saved","inline","hybrid"],"type":"string"},"subject_id":{"description":"Top-level saved subject selector.","type":"string"},"targets":{"items":{"additionalProperties":false,"properties":{"client_ref":{"type":"string"},"target":{"additionalProperties":false,"properties":{"company":{"additionalProperties":false,"properties":{"address":{"type":"string"},"channel_type":{"type":"string"},"city":{"type":"string"},"company_type":{"type":"string"},"country":{"type":"string"},"employee_count":{"type":["integer","string"]},"geo":{"type":"string"},"industry":{"type":"string"},"location":{"type":"string"},"name":{"type":"string"},"signal":{"type":"string"},"size":{"type":["integer","string"]},"state":{"type":"string"},"type":{"type":"string"},"website":{"type":"string"}},"type":"object"},"company_geo":{"type":"string"},"company_name":{"type":"string"},"company_size":{"type":["integer","string"]},"employee_count":{"type":["integer","string"]},"first_name":{"type":"string"},"last_name":{"type":"string"},"linkedin":{"type":"string"},"linkedin_url":{"type":"string"},"location":{"type":"string"},"person":{"additionalProperties":false,"properties":{"first_name":{"type":"string"},"last_name":{"type":"string"},"linkedin":{"type":"string"},"linkedin_url":{"type":"string"},"title":{"type":"string"}},"type":"object"},"title":{"type":"string"}},"type":"object"}},"required":["target"],"type":"object"},"maxItems":25,"minItems":1,"type":"array"},"writing":{"additionalProperties":false,"properties":{"brand_voice":{"oneOf":[{"type":"string"},{"type":"object"}]},"broker_language_preference":{"type":"string"},"case_studies":{"items":{"type":"object"},"type":"array"},"case_study_id":{"description":"A specific ID, auto, or none.","type":"string"},"case_study_selection":{"additionalProperties":false,"description":"Mutually exclusive with case_study_id.","properties":{"selected_ids":{"items":{"type":"string"},"type":"array"},"selection":{"enum":["auto","specific","none"],"type":"string"}},"type":"object"},"content_angle_id":{"description":"A specific ID, auto, or none.","type":"string"},"content_angle_selection":{"additionalProperties":false,"description":"Mutually exclusive with content_angle_id.","properties":{"selected_ids":{"items":{"type":"string"},"type":"array"},"selection":{"enum":["auto","specific","none"],"type":"string"}},"type":"object"},"content_angles":{"items":{"type":"object"},"type":"array"},"content_mode":{"enum":["personalization","contextualization"],"type":"string"},"cta":{"oneOf":[{"type":"string"},{"additionalProperties":false,"properties":{"body":{"type":"string"},"id":{"type":"string"},"instruction":{"type":"string"},"name":{"type":"string"}},"type":"object"}]},"cta_id":{"type":"string"},"differentiators":{"items":{"type":"object"},"type":"array"},"icps":{"items":{"type":"object"},"type":"array"},"instructions":{"maxLength":4000,"type":"string"},"pain_point_selection":{"additionalProperties":false,"properties":{"selected_ids":{"items":{"type":"string"},"type":"array"},"selection":{"enum":["auto","specific","none"],"type":"string"}},"type":"object"},"pain_points":{"items":{"type":"object"},"type":"array"},"personal_play_id":{"type":"string"},"play":{"additionalProperties":false,"properties":{"body":{"type":"string"},"example":{"type":"string"},"id":{"type":"string"},"instructions":{"type":"string"},"name":{"type":"string"},"subject":{"type":"string"}},"type":"object"},"play_source":{"enum":["template","personal"],"type":"string"},"selected_icp_id":{"type":"string"},"subject":{"additionalProperties":false,"properties":{"instructions":{"type":"string"},"mode":{"enum":["auto","specific"],"type":"string"},"text":{"type":"string"}},"type":"object"},"subject_id":{"type":"string"},"technique":{"additionalProperties":false,"properties":{"description":{"type":"string"},"example":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"prompt_instruction":{"type":"string"}},"type":"object"},"value_prop_id":{"description":"A specific ID, auto, or none.","type":"string"},"value_proposition_selection":{"additionalProperties":false,"description":"Mutually exclusive with value_prop_id.","properties":{"selected_ids":{"items":{"type":"string"},"type":"array"},"selection":{"enum":["auto","specific","none"],"type":"string"}},"type":"object"},"value_propositions":{"items":{"type":"object"},"type":"array"},"variant_objective":{"type":"string"}},"type":"object"}},"required":["source_mode","channel","targets"],"type":"object"}}},"required":true},"responses":{"202":{"description":"Successful response"},"207":{"description":"Successful response"},"400":{"description":"Validation error"},"401":{"description":"Missing or invalid authorization"},"403":{"description":"Forbidden"},"404":{"description":"Not found"}},"summary":"Start writing generation for up to 25 targets"}},"/writing-jobs/{job_id}":{"get":{"description":"Requires writing:read. Returns job state and billing reconciliation. wait_ms accepts 0 through 5000 ms; out-of-range values are rejected. It waits for progress or terminal-state changes, and last_event_count may provide the caller's last observed cursor. Completed email output includes body and semantically equivalent body_html.","parameters":[{"description":"Resource identifier.","in":"path","name":"job_id","required":true,"schema":{"type":"string"}},{"description":"include_ai_costs","in":"query","name":"include_ai_costs","required":false,"schema":{"type":"string"}},{"description":"Bounded long-poll duration in milliseconds, from 0 through 5000. Out-of-range values are rejected.","in":"query","name":"wait_ms","required":false,"schema":{"maximum":5000,"minimum":0,"type":"integer"}},{"description":"Known progress-event count; return when the count changes or wait_ms elapses.","in":"query","name":"last_event_count","required":false,"schema":{"minimum":0,"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WritingJobResponse"}}},"description":"Successful response"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidationErrorResponse"}}},"description":"Validation error"},"401":{"description":"Missing or invalid authorization"},"403":{"description":"Forbidden"},"404":{"description":"Not found"}},"summary":"Get a writing generation job"}},"/writing-plays":{"get":{"parameters":[{"description":"Zero-indexed page number.","in":"query","name":"page","required":false,"schema":{"minimum":0,"type":"integer"}},{"description":"Rows per page. Maximum 500. Values above 25 require at least one filter.","in":"query","name":"page_size","required":false,"schema":{"maximum":500,"minimum":1,"type":"integer"}},{"description":"Resource-specific fuzzy search.","in":"query","name":"search","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response"},"400":{"description":"Validation error"},"401":{"description":"Missing or invalid authorization"},"403":{"description":"Forbidden"},"404":{"description":"Not found"}},"summary":"List personal writing plays"},"post":{"description":"Send one play as `{name, subject, body}` or bulk-create up to 100 plays with `{plays: [...]}`. A single create returns `data` as one object, matching the CTA and subject create endpoints; a bulk create returns `data` as an array.","parameters":[],"requestBody":{"content":{"application/json":{"schema":{"properties":{"body":{"type":"string"},"name":{"type":"string"},"plays":{"items":{"properties":{"body":{"type":"string"},"name":{"type":"string"},"subject":{"type":"string"}},"required":["name","body"],"type":"object"},"maxItems":100,"type":"array"},"subject":{"type":"string"}},"type":"object"}}},"required":false},"responses":{"201":{"content":{"application/json":{"schema":{"properties":{"data":{"oneOf":[{"properties":{"body":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"subject":{"type":["string","null"]}},"required":["id","name","body"],"type":"object"},{"items":{"properties":{"body":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"subject":{"type":["string","null"]}},"required":["id","name","body"],"type":"object"},"type":"array"}]},"meta":{"type":"object"},"ok":{"type":"boolean"}},"required":["ok","data","meta"],"type":"object"}}},"description":"Successful response"},"400":{"description":"Validation error"},"401":{"description":"Missing or invalid authorization"},"403":{"description":"Forbidden"},"404":{"description":"Not found"}},"summary":"Add one or more personal writing plays"}},"/writing-plays/{id}":{"delete":{"description":"Soft-delete an owned active writing play and clear it from active preferences.","parameters":[{"description":"Resource identifier.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response"},"400":{"description":"Validation error"},"401":{"description":"Missing or invalid authorization"},"403":{"description":"Forbidden"},"404":{"description":"Not found"}},"summary":"Delete a personal writing play"},"get":{"parameters":[{"description":"Resource identifier.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response"},"400":{"description":"Validation error"},"401":{"description":"Missing or invalid authorization"},"403":{"description":"Forbidden"},"404":{"description":"Not found"}},"summary":"Get a personal writing play"},"patch":{"description":"Partially update an owned active writing play.","parameters":[{"description":"Resource identifier.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"body":{"type":"string"},"name":{"type":"string"},"subject":{"type":["string","null"]}},"type":"object"}}},"required":false},"responses":{"200":{"description":"Successful response"},"400":{"description":"Validation error"},"401":{"description":"Missing or invalid authorization"},"403":{"description":"Forbidden"},"404":{"description":"Not found"}},"summary":"Edit a personal writing play"}},"/writing-subjects":{"get":{"parameters":[{"description":"Zero-indexed page number.","in":"query","name":"page","required":false,"schema":{"minimum":0,"type":"integer"}},{"description":"Rows per page. Maximum 500. Values above 25 require at least one filter.","in":"query","name":"page_size","required":false,"schema":{"maximum":500,"minimum":1,"type":"integer"}},{"description":"Resource-specific fuzzy search.","in":"query","name":"search","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response"},"400":{"description":"Validation error"},"401":{"description":"Missing or invalid authorization"},"403":{"description":"Forbidden"},"404":{"description":"Not found"}},"summary":"List saved subject lines"},"post":{"parameters":[],"requestBody":{"content":{"application/json":{"schema":{"properties":{"name":{"type":"string"},"text":{"type":"string"}},"required":["name","text"],"type":"object"}}},"required":true},"responses":{"201":{"description":"Successful response"},"400":{"description":"Validation error"},"401":{"description":"Missing or invalid authorization"},"403":{"description":"Forbidden"},"404":{"description":"Not found"}},"summary":"Create a saved subject line"}},"/writing-subjects/{id}":{"delete":{"parameters":[{"description":"Resource identifier.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response"},"400":{"description":"Validation error"},"401":{"description":"Missing or invalid authorization"},"403":{"description":"Forbidden"},"404":{"description":"Not found"}},"summary":"Delete a saved subject line"},"get":{"parameters":[{"description":"Resource identifier.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response"},"400":{"description":"Validation error"},"401":{"description":"Missing or invalid authorization"},"403":{"description":"Forbidden"},"404":{"description":"Not found"}},"summary":"Get a saved subject line"},"patch":{"parameters":[{"description":"Resource identifier.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"properties":{"name":{"type":"string"},"text":{"type":"string"}},"type":"object"}}},"required":false},"responses":{"200":{"description":"Successful response"},"400":{"description":"Validation error"},"401":{"description":"Missing or invalid authorization"},"403":{"description":"Forbidden"},"404":{"description":"Not found"}},"summary":"Edit a saved subject line"}},"/writing/options":{"get":{"parameters":[{"description":"identity_id","in":"query","name":"identity_id","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response"},"400":{"description":"Validation error"},"401":{"description":"Missing or invalid authorization"},"403":{"description":"Forbidden"},"404":{"description":"Not found"}},"summary":"List selectable writing inputs"}},"/writing/temperature":{"get":{"description":"Return the authenticated user's override, the global fallback, and the effective Personal Play temperature. Requires writing:read.","parameters":[],"responses":{"200":{"description":"Successful response"},"400":{"description":"Validation error"},"401":{"description":"Missing or invalid authorization"},"403":{"description":"Forbidden"},"404":{"description":"Not found"}},"summary":"Get Personal Play temperature"},"patch":{"description":"Set the authenticated user's Personal Play temperature override. Send null to restore the global value. Requires writing:write.","parameters":[],"requestBody":{"content":{"application/json":{"example":{"temperature":0.3},"schema":{"properties":{"temperature":{"maximum":2,"minimum":0,"type":["number","null"]}},"required":["temperature"],"type":"object"}}},"required":true},"responses":{"200":{"description":"Successful response"},"400":{"description":"Validation error"},"401":{"description":"Missing or invalid authorization"},"403":{"description":"Forbidden"},"404":{"description":"Not found"}},"summary":"Set Personal Play temperature"},"post":{"description":"Set the authenticated user's Personal Play temperature override. Send null to restore the global value. Requires writing:write.","parameters":[],"requestBody":{"content":{"application/json":{"example":{"temperature":0.3},"schema":{"properties":{"temperature":{"maximum":2,"minimum":0,"type":["number","null"]}},"required":["temperature"],"type":"object"}}},"required":true},"responses":{"200":{"description":"Successful response"},"400":{"description":"Validation error"},"401":{"description":"Missing or invalid authorization"},"403":{"description":"Forbidden"},"404":{"description":"Not found"}},"summary":"Set Personal Play temperature"}}},"security":[{"BearerAuth":[]}],"servers":[{"url":"/v1"}]}
