Plane docs

Introduction

What Plane is, what a credential is, and how a tenant is shaped.

Plane runs agents for you.

An agent is a versioned JSON document: which model, what prompt, which tools, what it is allowed to do, what a caller may vary. You write it in your repository and push it. A session is a conversation with one version of one agent, and it lives as an append-only event log on Plane's side — so a turn survives a restart, a browser can replay it from any point, and the trace of what actually happened is still there next week.

Tools are MCP. Plane calls your endpoint, signed, so a tool handler runs on your infrastructure next to your database and Plane never holds your data. Model credentials are yours too: you register a provider with your own key and Plane spends it.

const session = await client.sessions.create({
  agentId,
  initialMessage: "where is order A-1001?",
  metadata: { customerId: "cus_42" }
})

What you get

The two credentials

Everything in the API is reachable with one of two things.

An API key, pl_<env>_…, sent as Authorization: Bearer. The key is the environment — everything it reads and writes is scoped to the environment it was minted in, and there is no header that points it somewhere else. This is what your application server, your CI job and the plane CLI hold.

curl https://plane.example.com/v1/agents/list \
  -H "Authorization: Bearer $PLANE_API_KEY" \
  -H "Content-Type: application/json" -d '{}'

The control plane's session cookie. A person signs in at /auth/login and gets an httpOnly cookie. A person belongs to organizations rather than to one environment, so a browser says which tenant it is looking at with two headers — x-plane-organization and x-plane-environment. Both are ignored for an API key.

Plane does not own your users. A session can assert an identity — { scope: "user", id: "u_412" } — and Plane stores it verbatim and keys per-user OAuth grants off it. There is no user table and no provisioning call. See Identity.

Organizations and environments

Two levels, and no third.

An organization is your company. It owns users, memberships and one set of signing keys.

An environment is the isolation unit and the only scope any row carries: agents, sessions, connections, providers, secrets, keys and usage all belong to exactly one. dev and prod at a small company, one per developer at a large one. Environments are free and encouraged, so nothing about Plane punishes you for isolating properly — and because an environment slug is unique per organization, two organizations both having a prod is the ordinary case.

An id from another environment answers 404, never 403. The row was not seen, so the API is not an existence oracle for a tenant you cannot reach.

Moving an agent from one environment to another is promotion, which resolves every connection, provider and secret the definition names in the target and refuses as a whole if one is missing.

Where to go next

On this page