Builder API

Sessions

List chat sessions and retrieve messages from your Chipp app

| View as Markdown
1 min read
# api # builder-api # rest # sessions # messages # chat-logs # transcripts

Sessions represent individual chat conversations with your app. Each session contains messages exchanged between a consumer and your AI.

List Sessions

plaintext
GET /api/v1/apps/{appId}/sessions

Returns a paginated list of chat sessions, newest first.

Query Parameters

ParameterTypeDefaultDescription
limitinteger25Results per page (1-100)
cursorstringPagination cursor from previous response
sourcestringFilter by channel
consumer_idUUIDFilter by consumer
started_afterISO 8601Sessions started after this date
started_beforeISO 8601Sessions started before this date
searchstringCase-insensitive substring search on session titles (max 200 chars)

Source values: APP, API, WHATSAPP, SLACK, EMAIL, VOICE, WIDGET, ACP

Example

bash
curl "https://build.chipp.ai/api/v1/apps/YOUR_APP_ID/sessions?limit=10&source=APP" \
  -H "Authorization: Bearer chipp_YOUR_API_KEY"

Response

json
{
  "data": [
    {
      "id": "550e8400-e29b-41d4-a716-446655440000",
      "consumer_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
      "consumer": {
        "email": "jane@example.com",
        "name": "Jane Smith"
      },
      "title": "Help with onboarding",
      "source": "APP",
      "mode": "default",
      "is_bookmarked": false,
      "is_multiplayer": false,
      "external_id": "patient-abc123",
      "query_params": [
        { "name": "rp_token", "value": "abc123" },
        { "name": "ab_variant", "value": "B" }
      ],
      "message_count": 12,
      "started_at": "2025-06-15T14:30:00Z",
      "ended_at": "2025-06-15T14:45:00Z",
      "last_activity_at": "2025-06-15T14:45:00Z"
    }
  ],
  "pagination": {
    "has_more": true,
    "next_cursor": "eyJpZCI6IjU1MGU4NDAw...",
    "limit": 10
  }
}

Response Fields

FieldTypeDescription
idUUIDSession identifier
consumer_idUUID or nullConsumer who opened this session
consumerobject or null{ email, name } for the consumer
titlestring or nullSession title (auto-generated or set by the builder)
sourcestringChannel: APP, WHATSAPP, SLACK, EMAIL, VOICE, WIDGET, API, etc.
modestringCurrent session mode: ai, human, or hybrid
is_bookmarkedbooleanWhether the session is bookmarked in the Conversations tab
is_multiplayerbooleanWhether this is a group chat session
external_idstring or nullThe value passed via ?chipp_external_id= in the share URL (for web sessions), or the channel-namespaced key for channel sessions (e.g. whatsapp:+15551234567). Null when not set. Use this for deterministic attribution without model involvement.
query_paramsarrayURL query parameters captured when the consumer opened the session, as [{ name, value }] objects. Empty array when none were present. Excludes Chipp control params (bt, session, share). Use for A/B variant, referral token, and campaign attribution.
message_countintegerTotal messages in this session
started_atISO 8601When the session was created
ended_atISO 8601 or nullWhen the session ended, if known
last_activity_atISO 8601 or nullTimestamp of last message or activity

Filtering by Date Range

bash
curl "https://build.chipp.ai/api/v1/apps/YOUR_APP_ID/sessions?started_after=2025-06-01T00:00:00Z&started_before=2025-06-30T23:59:59Z" \
  -H "Authorization: Bearer chipp_YOUR_API_KEY"

Filtering by Consumer

bash
curl "https://build.chipp.ai/api/v1/apps/YOUR_APP_ID/sessions?consumer_id=7c9e6679-7425-40de-944b-e07fc1f90ae7" \
  -H "Authorization: Bearer chipp_YOUR_API_KEY"

Get Session

plaintext
GET /api/v1/apps/{appId}/sessions/{sessionId}

Returns a single session by ID.

Example

bash
curl "https://build.chipp.ai/api/v1/apps/YOUR_APP_ID/sessions/550e8400-e29b-41d4-a716-446655440000" \
  -H "Authorization: Bearer chipp_YOUR_API_KEY"

Response

json
{
  "data": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "consumer_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
    "consumer": {
      "email": "jane@example.com",
      "name": "Jane Smith"
    },
    "title": "Help with onboarding",
    "source": "APP",
    "mode": "default",
    "is_bookmarked": false,
    "is_multiplayer": false,
    "external_id": "patient-abc123",
    "query_params": [
      { "name": "rp_token", "value": "abc123" },
      { "name": "ab_variant", "value": "B" }
    ],
    "message_count": 12,
    "started_at": "2025-06-15T14:30:00Z",
    "ended_at": "2025-06-15T14:45:00Z",
    "last_activity_at": "2025-06-15T14:45:00Z"
  }
}

Error: Session Not Found (404)

json
{
  "error": {
    "code": "not_found",
    "message": "Session not found"
  }
}

List Session Messages

plaintext
GET /api/v1/apps/{appId}/sessions/{sessionId}/messages

