Skip to main content
POST
/
api
/
v1
/
chats
Open a new chat session.
const options = {
  method: 'POST',
  headers: {'Content-Type': 'application/json'},
  body: JSON.stringify({
    agent_id: '<string>',
    channel: '<string>',
    external_id: {},
    ttl_seconds: 123,
    additional_data: {}
  })
};

fetch('https://blackbox.dasha.ai/api/v1/chats', options)
  .then(res => res.json())
  .then(res => console.log(res))
  .catch(err => console.error(err));
{
  "id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
  "agent_id": "<string>",
  "channel": "<string>",
  "messages": [
    {
      "role": "<string>",
      "content": "<string>",
      "tool_calls": [
        {
          "id": "<string>",
          "name": "<string>",
          "arguments": "<unknown>",
          "response": "<unknown>"
        }
      ],
      "time": "2023-11-07T05:31:56Z"
    }
  ],
  "created_time": "2023-11-07T05:31:56Z",
  "last_activity": "2023-11-07T05:31:56Z",
  "ttl_seconds": 123,
  "is_final": true,
  "status": "<string>",
  "final_reason": "<string>"
}

Sessions vs. completions

Stateful sessions (/api/v1/chats) are the server-owned counterpart of the stateless /api/v1/text-chat/completion endpoint. Use sessions when the transport itself is asynchronous (SMS, persistent web chat) and the client cannot reliably carry the encrypted state envelope across turns.

Body

Request body for POST /api/v1/chats — opens a new stateful chat session bound to the named agent on the named channel. The server owns the conversation transcript from this point forward; the client only needs to keep the returned session id between turns.

agent_id
string | null

Identifier of the agent that will drive this session. Frozen at open — a session is bound to one agent for its entire lifetime.

channel
string | null

Channel name the session lives on (web, twilio_sms, …). Together with DashaAI.BlackBox.AgentAPI.TextChat.Dtos.Chats.OpenChatRequest.ExternalIdRaw identifies the external endpoint and dedupes against already-open sessions.

external_id
object

Channel-specific external identifier (e.g. for Twilio SMS, { "from": "+1…", "to": "+1…", "provider_id": "…" }). Server hashes the canonical form into ExternalIdHash for the partial unique index that prevents two active sessions from sharing the same endpoint.

ttl_seconds
integer<int32> | null

Per-session inactivity timeout in seconds (60–86400). When set, the TTL sweeper finishes the session once LastActivity + TtlSeconds < now().

additional_data
object

Initial additional_data bag merged into agent prompt template variables. Server overwrites the reserved keys (DashaAI.BlackBox.AgentAPI.TextChat.ChatReservedKeys.Channel, DashaAI.BlackBox.AgentAPI.TextChat.ChatReservedKeys.SipEndpoint) before each LLM call.

Response

Session created. The returned id is the only piece the client needs to remember.

Public projection of a chat session — what callers see via GET /api/v1/chats/{id} and the list endpoint. Deliberately omits the orchestration State blob, the ExternalIdHash, and the worker hot-flags; those are server-internal.

id
string<uuid>

Session identifier.

agent_id
string | null

Agent driving this session. Frozen at open.

channel
string | null

Channel name (web, twilio_sms, …).

messages
object[] | null

Full conversation transcript so far, in send order.

created_time
string<date-time>

Session creation timestamp (UTC).

last_activity
string<date-time>

Most recent activity timestamp (inbound, outbound or assistant turn).

ttl_seconds
integer<int32> | null

Inactivity timeout in seconds; null when no TTL applies.

is_final
boolean

True once the session has terminated.

status
string | null

Status mirror of DashaAI.BlackBox.AgentAPI.TextChat.Dtos.Chats.ChatSessionDto.IsFinal for list-endpoint filtering (active / final).

final_reason
string | null

Reason for finalisation (ttl, user_end, agent_finish, …).