PlanCover Docs
API

API overview

What the chat API serves, where it lives, and the two headers every call carries.

The chat API is the HTTP surface of the PlanCover assistant. Any PlanCover team or service with an API key can call it.

It is a server-to-server API. Your backend holds the API key and calls the chat API; browsers and mobile apps call your backend, never the chat API directly with a key.

Base URL

Every path in these docs is relative to the base URL of one environment:

EnvironmentBase URLAPI keys
Production (prod)https://chat.142.93.215.84.sslip.iopcai_live_…
Staging (staging)https://chat-staging.142.93.215.84.sslip.iopcai_test_…

Interim hostnames

These sslip.io hostnames are interim, until PlanCover assigns the API a domain of its own. Read the base URL from configuration, such as a BASE_URL environment variable, rather than hard-coding it.

Keys are issued per environment, and a key works only in the environments its prefix allows: pcai_live_ keys in prod, pcai_test_ keys everywhere else. A staging key is refused in production, and a production key in staging. The third environment, dev, runs locally and has no shared host. See Authentication.

Endpoints

PathWhat it doesNeeds a key
POST /v1/chat/completionsStarts a turn, OpenAI Chat Completions style (Quickstart)Yes
POST /chat/streamStarts a turn and streams the answerYes
POST /chat/confirmResumes a turn paused on a confirmationYes
POST /chat/resumeResumes a turn paused for sign-inYes
POST /auth/sessionMints a member sessionYes
POST /auth/login, POST /auth/verifySigns a member in with an OTPYes
GET /auth/me, POST /auth/logoutReads or ends a member's sign-inYes
GET /documents/{handle}Streams a document the assistant citedYes
GET /health/live, GET /health/readyLiveness and readiness probesNo

The /chat/* endpoints speak the Native SSE API: eleven named events over text/event-stream.

POST /v1/chat/completions speaks OpenAI's Chat Completions protocol, so any OpenAI-style SDK can call the assistant. Start with the Quickstart.

Building with Claude Code, Codex or another coding agent? See Use with AI coding agents.

Every call carries two principals

HeaderIdentifiesRequired
Authorization: Bearer pcai_…Your integration: the team or service callingOn every route except /health/*
X-PlanCover-Session: <session id>The member the chat acts forFor continuity and member data

The key says who is calling. The session says who the conversation belongs to. They are separate on purpose: one integration talks for many members, and a member's session is never a key. Authentication covers both.

Errors

A refused call is a JSON response with a real HTTP status and the error envelope. The key, the session and the limits are all checked before a stream opens, so a refused chat turn is an HTTP status, not an error event on a 200. Only a failure after the stream has started arrives as an error event.

On this page