Capture
Send conversations to ConvoMem for memory extraction.
Overview
Capture is the primary way to send data to ConvoMem. It accepts single messages or full conversations and returns a capture ID for async processing.
The endpoint resolves customer identity, finds or creates an active conversation session, enqueues the message for memory extraction, and returns the session context. No explicit start/end lifecycle calls are required.
Memory extraction happens asynchronously. The response confirms the message was received and routed, but extracted memories may take a few seconds to appear in lookups.
Single message
Send a single user message. ConvoMem will associate it with the customer and channel you specify.
const result = await client.capture(
[{ role: 'user', content: 'I need help with my order' }],
{ email: '[email protected]' },
{ channel: 'CHAT' },
)Batch messages
Send a full conversation with multiple turns. This is useful when you want to capture both the user's message and the assistant's response in a single call.
const result = await client.capture(
[
{ role: 'user', content: 'What is my current plan?' },
{ role: 'assistant', content: 'You are on the Pro plan at $49/mo.' },
],
{ email: '[email protected]' },
{ channel: 'VOICE' },
)Request body
| Field | Type | Required | Description |
|---|---|---|---|
message | string | One of message or messages required | Single user message (max 10,000 chars) |
messages | array | One of message or messages required | Up to 200 conversation turns with role and content |
customerId | uuid | At least one identity field required | Customer UUID |
externalId | string | At least one identity field required | External system identifier |
email | string | At least one identity field required | Customer email address |
phoneNumber | string | At least one identity field required | Customer phone number |
socialHandles | array | At least one identity field required | Social handles as strings ("@jane") or { "value": "@jane", "platform": "twitter" } objects |
userName | string | No | Customer display name (backfills placeholder names) |
channel | enum | No (default: CHAT) | VOICE, CHAT, SMS, or EMAIL |
idempotencyKey | string | No | Idempotency key (max 128 chars) |
language | string | No | BCP-47 fallback for turns without a language hint |
occurredAt | ISO 8601 | No | Source time for a historical conversation; omit for live capture |
infer | boolean | No (default: true) | Set false for raw, non-system turn capture without LLM extraction |
endConversation | boolean | No | Persist these turns, then complete the conversation and enqueue analysis |
outcome | string | No | Outcome stored when endConversation is true |
escalate | boolean | No | Persist these turns, then escalate; mutually exclusive with endConversation |
reason | string | No | Escalation reason when escalate is true |
speakerId | string | No | External human-agent ID when attribution is enabled |
speakerName | string | No | Human-agent display name used with speakerId |
Each message in the messages array has:
| Field | Type | Required | Description |
|---|---|---|---|
role | enum | Yes | user, assistant, agent, or system |
content | string | Yes | The message text (max 10,000 chars) |
language | string | No | BCP-47 source-language hint for this turn |
Response
| Field | Type | Description |
|---|---|---|
conversationId | uuid | The conversation session ID (reused across calls while session is active) |
customerId | uuid | The resolved or newly created customer ID |
captureId | uuid | Pollable extraction job ID |
captureStatus | string | Initial status: queued |
status | enum | new if a new conversation was started, active if appended to an existing session |
isNewConversation | boolean | true when this call started a new conversation session |
isNewCustomer | boolean | true when the customer was created by this call |
Pass an idempotencyKey to safely retry captures without double-recording turns. If the
same key is replayed within 24 hours, the original result is returned from cache
instead of re-processing. Use a stable key per turn — e.g.
turn-${conversationId}-${turnIndex}.
If a request with that key is still in flight, you get 409 IDEMPOTENCY_IN_PROGRESS.
Wait 1–2 seconds and retry with the same key. Reusing a key with a different payload
returns 409 IDEMPOTENCY_KEY_REUSED.
Poll capture status
Use the returned captureId when your workflow must wait for memories before the next
step. A capture moves through queued, processing, and completed; a terminal error is
reported as failed with a stable public error message.
curl -H "X-API-Key: $CONVOMEM_API_KEY" \
"https://api.convomem.com/api/v1/capture/$CAPTURE_ID"const status = await client.getCaptureStatus(result.captureId)Do not close a conversation in a second request immediately after capture. When the last
turn is already known, send endConversation: true or escalate: true on the capture so
ConvoMem preserves the ordering: transcript, memories, conversation state, then analysis.
Identity resolution
ConvoMem resolves customers from whichever identity field you provide. You only need to supply one:
- customerId — Direct lookup by ConvoMem UUID. Fastest and most reliable.
- externalId — Your system's identifier for the customer. ConvoMem maps it to an internal customer record.
- email — Matches by email address. Creates a new customer if no match is found.
- phoneNumber — Matches by phone number. Creates a new customer if no match is found.
- socialHandles — Matches by social handle. A leading
@and letter case are ignored, and aplatformkeeps the same handle on different networks apart.
When multiple fields are provided, ConvoMem resolves in the order listed above. If the customer does not exist, a new profile is created automatically.
Use the same identity field across all captures for a given customer. Mixing email and
externalId for the same person can create duplicate profiles.
Channel types
| Channel | Use case |
|---|---|
VOICE | Phone calls, voice agents |
CHAT | Web chat, in-app messaging (default) |
SMS | Text message conversations |
EMAIL | Email thread capture |
The channel is used for analytics and to group conversations. It does not affect how messages are processed.
Rate limit
Capture scales with your plan — from 100/min on Trial up to 2,000/min on Scale, and unlimited on Custom. Each agent gets that budget independently, so a busy support agent never eats into what your sales agent has left.
Each call enqueues background AI work. Send the new turns since the prior capture in
chronological order. ConvoMem preserves legitimate repeated utterances; use a stable
idempotencyKey to identify network retries instead of deduplicating message text in your
integration.
See Errors & limits for the per-plan table and retry guidance.
What's next
- Memories — browse, add, and manage extracted memories
- Conversations — explicitly manage session lifecycle
- Webhooks — react to
memory.capturedafter extraction completes - AI agents — fire-and-forget patterns and tool definitions
SDK: TypeScript · Python · Rust