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
Versioned agents
Every change appends a version. A session is pinned to the one it started on, for life.
Durable sessions
The event log is the state. A crash mid-turn resumes; a reconnecting browser loses nothing.
Your tools, your data
Plane signs every outbound request with Ed25519 and publishes the public half.
Human in the loop
A tool call can be gated on a hook, or parked on a person, for hours.
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.