Chat with an agent
Start a chat, send it messages, and manage the messages still waiting, as the app does.
A chat is a conversation between one member and an agent. Through the API you can do what the chat page does: start a chat, send messages, read the agent's answers, and change the messages that are still waiting for a turn.
Use invoke an agent instead when you want a single run with typed input and output. A chat keeps its history, so each message builds on the ones before it; What the agent reads says how much of a long chat a turn sees.
Choose a credential
A chat is private to the member who started it. Call these endpoints with that
member's user API key (gsmc_uk_), or with a delegated token (gsmc_dt_) from
an application acting for them. Another member's chat answers 404, even to a
workspace admin's key. A workspace owner or admin can only stop the running turn
of another member's chat or delete it, signed in to the app, and can't read it.
An automation account has no chats.
A user API key needs no scopes. A delegated token needs:
| To | Scopes |
|---|---|
| List chats | chats:list |
| Read a chat, its messages or queue | chats:read |
| Start a chat | chats:create, agents:invoke |
| Send a message or retry one | chats:edit, agents:invoke |
| Edit, delete or reorder a message | chats:edit |
| Stop a turn | chats:edit, runs:edit |
| Delete a chat | chats:delete |
Start a chat and send a message
Start a chat with an agent you may run:
curl https://api.guestmachines.com/api/v1/chats \
-H "Authorization: Bearer $GUEST_MACHINES_API_KEY" \
-H "Content-Type: application/json" \
-d '{"agent_id": "5b0f3c84-6a51-4a9e-9a7e-1d2f0c6b8e21"}'Then send it a message. Give each message your own client_ref, so a retry
after a dropped connection returns the stored message instead of sending it
twice:
curl https://api.guestmachines.com/api/v1/chats/$CHAT_ID/messages \
-H "Authorization: Bearer $GUEST_MACHINES_API_KEY" \
-H "Content-Type: application/json" \
-d '{"content": "Summarize the open incidents.", "client_ref": "incidents-1"}'A 202 returns the stored message with status queued. When one of the chat's
turns takes it in, it appears in the chat's
messages with the
same client_ref, and the agent's answer follows it as an assistant message
once the turn ends; its run_id names the run that wrote it. Poll the messages,
or the chat itself: is_running stays true while a turn works.
Messages carry text only. Attach files in the app.
Messages wait their turn
A chat works on one message at a time. A message sent while a turn works waits
in the chat's queue, and the next turn takes in the first one. Set send_now
to give a message to the turn working now instead: it reads the message before
its next step, as Send now does in the app. With no turn working, the
message waits like any other.
List the waiting messages to see the queue in the order the chat will take it in:
| Status | Meaning |
|---|---|
steering | Given to the working turn, which reads it before its next step. Always listed first. |
queued | Waiting for the chat's next turn. |
failed | Its turn couldn't start; failure_message says why. It stays until you act on it. |
Until a turn takes a queued or failed message in, you can:
- edit its text;
- delete it;
- move it in
front of another message with
before_id, or last withbefore_id: null; - retry it, if it failed.
Every open app tab of the chat shows each change at once. A 409 means the
chat took the message in meanwhile, or it is steering the working turn: list
the queue again and decide from what it shows. Up to 20 messages can wait in a
chat; a send answers 409 with code chat.messages_full until some are taken
in or deleted.
Whose turn it is
The turn that takes a message in runs with the credential that last sent, edited or retried it. A message sent with your user API key runs as a run that key starts would: its spend counts against the key's budget. A message sent by a delegated application runs as that application acting for you. Either way, like any run a key or an application starts, the turn can't read your private environment variables.
In a chat with the Concierge, a delegated application's turns stay within what
you consented to for that application: the Concierge reads and changes only
what those scopes cover, checked at every step, so a chat-only application
can't use it to read your agents, workflows, schedules, webhooks, runs or
usage. A wildcard you consented to covers every scope under it, so agents:*
covers the Concierge's agent reads and changes. Once you withdraw consent, or
the application is suspended or revoked, the Concierge's next read or change is
refused. What the Concierge changes in such a chat is recorded in the audit log
as the application acting for you, naming both, as the application's own calls
are.
If the key is revoked, expires or becomes read-only, or you withdraw the
application's consent, before the turn starts, the message is listed as
failed with the reason. Retry it with the credential you use now to send it
again.
What the agent reads
Each turn shows the agent the chat's newest messages word for word, as many as fit a share of its model's input, so the rest is left for the agent's own work. A chat that outgrows that share keeps a summary of the messages before them: after a turn ends, a model folds the messages that no longer fit into it, keeping decisions, promises, names, numbers, files and your stated preferences, and citing message numbers. The next turn reads the summary first, as information rather than instructions, then the newest messages. The summary's cost is added to the run of the turn that ended.
Until the summary covers a message, a turn is only told how many earlier messages it isn't shown. Whatever the summary says, the agent can read or search any earlier message word for word when it needs the exact words.
See what the agent reads
to get the summary and verbatim_from_message_id, the oldest message the next
turn reads word for word. The chat page marks that message, and View
Summary there opens the summary. Deleting a chat deletes its summary.
Stop a turn
Stop the chat to cancel the turn it is working on, as Stop does in the app. The messages still waiting stay, and the next one starts the chat's next turn.