Skip to main content
A Follow-up is the mark of pending work on one Bank Movement or one Invoice, stored on that record. It proposes how to book or match the record, asks a person a question, or marks the record as waiting on something. An agent such as Erwin or a person can write it. A person then approves it or discards it, in the app or through the API. Until someone approves it, a Follow-up changes nothing in the books. Use Follow-ups when an agent or integration prepares reconciliation work but a person should confirm it. The agent writes the Follow-up. The person reviews the proposed steps and approves them with one write.
Each host has one route under its own path:
  • Bank Movement: /api/entities/:entityId/bank-accounts/:bankAccountId/movements/:movementId/follow-up
  • Invoice: /api/entities/:entityId/invoices/:invoiceId/follow-up
Both routes accept the same bodies and return the same errors. This page writes …/follow-up for either one.

Which records can hold a Follow-up

An Invoice or Bank Movement excluded from the books is no pending work, so it holds no Follow-up. Excluding a record clears its Follow-up. A PUT or an approval on an excluded record answers 409 with INVOICE_EXCLUDED_ERROR or BANK_MOVEMENT_EXCLUDED_ERROR. A record holds at most one Follow-up. Writing a new one replaces the current one. Every Bank Movement and Invoice row carries a followUp field. It holds the Follow-up as written, or null when the record has none. To find records by Follow-up, filter GET /movements or GET /invoices/pages with followUpKind. It takes proposal, question, waiting, or none (records with no Follow-up).

Kinds

The kind field tells the three Follow-ups apart. Each kind has its own fields and says who moves next. A question with an empty options array is an open question. No approval can run it. In the app, a person answers it to Erwin from the record’s panel, and Erwin writes a new Follow-up from the answer. A record that waits stays unbooked. For example, when only one leg of an internal transfer has arrived, leave that leg unbooked and mark it waiting. Do not book it to the bridge account.

In the app

The panel of a Bank Movement or an Invoice shows its Follow-up in a Follow-up section (Seguimiento in Spanish), with the proposed steps of each Plan named in full:
  • Approve runs the Plan of a proposal. For a question, Choose runs the Plan of the option you pick. The app blocks either one, and says why, while the Plan names a record the Entity doesn’t hold, such as a missing account or the missing Recognition Account of a deferred line.
  • A line that a booking defers shows its terms in one sentence under it: the months, the Recognition Account, and the amount of each month. For example, Diferido de oct 2026 a dic 2026 (3 meses) · se reconoce en 4.01.01.02 Ventas B2B · $350.000 / mes.
  • Discard removes the Follow-up of any kind.
  • Answer Erwin (Responder a Erwin) lets you write to Erwin about that record, for every kind. Use it to answer a question, correct a proposal, or tell Erwin what a record waits on. Your answer is posted to Erwin in the record’s ERP Thread, and the panel opens its Thread tab (Hilo), where you follow what Erwin does. Erwin acts with your rights, and writes, replaces, or settles the Follow-up through these routes.
A person does not set a Follow-up directly in the app. To mark a record waiting, ask Erwin in the record’s ERP Thread. Listings show the Follow-up as a chip with its kind: Proposal, Question, or Waiting (Propuesta, Pregunta, En espera):
  • The bank Movement listings, of one Bank Account and of every account, and the Invoice listings show it in their own Follow-up column. Hover or focus the chip to read the reason or the question. You can hide the column from the Display menu.
  • In these listings, approve a proposal or discard a Follow-up of any kind from the row itself, without opening the panel. To answer a question, open the panel and choose an option.
  • The Filters menu of each listing filters by Follow-up kind, or by the records with none.

Plans

A Plan is an ordered list of acts that an approval runs. Each act matches one existing API route. It carries the path ids of that route and the same body that route takes. A Plan needs at least one act. Keep these rules in mind when you build one:
  • You choose every id. Each entry id and each line id in the Plan is a UUID you generate. See Ledger Entry Line ids.
  • A later act can name a line an earlier act creates. Use the line id you gave it. For example, one Plan can book an Invoice and then match a Movement to the Invoice’s Control Line.
  • An act can target a record other than the host. A Plan on one leg of an internal transfer can book both legs and match the bridge lines.
  • A bookInvoice act carries no booking version. Writing the Follow-up changes the Invoice, so a version read before the write never matches at approval. Sintropix drops expectedBookingVersion from the act’s booking and does not store it. The Follow-up id guards the Plan instead: an approval names the Follow-up it read, and a replaced one refuses to run.
  • An assign clears the rest parked on the Suspense Account. Use it on a Bank Movement booked with a Suspense line. With a lineId, it settles that open line. With lineId: null, it books the amount to the accounts of its lines. It adds lines to the Ledger Entry that booked the Movement, so it names no entry of its own.
  • Sintropix validates the acts only on approval. A PUT checks the shape of the Plan, not whether each booking balances or each line is still open. Check the bodies before you write them.

