POST a message and read the reply back, either by polling the items list or
by holding an event stream open. There is no SDK you must use and no media stack
to install; curl is enough.
That also makes text the cheapest surface to build on. The prompt, the tools, the
knowledge bases and the handoffs behave the same here as they do on a call, so a
text agent is the quickest way to get a script working before you put a voice
in front of it.
The three things you are handling
A thread has many items and, over time, several sessions: the agent stays warm
for a minute after each reply and then closes, so a conversation that runs all
afternoon is a series of sessions on one thread. See the window
lifecycle below.
Which conversation a message opens follows the answering agent’s
conversation.context. A text agent is always transcript — the setting is
forced when you save, and summary is refused outright, because the analysis
pass that writes those summaries is voice and video only. So the same
contact_key always reaches the same thread, and the agent always has the whole
history. See conversation memory.
contact_key
contact_key is your own stable id for the person: a user id, an account
number, a session id if that is all you have. It is what makes the same key reach
the same thread, and the only way to list somebody’s whole history back.
- Unique in the workspace, 1–256 characters.
- Must not start with a reserved prefix:
telegram:,sip:,agent_copilot:,tool_copilot:,knowledge_copilot:ortask_copilot:. Those name threads the platform builds itself, and the check is case-insensitive.
Opening a conversation
POST /v1/conversations binds a contact_key to an agent. It sends nothing and
starts nothing.
string
required
Your own id for the person. See the rules above.
uuid
The published text agent that answers.
agent, agent_version,
agent_override and agent_team are accepted here too, exactly as they are on
a call — see per-call configuration. A
resolved agent whose channel is not text is refused with this endpoint runs text agents; '<name>' resolves to a voice agent - place a voice or video call with POST /v1/calls/token instead.object
What the agent already knows about the person, read as
{{userdata.field}} from
the prompt and every tool. It is merged onto the contact’s record, so it
survives into their next thread and a tool may overwrite it mid-conversation.
See userdata.object
Values for the
{{vars.*}} the agents on this thread declare. Fixed for the
thread’s whole life — whatever turn 1 was opened with is what turn 40 reads —
and never written onto anybody’s record. Strings only. See
variables.Re-posting to
POST /v1/conversations with a key you already have does not reset
the thread’s vars; it replaces that bag whole. Posting a message never
touches it — POST /v1/conversations/messages takes no vars at all. If a value
has to change per turn, it is userdata, not a variable.Sending a turn
POST /v1/conversations/messages is addressed by contact_key, not by
conversation id.
string
required
Which thread. A key with no conversation is a
404, so opening one is not
optional.uuid
required
A UUID you generate. Re-sending with the same one returns the existing item
rather than posting a second copy, which is what makes a retry after a timeout
safe.
string
Up to 100,000 characters. May be empty only when
images is not — a request
with neither is refused with a message must carry text, an image, or both.202 and carries only your own item. The agent has not
answered yet and will not answer inside this request. Two ways to get the reply:
Reading the reply
Poll the items
GET /v1/conversations/{conversation_id}/items?order=desc returns the newest
window, chronological within the page. Give it a few seconds.
Expect several items rather than one when the agent calls tools: a
function_call and a function_call_output land beside the message. Every item
the agent produced carries trigger_item_id pointing back at the message that
caused it, which is how you pick out the answer to this turn.
Or hold the stream open
GET /v1/conversations/{conversation_id}/events is a server-sent event stream
that pushes the reply token by token. Open it before you send, or you miss
that turn’s frames.
Every frame
Each frame repeats its own name in anevent field, so a client narrows the
union with a plain switch rather than pairing each frame with its name by hand.
turn.status is one of running, done, error or canceled.
Two rules that decide whether your client is correct:
assistant.deltaframes append. They are not cumulative. Concatenate them; do not replace.assistant.completed.textis every delta joined, which is there precisely so a client that missed some can replace what it accumulated instead of trying to reconcile it. Prefer it when it is present.
GET /v1/conversations/{conversation_id}/items, which is the record.
In React
Items
Every row in a conversation is an item, and there are five kinds.
Three fields say what to do with an item:
On a thread you drive over the API, outbound messages are
not_applicable — there is no provider to deliver to; you read them from the
items list or the stream. pending → sending → sent is what a
Telegram thread shows. skipped is a trigger whose
reply_mode told the platform not to send.trigger_item_id (which inbound message caused this),
session_id, agent_id and agent_version (so a thread that handed off reads
correctly line by line), attachments, and per-turn metrics. The full field
reference is on conversations.
Images
Attach up to four images per message, as base64data: URLs beside the text:
attachments, each with a URL signed per
request and an url_expires_at; the stream carries the signed URLs too, so a
browser can render the photo it just sent without a reload.
Sending an image to an agent whose model cannot read one is refused with a 409
naming the model — <provider>/<model> cannot read images — pick a model that can — before anything is decoded or uploaded. Formats, sizes and the
per-conversation ceiling are on vision and
images.
If you are building the sender in a browser, @talqing/sdk/browser exports
talqingImageDataUrl(file), which validates, downscales and encodes a File into
exactly the data_url above.
The window lifecycle
The agent does not start and stop per message. The first message of a thread cold starts a session — compiling the agent, connecting its MCP servers, loading its knowledge — and that session then stays warm and is reused by every message that follows. Cold start is why the first reply of a quiet thread is slower than the rest. The idle timeout is 60 seconds. With nothing pending for a minute, the session finalizes withclose_reason: "idle_timeout", its usage is sealed and its cost is
priced. The next message opens a new session on the same thread — and a text agent
carries the whole transcript, so nothing is forgotten.
The first four are normal endings and the session’s status is
completed. Only
orphaned is a failure — the session is marked failed, and its usage is
whatever had been recorded when the worker died. None of the five loses the
thread: the conversation and every item on it are untouched, and the next
message picks up where the last one left off.
Jobs are latest-wins. Send a second message while the agent is still working
on the first and the in-flight turn is superseded: the turn frame reports
status: "canceled" with superseded_by_item_id naming the message that
displaced it, and the agent answers the newer message. That is what makes a chat
box where someone corrects themselves mid-sentence behave the way they expect.
A handoff keeps the window warm. Unlike a cold restart, the session stays open
and runs the new compiled agent from the next turn; the move is recorded as an
internal agent_handoff item. See handoffs.
What it costs
Text carries no platform fee. A text conversation costs your workspace only what your own language-model key was charged for the tokens — Talqing bills per-minute only on voice and video. See pricing and credits. Per-session usage and cost are onGET /v1/conversations/{conversation_id}/sessions; cost is null until billing
has run.
Next
Telegram
Put the same published text agent in front of a Telegram bot.
Conversations
Reading threads back: sessions, versions, and a person’s whole history.
Conversation memory
What an agent carries from one conversation to the next.