REST API reference
The documented api.plori.ai/v1 surface: create agents, submit and track runs, schedules, credits, and the public rate cards. OpenAPI 3.1 spec included.
Everything the dashboard and the MCP tools do runs over one REST API at
https://api.plori.ai/v1. If you are writing code rather than operating an MCP
client, call it directly. The machine-readable contract is the OpenAPI 3.1
document at https://plori.ai/openapi.json; this page is the human version of
the same surface.
Authentication
Every endpoint except the two public rate cards takes a bearer credential:
Authorization: Bearer plori_sk_...
Either a plori API key (plori_sk_…, minted in the dashboard under Settings →
API keys, or by plori login for the CLI) or an OAuth 2.1 access token from
the same flow MCP clients use. The full credential walkthrough, including how an
agent can obtain a key non-interactively, is at
plori.ai/auth.md.
The golden path: create, invoke, read
Create an agent (get-or-create by name, so reruns are safe):
curl -s https://api.plori.ai/v1/agents \
-H "Authorization: Bearer $PLORI_KEY" \
-d '{"name": "my-agent", "if_exists": "return"}'
Send it work. The response is always 202 with the run's ids — the endpoint
submits and returns, it does not block:
curl -s https://api.plori.ai/v1/agents/$AGENT_ID/runs \
-H "Authorization: Bearer $PLORI_KEY" \
-H "Idempotency-Key: hello-1" \
-d '{"message": "Say hello and tell me what tools you have."}'
# -> {"run_id": "...", "session_id": "..."}
Poll the run until it finishes:
curl -s https://api.plori.ai/v1/agents/$AGENT_ID/runs/$RUN_ID \
-H "Authorization: Bearer $PLORI_KEY"
The run object carries status and accounting (credits, tokens, stop reason) —
not the reply text. Read the reply where the live surfaces read it: the
session WebSocket (GET /v1/ws, the browser's transport), the CLI
(plori result), or the MCP invoke_agent / get_run_result tools, which can
wait for the answer and return it in one call. If you want request/response
simplicity end to end, MCP is the better integration surface; the REST API is
the submit-and-track layer underneath.
Retries, idempotency, and concurrency
A run is nondeterministic and billable, so never retry blindly. Send an
Idempotency-Key header (or idempotency_key in the body): a retry with the
same key within 24 hours returns the original run (X-Plori-Idempotent-Replay: true) instead of starting a second one. The same key with a different payload
is a 422; a retry while the first request is still in flight is a 409 with
Retry-After.
How many runs an account may have in flight at once is set by its plan (1 Free,
2 Pro, 5 Power, counted across all its agents); past that a run is a 429 with
Retry-After. Running out of credits is a 402 whose body carries
"code": "insufficient_credits".
Endpoints
| Method and path | What it does |
|---|---|
POST /v1/agents |
Create an agent; if_exists: "return" makes it get-or-create by name |
GET /v1/agents |
List your agents |
GET /v1/agents/{agentID} |
One agent, including its warm/sleeping status |
POST /v1/agents/{agentID}/runs |
Submit a run (202 {run_id, session_id}; Idempotency-Key, max_turn_tokens) |
GET /v1/agents/{agentID}/runs |
Run history |
GET /v1/agents/{agentID}/runs/{runID} |
One run's status and cost |
POST /v1/agents/{agentID}/runs/{runID}/cancel |
Cancel an in-flight run (cascades to delegated child runs) |
POST /v1/agents/{agentID}/schedules |
Defer a one-shot run (fire_at RFC3339 or delay_seconds) |
GET /v1/agents/{agentID}/schedules |
List schedules |
GET /v1/agents/{agentID}/schedules/{scheduleID} |
One schedule |
DELETE /v1/agents/{agentID}/schedules/{scheduleID} |
Cancel a pending schedule (returns the updated schedule) |
GET /v1/users/{userID}/credits |
Balance, plan, and purchase options (your own account only) |
GET /v1/pricing/models |
Public model rate card (no auth) |
GET /v1/pricing/tools |
Public tool and workflow rate card (no auth) |
Errors share one shape, {"error": "<message>"}, with the two exceptions noted
above (402 adds code and audience).
Endpoints not in this table (files, memory, workflows, billing checkout, …) exist but are internal: the dashboard's private surface, subject to change without notice. If you need one of them in the documented API, tell us: [email protected].
Keep this page honest
The OpenAPI document is drift-checked in CI against the live route table, so every path and method above is served exactly as written. Pricing numbers live on the rate cards and in the two pricing endpoints, never hand-copied here.