---
title: "Create a session"
method: POST
path: "/api/v1/sessions"
tags: ["sessions"]
---

# Create a session

`POST /api/v1/sessions`

## Request

- Base URL: `https://api.trigger.dev`
- URL: `https://api.trigger.dev/api/v1/sessions`
- Auth: one of:
  - HTTP bearer
  - HTTP bearer
- TypeScript: <https://skmtc.dev/triggerdotdev/apis/trigger-dev-v3-rest-api/docs/api/v1/sessions/post.ts> (a function with typed inputs; its response is checked against the schema)

Create a Session and trigger its first run in one atomic call. A Session is the durable identity for a bi-directional stream of records (the `.in` and `.out` channels) that survives across the runs processing it.

Idempotent on `externalId` within an environment. Calling create again with an `externalId` that already maps to an open session returns the existing session with `isCached: true` and `201` becomes `200`. Reusing an `externalId` whose session is already closed or expired returns `409`.

Authorize with a secret key, or a public token carrying `write:sessions` for the session you are creating.

## Request body

- CreateSessionRequestBody: Body for `POST /api/v1/sessions`. The whole body must be 32KB or smaller.
  - `type` string, required: Free-form discriminator for the session, e.g. `chat.agent`. Not validated against an enum.
  - `taskIdentifier` string, required: The task this session triggers runs against.
  - `triggerConfig` SessionTriggerConfig, required: Trigger options applied to every run a session schedules. `basePayload` is the wire payload merged into each run; the remaining fields map onto the standard trigger options.
    - `basePayload` object, required: Base payload passed to every run this session triggers. For `chat.agent` this carries `{ chatId, ...clientData }`.
    - `machine` string: Machine preset for each run, e.g. `small-1x`.
    - `queue` string: Queue to schedule runs on.
    - `tags` string[]: Tags applied to every run this session triggers.
    - `maxAttempts` integer: Maximum retry attempts per run.
    - `maxDuration` integer: Per-run wall-clock cap in seconds.
    - `lockToVersion` string: Pin every run to a specific worker version.
    - `region` string: Region to schedule runs in.
    - `idleTimeoutInSeconds` integer: Idle timeout surfaced to `chat.agent` via the wire payload.
  - `externalId` string: Your stable identity for the session, unique per environment. Cannot start with the reserved `session_` prefix. Reusing an `externalId` makes create idempotent; reusing one whose session is closed or expired returns `409`.
  - `tags` string[]: Up to 10 tags on the session row, for dashboard filtering.
  - `metadata` object: Arbitrary JSON metadata.
  - `expiresAt` string, date-time: Absolute expiry timestamp for retention.

## Response `200`

An open session already existed for this `externalId`. The existing session is returned with `isCached: true`.

- CreatedSessionResponseBody: A session row.
  - `id` string, required: The session's friendly ID, prefixed with `session_`.
  - `externalId` string, nullable: Your stable identity for the session, if one was set.
  - `type` string, required: The session type discriminator.
  - `taskIdentifier` string, required: The task this session triggers runs against.
  - `triggerConfig` SessionTriggerConfig: Trigger options applied to every run a session schedules. `basePayload` is the wire payload merged into each run; the remaining fields map onto the standard trigger options.
    - `basePayload` object, required: Base payload passed to every run this session triggers. For `chat.agent` this carries `{ chatId, ...clientData }`.
    - `machine` string: Machine preset for each run, e.g. `small-1x`.
    - `queue` string: Queue to schedule runs on.
    - `tags` string[]: Tags applied to every run this session triggers.
    - `maxAttempts` integer: Maximum retry attempts per run.
    - `maxDuration` integer: Per-run wall-clock cap in seconds.
    - `lockToVersion` string: Pin every run to a specific worker version.
    - `region` string: Region to schedule runs in.
    - `idleTimeoutInSeconds` integer: Idle timeout surfaced to `chat.agent` via the wire payload.
  - `currentRunId` string, nullable: Friendly ID of the live run for this session, if any. Prefixed with `run_`. Omitted on list rows.
  - `tags` string[], required: Tags on the session row.
  - `metadata` object, nullable: Arbitrary JSON metadata, or `null` if unset.
  - `closedAt` string, date-time, nullable: When the session was closed, or `null` if open.
  - `closedReason` string, nullable: The optional reason recorded when the session was closed.
  - `expiresAt` string, date-time, nullable: The session's retention deadline, or `null` if none.
  - `createdAt` string, date-time, required
  - `updatedAt` string, date-time, required
  - `runId` string, required: Friendly ID of the first run triggered alongside the session.
  - `publicAccessToken` string, required: Session-scoped public access token carrying `read:sessions:{key}` and `write:sessions:{key}`. Default TTL is 1 hour. Safe to pass to frontend clients.
  - `isCached` boolean, required: `true` if an open session already existed for this `externalId` (idempotent upsert), `false` if newly created.

## Other responses

- `201`: Session created and its first run triggered.
- `401`: Unauthorized
- `409`: An `externalId` was reused, but its session is already closed or expired. Closed and expired sessions cannot be reopened.
- `422`: Validation failed — for example the request body exceeds 32KB, or `externalId` starts with the reserved `session_` prefix.

## Changes

- **2026-06-14** `6e21987d1377`: 1 info
  - endpoint added

[Operation history](https://skmtc.dev/triggerdotdev/apis/trigger-dev-v3-rest-api/changes/api/v1/sessions/post.md)

---

[API](https://skmtc.dev/triggerdotdev/apis/trigger-dev-v3-rest-api.md) - [All operations](https://skmtc.dev/triggerdotdev/apis/trigger-dev-v3-rest-api/llms.txt) - [OpenAPI document](https://skmtc.dev/triggerdotdev/apis/trigger-dev-v3-rest-api/revisions/441161111493?raw)
