Associate an anonymous visitor with a logged-in user
Links a visitorId to a userId and (optionally) attaches traits. A side effect back-fills the userId onto all prior events/visits for that visitor, so pre-login attribution is stitched to the identified user.
This is a dedicated endpoint — NOT a Segment-style /api/v1/t with type:"identify"; the ingest endpoint has no type field.
Trait rules (server-side sanitizeTraits): reserved keys email/phone/name/locale/timezone are lifted to encrypted top-level user columns (send null to clear); other keys go to a JSON column. Keys whose name contains dangerous substrings (password, pwd, idcard, passport, ssn, bankcard, cvv, token, secret, private_key, api_key, …) are dropped and echoed in dropped_keys. Payload must be ≤ 8 KiB and nested ≤ 2 levels — over → 400. Audit logs record key counts only, never values.
Note: to receive event-triggered email, a user must be identified with a non-empty traits.email; otherwise trigger consumers skip them.
Auth: X-API-Key (also ?_ak / ?key), no extra scope gate.
Authorizations
Section titled “Authorizations”Request Bodyrequired
Section titled “Request Bodyrequired”Visitor→user association payload.
object
Anonymous visitor ID (alias visitor_id). Required, non-empty.
Logged-in user ID (alias user_id). Required, non-empty.
Optional user traits. Reserved keys email/phone/name/timezone/locale are lifted to encrypted columns (null clears). Dangerous keys are dropped and echoed in dropped_keys. ≤ 8 KiB, nested ≤ 2 levels.
object
Example
{ "visitorId": "vid_abc123", "userId": "uid_456", "traits": { "email": "user@example.com", "name": "张三", "plan": "pro" }}Responses
Section titled “Responses”Identity recorded. dropped_keys lists any trait keys filtered out.
object
Invalid JSON, missing visitorId/userId, or a traits validation failure (size / depth / shape).
object
Human-readable error message.
Seconds to wait before retrying (present on 429/503).
Examples
{ "error": "visitorId 和 userId 不能为空"}{ "error": "无效的 JSON 格式"}{ "error": "traits payload exceeds 8 KiB limit"}Missing or invalid API key.
object
Human-readable error message.
Seconds to wait before retrying (present on 429/503).
Examplegenerated
{ "error": "example", "retryAfter": 1, "message": "example", "affectedIndices": [ 1 ]}Internal error while persisting the identity (no PII leaked).
object
Human-readable error message.
Seconds to wait before retrying (present on 429/503).
Example
{ "error": "identify failed"}