Returns the messages in a session, ordered chronologically.

Query Parameters

ParameterTypeDefaultDescription
limitinteger25Results per page (1-100)
cursorstringPagination cursor from previous response
rolestringFilter by role: user, assistant, system, or tool
created_afterISO 8601Messages created after this date
created_beforeISO 8601Messages created before this date
includestringComma-separated list of extra fields to include

Include values:

  • tool_details — Adds tool_calls and tool_results fields to each message. These are arrays when the message invoked tools, or null when it did not

Example

bash
curl "https://build.chipp.ai/api/v1/apps/YOUR_APP_ID/sessions/550e8400-e29b-41d4-a716-446655440000/messages?limit=50" \
  -H "Authorization: Bearer chipp_YOUR_API_KEY"

Response

json
{
  "data": [
    {
      "id": "msg-001",
      "session_id": "550e8400-e29b-41d4-a716-446655440000",
      "role": "user",
      "content": "How do I get started with your platform?",
      "model": null,
      "token_count": 42,
      "latency_ms": null,
      "audio_url": null,
      "audio_duration_ms": null,
      "tags": [],
      "feedback": null,
      "created_at": "2025-06-15T14:30:00Z"
    },
    {
      "id": "msg-002",
      "session_id": "550e8400-e29b-41d4-a716-446655440000",
      "role": "assistant",
      "content": "Welcome! Here's how to get started...",
      "model": "gpt-4.1",
      "token_count": 150,
      "latency_ms": 1200,
      "audio_url": null,
      "audio_duration_ms": null,
      "tags": [{ "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "name": "onboarding", "color": "#3b82f6" }],
      "feedback": null,
      "created_at": "2025-06-15T14:30:05Z"
    }
  ],
  "pagination": {
    "has_more": false,
    "next_cursor": null,
    "limit": 50
  }
}

Response Fields

FieldTypeDescription
idstringUnique message identifier
session_idUUIDThe session this message belongs to
rolestringuser, assistant, system, or tool
contentstringMessage text content
modelstring or nullLLM model used (null for user messages)
token_countinteger or nullToken count for this message
latency_msinteger or nullResponse latency in milliseconds
audio_urlstring or nullURL to audio recording, if applicable
audio_duration_msinteger or nullAudio duration in milliseconds
tagsarray of objectsTags applied to this message. Each object has id (UUID), name (string), and color (hex string)
feedbackobject or nullFeedback on this message, if any
created_atISO 8601When the message was created

With Tool Details

bash
curl "https://build.chipp.ai/api/v1/apps/YOUR_APP_ID/sessions/SESSION_ID/messages?include=tool_details" \
  -H "Authorization: Bearer chipp_YOUR_API_KEY"
json
{
  "data": [
    {
      "id": "msg-003",
      "session_id": "550e8400-e29b-41d4-a716-446655440000",
      "role": "assistant",
      "content": "Let me look that up for you.",
      "model": "gpt-4.1",
      "token_count": 180,
      "latency_ms": 2400,
      "audio_url": null,
      "audio_duration_ms": null,
      "tags": [],
      "feedback": null,
      "created_at": "2025-06-15T14:31:00Z",
      "tool_calls": [
        {
          "tool_name": "search_knowledge",
          "status": "completed"
        }
      ],
      "tool_results": [
        {
          "tool_name": "search_knowledge",
          "result": "..."
        }
      ]
    }
  ],
  "pagination": {
    "has_more": false,
    "next_cursor": null,
    "limit": 25
  }
}

Filtering by Role

To retrieve only user messages (useful for extracting questions/feedback):

bash
curl "https://build.chipp.ai/api/v1/apps/YOUR_APP_ID/sessions/SESSION_ID/messages?role=user" \
  -H "Authorization: Bearer chipp_YOUR_API_KEY"

Log a Conversation

plaintext
POST /api/v1/apps/{appId}/conversations/log

Push a chat turn into the Conversations tab from an external pipeline (n8n, Zapier, Make.com, or a custom backend that handles the AI loop itself). The endpoint creates the session and consumer on first call, and reuses them by session_id or external_id on subsequent calls.

Requires sessions:write scope. The default key minted by the Alchemist already includes this; if you minted a key via the management endpoint, see the overview for how to request sessions:write explicitly.

Request Body

FieldTypeRequiredDescription
messagesarrayyes1–50 turns. Each item: role (user or assistant), content (1–100,000 chars), optional model (string, ≤255 chars).
session_idUUIDnoContinue an existing session. Server validates the session belongs to this app.
external_idstringnoStable identifier to dedupe sessions across calls. First call creates a session bound to this id; subsequent calls with the same external_id append to it.
channelstringnoOne of api (default), custom, whatsapp, sms, imessage, telegram, discord, teams, slack, email. Drives the badge in the Conversations tab and the consumer resolution (named channels prefix the identifier with the channel name; api / custom resolve to an anonymous-style consumer).
consumerobjectno{ channel_user_id?, email?, name? }. For named channels, channel_user_id is the platform identifier (phone number for WhatsApp/SMS, Slack user id, etc.). For api/custom, omit and a fresh anonymous consumer is created per external_id.
titlestringnoSession title (1–255 chars). Only applied when creating a new session.
notify_subscribersbooleannoDefault true. When false, suppresses the per-app chat notification email for this turn.
detect_tagsbooleannoDefault true. When false, skips tag detection for this turn. Always skipped for ZDR (Zero Data Retention) apps regardless of this flag.
client_request_idstringnoIdempotency key. Repeating the call with the same client_request_id within 10 minutes returns the cached result without re-inserting messages. Use this from n8n / Zapier where retries on transient failures are automatic.

Example: WhatsApp Bridge

bash
curl -X POST "https://build.chipp.ai/api/v1/apps/YOUR_APP_ID/conversations/log" \
  -H "Authorization: Bearer chipp_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "channel": "whatsapp",
    "external_id": "wa-thread-+15551234567",
    "consumer": {
      "channel_user_id": "+15551234567",
      "name": "Jane Smith"
    },
    "messages": [
      { "role": "user", "content": "Hi, what are your hours?" },
      { "role": "assistant", "content": "We are open 9-5 EST.", "model": "gpt-4.1" }
    ],
    "client_request_id": "n8n-execution-abc123"
  }'

Example: Continuing a Session

bash
curl -X POST "https://build.chipp.ai/api/v1/apps/YOUR_APP_ID/conversations/log" \
  -H "Authorization: Bearer chipp_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "session_id": "550e8400-e29b-41d4-a716-446655440000",
    "messages": [
      { "role": "user", "content": "Can you also tell me your address?" },
      { "role": "assistant", "content": "We are at 123 Main St.", "model": "gpt-4.1" }
    ]
  }'