PUT …/follow-up

Set or replace the Follow-up of a record. Setting one changes no books. Body: one of three shapes, chosen by kind. Retrying a PUT with the same id and the same body changes nothing. Sending the current id with a different body answers 409 FOLLOW_UP_ALREADY_EXISTS_ERROR. An approval names a Follow-up by its id, so a new body always needs a new id. Response (200): the host’s own update answer.
  • Bank Movement: { movement, bankAccount }
  • Invoice: the same answer as PATCH /invoices/:invoiceId
This example proposes matching a Movement to the Control Line of an open Invoice:
A record waiting on a document that has not arrived yet:
A Plan that assigns the rest of an overpaid Movement to the Control Line of another Invoice:
A question with two options, where each plan matches the Movement to a different Invoice:

GET …/follow-up

Read the Follow-up of a record with every record in its Plan named, so you can show it to a person without extra reads. Response (200): { followUp }, where followUp is null when the record has none. Otherwise it has the fields written with PUT, except that each act in plan (and in each option’s plan) is replaced by its named detail:
  • movement names the Movement with its date, amount, side, description, and Bank Account.
  • invoice names the Invoice with its document kind, number, direction, issue date, total, currency, and Partner.
  • controlLineId is the id of the line in newLines that the booking makes the Invoice’s Control Line, or null for a tax_only document, which books no Control Line. Another line in newLines can post to the same account. In the app, the Plan marks the Control Line as línea del documento.
  • Each item in newLines is a line the act creates: its id, side, functionalAmount, transactionCurrency, and transactionAmount, with its account ({ id, code, name }) and partner ({ id, name }) named, and its deferral.
  • deferral is null unless the line carries deferral in a bookInvoice act. Then it holds the terms the booking will defer the line by: startMonth (YYYY-MM), monthCount (integer), and recognitionAccount ({ id, code, name }), the account each Release will land in.
  • Each target is a line to settle. Its kind is existing (a line on the books, with its current openAmount and any Invoice it controls), new (a line an earlier act creates, with its actIndex), or notFound. The target of an assign is null when its lineId is null.
A named record is null when the Plan names a record the Entity does not hold. That includes the recognitionAccount of a deferral. Approving that Plan fails. A bookInvoice act whose Plan defers a line reads, for example:
The example shows only the deferred line. The other lines of the booking, including the Control Line, carry "deferral": null.

POST …/follow-up/approve

Run the Plan of the current Follow-up, then clear it. Sintropix runs every act in order in one transaction, through the same checks as the act’s own route. If any act fails, nothing is written and the Follow-up stays. Body The body accepts no other fields. Response (200): the host’s own update answer plus acts. acts holds one result per act, in Plan order. Each result carries its act and the same answer as the act’s own route.

DELETE …/follow-up

Discard the Follow-up of a record. Discarding changes no books. Response (200): the host’s own update answer. For a Bank Movement, { movement, bankAccount }. For an Invoice, the same answer as PATCH /invoices/:invoiceId.

When Sintropix clears a Follow-up

A Follow-up advises on the record as it stood when it was written. Sintropix clears it when the record’s reconciliation changes:
  • Booking or matching the Bank Movement.
  • Unbooking the Ledger Entry that booked the Bank Movement.
  • Assigning or unassigning the Bank Movement’s Suspense line.
  • Booking the Invoice.
  • Creating or deleting an Allocation on a line of the Bank Movement or the Invoice.
  • Excluding the Bank Movement or the Invoice from the books.
An approval that names a cleared or replaced Follow-up answers 409 FOLLOW_UP_STALE_ERROR. Read the record again and review its current Follow-up.

Audit trail

Setting, approving, and discarding a Follow-up appear in the audit trail as changes to the host row. In row images, the Follow-up sits under the follow_up key. Images written before Follow-ups replaced Recommendations keep it under recommendation, with a status of confident, needs_clarification, or waiting instead of a kind.

Domain errors

An act that fails on approval answers with the error of its own route, for example LEDGER_ENTRY_LINE_ALREADY_EXISTS_ERROR.

Status codes