> ## Documentation Index
> Fetch the complete documentation index at: https://docs.noxus.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Agents: chat & stream

> Create a conversation with an agent, then chat, stream replies, or tail events

Agents are driven through **conversations**. You create a conversation bound to
an agent, then send messages to it:

* **Create** — `POST /v1/conversations?assistant_id={agent_id}`.
* **Chat (blocking)** — `POST /v1/conversations/{conversation_id}/chat` returns the final reply.
* **Stream a reply** — `POST /v1/conversations/{conversation_id}/stream` (Server-Sent Events).
* **Tail events** — `GET /v1/conversations/{conversation_id}/events` (SSE for a run started elsewhere).

The streaming endpoints accept `?format=json` for normalised `{event, data}`
envelopes; omit it to receive raw Vercel AI SDK frames. Replace `agent_id` and
`your_api_key` below.

## Send a message and get the reply (blocking)

<Note>
  Simplest request/response. `chat` blocks until the agent finishes and returns
  its final message — use it when you only need the answer, not the
  intermediate steps.
</Note>

<CodeGroup>
  ```python Python SDK theme={null}
  # pip install noxus-sdk
  from noxus_sdk.client import Client
  from noxus_sdk.resources.conversations import MessageRequest

  client = Client(api_key="your_api_key")

  conversation = client.conversations.create("My Conversation", agent_id="agent_id")
  print(f"conversation: {conversation.id}")

  reply = conversation.chat(MessageRequest(content="Hello!"))
  print(reply.parts)
  ```

  ```python Python REST theme={null}
  import requests

  base = "https://backend.noxus.ai"
  headers = {"X-API-KEY": "your_api_key", "Content-Type": "application/json"}

  # 1. Create the conversation
  conv = requests.post(
      f"{base}/v1/conversations?assistant_id=agent_id",
      json={"name": "My Conversation"},
      headers=headers,
  ).json()
  cid = conv["id"]

  # 2. Chat (blocking) — returns the agent's last message
  reply = requests.post(
      f"{base}/v1/conversations/{cid}/chat?assistant_id=agent_id",
      json={"content": "Hello!"},
      headers=headers,
  ).json()
  print(reply["parts"])
  ```

  ```javascript Node theme={null}
  const base = "https://backend.noxus.ai";
  const headers = { "X-API-KEY": "your_api_key", "Content-Type": "application/json" };

  // 1. Create the conversation
  const conv = await fetch(`${base}/v1/conversations?assistant_id=agent_id`, {
    method: "POST",
    headers,
    body: JSON.stringify({ name: "My Conversation" }),
  }).then((r) => r.json());

  // 2. Chat (blocking)
  const reply = await fetch(
    `${base}/v1/conversations/${conv.id}/chat?assistant_id=agent_id`,
    { method: "POST", headers, body: JSON.stringify({ content: "Hello!" }) }
  ).then((r) => r.json());
  console.log(reply.parts);
  ```

  ```bash cURL theme={null}
  #!/bin/bash
  base="https://backend.noxus.ai"

  # 1. Create the conversation
  cid=$(curl -s -X POST "$base/v1/conversations?assistant_id=agent_id" \
    -H "X-API-KEY: your_api_key" -H "Content-Type: application/json" \
    -d '{"name": "My Conversation"}' | jq -r '.id')

  # 2. Chat (blocking)
  curl -X POST "$base/v1/conversations/$cid/chat?assistant_id=agent_id" \
    -H "X-API-KEY: your_api_key" -H "Content-Type: application/json" \
    -d '{"content": "Hello!"}'
  ```
</CodeGroup>

## Stream the reply token-by-token (SSE)

<Note>
  Streams the agent's response as it is generated. Best for chat UIs — render
  text deltas, tool calls, and steps as they arrive instead of waiting for the
  whole answer. Events look like `text-delta`, `finish-step`, etc.
</Note>

<CodeGroup>
  ```python Python SDK theme={null}
  from noxus_sdk.client import Client
  from noxus_sdk.resources.conversations import MessageRequest

  client = Client(api_key="your_api_key")
  conversation = client.conversations.create("My Conversation", agent_id="agent_id")

  for event in conversation.stream(MessageRequest(content="Hello!")):
      print(event.event, event.data)  # e.g. "text-delta", {...}
  ```

  ```python Python REST theme={null}
  import json
  import requests

  base = "https://backend.noxus.ai"
  cid = "<conversation_id>"  # from the create step
  headers = {"X-API-KEY": "your_api_key", "Content-Type": "application/json"}

  with requests.post(
      f"{base}/v1/conversations/{cid}/stream?assistant_id=agent_id&format=json",
      json={"content": "Hello!"},
      headers=headers,
      stream=True,
  ) as resp:
      for line in resp.iter_lines():
          if line and line.startswith(b"data:"):
              print(json.loads(line[len(b"data:"):]))
  ```

  ```javascript Node theme={null}
  const base = "https://backend.noxus.ai";
  const cid = "<conversation_id>"; // from the create step

  const resp = await fetch(
    `${base}/v1/conversations/${cid}/stream?assistant_id=agent_id&format=json`,
    {
      method: "POST",
      headers: { "X-API-KEY": "your_api_key", "Content-Type": "application/json" },
      body: JSON.stringify({ content: "Hello!" }),
    }
  );
  const reader = resp.body.getReader();
  const decoder = new TextDecoder();
  while (true) {
    const { done, value } = await reader.read();
    if (done) break;
    process.stdout.write(decoder.decode(value)); // SSE frames
  }
  ```

  ```bash cURL theme={null}
  #!/bin/bash
  base="https://backend.noxus.ai"
  cid="<conversation_id>"  # from the create step

  # -N disables buffering so deltas arrive live
  curl -N -X POST "$base/v1/conversations/$cid/stream?assistant_id=agent_id&format=json" \
    -H "X-API-KEY: your_api_key" -H "Content-Type: application/json" \
    -d '{"content": "Hello!"}'
  ```
