> ## Documentation Index
> Fetch the complete documentation index at: https://docs.tilion.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Plans

## POST /v1/plan

Compile a prompt into a plan without running it. A plan is a typed description of the job: the goal, the target entity and output schema, phases of sub-tasks with their executors, success criteria, a cost estimate, the gaps (sources with no scraper yet), the assumptions made, and clarifying questions you can answer in a follow-up `answers` object (to this route or to `POST /v1/workflow`).

Auth: Bearer API key.

Request:

| Field | Type | Default | Meaning |
| - | - | - | - |
| `prompt` | string | required | the task, 1 to 8000 characters |
| `answers` | object | null | answers to a previous plan's `clarifications`, keyed by what each one `resolves` |

Response:

| Field | Type | Meaning |
| - | - | - |
| `goal` | string | the prompt as understood |
| `task_type` | string | for example `data_collection` |
| `target` | object | `entity`, `count`, `output_schema`, `constraints`, `dedup_key` |
| `phases[]` | object\[] | `name`, `parallel`, `subtasks[]` (`intent`, `executor` with `kind` and `ref`, `inputs`, `outputs`, `expected_rows_band`, `expected_success_rate`, `cost_per_run_credits`, `fallback`) |
| `success` | object | `min_records`, `required_fields`, `field_validity_min`, `unique_by`, `notes` |
| `estimate` | object | `plan_tokens`, `runtime_tokens`, `browser_seconds`, `egress_mb`, `est_usd`, `wall_clock_s`, `confidence`, `dominant_risk` |
| `gaps[]` | object\[] | `what`, `for_subtask`, `blocker` |
| `assumptions` | string\[] | what the planner assumed |
| `clarifications[]` | object\[] | `question`, `resolves`, `why`, `options` |
| `is_valid` | boolean | the plan's phases are consistent |

Request and answer (phases trimmed to the first sub-task of each):

```json theme={"dark"}
{"prompt": "Find the current price of the Kindle Paperwhite on amazon.com"}
```

```json theme={"dark"}
{"goal": "Find the current price of the Kindle Paperwhite on amazon.com", "task_type": "data_collection", "target": {"entity": "listing", "count": null, "output_schema": ["product_name", "price", "currency", "availability", "url"], "constraints": ["site=amazon.com", "product=Kindle Paperwhite"], "dedup_key": ["url"]}, "phases": [{"name": "discover_sources", "parallel": false, "subtasks": [{"intent": "find sources holding listings", "executor": {"kind": "search", "ref": "...", "params": {}}, "inputs": [], "outputs": ["candidate_sources"], "expected_rows_band": [0, 0], "expected_success_rate": 0.0, "cost_per_run_credits": 0.0, "fallback": null}]}, {"name": "select", "parallel": false, "subtasks": [{"intent": "rank candidate sources by coverage × our success ÷ cost", "executor": {"kind": "transform", "ref": "select_sources", "params": {}}, "inputs": ["candidate_sources"], "outputs": ["selected_sources"], "expected_rows_band": [0, 0], "expected_success_rate": 0.0, "cost_per_run_credits": 0.0, "fallback": null}]}, {"name": "collect", "parallel": true, "subtasks": ["..."]}, {"name": "dedupe", "parallel": false, "subtasks": ["..."]}, {"name": "validate", "parallel": false, "subtasks": ["..."]}, {"name": "assemble", "parallel": false, "subtasks": ["..."]}], "success": {"min_records": 1, "required_fields": ["url"], "field_validity_min": 0.9, "unique_by": ["url"], "notes": "..."}, "estimate": {"plan_tokens": 448, "runtime_tokens": 0, "browser_seconds": 30.0, "egress_mb": 7.5, "est_usd": 0.01, "wall_clock_s": 8.0, "confidence": 0.5, "dominant_risk": "no scraper yet"}, "gaps": ["..."], "assumptions": ["..."], "clarifications": ["..."], "is_valid": true}
```

Errors:

| Status | `detail` | When |
| - | - | - |
| 402 | `insufficient_credits`, `quota_exceeded` | before the model call |
| 422 | validation list | `prompt` missing, empty or over 8000 characters |
| 429 | `rate_limited` | the per-key drive limit |

Notes:

* Timing: 2 to 3 s; one model call.
* Billing: one plan call (2 credits) when the model produced the plan. When no model is available the planner falls back to a zero-token heuristic, says so in `assumptions`, and is not billed.
* No session is needed; nothing is executed.

## GET /v1/plan/health

Whether planning uses a model.

Auth: Bearer API key.

Response: `ok` (always true when the route answers), `understander` (`llm` or `heuristic`), `provider` (the model provider, or null in heuristic mode).

Errors: 401 only.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.