Developer API
Call Rigor from your code
Production-quality deliverables from a single API call. Rigor classifies your task, builds a methodology-driven plan, and executes each step — returning a structured deliverable with sources, quality score, and cost breakdown. Base URL: https://plith.ai
The Plith Rigor API classifies tasks across 60+ types, composes methodology sequences from 60+ proven frameworks, applies model-adaptive routing at each step, and returns quality-scored outputs with automated review and revision loops. REST API: JSON in, JSON or SSE out. Plan calls are free; execute calls consume credits at 1,000 credits per USD. API signups receive 5,000 credits (2,500 on key creation, 2,500 after email verification).
Authentication
All API requests require an API key sent via the x-api-key header. The Authorization header is not read — requests without x-api-key return 401 missing_api_key.
Keys are created at signup or via POST /api/keys. Your key identifies your organization — all workflows, billing, and data are scoped to it.
Anonymous mode (MCP only)
When connecting via MCP (Smithery, Claude Desktop, Cursor, etc.) without an API key, rigor_plan is available for evaluation against a demo org. Anonymous calls are rate-limited to 30 requests / minute and 500 requests / day per IP.
Quick start
1 · Get a key
curl -X POST https://plith.ai/api/keys \
-H "Content-Type: application/json" \
-d '{"email": "you@example.com", "name": "My Org"}'
// Response — store api_key immediately, it cannot be retrieved again
{
"org_id": "a1b2c3d4-...",
"api_key": "plth_live_xxxxxxxxxxxx...",
"workspace_id": "ws_...",
"email_verified": false,
"credits": 2500,
"message": "Store this key securely — it will not be shown again. Verify your email to unlock 2,500 bonus credits."
}2 · Plan a workflow (free)
curl -X POST https://plith.ai/api/rigor/plan \
-H "x-api-key: YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"task_description": "Design a caching layer for our API gateway"}'Returns a workflow_id and step sequence. No credits used.
3 · Execute
curl -X POST https://plith.ai/api/rigor/execute \
-H "x-api-key: YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"workflow_id": "wr_2a4b6c8d...", "delivery": {"method": "polling"}}'4 · Get results
curl https://plith.ai/api/rigor/status/wr_2a4b6c8d... \ -H "x-api-key: YOUR_KEY"
Returns progress during execution and the full deliverable when complete.
Credits & billing
Plith is metered in credits at 1,000 credits per USD. New organizations receive 2,500 free credits immediately on signup. Verify your email to unlock 2,500 bonus credits (5,000 total). No monthly stipend — credits never expire.
Credit packs
| Amount | Credits |
|---|---|
| $10 | 10,000 |
| $25 | 25,000 |
| $100 | 100,000 |
| $250 | 250,000 |
| Custom ($5–$10,000) | 1,000 credits per dollar |
Purchase via POST /api/billing/checkout. Credits are deducted after each successful call; the amount deducted is reported as credits_used; your new balance as credits_remaining.
For Rigor workflows, credits accumulate server-side as steps execute. The pre-execution estimate appears in plan.cost; final usage is reported by GET /api/rigor/status as credits_used.
Rate limits
| Scope | Limit |
|---|---|
| Rigor endpoints (per org, sliding window) | 120 req / min |
/api/rigor/execute (per org, UTC day) | 1,000 req / day |
| Concurrent active workflows per org | Free: 1 · Pro: 3 · Team: 10 · Enterprise: unlimited |
/api/rigor/workflows/actions | 120 req / min |
| Anonymous MCP (per IP) | 30 req / min, 500 / day |
POST /api/keys (per IP) | 3 per 24 hours |
Active workflows (counting toward the concurrent limit): queued, executing, step_executing, resuming, quality_review, interactive_waiting, pending_approval, pending_human_review. When a rate limit is exceeded, the response includes retry_after (seconds) and a Retry-After HTTP header.
POST /api/rigor/plan
Classifies the task and builds a workflow plan without executing it. The plan is persisted so a subsequent /execute call can pass the workflow_id to skip re-classification.
Request body
| Field | Type | Required | Description |
|---|---|---|---|
task_description | string (≥ 2 words) | Yes | What you want produced. Be specific. |
task_type | string | No | Hint to skip auto-classification. |
available_mcp_connections | object[] | No | Each: { id, label, server_url, capabilities } |
preferences | object | No | See preferences fields below. |
context | object | No | { additional_context: string } |
preferences fields
| Field | Type | Description |
|---|---|---|
rigor_level | "quick" | "standard" | "thorough" | Review depth. Default auto-detected. |
max_budget_usd | number | Budget ceiling; triggers budget_below_estimate warning. |
skip_frameworks | string[] | Framework display names to exclude. |
only_frameworks | string[] | Restrict to these frameworks (mutex with skip). |
add_frameworks | (string | obj)[] | Inject frameworks: { name, before_step } |
require_approval | boolean | Pause at pending_approval before the final step. |
approval_before_step | number[] | Zero-based step indices for approval gates. Out-of-range indices return 400 invalid_step_index. |
execution | string | Set to 'direct' to execute all steps in a single composed call (Pro+). When omitted, each step runs as a separate call with intermediate outputs available via SSE. |
Response (200)
{
"ok": true,
"plan": {
"workflow_id": "wr_2a4b6c8d...",
"classification": { "task_type": "solution_design", "value_class": "operational" },
"sequence": [
{ "step": 1, "name": "Requirements Analysis", "estimated_credits": 80, "priority_class": "must" },
{ "step": 2, "name": "Solution Design", "estimated_credits": 240, "priority_class": "must" },
{ "step": 3, "name": "Assumption Verification","estimated_credits": 100, "priority_class": "should", "auto_added": true },
{ "step": 4, "name": "Multi-Perspective Review", "estimated_credits": 120, "priority_class": "must" }
],
"cost": { "credits": 540, "usd": 0.54, "range": { "estimated_min": 400, "estimated_max": 680 } },
"rigor_level": "standard",
"allowed_modes": ["direct"],
"execution_fallback": false,
"warnings": [],
"info": ["Review: Haiku + Sonnet"]
}
}Review steps are named "Multi-Perspective Review". When a plan contains multiple review passes, each is qualified by tier: "Multi-Perspective Review (Lightweight)", "Multi-Perspective Review (Standard)", or "Multi-Perspective Review (Full)". Model names are never included in step names.
When preferences.execution: 'direct' is requested and the workflow is eligible, the response includes "execution": "direct". If the request was overridden (tier, workflow size, or approval conflict), execution_fallback: true appears instead. allowed_modes is always present — it contains "direct" when the org and workflow size qualify; empty array otherwise.
The plan sequence always ends with a Synthesis step. This terminal step compiles outputs from all prior framework steps into a unified deliverable with structured findings and cited references. It carries priority_class: "must" and its estimated cost is included in cost.credits.
Errors: 401 unauthorized · 400 invalid_body · 400 missing_field · 400 invalid_task_description · 400 vague_task_description · 429 rate_limit_exceeded · 504 plan_timeout · 500 plan_error
POST /api/rigor/execute
Executes a workflow end-to-end. Pass workflow_id to re-use a stored plan, or pass task_description to classify, plan, persist, and dispatch in a single call. Cost equals the plan's cost.credits. First Rigor workflow per org is free.
Delivery modes
| Mode | Set by | Returns |
|---|---|---|
| sse (default) | delivery.method: "sse" + Accept: text/event-stream | Event stream until completion or 290 s timeout |
| polling | delivery.method: "polling" | workflow_id + poll_url |
| webhook | delivery.method: "webhook" + HTTPS delivery.webhook_url | workflow_id + webhook_secret (32-byte hex HMAC) |
| interactive | mode: "interactive" | Returns interactive_waiting; driven step-by-step via /step |
SSE events
| Event | When |
|---|---|
workflow_started | Workflow metadata + steps preview |
step_started · step_completed · step_skipped | Per step |
quality_review | Score + summary after execution |
workflow_completed · workflow_pending_approval · workflow_error | Terminal events |
processing | Heartbeat every 15 s while waiting |
stream_timeout | Stream closes at 290 s; workflow continues — poll status |
Reconnect: each event carries an id: field of the form workflow_id:step_or_marker. To resume after a drop, resend the request with Last-Event-ID set to the last received id — missed events will be replayed.
GET /api/rigor/status/{workflow_id}
Returns workflow state and results. Only the owning organization can read a workflow.
Status values
pending · planned · queued · executing · step_executing · resuming · quality_review · interactive_waiting · pending_approval · pending_human_review · approved · completed · failed · cancelled · timed_out · blocked · halted
{
"ok": true,
"workflow": {
"workflow_id": "wr_2a4b6c8d...",
"status": "completed",
"task_type": "solution_design",
"current_step": 5,
"total_steps": 5,
"quality_score": 92,
"quality_review": {
"score": 92,
"summary": "Strong design with clear trade-offs.",
"path_to_100": ["Add p50/p95/p99 latency targets per cache tier."]
},
"deliverable": { "title": "...", "sections": [{ "heading": "...", "content": "..." }] },
"credits_used": 530,
"error": null
}
}POST /api/rigor/approve
{
"workflow_id": "wr_2a4b6c8d...",
"decision": "approved",
"notes": "OK to proceed",
"agent_id": "my-review-bot"
}Decision endpoint for workflows paused at pending_approval. On approval, the workflow automatically resumes. On rejection, the workflow is marked failed. Errors: 404 not_found · 409 invalid_status · 500 approve_failed
POST /api/rigor/resume
{
"workflow_id": "wr_2a4b6c8d...",
"revision_guidance": "Focus the rewrite on enterprise buyers; ignore SMB."
}Resumes a workflow from the last completed step. Permitted source statuses: executing, failed, approved, blocked, timed_out, pending_approval. Uses an optimistic lock — concurrent resume calls return resume_conflict.
POST /api/rigor/step
{
"workflow_id": "wr_2a4b6c8d...",
"action": "next",
"feedback": "Focus on security implications."
}Drives a workflow created with mode: "interactive". action accepts "next" | "skip" | "abort". Sessions expire after 30 minutes of inactivity. Errors: 409 invalid_status · 410 session_expired · 409 concurrent_step
GET /api/rigor/workflows
Lists workflows for the authenticated org with filtering and cursor-based pagination. Also returns a real-time concurrent-usage summary against your plan's concurrent workflow limit.
| Param | Type | Description |
|---|---|---|
status | string | Comma-separated (executing,queued). |
task_type | string | Filter by task type. |
created_after | ISO 8601 | After this time. |
created_before | ISO 8601 | Before this time. |
cursor | string | Opaque cursor from prior pagination.cursor. |
limit | integer | 1–100, default 20. |
POST /api/rigor/workflows/actions
{
"action": "cancel",
"workflow_ids": ["wr_aaa...", "wr_bbb..."],
"confirm": false,
"force": false
}Bulk workflow action endpoint. Currently supports action: "cancel". Two-phase: confirm: false (default) shows a preview, confirm: true executes. Max 20 workflow IDs per call.
GET /api/rigor/lineage/{workflowId}
Walks the prior_workflow_id chain backward and returns the full lineage, ordered oldest-first. Capped at 10 hops. Errors: 404 not_found · 422 chain_depth_exceeded
GET /api/rigor/templates
{
"templates": [{
"id": "uuid",
"task_type": "solution_design",
"template_name": "Solution Design",
"template_prompt": "...",
"placeholder_fields": ["system_name", "constraints"],
"description": "Architecture and design document for a technical system.",
"display_order": 1,
"version": 1,
"category": "Engineering"
}]
}Returns deliverable templates — 43 types across 8 categories. No auth required. Query: ?task_type= and/or ?category=.
POST /api/rigor/enhance
{ "task_description": "Design a caching layer", "tier": "llm" }Scores and optionally enhances a task description. tier: "deterministic" (default) is free, rule-based, no auth. tier: "llm" uses an LLM for richer suggestions — 270 credits, requires x-api-key. Response includes score (0–100), suggestions[], and (for llm tier) enhanced_prompt — a rewritten task. Errors: 400 input_too_long (10,000 char max) · 500 enhance_error
Execution modes
Rigor supports 2 execution approaches, controlled by the optional preferences.execution field.
Default (field omitted)
Each framework step runs as a separate LLM call. Intermediate step outputs are available in real-time via SSE events and GET /api/rigor/status as execution progresses. Supports interactive mode and approval gates.
Direct (execution: 'direct', Pro+)
All framework steps execute in a single composed LLM call. Faster with lower credit cost, but no intermediate outputs during execution. Requires Pro+ tier and is subject to workflow size limits — when the workflow exceeds the composition limit, execution falls back to default multi-call mode automatically and execution_fallback: true appears in the plan response.
Both approaches execute the same framework sequence and produce the same deliverable structure.
Incompatibility with approval gates
Direct execution cannot be combined with require_approval: true or mode: "interactive". If both are requested, the system honors the approval preference and falls back to default multi-call execution — execution_fallback: true will appear in the response. Direct mode executes all framework steps in a single LLM call with no intermediate outputs, so there are no steps to pause between for approval.
When allowed_modes in the plan response does not contain "direct", the workflow is not eligible for direct mode regardless of the preferences.execution field.
POST /api/rigor/plan
{
"task_description": "Competitive analysis of enterprise platforms",
"preferences": {
"rigor_level": "standard",
"execution": "direct"
}
}
// Response when eligible:
// "allowed_modes": ["direct"], "execution": "direct", "execution_fallback": false
// Response when fallback triggered (tier or approval conflict):
// "allowed_modes": [], "execution_fallback": truePOST /api/rigor/connections
Registers a new MCP server connection. Server URL is validated for SSRF safety at registration time. Credentials are encrypted at rest immediately and never returned. Returns 201 with connection.status: "pending". Call /test to promote to active.
| Field | Type | Required | Description |
|---|---|---|---|
label | string | Yes | Human-readable name. |
server_url | string | Yes | HTTPS URL. |
auth_type | string | Yes | bearer_token | api_key | oauth | none |
transport | string | No | streamable-http (default) or sse |
auth_credential | object | Conditional | Required when auth_type is not none. |
GET /api/rigor/connections
Returns all connections registered for your organization. Credentials are never included. Status values: pending, active, error, revoked. capabilities is null until a connection test completes.
PATCH /api/rigor/connections/{id}
Updates a registered connection. All fields optional.
POST /api/rigor/connections/{id}/test
Tests connectivity. Performs DNS-level SSRF check. On success, status → active, last_tested_at recorded. On SSRF failure, status → error and the response is 400.
DELETE /api/rigor/connections/{id}
Soft delete. Record retained for audit, status set to revoked, credentials cleared. Revoked connections cannot be used in workflow execution.
Connection security
| Control | What it does |
|---|---|
| Credential encryption | AES-256-GCM at rest. Never returned in any response. |
| SSRF — registration | HTTPS only, no private IPs, no cloud metadata endpoints, no internal hostnames. |
| SSRF — test | DNS resolved at test time; all A/AAAA records checked against blocklist. |
| Read-only enforcement | Only resources/read and resources/list are executed. tools/call, prompts/*, sampling/*, all writes are blocked regardless of server capabilities. |
| Org isolation | Every request filtered by your org ID, derived from your API key. |
| Content sanitization | External MCP content wrapped in containment framing, scanned for prompt-injection patterns. |
Limits: max 10 connections per org · duplicate server_url rejected with 409 · HTTPS only.
MCP tools
Connect to Plith via MCP at https://plith.ai/api/mcp/rigor. Compatible with Claude Desktop, Cursor, Windsurf, Smithery, and any MCP-compatible client. Authenticate via the x-api-key header, or use anonymous mode (rate-limited: 30 req/min, 500 req/day per IP) for evaluation.
Discoverable tools
| Tool | Description |
|---|---|
rigor_plan | Plan a workflow without executing it (free). Available anonymously for evaluation. |
rigor_execute | Execute a planned or fresh workflow. |
rigor_status | Get workflow progress and results. |
Hidden tools
Callable but do not appear in tools/list:
| Tool | Description |
|---|---|
rigor_resume | Resume a stalled or failed workflow. |
rigor_approve | Approve or reject a workflow pending human review. |
rigor_step | Drive a single step of an interactive workflow. |
rigor_connections | Manage MCP connections. |
Plan-then-execute (recommended)
Plan first to see the step sequence and cost estimate. Execute only when satisfied.
# Step 1: Plan (free)
POST /api/rigor/plan
{ "task_description": "...", "preferences": { "rigor_level": "standard" } }
→ { plan: { workflow_id: "wr_...", sequence: [...], cost: { credits: 540 } } }
# Step 2: Execute with polling delivery
POST /api/rigor/execute
{ "workflow_id": "wr_...", "delivery": { "method": "polling" } }
→ { workflow_id: "wr_...", status: "queued", poll_url: "/api/rigor/status/wr_..." }
# Step 3: Poll until "completed"
GET /api/rigor/status/wr_...
→ { workflow: { status: "completed", deliverable: { ... } } }Webhook delivery
Receive results pushed to your endpoint instead of polling. Store webhook_secret and verify incoming payloads via HMAC-SHA256.
POST /api/rigor/execute
{
"workflow_id": "wr_...",
"delivery": {
"method": "webhook",
"webhook_url": "https://your-server.example.com/rigor-webhook"
}
}
→ { webhook_url: "...", webhook_status: "registered", webhook_secret: "..." }Approval gate
Request a human decision before final steps execute.
# Plan with approval gate
POST /api/rigor/plan
{ "task_description": "...", "preferences": { "require_approval": true } }
# Execute — workflow will pause at pending_approval
POST /api/rigor/execute
{ "workflow_id": "wr_...", "delivery": { "method": "polling" } }
# Poll until status === "pending_approval", then approve
POST /api/rigor/approve
{ "workflow_id": "wr_...", "decision": "approved", "notes": "Looks good" }
# workflow automatically resumes after approvalrequire_approval is incompatible with preferences.execution: 'direct'. If both are set, the system honors the approval preference and falls back to default multi-call execution. execution_fallback: true will appear in the plan response.
Interactive mode
Drive execution one step at a time. Sessions expire after 30 minutes of inactivity.
POST /api/rigor/execute
{ "task_description": "...", "mode": "interactive" }
→ { status: "interactive_waiting", sequence: [...] }
POST /api/rigor/step
{ "workflow_id": "wr_...", "action": "next" }
→ { status: "step_executing", poll_url: "..." }Workflow chaining
Inherit context from a completed workflow into a new one. Chain depth limit: 10 links.
POST /api/rigor/execute
{
"task_description": "Implement the solution from the prior design",
"prior_workflow_id": "wr_parent...",
"context_fields": ["deliverable", "quality_review"]
}Worked example
A complete plan → execute → poll cycle for a Solution Design.
curl -X POST https://plith.ai/api/rigor/plan \
-H "x-api-key: YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"task_description": "Design a caching layer for our API"}'
# → plan.cost.credits = 560 · estimated cost shown before committing
curl -X POST https://plith.ai/api/rigor/execute \
-H "x-api-key: YOUR_KEY" \
-d '{"workflow_id": "wr_...", "delivery": {"method": "polling"}}'
# → status: queued · poll_url returned
curl https://plith.ai/api/rigor/status/wr_... \
-H "x-api-key: YOUR_KEY"
# → status: completed · quality_score: 92 · credits_used: 545Error reference
All endpoints return errors in this envelope:
{
"error": {
"code": "missing_field",
"message": "workflow_id is required.",
"request_id": "req_abc123def456...",
"fix": "POST /api/rigor/plan with your task_description",
"docs": "https://plith.ai/docs/errors#missing_field",
"details": { "field": "workflow_id" }
}
}fix, docs, and details are included only when available. request_id is always present.
Auth
| Code | HTTP | Summary |
|---|---|---|
missing_api_key | 401 | Provide x-api-key header. |
invalid_api_key | 401 | Key not found or revoked. |
forbidden | 403 | Resource belongs to a different org. |
Validation
| Code | HTTP | Summary |
|---|---|---|
invalid_body | 400 | Body must be valid JSON. |
missing_field | 400 | <field> required. |
invalid_task_description | 400 | Must contain at least 2 words. |
vague_task_description | 400 | Classifier confidence too low. |
input_too_long | 400 | Input exceeds maximum length. |
invalid_step_index | 400 | approval_before_step index out of range. |
Rate limiting
| Code | HTTP | Summary |
|---|---|---|
rate_limit_exceeded | 429 | Wait per Retry-After header. |
concurrent_limit_exceeded | 429 | Plan's concurrent workflow limit reached (Free: 1, Pro: 3, Team: 10). |
Workflow state
| Code | HTTP | Summary |
|---|---|---|
not_found | 404 | Workflow not found. |
no_plan | 400 | Workflow has no plan. |
insufficient_credits | 402 | Top up via /api/billing/checkout. |
workspace_budget_exceeded | 402 | Adjust budget or reduce plan. |
workflow_has_progress | 409 | Use /resume. |
invalid_status | 409 | Action not allowed in current state. |
duplicate_task | 409 | Identical task in last 5 min. |
already_complete | 409 | Nothing to resume. |
resume_conflict | 409 | Another resume in progress. |
pending_human_review | 409 | Use /approve. |
Chaining & connections
| Code | HTTP | Summary |
|---|---|---|
prior_not_found | 404 | Prior workflow not found. |
prior_not_terminal | 409 | Wait for prior to complete. |
chain_depth_exceeded | 422 | Max 10 hops. |
context_too_large | 422 | Use context_fields to restrict. |
feature_not_enabled | 501 | MCP gateway disabled. |
session_expired | 410 | 30-min TTL — use /resume. |
plan_timeout | 504 | Simplify or split the task. |
provider_exhausted | 503 | All providers failed — retry. |
internal_error | 500 | Retry; include request_id. |
Response conventions
Every successful response includes:
| Field | Type | Description |
|---|---|---|
request_id | string | Always req_ + 24 hex chars. Include when contacting support. |
credits_used | number | Credits deducted by this request. 0 for free endpoints. |
credits_remaining | number | Org balance after this request. |
fallback_behavior | string | What the system did when upstream was degraded — "none" when normal. |
Rigor workflow endpoints (/plan, /execute, /status, /approve, /resume, /step) use product-specific response shapes and do not include credits_used / credits_remaining at the top level. Credit usage for workflows is reported via the status endpoint as workflow.credits_used.