Platform concepts
Sessions
A session is one conversation with one agent; each message you send starts a run, and files can travel with it.
A session is a conversation with one agent — what the web app shows as a chat. It holds the transcript, and every message you send into it starts a run: the agent's work on that message. The run streams its progress while it happens and leaves its answer in the transcript when it finishes.
Sessions need the sessions:read scope to read and sessions:write to change; opening one
and sending messages also need runs:create.
Opening a session
curl -X POST https://api.snaga.ai/api/v1/sessions \
-H "Authorization: Bearer $SNAGA_API_KEY" \
-H "Content-Type: application/json" \
-d '{"agent_id": "<agent_id>"}'
The answer is 201 with the session and its session_id. A new session is active and
expires 24 hours after it is created. Two details are worth knowing:
- If the same agent already has an active session created in the last 30 seconds with no
messages and no runs, that one is returned with
200instead of a new one. This absorbs double clicks. - Your plan limits how many sessions can be active at once; past it the call is
403.
Sending a message
curl -X POST https://api.snaga.ai/api/v1/sessions/<session_id>/messages \
-H "Authorization: Bearer $SNAGA_API_KEY" \
-H "Content-Type: application/json" \
-d '{"content": "Summarise this week'\''s competitor news"}'
The answer is 202 Accepted with a run_id. The agent works in the background; there are
two ways to follow it:
| Stream | What it carries |
|---|---|
GET /api/v1/runs/{runId}/events | The events of this one run. |
GET /api/v1/sessions/{sessionId}/events | Everything in the session: connected, run_added, each run's events, run_done, session_closed. |
Both are Server-Sent Events. To resume after a dropped connection, send the last event id
you received as Last-Event-ID. Ignore event names you do not recognise — that is how new
ones arrive. See pagination and streaming.
Reading the transcript
GET /api/v1/sessions/{sessionId}/messages returns the conversation. Without limit you get
the whole transcript. With limit (1–500) and cursor (an offset) you get one page, with
has_more and the cursor for the next one; a cursor the platform cannot read is
400 INVALID_CURSOR. messages and items carry the same list, and total always counts
the whole transcript, not the page. Each entry has a role (user,
assistant, system or tool_result), its content, the run_id it belongs to, a
timestamp, and a stable message_id. Assistant entries also carry the tools the run
called.
If the agent is still working, the answer describes the run in flight, so a client opened
mid-answer can attach to it instead of showing an idle chat. A session that does not exist
is 404, never an empty list.
GET /api/v1/sessions/{sessionId}/export gives the conversation as md (the default) or
json (?format=json).
Attaching files
Files are uploaded first, then referenced by id in a message. Upload as multipart/form-data
or as base64 JSON; an upload can be up to 50 MiB.
curl -X POST https://api.snaga.ai/api/v1/files \
-H "Authorization: Bearer $SNAGA_API_KEY" \
-F "[email protected]"
The answer is 201 with the file's file_id, filename, mime_type, size_bytes and
sha256. Then send it:
{ "content": "What are the three main risks in this report?", "file_ids": ["<file_id>"] }
content may be an empty string when file_ids has at least one id — a picture with no
caption is an ordinary message. A message with neither text nor files is refused.
| Call | What it does |
|---|---|
GET /api/v1/files | Pages through your company's files; metadata only. |
GET /api/v1/files/{fileId} | One file's metadata. |
GET /api/v1/files/{fileId}/content | The bytes, with the file's own content type. Supports Range. |
DELETE /api/v1/files/{fileId} | Deletes the file. There is no undo. |
Uploaded files stay until you delete them. Files an agent produces and its workspaces are covered in files and workspaces.
Organising sessions
GET /api/v1/sessions lists sessions; filter with agent_id, and page with limit and
cursor. PUT /api/v1/sessions/{sessionId} changes what you can change about a session:
| Field | Effect |
|---|---|
archived | true hides it from the list (it stays readable by id); the next message unarchives it. List archived ones with ?archived=true or ?archived=all. |
pinned | true pins it for every client; list pinned ones with ?pinned=true. |
metadata | A small label bag, merged into what is stored. |
Sharing and branching
POST /api/v1/sessions/{sessionId}/share with {"role": "viewer"} (or "editor") creates a
link anyone can open, optionally expiring after expires_in_hours. Each call creates a new
link and the previous one stops working; DELETE on the same path revokes it.
POST /api/v1/sessions/{sessionId}/branch forks the conversation from an earlier run, so
you can try a different direction without losing the original. Switch with
PUT /api/v1/sessions/{sessionId}/branches/{branchId}/activate.
Closing a session
DELETE /api/v1/sessions/{sessionId} deletes the session and everything it owns: its runs
and their events, its share link, its tasks, and the memories extracted from it. It cannot
be undone. POST /api/v1/sessions/bulk-delete does the same for many sessions at once.
Related
- Runs — what happens after you send a message.
- Agents — who you are talking to.
- Memory and knowledge — what an agent remembers between sessions.