Response (200)

json
{
  "data": {
    "session_id": "550e8400-e29b-41d4-a716-446655440000",
    "consumer_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
    "source": "WHATSAPP",
    "is_new_session": true,
    "messages": [
      {
        "id": "msg-001",
        "role": "user",
        "created_at": "2025-06-15T14:30:00Z"
      },
      {
        "id": "msg-002",
        "role": "assistant",
        "created_at": "2025-06-15T14:30:01Z"
      }
    ]
  }
}

Errors

StatusCodeWhen
400validation_errorBody fails validation (missing required field, oversized message, unknown channel).
403insufficient_scopeAPI key lacks sessions:write.
403forbiddensession_id belongs to a different app.
404not_foundsession_id references a deleted session or doesn’t exist.
503Transient database issue. Safe to retry (the Cloudflare Worker retries automatically up to 4 times).

Idempotency Guarantee

When client_request_id is provided, the endpoint caches the response for 10 minutes. Replaying the same client_request_id returns the cached session_id + messages array WITHOUT creating duplicate rows. This makes the endpoint safe for at-least-once delivery semantics (n8n / Zapier retries, Make.com retry policies, your own backoff loop).

Encrypted / ZDR Apps

For apps with org-level Zero Data Retention enabled, messages go to ephemeral Redis storage (4-hour TTL) instead of the database. Tag detection is automatically skipped. The session still appears in the Conversations tab while messages are in the TTL window.


Conversation Export and Attribution

Self-attributing transcripts

Every session in the Builder API carries two attribution fields that let you tie a transcript back to the referral token, A/B arm, or patient identifier that the consumer arrived with — with zero custom plumbing.

FieldWhat it holds
external_idThe value passed via ?chipp_external_id= in the share URL (or a channel-namespaced key like whatsapp:+15551234567 for channel sessions). null when not set.
query_paramsEvery other URL query param captured at session creation, as [{ name, value }]. Excludes Chipp control params (bt, session, share). Empty array when none were present.

Example: A link like https://app.chipp.ai/chat/my-app?rp_token=abc123&ab_variant=B produces:

json
{
  "external_id": null,
  "query_params": [
    { "name": "rp_token",    "value": "abc123" },
    { "name": "ab_variant",  "value": "B" }
  ]
}

Because these fields are set at session creation and never change, you can join query_params to your patient/user records offline without a real-time side-channel. The rp_token in the transcript IS the attribution token — no session_id -> rp_token mapping table required.

Detecting completion with tool markers

When you fetch messages with ?include=tool_details, each message gains a tools array. For the org-wide export API (see below) this array contains compact markers that summarize tool and component invocations without the heavy code blobs. Detect that a consumer reached the natural wrap-up screen:

javascript
const completed = messages.some(
  m => m.tools?.some(t => t.name === "render_completion_screen")
);

Each marker shape: { id?, name?, type?, component?, success? }.

Scripted / cron pull (org-wide API)

The Builder API (chipp_ keys) covers a single app. For pulling data across all apps on a schedule, use the org-wide export API (chipp_org_* keys) — it exposes the same external_id, query_params, and tools fields over HTTP and is designed for warehouse sync and cron jobs.

See the Org Export API guide for authentication, endpoint reference, and a Snowflake sync recipe.