---
title: "Create a browser session"
method: POST
path: "/v1/sessions"
---

# Create a browser session

`POST /v1/sessions`

## Request

- Base URL: `https://api.runbear.io`
- URL: `https://api.runbear.io/v1/sessions`
- Auth: HTTP bearer

Mint a short-lived session pass plus a resume token for one browser visitor, and create the single thread that pass is bound to. Call this from YOUR server after authenticating the visitor — the org API key must never reach the browser. The returned `pass` is the only credential the browser holds; it can read and run exactly one thread of one agent and nothing else.

## Request body

- CreateSessionRequest
  - `assistant_id` string, uuid, required: Unique identifier of the agent this session may talk to. The pass carries it; a request naming any other agent is rejected.
  - `thread_id` string, uuid: Resume an existing thread instead of creating one. The thread must belong to your organization AND to `assistant_id`. Those are the ONLY two checks Runbear makes: it holds no visitor identity against a thread, so it cannot tell whether the visitor you are minting for is the one who owns this conversation. If this value came from the browser, verify against your own records that it belongs to the authenticated visitor before forwarding it — in a single-agent deployment both of Runbear's checks pass for every thread in your account. Omit to create a new thread — the usual case.
  - `endUser` string: An opaque, stable identifier for the signed-in visitor (your user id — never an email). Runbear salts and hashes it server-side and binds the resume token to it; refresh must then present the same value. Omit only for genuinely anonymous widgets: without it the resume token is a pure bearer credential and is issued with a materially shorter lifetime (2 hours instead of 24).

## Response `201`

Default Response

- SessionCredentials
  - `session` Session, required
    - `id` string, uuid, required: Stable id for this visitor session. Log it — it is the join key across the session's requests.
    - `assistant_id` string, uuid, required: The one agent this session may talk to.
    - `thread_id` string, uuid, required: The one thread this session may read and run. Created by this call unless you passed `thread_id`. Always present — the browser must never create a thread itself.
    - `expiresAt` string, required: The resume token's expiry: the last instant at which a fresh pass can be obtained. Refreshing issues a new pass but never moves it. A pass issued just before this instant keeps its own full lifetime, so chat can continue for up to 15 minutes past it — after that the session is over and you must create a new one.
  - `pass` SessionCredential, required
    - `token` string, required: Send as `Authorization: Bearer <token>`. Never place it in a URL or query parameter.
    - `expiresAt` string, required: Instant after which this token is rejected.
    - `expiresInSeconds` integer, required: Seconds from issuance until `expiresAt`, measured by the server. Prefer this over comparing `expiresAt` to a browser clock.
  - `resumeToken` SessionCredential
    - `token` string, required: Send as `Authorization: Bearer <token>`. Never place it in a URL or query parameter.
    - `expiresAt` string, required: Instant after which this token is rejected.
    - `expiresInSeconds` integer, required: Seconds from issuance until `expiresAt`, measured by the server. Prefer this over comparing `expiresAt` to a browser clock.

## Other responses

- `400`: The request body failed validation. `code` is `FST_ERR_VALIDATION`.
- `401`: The organization API key is missing or invalid.
- `403`: The key lacks the chat capability, its agent allowlist excludes `assistant_id`, or a browser session pass was presented — a pass can never mint another pass (`forbidden_for_session_pass`).
- `404`: The agent or the supplied thread is not available to this organization. Absent, foreign and wrongly-owned resources are deliberately indistinguishable.
- `422`: The agent has a type the public API cannot run, so no session could be bound to it.
- `429`: Mint rate limit exceeded for this organization and agent. Retry after the number of seconds in the `Retry-After` header.

---

[API](https://skmtc.dev/runbear/apis/runbear-api.md) - [All operations](https://skmtc.dev/runbear/apis/runbear-api/llms.txt) - [OpenAPI document](https://skmtc.dev/runbear/apis/runbear-api/revisions/c6a9c3066a5a?raw)
