API overview and authentication
Reaching Pi Durable Platform agents from your own app: the three kinds of credentials, which routes take which, the response envelope, revisions, and choosing between a service account and OAuth Connect.
Your app reaches Pi Durable Platform's agents through its HTTP API, at the platform's APP_URL (here https://agents.example.com). The app never talks to an agent's runtime: it sends messages to the platform and follows the conversation as server-sent events.
# Send a message (202), then follow the thread
curl -X POST https://agents.example.com/v1/agents/$AGENT/threads/conv-1/messages \
-H "Authorization: Bearer $PDP_KEY" -H "Content-Type: application/json" \
-d '{"text": "Hello", "requestId": "m1"}'
curl -N https://agents.example.com/v1/agents/$AGENT/threads/conv-1/events \
-H "Authorization: Bearer $PDP_KEY"Credentials
Send one as Authorization: Bearer <credential>.
| Credential | Prefix | Acts as | Get it from |
|---|---|---|---|
| Service account key | pdp_sa_ | The team's service account, in its own team, with its role (member or editor) | A team owner or admin: Service accounts |
| Personal API key | pdp_ | A person, with their access | The person: API keys |
| OAuth Connect access token | pdpat_ | A person who connected your app, without their platform role | OAuth Connect |
Which to use
- Your app acts for itself, for example giving each of its users an agent of their own inside your team: a service account. The conversations belong to the app; see Agents by key.
- Your app acts for a person (their personal workspace, their teams' agents, their private threads): OAuth Connect. The person signs in to the platform once and allows your app.
- A person's own script: a personal API key.
Both service-account mode and OAuth Connect are supported; an app can offer both, and use OAuth Connect where the platform advertises it (connect in GET /v1/auth/config).
Which routes take which credentials
Bearer credentials reach the agent routes and a few readings:
- agents, threads, messages, events and thread MCP servers (
/v1/agents…,/v1/teams/{team}/agents…); - template listings (
GET /v1/agent-templates, the team's templates); - a team's models, usage, limits and MCP servers;
GET /v1/me,GET /v1/teamsandGET /v1/teams/{team}, for people only: a service account key gets403 person_required.
Everything else (administration, members, invites, creating keys, service accounts, connected apps, consent) needs a browser session. PUT …/agents/by-key/… is for service accounts only.
Conventions
- Envelope: success is
{"data": …}; an error is{"error": {"code": "…", "message": "…"}}with an HTTP status. See Errors and limits. - Request IDs: every response has
X-Request-ID. Quote it when you report a problem; it's in the platform's logs and audit log. - Not allowed looks like not found: an agent or thread the caller may not use answers
404, the same as one that doesn't exist. - Revisions: objects that can be edited carry a
revision, returned asETag.PATCHsends it back asIf-Match: missing is428 revision_required, stale is412 revision_conflict. - IDs are UUIDs. Teams also have slugs; routes with
{team}take either. - Times are RFC 3339 strings in resources, and Unix milliseconds in conversations (
at,createdAtof threads, …). - Browser sessions also need
X-CSRF-Token(fromGET /v1/me) and a same-originOriginon writes. Bearer requests need neither.
Checking a credential
curl https://agents.example.com/v1/me -H "Authorization: Bearer $TOKEN"For a person, it returns who they are, their groups, their teams and their capabilities (always false for an app's token). It wakes no agent. For a service account, use GET /v1/agents instead.
Next
OAuth Connect
Agents by key
Threads, messages and events
Private threads and authors
Thread MCP servers
Errors and limits
The full reference is generated from the OpenAPI document: see API reference. The API may change between releases before 1.0.