This quickstart is code only — no dashboard. One script creates a text agent, publishes it, opens a conversation, sends a message and prints the reply. It runs in about a minute. A text agent needs only a language-model key. No speech-to-text, no text-to-speech, and no platform fee: a text conversation costs your workspace only what your own LLM key was charged.

Before you start

1

Get a personal access token

In the dashboard, go to Organization → API Tokens and create one. The full value is shown once. Export it as TALQING_API_KEY.
2

Add one LLM provider key

On the BYOK page, add a key for the provider whose model you are about to use — OpenAI in this example. Talqing holds no provider keys of its own, so publishing an agent whose provider has no key is refused with no OpenAI API key for this workspace - add one under BYOK. See provider keys.
3

Pick a region

https://api.in.talqing.com (India) or https://api.us.talqing.com (United States). The agent you create belongs to that region. Your token works against both. See regions.

The whole script

What each call does

1

Create the agent

POST /v1/agents takes the whole config. Only name is required; channel: "text" is what removes the speech slots. gpt-5.6-luna is a cheap, fast general model — see the full catalog before picking another, because a provider or model that is not in it is refused.
cURL
2

Publish it

POST /v1/agents/{agent_id}/publish freezes the draft as version 1. Opening a conversation against an unpublished agent is refused with publish 'Northwind support' before calling it. Publish is also where the provider-key check runs.
cURL
3

Open the conversation

POST /v1/conversations binds a contact_key — your own stable id for the person, up to 256 characters — to this agent. It sends nothing. Post the same key again later and you get the same thread, with everything the agent has learned about that contact still in userdata.
cURL
4

Send a message

POST /v1/conversations/messages is addressed by contact_key, not by conversation id — the same key always reaches the same thread. client_message_id is a UUID you generate; re-sending with the same one is ignored rather than duplicated. Sending to a contact_key with no conversation is a 404, so step 3 is not optional.It returns 202 carrying only your item. The agent replies asynchronously.
cURL
5

Read the reply

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, and the reply is the item whose type is message and whose direction is outbound. Every item the agent produced carries trigger_item_id pointing back at the message that caused it, which is how the script above picks out the answer to this turn.
cURL

Streaming instead of polling

GET /v1/conversations/{conversation_id}/events is a server-sent event stream: a conversation.snapshot first and on every reconnect, then item.created, turn, and assistant.started / assistant.delta / assistant.completed as the reply is generated. assistant.delta frames append — they are not cumulative — and assistant.completed carries every delta joined, so a client that missed some can replace what it accumulated rather than reconcile it. Open the stream before you send, or you will miss the frames for that turn.
Delivery is best-effort. A dropped frame resyncs from the snapshot on reconnect, and list_conversation_items is always the canonical record.
The conversation stays warm between messages and finalizes after 60 seconds with nothing pending. That is a session ending, not the conversation: the next message opens a new session on the same thread, and a text agent always carries the whole transcript across them.

Next

Text conversations

Items, delivery status, the full event stream and the window lifecycle.

Agents overview

Every field of a config, and why every write sends the whole thing.

Tools

Give the agent something to call before it answers.