</CodeGroup>

## Tail an in-progress conversation (SSE)

<Note>
  Attach to the live event stream of a run that was started elsewhere — for
  example a message you sent asynchronously, or a run shared across workers.
  Pass `?etag=` to resume from a specific point in the stream.
</Note>

<CodeGroup>
  ```python Python SDK theme={null}
  from noxus_sdk.client import Client

  client = Client(api_key="your_api_key")
  conversation = client.conversations.get("conversation_id")

  for event in conversation.iter_messages():  # or: async for ... in aiter_messages()
      print(event.event, event.data)
  ```

  ```python Python REST theme={null}
  import json
  import requests

  base = "https://backend.noxus.ai"
  cid = "conversation_id"

  with requests.get(
      f"{base}/v1/conversations/{cid}/events?format=json",
      headers={"X-API-KEY": "your_api_key"},
      stream=True,
  ) as resp:
      for line in resp.iter_lines():
          if line and line.startswith(b"data:"):
              print(json.loads(line[len(b"data:"):]))
  ```

  ```javascript Node theme={null}
  const base = "https://backend.noxus.ai";
  const cid = "conversation_id";

  const resp = await fetch(`${base}/v1/conversations/${cid}/events?format=json`, {
    headers: { "X-API-KEY": "your_api_key" },
  });
  const reader = resp.body.getReader();
  const decoder = new TextDecoder();
  while (true) {
    const { done, value } = await reader.read();
    if (done) break;
    process.stdout.write(decoder.decode(value));
  }
  ```

  ```bash cURL theme={null}
  #!/bin/bash
  base="https://backend.noxus.ai"
  cid="conversation_id"

  curl -N "$base/v1/conversations/$cid/events?format=json" \
    -H "X-API-KEY: your_api_key"
  ```
</CodeGroup>

## Send a message with file attachments

Attach files to a message via its `files` array. Each file needs a `name` plus
**either** a public `url` **or** base64 `b64_content` (set `type` to the MIME
type). A `url` is fetched server-side: it must be publicly reachable (private,
loopback, and cloud-metadata addresses are rejected) and downloads are capped at
25 MB. This works with `chat` and with `stream` alike — the agent can read the
attachment as part of the turn.

<CodeGroup>
  ```python Python SDK theme={null}
  from noxus_sdk.client import Client
  from noxus_sdk.resources.conversations import MessageRequest, ConversationFile

  client = Client(api_key="your_api_key")
  conversation = client.conversations.create("My Conversation", agent_id="agent_id")

  message = MessageRequest(
      content="Summarise this document",
      files=[ConversationFile(name="report.pdf", url="https://example.com/report.pdf")],
      # Or inline base64:
      # files=[ConversationFile(name="report.pdf", b64_content="<base64>", type="application/pdf")],
  )
  print(conversation.chat(message).parts)
  ```

  ```python Python REST theme={null}
  import requests

  base = "https://backend.noxus.ai"
  headers = {"X-API-KEY": "your_api_key", "Content-Type": "application/json"}
  cid = "<conversation_id>"  # from the create step

  body = {
      "content": "Summarise this document",
      "files": [
          {
              "status": "success",
              "name": "report.pdf",
              "url": "https://example.com/report.pdf",
              "type": "application/pdf",
          }
      ],
  }
  reply = requests.post(
      f"{base}/v1/conversations/{cid}/chat?assistant_id=agent_id",
      json=body, headers=headers,
  ).json()
  print(reply["parts"])
  ```

  ```bash cURL theme={null}
  #!/bin/bash
  base="https://backend.noxus.ai"
  cid="<conversation_id>"  # from the create step

  curl -X POST "$base/v1/conversations/$cid/chat?assistant_id=agent_id" \
    -H "X-API-KEY: your_api_key" -H "Content-Type: application/json" \
    -d '{
      "content": "Summarise this document",
      "files": [
        {"status": "success", "name": "report.pdf", "url": "https://example.com/report.pdf", "type": "application/pdf"}
      ]
    }'
  ```
</CodeGroup>

<Note>
  Use a public `url` for files already hosted somewhere (fetched server-side,
  max 25 MB); use `b64_content` to inline a local file or one behind auth. The
  agent needs an enabled file-capable tool (e.g. file attachment / code
  execution) to act on attachments.
</Note>

<Tip>
  Chat flows use the same conversation endpoints — create the conversation with
  `settings.agent_flow_id` set to the chat flow's id instead of passing
  `assistant_id`, then chat / stream exactly as above.
</Tip>
