Consumers
List and look up consumers who have interacted with your Chipp app
Consumers are the people who interact with your Chipp app. Each consumer has a unique ID and may have an email, name, or other identifying information depending on how they authenticated.
Sensitive authentication fields (password hashes, tokens) are never exposed through the Builder API.
List Consumers
GET /api/v1/apps/{appId}/consumersReturns a paginated list of consumers. Uses offset-based pagination.
Query Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
limit | integer | 25 | Results per page (1-100) |
offset | integer | 0 | Number of results to skip |
search | string | — | Search by name, email, or identifier |
has_email | string | — | Filter by email presence: "true" or "false" |
created_after | ISO 8601 | — | Consumers created after this date |
created_before | ISO 8601 | — | Consumers created before this date |
Example
curl "https://build.chipp.ai/api/v1/apps/YOUR_APP_ID/consumers?limit=20&has_email=true" \
-H "Authorization: Bearer chipp_YOUR_API_KEY"Response
{
"data": [
{
"id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
"identifier": "jane@example.com",
"email": "jane@example.com",
"name": "Jane Smith",
"picture_url": null,
"email_verified": true,
"credits": 100,
"subscription_active": false,
"mode": "default",
"is_anonymous": false,
"created_at": "2025-05-20T10:00:00Z",
"updated_at": "2025-06-15T10:00:00Z"
},
{
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"identifier": "anon_x7k2m",
"email": null,
"name": null,
"picture_url": null,
"email_verified": false,
"credits": 0,
"subscription_active": false,
"mode": "default",
"is_anonymous": true,
"created_at": "2025-06-10T15:30:00Z",
"updated_at": "2025-06-10T15:30:00Z"
}
],
"pagination": {
"has_more": true,
"total": 142,
"limit": 20,
"offset": 0
}
}Response Fields
| Field | Type | Description |
|---|---|---|
id | UUID | Unique consumer identifier |
identifier | string | Human-readable identifier (email or generated ID) |
email | string or null | Consumer’s email address, if provided |
name | string or null | Consumer’s display name, if provided |
picture_url | string or null | URL to the consumer’s profile picture |
email_verified | boolean | Whether the consumer’s email has been verified |
credits | integer | Consumer’s current credit balance |
subscription_active | boolean | Whether the consumer has an active subscription |
mode | string | Consumer’s current mode |
is_anonymous | boolean | Whether the consumer is anonymous |
created_at | ISO 8601 | When the consumer was first seen |
updated_at | ISO 8601 | When the consumer was last updated |
Paginating with Offset
# Page 1
curl "https://build.chipp.ai/api/v1/apps/YOUR_APP_ID/consumers?limit=25&offset=0" \
-H "Authorization: Bearer chipp_YOUR_API_KEY"
# Page 2
curl "https://build.chipp.ai/api/v1/apps/YOUR_APP_ID/consumers?limit=25&offset=25" \
-H "Authorization: Bearer chipp_YOUR_API_KEY"Filtering for Leads (Consumers with Email)
A common use case is syncing identified consumers to your CRM:
curl "https://build.chipp.ai/api/v1/apps/YOUR_APP_ID/consumers?has_email=true&created_after=2025-06-01T00:00:00Z" \
-H "Authorization: Bearer chipp_YOUR_API_KEY"Get Consumer
GET /api/v1/apps/{appId}/consumers/{consumerId}Returns a single consumer by ID.
Example
curl "https://build.chipp.ai/api/v1/apps/YOUR_APP_ID/consumers/7c9e6679-7425-40de-944b-e07fc1f90ae7" \
-H "Authorization: Bearer chipp_YOUR_API_KEY"Response
{
"data": {
"id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
"identifier": "jane@example.com",
"email": "jane@example.com",
"name": "Jane Smith",
"picture_url": null,
"email_verified": true,
"credits": 100,
"subscription_active": false,
"mode": "default",
"is_anonymous": false,
"created_at": "2025-05-20T10:00:00Z",
"updated_at": "2025-06-15T10:00:00Z",
"session_count": 8
}
}The single-consumer response includes all fields from the list response, plus session_count (integer) — the total number of chat sessions for this consumer.
Error: Consumer Not Found (404)
{
"error": {
"code": "not_found",
"message": "Consumer not found"
}
}Authenticate a Consumer (Server-Side)
POST /api/v1/apps/{appId}/consumers/authMint a Bearer token for a signed-in user. Call this from your backend to bridge your own auth (WorkOS, Auth0, Clerk, Okta, custom SSO) into a Chipp app — the returned token authenticates the user inside the chat iframe without requiring them to sign in again.
Optionally inject per-user metadata (territory, project, role, named colleagues, internal IDs) that the agent’s system prompt automatically references on every session. No webhook, no template syntax, no builder config required.
Requires a Builder API key with write scope on the consumers resource. Ask the Alchemist to mint one (“Create a Builder API key for this app called ‘My integration’.”) — Alchemist-minted keys default to write on both sessions and consumers. To script the setup with a builder session cookie, see Requesting Write Scopes.
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
email | string | yes | User’s email address. Lower-cased and trimmed before lookup. |
name | string | no | Display name. Max 255 chars. Updates the stored name on every call. |
metadata | object | no | Per-user context. Bounds and schema below. |
Example
curl -X POST https://build.chipp.ai/api/v1/apps/YOUR_APP_ID/consumers/auth \
-H "Authorization: Bearer chipp_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"email": "jane@example.com",
"name": "Jane Doe",
"metadata": {
"territory": "Northeast",
"projectId": "PRJ-4821",
"role": "Account Executive",
"managerName": "Sam Reynolds",
"vipFlag": true
}
}'Response
{
"data": {
"token": "eyJhbGciOi...",
"consumer": {
"id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
"email": "jane@example.com",
"name": "Jane Doe",
"identifier": "jane@example.com",
"credits": 0,
"picture_url": null
},
"expires_at": "2025-07-15T10:00:00Z"
}
}Pass data.token to the widget via ChippWidget.setUser({ token }). See the embed widget guide for the full flow.
Metadata Schema
The metadata field accepts arbitrary key/value pairs that surface verbatim under an ## About this user block at the end of the system prompt. The builder does not need to pre-configure fields.
Limits
- Up to 20 keys per request.
- Keys must match
^[a-zA-Z][a-zA-Z0-9_]*$, max 64 chars. EithercamelCaseorsnake_caseworks — the renderer humanizes both (projectId→ “Project id”,project_name→ “Project name”). - Values:
string(max 2000 chars),number(finite),boolean, ornull. - Total request body capped at 10 KB.
- Reserved keys are rejected:
- Top-level columns:
email,name,id,password,identifier,credits,isAnonymous,profile - Dossier fields the LLM manages:
timezone,language,preferences,context,notes
- Top-level columns:
Merge semantics
metadata is upserted per key, not replaced wholesale. Call /consumers/auth on every page load with whatever your backend currently knows — keys you don’t send are preserved from previous calls.
# First call: set territory + projectId
curl -X POST .../consumers/auth -d '{
"email": "jane@example.com",
"metadata": {"territory": "Northeast", "projectId": "PRJ-4821"}
}'
# Second call (later): update projectId only -- territory stays "Northeast"
curl -X POST .../consumers/auth -d '{
"email": "jane@example.com",
"metadata": {"projectId": "PRJ-9000"}
}'
# Third call: explicitly delete projectId by passing null
curl -X POST .../consumers/auth -d '{
"email": "jane@example.com",
"metadata": {"projectId": null}
}'Rendering
The values appear in the system prompt before the user’s first message:
## About this user
- Name: Jane Doe
- Territory: Northeast
- Project id: PRJ-9000
- Role: Account Executive
- Manager name: Sam Reynolds
- Vip flag: true- Missing keys never error and never render an empty line — the row is simply omitted.
- A key that collides with a
customFields(Collection Form) key only renders once, from the form value. - Builder-configured
customFieldsand server-injectedmetadatacoexist: the form is for things you ask the user, metadata is for things your backend already knows.
Errors
| Status | Code | When |
|---|---|---|
| 400 | auth_failed | Database error or other internal failure. The error message contains details. |
| 400 | (validation) | Invalid email, oversized metadata, reserved key, value out of bounds. The error field contains a human-readable message. |
| 403 | insufficient_scope | Builder API key missing consumers:write scope. |