---
title: "Opening Entries Preview"
method: POST
path: "/onboarding/opening-entries/preview"
tags: ["onboarding"]
---

# Opening Entries Preview

`POST /onboarding/opening-entries/preview`

## Request

- Base URL: `https://app.zeno-works.ch` (the document declares no server; this is the origin it was published from)
- URL: `https://app.zeno-works.ch/onboarding/opening-entries/preview`
- Auth: none declared

Validate (possibly user-edited) opening entries before the atomic create (eligible).

Stateless: no accountant call, no DB write. Returns per-entry validation warnings and
a ``postable`` flag the wizard uses to gate "Create". The GL post at create time stays
the final authority.

## Headers

- `authorization` string, nullable

## Cookies

- `access_token` string, nullable

## Request body

- OpeningEntriesPreviewRequest: Validate (possibly user-edited) opening entries before the atomic create (stateless). Carries the in-progress journal entries (accountant shape: ``[{header, lines:[…]}]``) plus the target-FY chart so the same render-time validation used post-onboarding (``export.validate.validate_document``) runs against the edited document. ``opening_balance_account_number`` is the clearing account the opening entries balance against. The accountant only synthesizes it into the proposal (never into the document chart), and the atomic create seeds it via ``ensure_opening_balance_account_for_fiscal_year`` right before posting — so the preview must add it to the validated chart too, or it rejects the clearing line as ``LINE_ACCOUNT_NOT_IN_CHART`` and over-blocks "Create".
  - `journal_entries` object[]
  - `chart_accounts` OnboardingChartAccountIn[]
    - `account_number` string, required
    - `account_name` string, nullable
    - `category` 'asset' | 'liability' | 'equity' | 'income' | 'expense' | 'tax' | 'other' | 'unknown': The account-type axis of a ledger account (Swiss-KMU chart of accounts). Distinct from — but derived from — ``LineRole`` (the journal-line semantic role). ``unknown`` is the conservative default when classification can't decide; ``other`` covers genuinely ambiguous / closing (9xxx) accounts.
    - `is_profit_loss` boolean
    - `is_contra` boolean
    - `is_intentional` boolean
    - `account_number_guess` string, nullable
    - `journal_usage_count` integer
    - `prior_year_turnover_cents` integer, nullable
    - `prior_year_turnover_fiscal_year` integer, nullable
  - `base_currency` string
  - `target_fiscal_year` integer, required
  - `opening_balance_account_number` string, nullable

## Response `200`

Successful Response

- OpeningEntriesPreviewResponse: Per-entry validation warnings + whether the edited document is safe to post. ``postable`` is ``True`` only when there are no blocking warnings (unbalanced entry, account not in the target-FY chart, non-positive amount, non-base currency) — the wizard gates "Create" on it. The GL post remains the final authority at create time.
  - `warnings` PreviewWarning[]
    - `entry_id` string, nullable
    - `line_id` string, nullable
    - `code` string, required
    - `message` string, required
    - `severity` string
  - `postable` boolean

## Other responses

- `422`: Validation Error

---

[API](https://skmtc.dev/zeno-works/apis/zeno-api.md) · [All operations](https://skmtc.dev/zeno-works/apis/zeno-api/llms.txt) · [OpenAPI document](https://skmtc.dev/zeno-works/apis/zeno-api/revisions/1eb93dde146c?raw)
