Docs

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.