---
title: "Entry Coding Inference Proposals"
method: POST
path: "/bank-entries/{entry_id}/coding-inference-proposals"
tags: ["reconciliation"]
---

# Entry Coding Inference Proposals

`POST /bank-entries/{entry_id}/coding-inference-proposals`

## 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}/coding-inference-proposals`
- Auth: none declared

Infer a coding for one suspensed entry from its counterparty-IBAN history.

The detail-page "infer coding from history" action (doc/pipeline.md
§"Bank-transaction coding from IBAN history"). Advisory: records a **held**
``autopost:bankcode:`` decision (idempotent — an existing decision is
returned as-is); the human books it via the accept-decision flow. The
service drops DB locks before the accountant call (two-transaction
choreography). 503 when the accountant is unreachable.

⚠️ **409 since ZET-316** — a contract change; this route previously only ever answered
200 or 503. It refuses when no fiscal year the company has books for covers the
movement's date and the R2-32 rollover rule will not open one (a prior year, or a gap
between two existing years). Coding the entry would otherwise have MINTED that year,
with no opening balances, as a side effect of an advisory inference. The remedy is named
in the message: open the year with ``POST /companies/{company_id}/gl/fiscal-years``. No
decision row is recorded for that refusal, so the entry stays inferable once the year
exists.

⚠️ **409 ``conflict.bankAccountNotMapped`` since F2779** — the entry's bank account has no
ledger account number (or one its fiscal-year chart lacks), so the accountant could not
resolve the bank leg. Refused before the accountant call; nothing is recorded.

## Path parameters

- `entry_id` string, required

## Headers

- `authorization` string, nullable

## Cookies

- `access_token` string, nullable

## Response `200`

Successful Response

- CodingInferenceResponse: The on-demand "infer coding from history" proposal (always advisory — a ``held`` decision the human books via the accept flow). ``no_history=True`` means no usable IBAN history exists (no decision was recorded); ``existing=True`` means a prior decision was returned as-is.
  - `no_history` boolean
  - `existing` boolean
  - `decision_id` string, nullable
  - `outcome` string, nullable
  - `status` string, nullable
  - `mode` string, nullable
  - `reason` string, nullable
  - `confidence` string, nullable
  - `history` CodingInferenceHistory: The IBAN-history rationale behind the proposal.
    - `count` integer
    - `constant_amount` boolean
    - `amount_match` boolean
    - `median_gap_days` integer, nullable
  - `lines` CodingInferenceLine[]
    - `side` string, required
    - `account` string, required
    - `amount_cents` integer, required
    - `vat_code` string, nullable
    - `text` string, nullable
  - `fx` CodingInferenceFx: FX marker on an inferred coding (ZET-384): the proposal's amounts are the movement's own ``entry_currency`` figures, and booking converts them into ``base_currency`` at the rate published for the movement's date — always held, review before booking. (Before ZET-384 the nominal was booked 1:1 as base.)
    - `entry_currency` string, required
    - `base_currency` string, required
    - `translation` string, required

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