Endpoint
identifyCompany().
Authentication
Requires your publishable widget key in theAuthorization header:
Request Body
Your system’s unique identifier for this company.
If provided, the user with this external ID is linked to the company.
Company attributes. Recognized fields (
name, domain, industry, plan, employee_count, signed_up_at, renewal_date, renewal_status, contract_term, payment_terms, on_contract, mrr, arr) are stored in dedicated columns. All other fields are stored in custom_fields.Do not send id, external_id, org_id, created_at, updated_at, health_score, team_size, or last_contacted_at. These are managed by Halo and the endpoint returns HTTP 400 if any of them appear in the body. Use signed_up_at to record the date the company onboarded in your product. See System-managed fields.Structured context entries for AI consumption. Stored in the
context jsonb column. Merged with existing context (new keys overwrite).JWT signed with your Identity Secret (HS256). Required when identity verification is enabled for your workspace and a
user_id is provided. The token’s user_id claim must match the user_id field. See Identity Verification.Example
signed_up_at, created_at, and updated_at are returned as Postgres timestamptz values serialized as ISO 8601 with microsecond precision and a +00:00 offset (the format shown above, e.g. 2026-04-11T12:25:19.492417+00:00, not the ...Z shorthand). created_at and updated_at are read-only Halo-managed timestamps and must not be echoed back into the traits body on subsequent calls. signed_up_at is customer-set and can be updated by sending the new value in traits on a follow-up identify call.
Rejected Traits
These keys trigger HTTP 400 if present in thetraits body. See System-managed fields for context.
| Key | Why |
|---|---|
id | Halo’s internal primary key. Pass your identifier as company_id instead. |
external_id | Halo’s mirror of the company_id you sent. Use company_id at the top level. |
org_id | Set by Halo from the API key. |
created_at | Halo sets this when the row is inserted. Pass signed_up_at if you want to record customer signup. |
updated_at | Maintained automatically by upsert_company and a database trigger. |
health_score | Computed by the health scoring engine. See Health Scores. |
team_size | Computed at chat time from linked end users. |
last_contacted_at | Set when your team sends a broadcast, series, reply, or chat to any user at the company. |
Behavior
- If a company with the same
company_idexists within your organization, it is updated - If it doesn’t exist, it is created
- If
user_idis provided and the user exists, the user is linked to the company - Context is merged: existing DB context keys are preserved, new keys are added, matching keys are overwritten
- The combined size of
traitsandcontextmust not exceed 50,000 bytes signed_up_aton update usesCOALESCEsemantics: a new value overwrites, butnullis ignored so an integration with a more authoritative date is never wiped.- Sending Halo-managed fields (
id,external_id,org_id,created_at,updated_at,health_score,team_size,last_contacted_at) intraitsreturns HTTP 400 with areserved_keysarray naming every offending key, so the caller can fix them all in one round trip.