---
title: "Preview a budget plan draft without writing it."
method: POST
path: "/v1/budget/plan/preview"
---

# Preview a budget plan draft without writing it.

`POST /v1/budget/plan/preview`

## Request

- Base URL: `https://api.candor.money`
- URL: `https://api.candor.money/v1/budget/plan/preview`
- Auth: HTTP bearer

Check a budget plan before saving it. Validates the same body as a budget create, checks each line against observed categories, and writes nothing.

## Headers

- `Idempotency-Key` string, required

## Request body

- object: The same body as a budget create, read without saving. Nothing is stored and the active plan is untouched.
  - `period` string, required: The month this plan governs, as YYYY-MM.
  - `currency` string, required: Three-letter uppercase ISO code the plan is denominated in, such as USD. Every line amount is read in it, so a plan in the wrong currency compares against the wrong spending.
  - `approval_note` string: What the user said about this plan, in their words, when they said something. Optional.
  - `approval_source` string: Where their words came from, such as the conversation or message, when you pass approval_note.
  - `policy_notes` string
  - `recurs_monthly` boolean: Whether this plan should carry into later months instead of applying to this period alone.
  - `lines` object[], required: Replaces the whole plan as a set. A category left out is unbudgeted, not carried over from the previous plan.
    - `category` string, required: The effective category this line governs, matching the category transactions carry after corrections and rules. A category nothing resolves to allocates money against spending that never arrives.
    - `monthly_amount` string, required: A positive amount in the plan's currency, as a decimal (`250.00`) or money text in that currency (`USD 250.00`); not `$250`.
    - `line_type` 'recurring' | 'flexible' | 'goal' | 'cushion' | 'other', required: How the line behaves against actuals: recurring is a committed obligation, flexible is discretionary, goal funds a saved goal, and cushion is deliberate slack rather than a spending target.
    - `policy_note` string
    - `rollover_enabled` boolean: Whether an underspend carries into the next period instead of resetting. This depends on the plan recurring: with recurs_monthly false there is no next period to carry into, and the request returns a warning saying nothing will accumulate.

## Response `200`

Envelope with the plan as Candor would store it, its monthly total, the active plan it would supersede, warnings for lines no posted category matches, and a budget.create continuation that saves it.

- ResponseEnvelope
  - `schema_version` string, required
  - `generated_at` string, date-time, required
  - `request_id` string, required
  - `status` 'success' | 'partial_success' | 'action_required' | 'error', required
  - `user_message` string: Optional concise user-safe message the calling agent may adapt.
  - `data_freshness` DataFreshness
    - `balances_last_synced_at` string
    - `coverage` 'complete' | 'partial' | 'stale' | 'unavailable', required
    - `holdings_last_synced_at` string
    - `transactions_last_synced_at` string
  - `metadata` object: Response-level protocol metadata such as package compatibility and workspace opening identity or timing. It is not financial workspace data and must not be treated as attention.
    - `view_url` string, uri: Authenticated dashboard destination related to this response. May open a section rather than reproduce the returned records or filters. Per-record view_url values identify exact supported record views. Use returned URLs instead of constructing paths.
  - `warnings` object[], required
  - `errors` AgentError[], required
    - `code` string, required
    - `expires_at` string
    - `idempotency_key` string: Stable key to reuse when retrying this identical logical operation.
    - `message` string, required
    - `recovery_url` string, uri
    - `required_capability` string
    - `retry_after_seconds` integer: Machine-actionable delay before retrying the identical logical operation.
    - `retryable` boolean, required
    - `suggested_command` string
  - `next_actions` AgentAction[], required
    - `intent` string, required
    - `command` string, required
    - `args` object, required
    - `shell` string, required
  - `action` WorkspaceAction
    - `id` string, required
    - `operation` string, required
    - `reason` string, required
    - `root_action_id` string, required
    - `parent_action_id` string
    - `task_key` string
    - `status` 'started' | 'succeeded' | 'refused' | 'failed', required
    - `created_at` string, date-time, required
    - `completed_at` string, date-time
  - `data` object, nullable, required: Operation-specific result data, or null when the request ends in an error.

## Other responses

- `default`: Structured Candor error envelope with machine-readable codes, recovery guidance, and retry timing when applicable.

---

[API](https://skmtc.dev/candor/apis/candor-api.md) · [All operations](https://skmtc.dev/candor/apis/candor-api/llms.txt) · [OpenAPI document](https://skmtc.dev/candor/apis/candor-api/revisions/6c050f72e956?raw)
