---
title: "Manual Code Entry"
method: POST
path: "/bank-entries/{entry_id}/manual-coding"
tags: ["reconciliation"]
---

# Manual Code Entry

`POST /bank-entries/{entry_id}/manual-coding`

## 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/bank-entries/{entry_id}/manual-coding`
- Auth: none declared

Book one bank movement by hand, straight from the entry (ZET-102 AC #3).

The fallback when no document exists: the caller supplies only the counter lines
(account + amount + optional VAT code), and the service resolves the balancing
leg — Suspense when the movement is already parked there, the bank account
otherwise. Posts through the same path as the inferred coding, recording the
surface it was booked from (a call made over MCP records ``origin=mcp``, not
``human``), so the movement is finalized and stays matched.

**A line carrying ``vat_code`` is GROSS**: it is split into a net counter line plus
one VAT leg on that code's tax account, so the lines still total the movement and the
booking reaches the MWST-Abrechnung. Do **not** also send an explicit line on that
VAT account — that would declare the tax twice and is refused (422).

**``use_default_vat`` asks the server to pick the code** for this movement's own
posting date instead of naming one (mutually exclusive with ``vat_code``, 422). It
exists so a bulk clear-out can apply one *treatment* to many movements without
applying one *rate*: the Swiss standard rate changed on 2024-01-01, and a caller that
resolved the code itself would silently share it across a selection that straddles
the boundary. Resolving to nothing is normal (not liable, a gross-booking method, or
an ambiguous catalog) and simply books the line VAT-less.

**No AR/AP control accounts here** (422): this door cannot open or clear a
receivable/payable, because it has no open item to tag and the subledger would
silently diverge from the ledger. Link the movement to what it pays
(``/accounting-invoices`` or ``/gl-open-items``) and settle it instead.

422 when the lines do not total the movement, no balancing account resolves, a line
hits an AR/AP control or a bank account's own ledger account, or a VAT code is
unusable/unpairable; 409 when the movement is already booked, matched to a document
(the error names the unlink routes that detach the match), its bank account is not
yet confirmed, or a line names another bank account that already holds the transfer.

**409 ``conflict.bankEntryPaysOpenItem``** when the movement looks like the payment of an
open item linked to no movement (same party; the same amount, or — for an item in another
currency — the foreign amount the movement's text states; dated within 35 days): link it
with ``link_gl_open_item`` and ``settle_entry`` instead. Send ``confirm_not_open_item_payment``
to book it anyway (any caller; the confirmation is recorded with the actor).

## Path parameters

- `entry_id` string, required

## Headers

- `authorization` string, nullable

## Cookies

- `access_token` string, nullable

## Request body

- ManualCodingRequest
  - `lines` ManualCodingLineIn[], required
    - `account` string, required
    - `amount_cents` integer, required
    - `vat_code` string, nullable
    - `text` string, nullable
    - `use_default_vat` boolean
  - `description` string, nullable
  - `posting_date` string, date, nullable
  - `confirm_not_open_item_payment` boolean

## Response `201`

Successful Response

- ManualCodingResponse
  - `msg` string, required
  - `journal_entry_id` string, required
  - `bank_entry` BankEntryDetail, required
    - `id` string, required
    - `company_id` string, required
    - `bank_account_id` string, required
    - `bank_statement_id` string, required
    - `entry_index` integer, required
    - `amount` string, required
    - `currency` string, required
    - `credit_debit` 'credit' | 'debit', required
    - `booking_date` string, date, nullable
    - `value_date` string, date, nullable
    - `account_servicer_ref` string, nullable
    - `end_to_end_id` string, nullable
    - `reference` string, nullable
    - `reference_type` string, nullable
    - `remittance_info` string, nullable
    - `additional_entry_info` string, nullable
    - `counterparty_name` string, nullable
    - `counterparty_iban` string, nullable
    - `counterparty_id` string, nullable
    - `reconciliation_status` 'unmatched' | 'partially_matched' | 'matched' | 'ignored', required
    - `settlement_status` 'unsettled' | 'settled' | 'partially_settled' | 'suspense': Clean-bank settlement state of a bank entry (distinct from ``reconciliation_status``, which the matcher owns). Set by ``settle_bank_entry``.
    - `matched_amount` string, required
    - `possible_duplicate` boolean, required
    - `is_own_payment` boolean
    - `created_at` string, date-time, required
    - `has_invoice` boolean
    - `has_journal` boolean
    - `has_ledger_match` boolean
    - `needs_review` boolean
    - `journal_exportable` boolean
    - `journal_export_blocked_reason` string, nullable
    - `journal_export_soft_warning` string, nullable
    - `counterparty_hint` InvoiageCoreAccountingReconciliationSchemasReconciliationCounterpartyBrief
      - `id` string, required
      - `kind` string, required
      - `name` string, required
      - `normalized_name` string, required
      - `vat_number` string, nullable
    - `counterparty` InvoiageCoreAccountingReconciliationSchemasReconciliationCounterpartyBrief
      - `id` string, required
      - `kind` string, required
      - `name` string, required
      - `normalized_name` string, required
      - `vat_number` string, nullable
    - `match_quality` 'full' | 'strong' | 'partial' | 'weak' | 'manual' | 'imported': Graded bank-entry ↔ invoice match quality (match-quality feature, 2026-06-09). Auto bands (from how many matchable fields line up, see ``services.reconciliation``): ``full`` > ``strong`` > ``partial`` > ``weak``. ``manual`` (user-created/confirmed) and ``imported`` (asserted by a source export) are provenance values that win over any auto band.
    - `links` BankEntryLinks
      - `items` LinkedItem[]
        - `link_id` string, required
        - `item_id` string, required
        - `allocated_amount` string, required
        - `match_quality` 'full' | 'strong' | 'partial' | 'weak' | 'manual' | 'imported', required: Graded bank-entry ↔ invoice match quality (match-quality feature, 2026-06-09). Auto bands (from how many matchable fields line up, see ``services.reconciliation``): ``full`` > ``strong`` > ``partial`` > ``weak``. ``manual`` (user-created/confirmed) and ``imported`` (asserted by a source export) are provenance values that win over any auto band.
        - `match_signals` object, nullable
        - `confidence` string, nullable
        - `filename` string, nullable
        - `direction` string, nullable
      - `journal_entries` LinkedJournalEntry[]
        - `link_id` string, required
        - `journal_entry_id` string, required
        - `allocated_amount` string, required
        - `match_quality` 'full' | 'strong' | 'partial' | 'weak' | 'manual' | 'imported', required: Graded bank-entry ↔ invoice match quality (match-quality feature, 2026-06-09). Auto bands (from how many matchable fields line up, see ``services.reconciliation``): ``full`` > ``strong`` > ``partial`` > ``weak``. ``manual`` (user-created/confirmed) and ``imported`` (asserted by a source export) are provenance values that win over any auto band.
        - `match_signals` object, nullable
        - `confidence` string, nullable
        - `document_number` string, nullable
        - `description` string, nullable
      - `accounting_invoices` LinkedAccountingInvoice[]
        - `link_id` string, required
        - `accounting_invoice_id` string, required
        - `allocated_amount` string, required
        - `released_amount_currency` string, nullable
        - `match_quality` 'full' | 'strong' | 'partial' | 'weak' | 'manual' | 'imported', required: Graded bank-entry ↔ invoice match quality (match-quality feature, 2026-06-09). Auto bands (from how many matchable fields line up, see ``services.reconciliation``): ``full`` > ``strong`` > ``partial`` > ``weak``. ``manual`` (user-created/confirmed) and ``imported`` (asserted by a source export) are provenance values that win over any auto band.
        - `match_signals` object, nullable
        - `confidence` string, nullable
        - `invoice_number` string, nullable
        - `counterparty_name` string, nullable
        - `direction` 'payable' | 'receivable'
        - `currency` string, nullable
        - `open_amount` string, nullable
        - `needs_discharge` boolean
        - `published_rate` string, nullable
        - `booking_rate` string, nullable
      - `gl_open_items` LinkedGlOpenItem[]
        - `link_id` string, required
        - `gl_open_item_id` string, required
        - `allocated_amount` string, required
        - `released_amount_currency` string, nullable
        - `match_quality` 'full' | 'strong' | 'partial' | 'weak' | 'manual' | 'imported', required: Graded bank-entry ↔ invoice match quality (match-quality feature, 2026-06-09). Auto bands (from how many matchable fields line up, see ``services.reconciliation``): ``full`` > ``strong`` > ``partial`` > ``weak``. ``manual`` (user-created/confirmed) and ``imported`` (asserted by a source export) are provenance values that win over any auto band.
        - `match_signals` object, nullable
        - `confidence` string, nullable
        - `document_no` string, nullable
        - `counterparty_name` string, nullable
        - `direction` 'payable' | 'receivable'
        - `open_amount` string, nullable
        - `currency` string, nullable
        - `due_date` string, date, nullable
        - `is_credit_note` boolean
        - `needs_discharge` boolean
        - `published_rate` string, nullable
        - `booking_rate` string, nullable
      - `gl_journal_entries` LinkedGlJournalEntry[]
        - `link_id` string, required
        - `gl_journal_entry_id` string, required
        - `allocated_amount` string, required
        - `match_quality` 'full' | 'strong' | 'partial' | 'weak' | 'manual' | 'imported', required: Graded bank-entry ↔ invoice match quality (match-quality feature, 2026-06-09). Auto bands (from how many matchable fields line up, see ``services.reconciliation``): ``full`` > ``strong`` > ``partial`` > ``weak``. ``manual`` (user-created/confirmed) and ``imported`` (asserted by a source export) are provenance values that win over any auto band.
        - `match_signals` object, nullable
        - `confidence` string, nullable
        - `entry_no` integer, nullable
        - `posting_date` string, date, nullable
        - `description` string, nullable
        - `status` 'draft' | 'posted' | 'reversed'
        - `transfer_bank_entry_id` string, nullable
    - `settlement_blocker` string, nullable
    - `pays_card_bill` boolean
    - `card_clearing_account_code` string, nullable

## 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)
