Users
A profile holds what an app knows about a recipient: traits, identifiers, the consent map, merged event history, and segment membership. When a profile is merged into another, requests to its usr_ id redirect to the survivor’s URL. GDPR export and erasure can target a single profile by its usr_ id, taking everything merged into it, or every profile across your apps that carries an identifier. All routes require session-token authentication, and erasure requires org:admin.
GET /v1/users
Section titled “GET /v1/users”List and search profiles
Auth: Session token.
Query parameters
{ "cursor": "string", "limit": 50, "direction": "asc", "q": "string", "appId": "string", "trait": "string", "traitValue": "string", "segmentId": "string"}| Field | Type | Required | Constraints |
|---|---|---|---|
cursor |
string | no | |
limit |
integer | no | default 50; 1 ≤ x ≤ 100 |
direction |
“asc” | “desc” | no | default "asc" |
q |
string | no | length 0–200 |
appId |
string | no | length 0–200 |
trait |
string | no | length 1–200 |
traitValue |
string | no | length 1–500 |
segmentId |
string | no | length 1–200 |
Response 200
{ "data": [ { "id": "string", "orgId": "string", "appId": "string", "sourceId": "string", "traits": { "key": {} }, "consent": { "key": true }, "mergedInto": "string", "createdAt": "2026-01-15T09:30:00.000Z", "updatedAt": "2026-01-15T09:30:00.000Z", "identifiers": [ { "kind": "anonymousId", "value": "string", "createdAt": "2026-01-15T09:30:00.000Z" } ], "anonymous": true, "lastEventAt": "2026-01-15T09:30:00.000Z", "liveAutomations": 42, "lastDeliveryAt": "2026-01-15T09:30:00.000Z" } ], "meta": { "requestId": "string", "nextCursor": "string", "hasMore": true, "warnings": [ { "code": "string", "message": "string", "suggestion": "string" } ] }}| Field | Type | Required | Constraints |
|---|---|---|---|
data |
object[] | yes | |
data[] |
object | yes | |
data[].id |
string | yes | |
data[].orgId |
string | yes | |
data[].appId |
string | yes | |
data[].sourceId |
string | yes | |
data[].traits |
record<string, any> | yes | |
data[].consent |
record<string, boolean> | yes | |
data[].mergedInto |
string | null | yes | |
data[].createdAt |
string (date-time) | yes | |
data[].updatedAt |
string (date-time) | yes | |
data[].identifiers |
object[] | yes | |
data[].identifiers[] |
object | yes | |
data[].identifiers[].kind |
“anonymousId” | “userId” | “clerkId” | “email” | yes | |
data[].identifiers[].value |
string | yes | |
data[].identifiers[].createdAt |
string (date-time) | yes | |
data[].anonymous |
boolean | yes | |
data[].lastEventAt |
string (date-time) | null | yes | |
data[].liveAutomations |
integer | yes | 0 ≤ x ≤ ∞ |
data[].lastDeliveryAt |
string (date-time) | null | yes | |
meta |
object | no | |
meta.requestId |
string | no | |
meta.nextCursor |
string | null | no | |
meta.hasMore |
boolean | no | |
meta.warnings |
object[] | no | |
meta.warnings[] |
object | no | |
meta.warnings[].code |
string | yes | |
meta.warnings[].message |
string | yes | |
meta.warnings[].suggestion |
string | no |
Errors follow the shared envelope and code table.
GET /v1/users/find
Section titled “GET /v1/users/find”Find a profile by one identifier (
Auth: Session token.
Query parameters
{ "identifier": "string"}| Field | Type | Required | Constraints |
|---|---|---|---|
identifier |
string | yes | length 3–220 |
Response 200
{ "data": { "id": "string", "orgId": "string", "appId": "string", "sourceId": "string", "traits": { "key": {} }, "consent": { "key": true }, "mergedInto": "string", "createdAt": "2026-01-15T09:30:00.000Z", "updatedAt": "2026-01-15T09:30:00.000Z", "identifiers": [ { "kind": "anonymousId", "value": "string", "createdAt": "2026-01-15T09:30:00.000Z", "sourceId": "string", "sourceName": "string" } ], "anonymous": true, "mergedIds": [ "string" ], "email": { "address": "string", "source": "string" } }, "meta": { "requestId": "string", "nextCursor": "string", "hasMore": true, "warnings": [ { "code": "string", "message": "string", "suggestion": "string" } ] }}| Field | Type | Required | Constraints |
|---|---|---|---|
data |
object | yes | |
data.id |
string | yes | |
data.orgId |
string | yes | |
data.appId |
string | yes | |
data.sourceId |
string | yes | |
data.traits |
record<string, any> | yes | |
data.consent |
record<string, boolean> | yes | |
data.mergedInto |
string | null | yes | |
data.createdAt |
string (date-time) | yes | |
data.updatedAt |
string (date-time) | yes | |
data.identifiers |
object[] | yes | |
data.identifiers[] |
object | yes | |
data.identifiers[].kind |
“anonymousId” | “userId” | “clerkId” | “email” | yes | |
data.identifiers[].value |
string | yes | |
data.identifiers[].createdAt |
string (date-time) | yes | |
data.identifiers[].sourceId |
string | null | yes | |
data.identifiers[].sourceName |
string | null | yes | |
data.anonymous |
boolean | yes | |
data.mergedIds |
string[] | yes | |
data.email |
object | null | yes | |
data.email.address |
string | yes | |
data.email.source |
string | yes | |
meta |
object | no | |
meta.requestId |
string | no | |
meta.nextCursor |
string | null | no | |
meta.hasMore |
boolean | no | |
meta.warnings |
object[] | no | |
meta.warnings[] |
object | no | |
meta.warnings[].code |
string | yes | |
meta.warnings[].message |
string | yes | |
meta.warnings[].suggestion |
string | no |
Errors follow the shared envelope and code table.
POST /v1/users/export
Section titled “POST /v1/users/export”Export everything held on the people one identifier names
Auth: Session token.
Request body
{ "data": { "kind": "anonymousId", "value": "string" }}| Field | Type | Required | Constraints |
|---|---|---|---|
data |
object | yes | |
data.kind |
“anonymousId” | “userId” | “clerkId” | “email” | yes | |
data.value |
string | yes | length 1–200 |
Response 200
{ "data": { "exportedAt": "2026-01-15T09:30:00.000Z", "users": [ { "id": "string", "orgId": "string", "appId": "string", "sourceId": "string", "traits": { "key": {} }, "consent": { "key": true }, "mergedInto": "string", "createdAt": "2026-01-15T09:30:00.000Z", "updatedAt": "2026-01-15T09:30:00.000Z", "identifiers": [ { "kind": "anonymousId", "value": "string", "createdAt": "2026-01-15T09:30:00.000Z", "sourceId": "string", "sourceName": "string" } ], "anonymous": true, "mergedIds": [ "string" ], "email": { "address": "string", "source": "string" } } ], "events": [ { "id": "string", "orgId": "string", "appId": "string", "sourceId": "string", "profileId": "string", "event": "string", "properties": { "key": {} }, "timestamp": "2026-01-15T09:30:00.000Z", "receivedAt": "2026-01-15T09:30:00.000Z", "messageId": "string", "client": "string" } ], "eventSummaries": [ { "orgId": "string", "appId": "string", "profileId": "string", "event": "string", "count": 42, "firstAt": "2026-01-15T09:30:00.000Z", "lastAt": "2026-01-15T09:30:00.000Z", "recent": [ "2026-01-15T09:30:00.000Z" ] } ], "automations": [ { "id": "string", "orgId": "string", "automation": "string", "profileId": "string", "workflowId": "string", "runId": "string", "completedAt": "2026-01-15T09:30:00.000Z", "sent": true, "createdAt": "2026-01-15T09:30:00.000Z" } ], "deliveries": [ { "id": "string", "orgId": "string", "profileId": "string", "automation": "string", "executionId": "string", "appId": "string", "broadcastId": "string", "kind": "automation", "step": "string", "channel": "email", "status": "sent", "dryRun": true, "recipient": "string", "providerId": "string", "error": "string", "createdAt": "2026-01-15T09:30:00.000Z", "updatedAt": "2026-01-15T09:30:00.000Z", "sentAt": "2026-01-15T09:30:00.000Z", "settledAt": "2026-01-15T09:30:00.000Z", "openedAt": "2026-01-15T09:30:00.000Z", "openCount": 42, "spamScore": 42, "spamSymbols": [ "string" ] } ], "suppressedAddresses": [ { "id": "string", "orgId": "string", "address": "string", "type": "bounce", "reason": "string", "source": "string", "suppressedAt": "2026-01-15T09:30:00.000Z", "createdAt": "2026-01-15T09:30:00.000Z", "updatedAt": "2026-01-15T09:30:00.000Z" } ], "emailAddresses": [ { "id": "string", "orgId": "string", "address": "string", "verifiedAt": "2026-01-15T09:30:00.000Z", "verificationMethod": "link", "createdAt": "2026-01-15T09:30:00.000Z", "updatedAt": "2026-01-15T09:30:00.000Z" } ] }, "meta": { "requestId": "string", "nextCursor": "string", "hasMore": true, "warnings": [ { "code": "string", "message": "string", "suggestion": "string" } ] }}| Field | Type | Required | Constraints |
|---|---|---|---|
data |
object | yes | |
data.exportedAt |
string (date-time) | yes | |
data.users |
object[] | yes | |
data.users[] |
object | yes | |
data.users[].id |
string | yes | |
data.users[].orgId |
string | yes | |
data.users[].appId |
string | yes | |
data.users[].sourceId |
string | yes | |
data.users[].traits |
record<string, any> | yes | |
data.users[].consent |
record<string, boolean> | yes | |
data.users[].mergedInto |
string | null | yes | |
data.users[].createdAt |
string (date-time) | yes | |
data.users[].updatedAt |
string (date-time) | yes | |
data.users[].identifiers |
object[] | yes | |
data.users[].identifiers[] |
object | yes | |
data.users[].identifiers[].kind |
“anonymousId” | “userId” | “clerkId” | “email” | yes | |
data.users[].identifiers[].value |
string | yes | |
data.users[].identifiers[].createdAt |
string (date-time) | yes | |
data.users[].identifiers[].sourceId |
string | null | yes | |
data.users[].identifiers[].sourceName |
string | null | yes | |
data.users[].anonymous |
boolean | yes | |
data.users[].mergedIds |
string[] | yes | |
data.users[].email |
object | null | yes | |
data.users[].email.address |
string | yes | |
data.users[].email.source |
string | yes | |
data.events |
object[] | yes | |
data.events[] |
object | yes | |
data.events[].id |
string | yes | |
data.events[].orgId |
string | yes | |
data.events[].appId |
string | yes | |
data.events[].sourceId |
string | yes | |
data.events[].profileId |
string | yes | |
data.events[].event |
string | yes | |
data.events[].properties |
record<string, any> | yes | |
data.events[].timestamp |
string (date-time) | yes | |
data.events[].receivedAt |
string (date-time) | yes | |
data.events[].messageId |
string | null | yes | |
data.events[].client |
string | null | yes | |
data.eventSummaries |
object[] | yes | |
data.eventSummaries[] |
object | yes | |
data.eventSummaries[].orgId |
string | yes | |
data.eventSummaries[].appId |
string | yes | |
data.eventSummaries[].profileId |
string | yes | |
data.eventSummaries[].event |
string | yes | |
data.eventSummaries[].count |
integer | yes | |
data.eventSummaries[].firstAt |
string (date-time) | yes | |
data.eventSummaries[].lastAt |
string (date-time) | yes | |
data.eventSummaries[].recent |
string (date-time)[] | yes | |
data.automations |
object[] | yes | |
data.automations[] |
object | yes | |
data.automations[].id |
string | yes | |
data.automations[].orgId |
string | yes | |
data.automations[].automation |
string | yes | |
data.automations[].profileId |
string | yes | |
data.automations[].workflowId |
string | yes | |
data.automations[].runId |
string | yes | |
data.automations[].completedAt |
string (date-time) | yes | |
data.automations[].sent |
boolean | yes | |
data.automations[].createdAt |
string (date-time) | yes | |
data.deliveries |
object[] | yes | |
data.deliveries[] |
object | yes | |
data.deliveries[].id |
string | yes | |
data.deliveries[].orgId |
string | yes | |
data.deliveries[].profileId |
string | null | yes | |
data.deliveries[].automation |
string | null | yes | |
data.deliveries[].executionId |
string | null | yes | |
data.deliveries[].appId |
string | null | yes | |
data.deliveries[].broadcastId |
string | null | yes | |
data.deliveries[].kind |
“automation” | “test” | “api” | “broadcast” | yes | |
data.deliveries[].step |
string | yes | |
data.deliveries[].channel |
“email” | “webhook” | yes | |
data.deliveries[].status |
“sent” | “delivered” | “bounced” | “complained” | “failed” | “skipped_disabled” | “skipped_paused” | “skipped_suspended” | “skipped_suppressed” | “skipped_quota” | “skipped_unknown_purpose” | “skipped_frequency_cap” | “skipped_consent” | “skipped_domain” | “skipped_ssrf” | “skipped_spam” | “would_send” | “would_skip_disabled” | “would_skip_paused” | “would_skip_suspended” | “would_skip_suppressed” | “would_skip_quota” | “would_skip_unknown_purpose” | “would_skip_frequency_cap” | “would_skip_consent” | “would_skip_domain” | “would_skip_ssrf” | “would_skip_spam” | yes | |
data.deliveries[].dryRun |
boolean | yes | |
data.deliveries[].recipient |
string | null | yes | |
data.deliveries[].providerId |
string | null | yes | |
data.deliveries[].error |
string | null | yes | |
data.deliveries[].createdAt |
string (date-time) | yes | |
data.deliveries[].updatedAt |
string (date-time) | yes | |
data.deliveries[].sentAt |
string (date-time) | null | yes | |
data.deliveries[].settledAt |
string (date-time) | null | yes | |
data.deliveries[].openedAt |
string (date-time) | null | yes | |
data.deliveries[].openCount |
integer | yes | -2147483648 ≤ x ≤ 2147483647 |
data.deliveries[].spamScore |
number | null | yes | |
data.deliveries[].spamSymbols |
string[] | null | yes | |
data.suppressedAddresses |
object[] | yes | |
data.suppressedAddresses[] |
object | yes | |
data.suppressedAddresses[].id |
string | yes | |
data.suppressedAddresses[].orgId |
string | yes | |
data.suppressedAddresses[].address |
string | yes | |
data.suppressedAddresses[].type |
“bounce” | “complaint” | “manual” | null | yes | |
data.suppressedAddresses[].reason |
string | null | yes | |
data.suppressedAddresses[].source |
string | null | yes | |
data.suppressedAddresses[].suppressedAt |
string (date-time) | yes | |
data.suppressedAddresses[].createdAt |
string (date-time) | yes | |
data.suppressedAddresses[].updatedAt |
string (date-time) | yes | |
data.emailAddresses |
object[] | yes | |
data.emailAddresses[] |
object | yes | |
data.emailAddresses[].id |
string | yes | |
data.emailAddresses[].orgId |
string | yes | |
data.emailAddresses[].address |
string | yes | |
data.emailAddresses[].verifiedAt |
string (date-time) | null | yes | |
data.emailAddresses[].verificationMethod |
“link” | “imported” | “provider” | null | yes | |
data.emailAddresses[].createdAt |
string (date-time) | yes | |
data.emailAddresses[].updatedAt |
string (date-time) | yes | |
meta |
object | no | |
meta.requestId |
string | no | |
meta.nextCursor |
string | null | no | |
meta.hasMore |
boolean | no | |
meta.warnings |
object[] | no | |
meta.warnings[] |
object | no | |
meta.warnings[].code |
string | yes | |
meta.warnings[].message |
string | yes | |
meta.warnings[].suggestion |
string | no |
Errors follow the shared envelope and code table.
POST /v1/users/erase
Section titled “POST /v1/users/erase”Erase every person one identifier names (GDPR)
Admin only. Terminates active automation executions, then permanently deletes every profile across your apps that carries the identifier, along with their merged profiles, and their event and delivery history. This action cannot be undone.
Auth: Session token.
Request body
{ "data": { "kind": "anonymousId", "value": "string" }}| Field | Type | Required | Constraints |
|---|---|---|---|
data |
object | yes | |
data.kind |
“anonymousId” | “userId” | “clerkId” | “email” | yes | |
data.value |
string | yes | length 1–200 |
Response 200
{ "data": { "profileIds": [ "string" ], "terminatedInstances": 42 }, "meta": { "requestId": "string", "nextCursor": "string", "hasMore": true, "warnings": [ { "code": "string", "message": "string", "suggestion": "string" } ] }}| Field | Type | Required | Constraints |
|---|---|---|---|
data |
object | yes | |
data.profileIds |
string[] | yes | |
data.terminatedInstances |
integer | yes | 0 ≤ x ≤ ∞ |
meta |
object | no | |
meta.requestId |
string | no | |
meta.nextCursor |
string | null | no | |
meta.hasMore |
boolean | no | |
meta.warnings |
object[] | no | |
meta.warnings[] |
object | no | |
meta.warnings[].code |
string | yes | |
meta.warnings[].message |
string | yes | |
meta.warnings[].suggestion |
string | no |
Errors follow the shared envelope and code table.
GET /v1/users/{profileId}
Section titled “GET /v1/users/{profileId}”Fetch one profile with its identifiers
Auth: Session token.
Response 200
{ "data": { "id": "string", "orgId": "string", "appId": "string", "sourceId": "string", "traits": { "key": {} }, "consent": { "key": true }, "mergedInto": "string", "createdAt": "2026-01-15T09:30:00.000Z", "updatedAt": "2026-01-15T09:30:00.000Z", "identifiers": [ { "kind": "anonymousId", "value": "string", "createdAt": "2026-01-15T09:30:00.000Z", "sourceId": "string", "sourceName": "string" } ], "anonymous": true, "mergedIds": [ "string" ], "email": { "address": "string", "source": "string" } }, "meta": { "requestId": "string", "nextCursor": "string", "hasMore": true, "warnings": [ { "code": "string", "message": "string", "suggestion": "string" } ] }}| Field | Type | Required | Constraints |
|---|---|---|---|
data |
object | yes | |
data.id |
string | yes | |
data.orgId |
string | yes | |
data.appId |
string | yes | |
data.sourceId |
string | yes | |
data.traits |
record<string, any> | yes | |
data.consent |
record<string, boolean> | yes | |
data.mergedInto |
string | null | yes | |
data.createdAt |
string (date-time) | yes | |
data.updatedAt |
string (date-time) | yes | |
data.identifiers |
object[] | yes | |
data.identifiers[] |
object | yes | |
data.identifiers[].kind |
“anonymousId” | “userId” | “clerkId” | “email” | yes | |
data.identifiers[].value |
string | yes | |
data.identifiers[].createdAt |
string (date-time) | yes | |
data.identifiers[].sourceId |
string | null | yes | |
data.identifiers[].sourceName |
string | null | yes | |
data.anonymous |
boolean | yes | |
data.mergedIds |
string[] | yes | |
data.email |
object | null | yes | |
data.email.address |
string | yes | |
data.email.source |
string | yes | |
meta |
object | no | |
meta.requestId |
string | no | |
meta.nextCursor |
string | null | no | |
meta.hasMore |
boolean | no | |
meta.warnings |
object[] | no | |
meta.warnings[] |
object | no | |
meta.warnings[].code |
string | yes | |
meta.warnings[].message |
string | yes | |
meta.warnings[].suggestion |
string | no |
Errors follow the shared envelope and code table.
DELETE /v1/users/{profileId}
Section titled “DELETE /v1/users/{profileId}”Erase a user (GDPR)
Admin only. Terminates active automation executions, then permanently deletes the profile, any profiles merged into it, and their event and delivery history. This action cannot be undone.
Auth: Session token.
Response 200
{ "data": { "profileIds": [ "string" ], "terminatedInstances": 42 }, "meta": { "requestId": "string", "nextCursor": "string", "hasMore": true, "warnings": [ { "code": "string", "message": "string", "suggestion": "string" } ] }}| Field | Type | Required | Constraints |
|---|---|---|---|
data |
object | yes | |
data.profileIds |
string[] | yes | |
data.terminatedInstances |
integer | yes | 0 ≤ x ≤ ∞ |
meta |
object | no | |
meta.requestId |
string | no | |
meta.nextCursor |
string | null | no | |
meta.hasMore |
boolean | no | |
meta.warnings |
object[] | no | |
meta.warnings[] |
object | no | |
meta.warnings[].code |
string | yes | |
meta.warnings[].message |
string | yes | |
meta.warnings[].suggestion |
string | no |
Errors follow the shared envelope and code table.
GET /v1/users/{profileId}/export
Section titled “GET /v1/users/{profileId}/export”Export everything held on a user (GDPR)
Auth: Session token.
Response 200
{ "data": { "exportedAt": "2026-01-15T09:30:00.000Z", "users": [ { "id": "string", "orgId": "string", "appId": "string", "sourceId": "string", "traits": { "key": {} }, "consent": { "key": true }, "mergedInto": "string", "createdAt": "2026-01-15T09:30:00.000Z", "updatedAt": "2026-01-15T09:30:00.000Z", "identifiers": [ { "kind": "anonymousId", "value": "string", "createdAt": "2026-01-15T09:30:00.000Z", "sourceId": "string", "sourceName": "string" } ], "anonymous": true, "mergedIds": [ "string" ], "email": { "address": "string", "source": "string" } } ], "events": [ { "id": "string", "orgId": "string", "appId": "string", "sourceId": "string", "profileId": "string", "event": "string", "properties": { "key": {} }, "timestamp": "2026-01-15T09:30:00.000Z", "receivedAt": "2026-01-15T09:30:00.000Z", "messageId": "string", "client": "string" } ], "eventSummaries": [ { "orgId": "string", "appId": "string", "profileId": "string", "event": "string", "count": 42, "firstAt": "2026-01-15T09:30:00.000Z", "lastAt": "2026-01-15T09:30:00.000Z", "recent": [ "2026-01-15T09:30:00.000Z" ] } ], "automations": [ { "id": "string", "orgId": "string", "automation": "string", "profileId": "string", "workflowId": "string", "runId": "string", "completedAt": "2026-01-15T09:30:00.000Z", "sent": true, "createdAt": "2026-01-15T09:30:00.000Z" } ], "deliveries": [ { "id": "string", "orgId": "string", "profileId": "string", "automation": "string", "executionId": "string", "appId": "string", "broadcastId": "string", "kind": "automation", "step": "string", "channel": "email", "status": "sent", "dryRun": true, "recipient": "string", "providerId": "string", "error": "string", "createdAt": "2026-01-15T09:30:00.000Z", "updatedAt": "2026-01-15T09:30:00.000Z", "sentAt": "2026-01-15T09:30:00.000Z", "settledAt": "2026-01-15T09:30:00.000Z", "openedAt": "2026-01-15T09:30:00.000Z", "openCount": 42, "spamScore": 42, "spamSymbols": [ "string" ] } ], "suppressedAddresses": [ { "id": "string", "orgId": "string", "address": "string", "type": "bounce", "reason": "string", "source": "string", "suppressedAt": "2026-01-15T09:30:00.000Z", "createdAt": "2026-01-15T09:30:00.000Z", "updatedAt": "2026-01-15T09:30:00.000Z" } ], "emailAddresses": [ { "id": "string", "orgId": "string", "address": "string", "verifiedAt": "2026-01-15T09:30:00.000Z", "verificationMethod": "link", "createdAt": "2026-01-15T09:30:00.000Z", "updatedAt": "2026-01-15T09:30:00.000Z" } ] }, "meta": { "requestId": "string", "nextCursor": "string", "hasMore": true, "warnings": [ { "code": "string", "message": "string", "suggestion": "string" } ] }}| Field | Type | Required | Constraints |
|---|---|---|---|
data |
object | yes | |
data.exportedAt |
string (date-time) | yes | |
data.users |
object[] | yes | |
data.users[] |
object | yes | |
data.users[].id |
string | yes | |
data.users[].orgId |
string | yes | |
data.users[].appId |
string | yes | |
data.users[].sourceId |
string | yes | |
data.users[].traits |
record<string, any> | yes | |
data.users[].consent |
record<string, boolean> | yes | |
data.users[].mergedInto |
string | null | yes | |
data.users[].createdAt |
string (date-time) | yes | |
data.users[].updatedAt |
string (date-time) | yes | |
data.users[].identifiers |
object[] | yes | |
data.users[].identifiers[] |
object | yes | |
data.users[].identifiers[].kind |
“anonymousId” | “userId” | “clerkId” | “email” | yes | |
data.users[].identifiers[].value |
string | yes | |
data.users[].identifiers[].createdAt |
string (date-time) | yes | |
data.users[].identifiers[].sourceId |
string | null | yes | |
data.users[].identifiers[].sourceName |
string | null | yes | |
data.users[].anonymous |
boolean | yes | |
data.users[].mergedIds |
string[] | yes | |
data.users[].email |
object | null | yes | |
data.users[].email.address |
string | yes | |
data.users[].email.source |
string | yes | |
data.events |
object[] | yes | |
data.events[] |
object | yes | |
data.events[].id |
string | yes | |
data.events[].orgId |
string | yes | |
data.events[].appId |
string | yes | |
data.events[].sourceId |
string | yes | |
data.events[].profileId |
string | yes | |
data.events[].event |
string | yes | |
data.events[].properties |
record<string, any> | yes | |
data.events[].timestamp |
string (date-time) | yes | |
data.events[].receivedAt |
string (date-time) | yes | |
data.events[].messageId |
string | null | yes | |
data.events[].client |
string | null | yes | |
data.eventSummaries |
object[] | yes | |
data.eventSummaries[] |
object | yes | |
data.eventSummaries[].orgId |
string | yes | |
data.eventSummaries[].appId |
string | yes | |
data.eventSummaries[].profileId |
string | yes | |
data.eventSummaries[].event |
string | yes | |
data.eventSummaries[].count |
integer | yes | |
data.eventSummaries[].firstAt |
string (date-time) | yes | |
data.eventSummaries[].lastAt |
string (date-time) | yes | |
data.eventSummaries[].recent |
string (date-time)[] | yes | |
data.automations |
object[] | yes | |
data.automations[] |
object | yes | |
data.automations[].id |
string | yes | |
data.automations[].orgId |
string | yes | |
data.automations[].automation |
string | yes | |
data.automations[].profileId |
string | yes | |
data.automations[].workflowId |
string | yes | |
data.automations[].runId |
string | yes | |
data.automations[].completedAt |
string (date-time) | yes | |
data.automations[].sent |
boolean | yes | |
data.automations[].createdAt |
string (date-time) | yes | |
data.deliveries |
object[] | yes | |
data.deliveries[] |
object | yes | |
data.deliveries[].id |
string | yes | |
data.deliveries[].orgId |
string | yes | |
data.deliveries[].profileId |
string | null | yes | |
data.deliveries[].automation |
string | null | yes | |
data.deliveries[].executionId |
string | null | yes | |
data.deliveries[].appId |
string | null | yes | |
data.deliveries[].broadcastId |
string | null | yes | |
data.deliveries[].kind |
“automation” | “test” | “api” | “broadcast” | yes | |
data.deliveries[].step |
string | yes | |
data.deliveries[].channel |
“email” | “webhook” | yes | |
data.deliveries[].status |
“sent” | “delivered” | “bounced” | “complained” | “failed” | “skipped_disabled” | “skipped_paused” | “skipped_suspended” | “skipped_suppressed” | “skipped_quota” | “skipped_unknown_purpose” | “skipped_frequency_cap” | “skipped_consent” | “skipped_domain” | “skipped_ssrf” | “skipped_spam” | “would_send” | “would_skip_disabled” | “would_skip_paused” | “would_skip_suspended” | “would_skip_suppressed” | “would_skip_quota” | “would_skip_unknown_purpose” | “would_skip_frequency_cap” | “would_skip_consent” | “would_skip_domain” | “would_skip_ssrf” | “would_skip_spam” | yes | |
data.deliveries[].dryRun |
boolean | yes | |
data.deliveries[].recipient |
string | null | yes | |
data.deliveries[].providerId |
string | null | yes | |
data.deliveries[].error |
string | null | yes | |
data.deliveries[].createdAt |
string (date-time) | yes | |
data.deliveries[].updatedAt |
string (date-time) | yes | |
data.deliveries[].sentAt |
string (date-time) | null | yes | |
data.deliveries[].settledAt |
string (date-time) | null | yes | |
data.deliveries[].openedAt |
string (date-time) | null | yes | |
data.deliveries[].openCount |
integer | yes | -2147483648 ≤ x ≤ 2147483647 |
data.deliveries[].spamScore |
number | null | yes | |
data.deliveries[].spamSymbols |
string[] | null | yes | |
data.suppressedAddresses |
object[] | yes | |
data.suppressedAddresses[] |
object | yes | |
data.suppressedAddresses[].id |
string | yes | |
data.suppressedAddresses[].orgId |
string | yes | |
data.suppressedAddresses[].address |
string | yes | |
data.suppressedAddresses[].type |
“bounce” | “complaint” | “manual” | null | yes | |
data.suppressedAddresses[].reason |
string | null | yes | |
data.suppressedAddresses[].source |
string | null | yes | |
data.suppressedAddresses[].suppressedAt |
string (date-time) | yes | |
data.suppressedAddresses[].createdAt |
string (date-time) | yes | |
data.suppressedAddresses[].updatedAt |
string (date-time) | yes | |
data.emailAddresses |
object[] | yes | |
data.emailAddresses[] |
object | yes | |
data.emailAddresses[].id |
string | yes | |
data.emailAddresses[].orgId |
string | yes | |
data.emailAddresses[].address |
string | yes | |
data.emailAddresses[].verifiedAt |
string (date-time) | null | yes | |
data.emailAddresses[].verificationMethod |
“link” | “imported” | “provider” | null | yes | |
data.emailAddresses[].createdAt |
string (date-time) | yes | |
data.emailAddresses[].updatedAt |
string (date-time) | yes | |
meta |
object | no | |
meta.requestId |
string | no | |
meta.nextCursor |
string | null | no | |
meta.hasMore |
boolean | no | |
meta.warnings |
object[] | no | |
meta.warnings[] |
object | no | |
meta.warnings[].code |
string | yes | |
meta.warnings[].message |
string | yes | |
meta.warnings[].suggestion |
string | no |
Errors follow the shared envelope and code table.
PATCH /v1/users/{profileId}/consent
Section titled “PATCH /v1/users/{profileId}/consent”Update consent purposes
Auth: Session token.
Request body
{ "data": { "marketing.newsletter": true }}| Field | Type | Required | Constraints |
|---|---|---|---|
data |
record<string, boolean> | yes |
Response 200
{ "data": { "id": "string", "orgId": "string", "appId": "string", "sourceId": "string", "traits": { "key": {} }, "consent": { "key": true }, "mergedInto": "string", "createdAt": "2026-01-15T09:30:00.000Z", "updatedAt": "2026-01-15T09:30:00.000Z", "identifiers": [ { "kind": "anonymousId", "value": "string", "createdAt": "2026-01-15T09:30:00.000Z", "sourceId": "string", "sourceName": "string" } ], "anonymous": true, "mergedIds": [ "string" ], "email": { "address": "string", "source": "string" } }, "meta": { "requestId": "string", "nextCursor": "string", "hasMore": true, "warnings": [ { "code": "string", "message": "string", "suggestion": "string" } ] }}| Field | Type | Required | Constraints |
|---|---|---|---|
data |
object | yes | |
data.id |
string | yes | |
data.orgId |
string | yes | |
data.appId |
string | yes | |
data.sourceId |
string | yes | |
data.traits |
record<string, any> | yes | |
data.consent |
record<string, boolean> | yes | |
data.mergedInto |
string | null | yes | |
data.createdAt |
string (date-time) | yes | |
data.updatedAt |
string (date-time) | yes | |
data.identifiers |
object[] | yes | |
data.identifiers[] |
object | yes | |
data.identifiers[].kind |
“anonymousId” | “userId” | “clerkId” | “email” | yes | |
data.identifiers[].value |
string | yes | |
data.identifiers[].createdAt |
string (date-time) | yes | |
data.identifiers[].sourceId |
string | null | yes | |
data.identifiers[].sourceName |
string | null | yes | |
data.anonymous |
boolean | yes | |
data.mergedIds |
string[] | yes | |
data.email |
object | null | yes | |
data.email.address |
string | yes | |
data.email.source |
string | yes | |
meta |
object | no | |
meta.requestId |
string | no | |
meta.nextCursor |
string | null | no | |
meta.hasMore |
boolean | no | |
meta.warnings |
object[] | no | |
meta.warnings[] |
object | no | |
meta.warnings[].code |
string | yes | |
meta.warnings[].message |
string | yes | |
meta.warnings[].suggestion |
string | no |
Errors follow the shared envelope and code table.
GET /v1/users/{profileId}/segments
Section titled “GET /v1/users/{profileId}/segments”The segments a profile belongs to
Auth: Session token.
Query parameters
{ "cursor": "string", "limit": 50}| Field | Type | Required | Constraints |
|---|---|---|---|
cursor |
string | no | |
limit |
integer | no | default 50; 1 ≤ x ≤ 100 |
Response 200
{ "data": [ { "segmentId": "string", "name": "string", "since": "2026-01-15T09:30:00.000Z" } ], "meta": { "requestId": "string", "nextCursor": "string", "hasMore": true, "warnings": [ { "code": "string", "message": "string", "suggestion": "string" } ] }}| Field | Type | Required | Constraints |
|---|---|---|---|
data |
object[] | yes | |
data[] |
object | yes | |
data[].segmentId |
string | yes | |
data[].name |
string | yes | |
data[].since |
string (date-time) | yes | |
meta |
object | no | |
meta.requestId |
string | no | |
meta.nextCursor |
string | null | no | |
meta.hasMore |
boolean | no | |
meta.warnings |
object[] | no | |
meta.warnings[] |
object | no | |
meta.warnings[].code |
string | yes | |
meta.warnings[].message |
string | yes | |
meta.warnings[].suggestion |
string | no |
Errors follow the shared envelope and code table.
GET /v1/users/{profileId}/timeline
Section titled “GET /v1/users/{profileId}/timeline”Everything that happened to a profile, newest first
Its events, the sends made to it, its automation runs (each start, each wait an event answered, each end) and the segments it entered and left, in one list. A profile that absorbed others in a merge includes their history too. types narrows it, for example run,delivery.
Auth: Session token.
Query parameters
{ "cursor": "string", "limit": 50, "types": "string"}| Field | Type | Required | Constraints |
|---|---|---|---|
cursor |
string | no | |
limit |
integer | no | default 50; 1 ≤ x ≤ 100 |
types |
string | no |
Response 200
{ "data": [ { "id": "string", "at": "2026-01-15T09:30:00.000Z", "type": "event", "eventId": "string", "event": "string", "properties": { "key": {} } } ], "meta": { "requestId": "string", "nextCursor": "string", "hasMore": true, "warnings": [ { "code": "string", "message": "string", "suggestion": "string" } ] }}| Field | Type | Required | Constraints |
|---|---|---|---|
data |
array of variants | yes | |
data[] |
one of | yes | |
data[]〈event〉 |
object | yes | |
data[]〈event〉.id |
string | yes | |
data[]〈event〉.at |
string (date-time) | yes | |
data[]〈event〉.type |
“event” | yes | |
data[]〈event〉.eventId |
string | yes | |
data[]〈event〉.event |
string | yes | |
data[]〈event〉.properties |
record<string, any> | yes | |
data[]〈segment〉 |
object | yes | |
data[]〈segment〉.id |
string | yes | |
data[]〈segment〉.at |
string (date-time) | yes | |
data[]〈segment〉.type |
“segment” | yes | |
data[]〈segment〉.eventId |
string | yes | |
data[]〈segment〉.change |
“entered” | “exited” | yes | |
data[]〈segment〉.segmentId |
string | yes | |
data[]〈segment〉.segmentName |
string | yes | |
data[]〈segment〉.cause |
object | null | yes | |
data[]〈segment〉.cause.eventId |
string | null | yes | |
data[]〈segment〉.cause.event |
string | yes | |
data[]〈segment〉.cause.segmentName |
string | null | yes | |
data[]〈delivery〉 |
object | yes | |
data[]〈delivery〉.id |
string | yes | |
data[]〈delivery〉.at |
string (date-time) | yes | |
data[]〈delivery〉.type |
“delivery” | yes | |
data[]〈delivery〉.deliveryId |
string | yes | |
data[]〈delivery〉.step |
string | yes | |
data[]〈delivery〉.channel |
“email” | “webhook” | yes | |
data[]〈delivery〉.status |
“sent” | “delivered” | “bounced” | “complained” | “failed” | “skipped_disabled” | “skipped_paused” | “skipped_suspended” | “skipped_suppressed” | “skipped_quota” | “skipped_unknown_purpose” | “skipped_frequency_cap” | “skipped_consent” | “skipped_domain” | “skipped_ssrf” | “skipped_spam” | “would_send” | “would_skip_disabled” | “would_skip_paused” | “would_skip_suspended” | “would_skip_suppressed” | “would_skip_quota” | “would_skip_unknown_purpose” | “would_skip_frequency_cap” | “would_skip_consent” | “would_skip_domain” | “would_skip_ssrf” | “would_skip_spam” | yes | |
data[]〈delivery〉.error |
string | null | yes | |
data[]〈delivery〉.automation |
string | null | yes | |
data[]〈delivery〉.executionId |
string | null | yes | |
data[]〈run〉 |
object | yes | |
data[]〈run〉.id |
string | yes | |
data[]〈run〉.at |
string (date-time) | yes | |
data[]〈run〉.type |
“run” | yes | |
data[]〈run〉.change |
“started” | “resumed” | “ended” | yes | |
data[]〈run〉.executionId |
string | yes | |
data[]〈run〉.appId |
string | yes | |
data[]〈run〉.automationKey |
string | yes | |
data[]〈run〉.status |
“running” | “waiting” | “completed” | “failed” | “cancelled” | yes | |
data[]〈run〉.step |
string | null | yes | |
data[]〈run〉.error |
string | null | yes | |
data[]〈run〉.cause |
object | null | yes | |
data[]〈run〉.cause.eventId |
string | null | yes | |
data[]〈run〉.cause.event |
string | yes | |
data[]〈run〉.cause.segmentName |
string | null | yes | |
meta |
object | no | |
meta.requestId |
string | no | |
meta.nextCursor |
string | null | no | |
meta.hasMore |
boolean | no | |
meta.warnings |
object[] | no | |
meta.warnings[] |
object | no | |
meta.warnings[].code |
string | yes | |
meta.warnings[].message |
string | yes | |
meta.warnings[].suggestion |
string | no |
Errors follow the shared envelope and code table.
GET /v1/users/{profileId}/runs
Section titled “GET /v1/users/{profileId}/runs”The automations a profile has completed
Auth: Session token.
Query parameters
{ "cursor": "string", "limit": 50}| Field | Type | Required | Constraints |
|---|---|---|---|
cursor |
string | no | |
limit |
integer | no | default 50; 1 ≤ x ≤ 100 |
Response 200
{ "data": [ { "id": "string", "appId": "string", "automationKey": "string", "completedAt": "2026-01-15T09:30:00.000Z", "executionId": "string" } ], "meta": { "requestId": "string", "nextCursor": "string", "hasMore": true, "warnings": [ { "code": "string", "message": "string", "suggestion": "string" } ] }}| Field | Type | Required | Constraints |
|---|---|---|---|
data |
object[] | yes | |
data[] |
object | yes | |
data[].id |
string | yes | |
data[].appId |
string | yes | |
data[].automationKey |
string | yes | |
data[].completedAt |
string (date-time) | yes | |
data[].executionId |
string | null | yes | |
meta |
object | no | |
meta.requestId |
string | no | |
meta.nextCursor |
string | null | no | |
meta.hasMore |
boolean | no | |
meta.warnings |
object[] | no | |
meta.warnings[] |
object | no | |
meta.warnings[].code |
string | yes | |
meta.warnings[].message |
string | yes | |
meta.warnings[].suggestion |
string | no |
Errors follow the shared envelope and code table.