# Identities ## Create object **post** `/v2/prism/{teamId}/identity` Creates a record. For `document`, writing `content` (or HTML) stores the property and reads back, but the in-app editor is CRDT-backed and will render a blank page until that document has been opened and saved in the app. Treat API-created docs as data records, not as collaboratively edited pages, unless you only need the stored property values. ### Path Parameters - `teamId: optional string` ### Header Parameters - `"Idempotency-Key": optional string` ### Body Parameters - `default: optional map[unknown]` Properties keyed by property slug. Values can be strings, numbers, booleans, arrays, or null. For select/multiselect properties, values may be option slugs or option UUIDs on write; option slugs are returned on read. - `list: optional unknown` ### Returns - `id: string` - `default: optional map[unknown]` Properties keyed by property slug. - `list: optional unknown` ### Example ```http curl https://developers.micro.so/v2/prism/$TEAM_ID/identity \ -X POST \ -H "x-api-key: $MICRO_API_KEY" ``` #### Response ```json { "id": "11111111-1111-4111-8111-111111111111", "default": { "full_name": "Sarah Chen", "email": "sarah@example.com", "title": "Partner", "organization": "Acme Ventures" } } ``` ## List records of an object type **get** `/v2/prism/{teamId}/identity` Convenience list endpoint. Equivalent to `POST /v2/prism/{teamId}/{objectType}/query` with an empty body, plus query-string sugar for the common cases. Any unrecognized query parameter is interpreted as an equality filter on a property of that name; pass arrays for `in`. Values are received as strings, so non-string property filters via this endpoint may not work — use the `query` endpoint for typed comparisons or anything beyond simple equality. ### Path Parameters - `teamId: optional string` ### Query Parameters - `cursor: optional string` Opaque cursor from a previous response's `next_cursor`. Pass it back unchanged to fetch the next page. - `deleted: optional boolean` Include soft-deleted records. Pass the literal string `true`. - `include_total: optional boolean` When set to `true`, the response includes a `total` field with the unpaginated row count. Costs an extra pass; prefer `GET .../count` for the unfiltered total. - `limit: optional number` Maximum number of rows to return. Capped server-side at 50. - `list_id: optional string` Scope properties to a specific list/app. - `select: optional string` Comma-separated property slugs to return. Use dot notation for relationships. `id` is always returned at the top level. Defaults to all properties. - `sort: optional string` Comma-separated list of slugs. Prefix with `-` for descending. Example: `sort=-updated_at,name`. ### Returns - `data: array of object { id, is_user_object, properties, source }` - `id: string` - `is_user_object: optional boolean` - `properties: optional map[unknown]` Selected property values keyed by property slug. For select/multiselect properties, option slugs are returned. For reference properties, values are nested `{ id, properties }` objects. - `source: optional array of string` - `has_more: boolean` Accurate end-of-data signal — false on the last page, never forces clients to overshoot. - `next_cursor: optional string` - `total: optional number` Populated only when `?include_total=true` was passed. ### Example ```http curl https://developers.micro.so/v2/prism/$TEAM_ID/identity \ -H "x-api-key: $MICRO_API_KEY" ``` #### Response ```json { "data": [ { "id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", "is_user_object": true, "properties": { "foo": "bar" }, "source": [ "string" ] } ], "has_more": true, "next_cursor": "next_cursor", "total": 0 } ``` ## Get object **get** `/v2/prism/{teamId}/identity/{identityId}` Get object ### Path Parameters - `teamId: optional string` - `identityId: string` ### Query Parameters - `select: optional string` Comma-separated property slugs to return. Use dot notation for relationships. `id` is always returned at the top level. Defaults to all properties. ### Returns - `id: string` - `default: optional map[unknown]` Properties keyed by property slug. - `list: optional unknown` ### Example ```http curl https://developers.micro.so/v2/prism/$TEAM_ID/identity/$IDENTITY_ID \ -H "x-api-key: $MICRO_API_KEY" ``` #### Response ```json { "id": "11111111-1111-4111-8111-111111111111", "default": { "full_name": "Sarah Chen", "email": "sarah@example.com", "title": "Partner", "organization": "Acme Ventures" } } ``` ## Patch object **patch** `/v2/prism/{teamId}/identity/{identityId}` Patch object ### Path Parameters - `teamId: optional string` - `identityId: string` ### Header Parameters - `"Idempotency-Key": optional string` - `"If-Match": optional string` ### Body Parameters - `default: optional map[unknown]` Properties keyed by property slug. Values can be strings, numbers, booleans, arrays, or null. For select/multiselect properties, values may be option slugs or option UUIDs on write; option slugs are returned on read. - `list: optional unknown` ### Returns - `id: string` - `default: optional map[unknown]` Properties keyed by property slug. - `list: optional unknown` ### Example ```http curl https://developers.micro.so/v2/prism/$TEAM_ID/identity/$IDENTITY_ID \ -X PATCH \ -H 'Content-Type: application/json' \ -H "x-api-key: $MICRO_API_KEY" \ -d '{}' ``` #### Response ```json { "id": "11111111-1111-4111-8111-111111111111", "default": { "full_name": "Sarah Chen", "email": "sarah@example.com", "title": "General Partner", "organization": "Acme Ventures" } } ``` ## Delete object **delete** `/v2/prism/{teamId}/identity/{identityId}` Delete object ### Path Parameters - `teamId: optional string` - `identityId: string` ### Header Parameters - `"If-Match": optional string` ### Example ```http curl https://developers.micro.so/v2/prism/$TEAM_ID/identity/$IDENTITY_ID \ -X DELETE \ -H "x-api-key: $MICRO_API_KEY" ``` ## Query **post** `/v2/prism/{teamId}/identity/query` Query ### Path Parameters - `teamId: optional string` ### Header Parameters - `"Idempotency-Key": optional string` ### Body Parameters - `query: object { select, combinator, cursor, 5 more }` - `select: array of string` Property slugs to select. Use dot notation for relationships (e.g. attendee.contact.first_name). `id` is always returned at the top level of each row and does not need to be selected. - `combinator: optional "AND" or "OR"` Logical operator for combining filters - `"AND"` - `"OR"` - `cursor: optional string` Opaque cursor from a previous response's `next_cursor`. Pass it back unchanged to fetch the next page. When set, `page` and `limit` are derived from the cursor and any explicit values are ignored. - `filter: optional array of map[object { "=" } or object { "!=" } or object { "<" } or 14 more]` Filters as [{ slug: { operator: value } }]. For select/multiselect properties, values may be option slugs or option UUIDs. - `PrismQueryFilterEq object { "=" }` - `"=": string or boolean` - `string` - `boolean` - `PrismQueryFilterNe object { "!=" }` - `"!=": string or boolean` - `string` - `boolean` - `PrismQueryFilterLt object { "<" }` - `"<": string` - `PrismQueryFilterGt object { ">" }` - `">": string` - `PrismQueryFilterLte object { "<=" }` - `"<=": string` - `PrismQueryFilterGte object { ">=" }` - `">=": string` - `Contains object { contains }` - `contains: string or boolean or array of string` - `string` - `boolean` - `array of string` - `BeginsWith object { begins_with }` - `begins_with: string` - `EndsWith object { ends_with }` - `ends_with: string` - `NotContains object { not_contains }` - `not_contains: string` - `Exists object { exists }` - `exists: boolean` - `NotExists object { not_exists }` - `not_exists: boolean` - `IsNull object { is_null }` - `is_null: string or boolean or array of string` - `string` - `boolean` - `array of string` - `IsNotNull object { is_not_null }` - `is_not_null: string or boolean or array of string` - `string` - `boolean` - `array of string` - `Between object { between }` - `between: string or boolean or array of string` - `string` - `boolean` - `array of string` - `In object { in }` - `in: array of string` - `NotIn object { not_in }` - `not_in: array of string` - `limit: optional number` Maximum number of rows to return. Capped server-side at 50; requests above the cap are rejected. - `list_id: optional string` - `page: optional number` Page number (1-based). Prefer `cursor`. Page-number pagination drifts under concurrent writes; use it only for one-shot exports. - `sort: optional array of map["asc" or "desc"]` Sort order as [{ slug: direction }]. Array order determines sort priority - `"asc"` - `"desc"` - `id: optional string or array of string` - `string` - `array of string` - `boxes: optional array of string` - `cursor: optional string` Alternative location for the opaque cursor (a sibling of `query`). Use whichever feels more natural; if both are present, `query.cursor` wins. - `deleted: optional boolean` - `include_total: optional boolean` When true, the response includes a `total` field with the unpaginated row count. Costs an additional pass over the result set — for unfiltered totals prefer `GET /v2/prism/{teamId}/{objectType}/count` instead. - `sources: optional array of string` ### Returns - `data: array of object { id, is_user_object, properties, source }` - `id: string` - `is_user_object: optional boolean` - `properties: optional map[unknown]` Selected property values keyed by property slug. For select/multiselect properties, option slugs are returned. For reference properties, values are nested `{ id, properties }` objects. - `source: optional array of string` - `has_more: boolean` Accurate end-of-data signal. False when this page contains the last record; true only when at least one more record exists. (Implementation note: the server fetches one extra row internally to determine this — clients never need to overshoot to discover the end.) - `next_cursor: optional string` Opaque cursor pointing at the next page. Pass it back unchanged. Do not parse it. The current encoding is offset-based (page + limit), so it has the same concurrent-write drift the deprecated `page` parameter has; treat it as a black box so a future keyset cursor is a drop-in. Null when `has_more` is false. - `total: optional number` Only populated when the request set `include_total: true`. Total number of records matching the query, ignoring pagination. Opt-in because it costs an additional pass over the result set. ### Example ```http curl https://developers.micro.so/v2/prism/$TEAM_ID/identity/query \ -H 'Content-Type: application/json' \ -H "x-api-key: $MICRO_API_KEY" \ -d '{ "query": { "select": [ "full_name", "email", "title", "organization" ], "filter": [ { "full_name": { "=": "Sarah Chen" } } ], "limit": 10 } }' ``` #### Response ```json { "data": [ { "id": "11111111-1111-4111-8111-111111111111", "properties": { "full_name": "Sarah Chen", "email": "sarah@example.com", "title": "Partner", "organization": "Acme Ventures" }, "is_user_object": false, "source": null } ], "has_more": false, "next_cursor": null, "total": 1 } ``` ## Total record count for an object type **get** `/v2/prism/{teamId}/identity/count` Returns the total number of records of this object type that the caller can see. Avoids the page-overshoot anti-pattern — clients no longer need to keep paging until `has_more` flips false to discover the total. Currently does not apply query filters; for a filtered total, pass `include_total: true` in a POST `/query` body. Unfiltered counts on high-cardinality types (especially `engagement`) scan the full access-scoped set and can take tens of seconds or time out; prefer a filtered `include_total` query or accept that this endpoint is expensive there. ### Path Parameters - `teamId: optional string` ### Query Parameters - `list_id: optional string` Scope the count to a specific list/app. ### Returns - `total: number` Number of records matching the access scope. ### Example ```http curl https://developers.micro.so/v2/prism/$TEAM_ID/identity/count \ -H "x-api-key: $MICRO_API_KEY" ``` #### Response ```json { "total": 0 } ``` ## Find a record by property value **get** `/v2/prism/{teamId}/identity/by/{slug}/{value}` Returns the single record whose property `{slug}` equals `{value}`. 404 if nothing matches; 409 if more than one record matches. ### Path Parameters - `teamId: optional string` - `slug: string` - `value: string` ### Query Parameters - `list_id: optional string` Scope the lookup to a specific list/app. ### Returns - `id: string` - `default: optional map[unknown]` Properties keyed by property slug. - `list: optional unknown` ### Example ```http curl https://developers.micro.so/v2/prism/$TEAM_ID/identity/by/$SLUG/$VALUE \ -H "x-api-key: $MICRO_API_KEY" ``` #### Response ```json { "id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", "default": { "foo": "bar" }, "list": {} } ``` ## Upsert by property value **put** `/v2/prism/{teamId}/identity/by/{slug}/{value}` Idempotent create-or-update keyed on `{slug}={value}`. If exactly one record matches, it is patched and 200 is returned. If none match, a new record is created (with the lookup property set if absent) and 201 is returned. If multiple records match, 409 is returned and you should patch by id instead. ### Path Parameters - `teamId: optional string` - `slug: string` - `value: string` ### Query Parameters - `list_id: optional string` Scope the upsert to a specific list/app. Required to match or write list-scoped properties, including `app_stage`. ### Header Parameters - `"Idempotency-Key": optional string` ### Body Parameters - `default: optional map[unknown]` Properties keyed by property slug. Values can be strings, numbers, booleans, arrays, or null. For select/multiselect properties, values may be option slugs or option UUIDs on write; option slugs are returned on read. - `list: optional unknown` ### Returns - `id: string` - `default: optional map[unknown]` Properties keyed by property slug. - `list: optional unknown` ### Example ```http curl https://developers.micro.so/v2/prism/$TEAM_ID/identity/by/$SLUG/$VALUE \ -X PUT \ -H 'Content-Type: application/json' \ -H "x-api-key: $MICRO_API_KEY" \ -d '{}' ``` #### Response ```json { "id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", "default": { "foo": "bar" }, "list": {} } ``` ## Import objects **post** `/v2/prism/{teamId}/identity/import` Import multiple objects in batch. Properties are keyed by slug. Automatically routes based on size: small batches complete synchronously and return 200 with the final `ImportJob`; large batches start an async job, return 202 with `status: processing` and a `Location` header, and can be polled via `GET /v2/prism/{teamId}/imports/{jobId}`. ### Path Parameters - `teamId: optional string` ### Header Parameters - `"Idempotency-Key": optional string` ### Body Parameters - `objects: array of PrismObjectProperties` Array of objects to import with property values keyed by slug - `default: optional map[unknown]` Properties keyed by property slug. Values can be strings, numbers, booleans, arrays, or null. For select/multiselect properties, values may be option slugs or option UUIDs on write; option slugs are returned on read. - `list: optional unknown` - `options: optional object { caseInsensitive, create_missing_options, crm_id, 4 more }` - `caseInsensitive: optional boolean` Whether deduplication should be case insensitive - `create_missing_options: optional boolean` When true, unknown values for select/multiselect properties are created as new options instead of failing the import - `crm_id: optional string` Deprecated alias for list_id. - `dedupe_by: optional string or array of string` Property slug to deduplicate on. A single-element array is also accepted; compound (multi-slug) dedupe is not supported yet and is rejected with guidance. - `string` - `array of string` - `list_id: optional string` App/CRM ID for context (optional) - `require_list_stage: optional boolean` Require app_stage for every row in the selected list. app_stage is a reserved list-scoped alias for native status. - `update_existing: optional boolean` Patch a deduplicated record with the supplied properties instead of skipping it. ### Returns - `job_id: string` Null for sync imports (results inlined). Set for async imports. - `status: "complete" or "processing" or "failed"` - `"complete"` - `"processing"` - `"failed"` - `total: number` Total number of rows in the import. - `created_at: optional string` - `error: optional object { code, message }` Set when status=failed; describes the job-level failure (not per-row). - `code: optional string` - `message: optional string` - `expires_at: optional string` - `failed: optional number` - `processed: optional number` Rows that have been attempted (succeeded + failed). - `results: optional array of object { id, created, error, 3 more }` Per-row outcomes. Always present for sync imports; populated for async imports once the job reaches `complete`. - `id: optional string` - `created: optional boolean` - `error: optional object { code, message }` - `code: optional string` - `message: optional string` - `existing: optional boolean` True if the row matched an existing record via the dedupe key. - `input_index: optional number` Zero-based position of this row in the request. - `updated: optional boolean` True if a matching record was updated. - `succeeded: optional number` - `updated_at: optional string` ### Example ```http curl https://developers.micro.so/v2/prism/$TEAM_ID/identity/import \ -H 'Content-Type: application/json' \ -H "x-api-key: $MICRO_API_KEY" \ -d '{ "objects": [ {} ] }' ``` #### Response ```json { "job_id": "job_id", "status": "complete", "total": 0, "created_at": "2019-12-27T18:11:19.117Z", "error": { "code": "code", "message": "message" }, "expires_at": "2019-12-27T18:11:19.117Z", "failed": 0, "processed": 0, "results": [ { "id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", "created": true, "error": { "code": "code", "message": "message" }, "existing": true, "input_index": 0, "updated": true } ], "succeeded": 0, "updated_at": "2019-12-27T18:11:19.117Z" } ``` ## Bulk update records (partial success) **post** `/v2/prism/{teamId}/identity/batch/update` Patch up to 100 records in a single call. Each item is attempted independently — failures don't abort the batch. Inspect `results[].status` per item. ### Path Parameters - `teamId: optional string` ### Header Parameters - `"Idempotency-Key": optional string` ### Body Parameters - `items: array of object { id }` - `id: string` ### Returns - `results: array of object { id, status, error, record }` - `id: string` Item ID, or null if the input was unparseable. - `status: "ok" or "error"` - `"ok"` - `"error"` - `error: optional object { code, message }` - `code: optional string` - `message: optional string` - `record: optional object { id, default, list }` Object returned by reads (get/create/patch/restore). id is always present. - `id: string` - `default: optional map[unknown]` Properties keyed by property slug. - `list: optional unknown` - `summary: object { failed, succeeded, total }` - `failed: number` - `succeeded: number` - `total: number` ### Example ```http curl https://developers.micro.so/v2/prism/$TEAM_ID/identity/batch/update \ -H 'Content-Type: application/json' \ -H "x-api-key: $MICRO_API_KEY" \ -d '{ "items": [ { "id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e" } ] }' ``` #### Response ```json { "results": [ { "id": "id", "status": "ok", "error": { "code": "code", "message": "message" }, "record": { "id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", "default": { "foo": "bar" }, "list": {} } } ], "summary": { "failed": 0, "succeeded": 0, "total": 0 } } ``` ## Bulk delete records (partial success) **post** `/v2/prism/{teamId}/identity/batch/delete` Soft-delete up to 100 records in a single call. Same partial-success contract as batch/update. ### Path Parameters - `teamId: optional string` ### Header Parameters - `"Idempotency-Key": optional string` ### Body Parameters - `ids: array of string` ### Returns - `results: array of object { id, status, error, record }` - `id: string` Item ID, or null if the input was unparseable. - `status: "ok" or "error"` - `"ok"` - `"error"` - `error: optional object { code, message }` - `code: optional string` - `message: optional string` - `record: optional object { id, default, list }` Object returned by reads (get/create/patch/restore). id is always present. - `id: string` - `default: optional map[unknown]` Properties keyed by property slug. - `list: optional unknown` - `summary: object { failed, succeeded, total }` - `failed: number` - `succeeded: number` - `total: number` ### Example ```http curl https://developers.micro.so/v2/prism/$TEAM_ID/identity/batch/delete \ -H 'Content-Type: application/json' \ -H "x-api-key: $MICRO_API_KEY" \ -d '{ "ids": [ "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e" ] }' ``` #### Response ```json { "results": [ { "id": "id", "status": "ok", "error": { "code": "code", "message": "message" }, "record": { "id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", "default": { "foo": "bar" }, "list": {} } } ], "summary": { "failed": 0, "succeeded": 0, "total": 0 } } ``` ## Duplicate object **post** `/v2/prism/{teamId}/identity/{identityId}/duplicate` Duplicate object ### Path Parameters - `teamId: optional string` - `identityId: string` ### Header Parameters - `"Idempotency-Key": optional string` ### Returns - `id: string` - `default: optional map[unknown]` Properties keyed by property slug. - `list: optional unknown` ### Example ```http curl https://developers.micro.so/v2/prism/$TEAM_ID/identity/$IDENTITY_ID/duplicate \ -X POST \ -H "x-api-key: $MICRO_API_KEY" ``` #### Response ```json { "id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", "default": { "foo": "bar" }, "list": {} } ``` ## Restore object **post** `/v2/prism/{teamId}/identity/{identityId}/restore` Restore object ### Path Parameters - `teamId: optional string` - `identityId: string` ### Header Parameters - `"Idempotency-Key": optional string` ### Returns - `id: string` - `default: optional map[unknown]` Properties keyed by property slug. - `list: optional unknown` ### Example ```http curl https://developers.micro.so/v2/prism/$TEAM_ID/identity/$IDENTITY_ID/restore \ -X POST \ -H "x-api-key: $MICRO_API_KEY" ``` #### Response ```json { "id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", "default": { "foo": "bar" }, "list": {} } ``` ## Domain Types ### Identity - `Identity object { default, list }` - `default: optional map[unknown]` Properties keyed by property slug. Values can be strings, numbers, booleans, arrays, or null. For select/multiselect properties, values may be option slugs or option UUIDs on write; option slugs are returned on read. - `list: optional unknown` ### Identity Create Response - `IdentityCreateResponse object { id, default, list }` Object returned by reads (get/create/patch/restore). id is always present. - `id: string` - `default: optional map[unknown]` Properties keyed by property slug. - `list: optional unknown` ### Identity List Response - `IdentityListResponse object { data, has_more, next_cursor, total }` - `data: array of object { id, is_user_object, properties, source }` - `id: string` - `is_user_object: optional boolean` - `properties: optional map[unknown]` Selected property values keyed by property slug. For select/multiselect properties, option slugs are returned. For reference properties, values are nested `{ id, properties }` objects. - `source: optional array of string` - `has_more: boolean` Accurate end-of-data signal — false on the last page, never forces clients to overshoot. - `next_cursor: optional string` - `total: optional number` Populated only when `?include_total=true` was passed. ### Identity Get Response - `IdentityGetResponse object { id, default, list }` Object returned by reads (get/create/patch/restore). id is always present. - `id: string` - `default: optional map[unknown]` Properties keyed by property slug. - `list: optional unknown` ### Identity Update Response - `IdentityUpdateResponse object { id, default, list }` Object returned by reads (get/create/patch/restore). id is always present. - `id: string` - `default: optional map[unknown]` Properties keyed by property slug. - `list: optional unknown` ### Identity Query Response - `IdentityQueryResponse object { data, has_more, next_cursor, total }` - `data: array of object { id, is_user_object, properties, source }` - `id: string` - `is_user_object: optional boolean` - `properties: optional map[unknown]` Selected property values keyed by property slug. For select/multiselect properties, option slugs are returned. For reference properties, values are nested `{ id, properties }` objects. - `source: optional array of string` - `has_more: boolean` Accurate end-of-data signal. False when this page contains the last record; true only when at least one more record exists. (Implementation note: the server fetches one extra row internally to determine this — clients never need to overshoot to discover the end.) - `next_cursor: optional string` Opaque cursor pointing at the next page. Pass it back unchanged. Do not parse it. The current encoding is offset-based (page + limit), so it has the same concurrent-write drift the deprecated `page` parameter has; treat it as a black box so a future keyset cursor is a drop-in. Null when `has_more` is false. - `total: optional number` Only populated when the request set `include_total: true`. Total number of records matching the query, ignoring pagination. Opt-in because it costs an additional pass over the result set. ### Identity Count Response - `IdentityCountResponse object { total }` - `total: number` Number of records matching the access scope. ### Identity Find Response - `IdentityFindResponse object { id, default, list }` Object returned by reads (get/create/patch/restore). id is always present. - `id: string` - `default: optional map[unknown]` Properties keyed by property slug. - `list: optional unknown` ### Identity Upsert Response - `IdentityUpsertResponse object { id, default, list }` Object returned by reads (get/create/patch/restore). id is always present. - `id: string` - `default: optional map[unknown]` Properties keyed by property slug. - `list: optional unknown` ### Identity Bulk Create Response - `IdentityBulkCreateResponse object { job_id, status, total, 8 more }` Status snapshot of an import job. Same shape used by the POST /import response and by GET /imports/{jobId}. - `job_id: string` Null for sync imports (results inlined). Set for async imports. - `status: "complete" or "processing" or "failed"` - `"complete"` - `"processing"` - `"failed"` - `total: number` Total number of rows in the import. - `created_at: optional string` - `error: optional object { code, message }` Set when status=failed; describes the job-level failure (not per-row). - `code: optional string` - `message: optional string` - `expires_at: optional string` - `failed: optional number` - `processed: optional number` Rows that have been attempted (succeeded + failed). - `results: optional array of object { id, created, error, 3 more }` Per-row outcomes. Always present for sync imports; populated for async imports once the job reaches `complete`. - `id: optional string` - `created: optional boolean` - `error: optional object { code, message }` - `code: optional string` - `message: optional string` - `existing: optional boolean` True if the row matched an existing record via the dedupe key. - `input_index: optional number` Zero-based position of this row in the request. - `updated: optional boolean` True if a matching record was updated. - `succeeded: optional number` - `updated_at: optional string` ### Identity Bulk Update Response - `IdentityBulkUpdateResponse object { results, summary }` Partial-success bulk operation result. Inspect `results[].status` per item; the operation as a whole returns 200 even if some items failed. - `results: array of object { id, status, error, record }` - `id: string` Item ID, or null if the input was unparseable. - `status: "ok" or "error"` - `"ok"` - `"error"` - `error: optional object { code, message }` - `code: optional string` - `message: optional string` - `record: optional object { id, default, list }` Object returned by reads (get/create/patch/restore). id is always present. - `id: string` - `default: optional map[unknown]` Properties keyed by property slug. - `list: optional unknown` - `summary: object { failed, succeeded, total }` - `failed: number` - `succeeded: number` - `total: number` ### Identity Bulk Delete Response - `IdentityBulkDeleteResponse object { results, summary }` Partial-success bulk operation result. Inspect `results[].status` per item; the operation as a whole returns 200 even if some items failed. - `results: array of object { id, status, error, record }` - `id: string` Item ID, or null if the input was unparseable. - `status: "ok" or "error"` - `"ok"` - `"error"` - `error: optional object { code, message }` - `code: optional string` - `message: optional string` - `record: optional object { id, default, list }` Object returned by reads (get/create/patch/restore). id is always present. - `id: string` - `default: optional map[unknown]` Properties keyed by property slug. - `list: optional unknown` - `summary: object { failed, succeeded, total }` - `failed: number` - `succeeded: number` - `total: number` ### Identity Duplicate Response - `IdentityDuplicateResponse object { id, default, list }` Object returned by reads (get/create/patch/restore). id is always present. - `id: string` - `default: optional map[unknown]` Properties keyed by property slug. - `list: optional unknown` ### Identity Restore Response - `IdentityRestoreResponse object { id, default, list }` Object returned by reads (get/create/patch/restore). id is always present. - `id: string` - `default: optional map[unknown]` Properties keyed by property slug. - `list: optional unknown`