---
title: "Open a session and mint a data-plane grant"
method: POST
path: "/api/v2/projects/{projectId}/sessions"
tags: ["Sessions"]
---

# Open a session and mint a data-plane grant

`POST /api/v2/projects/{projectId}/sessions`

## Request

- Base URL: `https://davinci-app.com`
- URL: `https://davinci-app.com/api/v2/projects/{projectId}/sessions`
- Auth: HTTP bearer

Loads the project, holds it open, and returns the credential for reaching it
directly.

A project unloads shortly after nothing is connected to it, so a session is
what keeps it resident between your requests. Poll the session (`getSession`)
to both refresh the grant and signal that you are still working.

The grant can never exceed the key that minted it. Omit `scopes` to inherit
the key's own scopes; supply them to narrow the grant further, which is worth
doing when one job needs less than the key can do.

## Request body

- CreateSessionRequest
  - `branch` string, nullable: Branch to open. Defaults to the branch in a compound project id, or `main`.
  - `scopes` string[]: Narrow the grant below the key's own scopes. Omit to inherit them. Asking for a scope the key does not hold is refused rather than silently reduced.
  - `ttlSeconds` integer: Grant lifetime. Capped at one hour regardless of what is requested.

## Response `201`

The session, with the grant needed to reach the data plane.

- Session
  - `sessionId` string, uuid, required
  - `projectId` string, required: Bare project id, without the branch suffix.
  - `branchName` string, required
  - `ownerId` string, required: Account or organization that owns the project. Files live under the owner's storage namespace, not the caller's, which is why a shared or org-owned project needs this rather than your own user id.
  - `dataPlane` DataPlaneAccess, required: Everything needed to address the data plane: where to send, what to send with, and the path parameters that are not obvious from the project id alone.
    - `url` string, uri, required: Base URL for data-plane operations. Names no specific machine, so it stays valid if the project moves.
    - `token` string, required: The grant, `dav_gr_…`. Returned only here and only once — it is not stored in recoverable form, so a lost grant is replaced by refreshing the session rather than looked up.
    - `expiresAt` string, date-time, required
    - `connectionId` string, required: Pass as the `connectionId` path parameter on upload.
    - `ownerId` string, required: Pass as the `ownerId` path parameter.
    - `userId` string, required: Pass as the `userId` path parameter on upload.
    - `projectKey` string, required: Pass as the `projectId` path parameter. Compound form `{projectId}--{branchName}`, since the data plane addresses a branch.
    - `operations` string[], required: Data-plane operations this grant authorizes.
  - `agent` AgentState: What the session's agent is doing. Present on a session read, absent on create because nothing has been asked of the agent yet.
    - `status` 'no_session' | 'project_not_running' | 'idle' | 'starting' | 'running' | 'paused' | 'completed' | 'failed' | 'unknown', required: - `no_session` — the machine has no record of this session; it lapsed or the project restarted. Create a new one. - `project_not_running` — the session is known but its project has unloaded. - `idle` — the session is live and no run has been started. - `starting` — a run is being set up. - `running` — a run is in progress. - `paused` — a run was stopped and can be continued with a new prompt. - `completed` — the run finished. - `failed` — the run ended in an error. `agent.error` says why, as does the transcript. - `unknown` — the machine could not be reached for this field. Retry; anything else in the same response is still valid. `paused`, `completed`, and `failed` are terminal for a run.
    - `taskId` string, nullable: Identifies the run. Also names the stored conversation.
    - `lastMessageId` string, nullable: The `messageId` of the most recent prompt the agent took.
    - `error` AgentFailure: Why the run failed. Present only while `status` is `failed`, so the read that tells you the run is over also tells you why — closing the session afterwards loses nothing.
      - `message` string, required: What went wrong, as the transcript records it.
      - `category` string, nullable: The model provider's error category when the failure came from the provider, such as `context_window`, `rate_limit`, or `unavailable`; otherwise null.

## Other responses

- `400`: Invalid request. Error code is `INVALID_SCOPES` for an unknown scope name or `INVALID_TTL` for a non-positive `ttlSeconds`.
- `401`: No credential was supplied, or the supplied credential is malformed, expired, or revoked. A credential that is present but unusable is never downgraded to an anonymous request.
- `403`: The caller lacks `project:connect` on this project, or asked for scopes the key does not hold (`INSUFFICIENT_SCOPES`).
- `404`: The resource does not exist in the parent named by the path, or is hidden from the caller. Absence and privacy denial are deliberately indistinguishable so project, organization, and private-team existence cannot be probed.
- `429`: Request rate exceeded, either globally or for this key.
- `500`: Unexpected server error.
- `503`: The project could not be opened or its machine is unavailable. Error code is `PROJECT_NOT_READY`, `SERVER_NOT_AVAILABLE`, or `GRANT_PUSH_FAILED`.

## Changes

- **2026-11-04** (v2) `8663bb3e802f`: 1 info
  - added the optional property `agent/error` to the response with the `201` status
- **2026-09-15** (v2) `67c8b8616dbb`: 7 info
  - the `success` response property const value `false` was added for the status `400`
  - the `success` response property const value `false` was added for the status `401`
  - the `success` response property const value `false` was added for the status `403`
  - the `success` response property const value `false` was added for the status `404`
  - …3 more
- **2026-09-15** (v2) `48948af37797`: 1 info
  - endpoint added

[Operation history](https://skmtc.dev/celedon-solutions/apis/davinci-public-api/changes/api/v2/projects/:projectId/sessions/post.md)

---

[API](https://skmtc.dev/celedon-solutions/apis/davinci-public-api.md) - [All operations](https://skmtc.dev/celedon-solutions/apis/davinci-public-api/llms.txt) - [OpenAPI document](https://skmtc.dev/celedon-solutions/apis/davinci-public-api/revisions/279218ca2e8d?raw)
