> ## Documentation Index
> Fetch the complete documentation index at: https://zenofirm.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# The queue

> Every bank and card line staged against a client's books, whatever door it came in by, coded by rules and the assistant, and posted only as a plan a person approved.

The queue is everything staged against a client's books that has not yet been
decided: lines from a live bank connection, lines from a statement file you
downloaded, charges on a company card that are somebody's expense claim. They
all stage identically and nothing after arrival can tell them apart, so a firm
can start on files and add a connection later without re-learning anything.

The queue is held **outside** the ledger. Lines are coded there — by the
client's rules, by history, or by the assistant working the books — and reach
QuickBooks only as a plan somebody approved. Nothing posts from the queue
itself.

The console's **Bank feeds** page shows it and takes verdicts: build a plan, exclude
a line, link one the ledger already holds, approve or send back a claim,
import a statement. The coding itself is done through
[the queue tools](/docs/cloud/tools#the-queue) by whichever assistant the firm has
connected. The page is where you read what was proposed, not where you type it.

## Before the first line arrives

A feed account is a bank or credit-card account you have told Zeno about
and mapped to the QuickBooks account its money lands in. Until an account is
mapped, its transactions are not staged at all — the mapping is what tells the
queue where a posting would go.

Set them up under **Settings → Bank connections**. That page is deliberately
apart from the queue: connecting a login and working a month of lines are
different jobs on different days.

## Getting transactions in

### From a statement file

Any CSV, OFX, QFX or `.qbo` file your bank hands you. In the console, open
**Bank feeds → Import statement**; from a chat client it is
`qb_preview_statement` and then `qb_import_statement`.

It is two steps on purpose. CSV column detection is a guess about somebody
else's spreadsheet, and a wrong guess quietly misfiles a month:

<Steps>
  <Step title="Preview">
    The file comes back with its header as written, which column was read as the
    date, the description, and the amount, and the first rows exactly as the
    importer would produce them — plus how many rows parse and how many it would
    skip. Nothing is staged.
  </Step>

  <Step title="Correct the mapping if it is wrong">
    Point each role at the right column. Pass the same column map to the import
    so the preview and the import cannot drift apart.
  </Step>

  <Step title="Stage it">
    Rows are parsed, deduplicated, and run through the client's coding rules on
    the way in. Nothing reaches QuickBooks.
  </Step>
</Steps>

<Note>
  **Sign convention.** Positive is money **in**, negative is money **out**. Many
  card exports sign it the other way round and list charges as positive; pass
  `invertAmounts` (the console offers a tick box) when that is what you are
  holding.
</Note>

A statement imported twice does not double. Zeno uses the bank's `FITID` when
the format carries one. Otherwise it compares a content hash and reference
details against the queue, so an overlapping date range is not restaged.

### From a live bank connection

Optional, and included in your subscription. Under **Settings → Bank
connections**, choose **Connect a bank**: Zeno returns a link, the person who holds the
banking credentials opens it in whatever browser they like, and signs in to
the bank directly. The credentials go to the bank. Zeno never sees them.

When they are done, the connection lists the accounts it discovered. Each one
stays disabled until you map it, because discovery is not a decision — one
business login routinely carries a savings account and a personal account
nobody will ever code.

After that, new transactions arrive on their own; **Sync now** pulls
immediately. Only posted transactions are staged, so a pending authorization
that changes amount overnight does not stage twice.

<Warning>
  **A lapsed login fails silently.** The sync keeps returning clean empty pages,
  so a dead feed reads exactly like a quiet month. Zeno flags the connection
  as needing reconnection and says how long it has been dark — treat that flag
  as work, not as a notice. Reconnecting keeps the cursor and the history.
</Warning>

Disconnecting a login stops the syncing. Lines already staged or posted keep
their history: disconnecting stops the future, never rewrites the past.

<Info>
  Bank feeds are included in every hosted plan — live connections and statement
  imports both. Connected accounts, bank lines, and statement imports are never
  metered; pricing is by client book only.
</Info>

## Working the queue

The queue's tabs are the questions a bookkeeper actually asks, not the states
the rows happen to be in:

| Tab                                         | What is in it                                                                                                                                                                               |
| ------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Needs coding**                            | Nothing has said what these are yet. Ask the assistant to code them, or teach a rule.                                                                                                       |
| **Rule suggested**                          | A suggest-confidence rule proposed something. The proposal is shown on the line and carried into the plan, where it is approved with everything else — a suggestion never posts on its own. |
| **Ready to plan**                           | Coded, not waiting on anyone, and eligible for the next plan.                                                                                                                               |
| **Claims to review**                        | Expense claims a cardholder has submitted. Approve, or send back with a reason. See [expense claims](/docs/cloud/expenses).                                                                      |
| **Awaiting cardholder**                     | Card charges whose claim is still in the cardholder's court. Shown so a reviewer can see what is owed; not theirs to work.                                                                  |
| **Linked**                                  | Already in the books. These never post.                                                                                                                                                     |
| **All pending** / **Excluded** / **Posted** | The rest of the lifecycle, for when you want it.                                                                                                                                            |

### What a person does here

The page never asks you for an account, a class, a payee or a memo. What a
line is coded to is shown as a fact — with a **rule** badge when a rule did it
— and comes from the client's coding rules, from how the counterparty has been
coded before, or from the assistant you asked to work the month. To change a
coding, tell the assistant; `qb_code_feed_lines` is the write, and
`qb_suggest_coding` is how it reads the history first.

What is yours on the page:

* **Build plan.** Select a run of lines — shift-click works — and build the
  plan from them, or build it from everything that is ready. The plan's review
  page is where the real decision is made.
* **Exclude**, with a reason: a personal charge, a duplicate the bank will
  reverse. Excluding takes a line out of the queue without posting it and
  records why. **Restore** puts it back.
* **Link** a line to a ledger candidate the scan found, when the books already
  hold that money. See [what should not post at all](#what-should-not-post-at-all).
* **Approve** or **send back** a submitted claim.
* **Import statement**, for a month the bank will only hand you as a file.

<Note>
  A line coded by a rule carries a badge saying so. Recoding it — over
  `qb_code_feed_lines` — clears that badge, because the badge means "a rule did
  this", and after the edit it no longer did.
</Note>

## What reaches QuickBooks, and what does not

The interface uses related language for actions with different effects:

|                                                                                              | Reaches QuickBooks                                |
| -------------------------------------------------------------------------------------------- | ------------------------------------------------- |
| **Posting a coded line** — it becomes a check, deposit, card charge, card credit or transfer | **Yes.** A real transaction in the register       |
| **Linking a line to a transaction already in the register**                                  | **No.** The link is Zeno's own record             |
| **Marking anything cleared or reconciled**                                                   | **No.** QuickBooks Online has no interface for it |

### Posting

A coded line becomes a real transaction through the ordinary route — plan,
verdict, apply — and lands in the register: money out of a bank account becomes
a **check**, money in a **deposit**, and on a card a **charge** or **credit**.
Two mirrored lines across two fed accounts fold into a single **transfer**,
because posting each side separately would post the transfer twice.

Every posted entry keeps the identifiers its reversal needs, so
[reverse](/docs/cloud/governed-work#reverse) undoes it natively.

### Linking

Zeno reads the client's register, so when a bank line corresponds to
something already entered — a cheque written last week, a payment applied from
an invoice — it finds it and offers to link them. Linking sets the bank line to
**matched**, which is what the **Linked** tab holds, and it means exactly one
thing:

> This line is already in the books. It will not post.

On the Bank feeds page a linked line shows the QuickBooks transaction it
stands for where its coding would otherwise be: what kind of transaction it
is, its date, the name on it, the account or accounts the money went to, and
the amount. A deposit that several ledger rows account for lists each of them.

That holds even when a plan was already built from the line: the plan shows
it as already posted from then on, and applying the plan skips it.

The transaction in QuickBooks is not touched. It gets no flag, no note, and no
reference back. If you open that transaction in QuickBooks it looks exactly as
it did before, because from QuickBooks' point of view nothing happened — which
is correct, since the money movement was already recorded. Zeno keeps the link
to prevent that bank line from posting a second time.

### Cleared and reconciled

Zeno cannot mark a transaction cleared in QuickBooks Online, and cannot read
whether it is. Neither is a shortcoming of this software: the QuickBooks Online
accounting API exposes no reconciliation interface, no cleared field, and
nothing for the **Banking** review queue. There is no request to make.

Reconciling an account happens in QuickBooks, in the **Reconcile** window, by a
person — exactly as it would if the transactions had been typed in by hand.

<Note>
  **The local edition differs here.** QuickBooks Desktop does allow the cleared
  flag to be set, so Zeno for QuickBooks Desktop can set it:
  `qb_set_cleared_status` marks a transaction **Cleared**, **NotCleared** or
  **Pending**, which is the primitive a reconciliation is built out of. Two
  limits come with it. It sets a flag and does not finish a reconciliation —
  there is no way to record the statement date and ending balance, so a person
  still completes that in the **Reconcile** window, and the register shows a
  cleared check mark rather than the **R** a completed reconciliation stamps.
  Transfers cannot be addressed this way at all; QuickBooks rejects them. See
  [what it can't do](/docs/quickbooks-desktop/limits#cleared-status-is-not-reconciliation).
</Note>

### The bank's balance beside the books

A live connection carries one figure the books do not: what the bank says the
account holds. The queue shows it beside the QuickBooks balance for each fed
account, and — because the two agree only in the moment a feed is fully
drained and posted — shows the difference broken into what causes it:

* **Not yet in QuickBooks** — pending lines on the feed, with how many of
  them already sit in a plan awaiting approval and how many are still
  uncoded. Working the queue closes this part.
* **Excluded on purpose** — lines at the bank that were kept out of the
  books: a personal charge, a duplicate the bank will reverse. A gap that
  stays, and should.
* **What the feed cannot see** — money in QuickBooks the bank has not
  reported yet (a cheque written and not cashed), or at the bank before the
  feed's start date. That is what a reconcile in QuickBooks answers.

Three things to know about the numbers. The bank figure is the bank's
**current** balance, the one that reconciles to a ledger; a banking app shows
the **available** balance, which has holds and pending charges taken off, so
the two differ on purpose and both are shown. It is a snapshot from the last
sync, stamped with the bank's own as-of, not a live read. And a card is
compared as an amount **owed** on both sides, so it does not look off by
twice its balance. The QuickBooks figure is read live every time the panel
is opened. `qb_bank_balance` gives the same figures to the assistant.

## What should not post at all

The most expensive mistake a feed makes is posting something the books already
hold. It reconciles either way, so nobody notices.

Zeno scans for that when the queue loads, before anyone spends time coding
a line that must never post. Two things come back:

* **Ledger candidates** — a transaction already in QuickBooks on the same
  account, within \$0.02 and ±5 business days. The cheque somebody hand-entered
  last Tuesday. Link the line to it and the plan skips it entirely.
* **Transfer pairs** — mirrored lines across two fed accounts that are *one*
  transfer, not a check plus a deposit.

Candidates appear on the line with a score and what the score means in words
— *exact amount, same day*; *close amount and date* — and **Link** beside each
one. A line with a strong candidate is not amber, because it needs linking,
not coding.

The automatic matcher is deliberately tight, and the lines it cannot answer
are exactly the ones a person has to sit down with. That sitting down happens
in the chat: `qb_match_options` gives the assistant everything the ledger
might hold for one line —

* the automatic candidates,
* **groups** of ledger rows that together sum to the line — four cheques
  entered by hand against one lodgement on the statement, which no single-row
  matcher can see,
* the transfer partner, when the line is half of one,
* and a free search of the register, for the cheque that cleared three weeks
  late or was entered for the wrong amount.

It always ends in a **link**, never a posting.

## Posting what is left

Coded lines become a plan, and the plan is an ordinary one:

* money out becomes Checks, or credit-card charges on a card account;
* money in becomes Deposits, or credit-card credits;
* mirrored pairs fold into a single Transfer;
* every entry carries `bankfeed:<id>`, so the posted transaction stays linked
  to the raw bank line it came from.

From there it is [plan, review, apply, reverse](/docs/cloud/governed-work) exactly
as any other batch: a person reads the table, approves it in their own words,
and only then does anything reach QuickBooks. A feed that posted its own
entries would be a second path to the ledger, and a second path is a path
where the gates are not.

By default every pending line with a coded account is included. Pick lines
explicitly when you want a subset. From the chat, `qb_plan_feed` can also
sweep the uncoded ones into a holding account the firm reviews later rather
than leaving them behind.

## Use one feed, not two

QuickBooks Online has a bank feed of its own. Which one feeds an account
decides more than where you click: it decides whether Zeno can work those
transactions at all.

### What staging here buys

The QuickBooks Online accounting API exposes nothing for the **Banking**
review queue — no way to list what is waiting there, accept it, match it, or
read the bank rules. A line sitting in QuickBooks' For Review queue is not
something Zeno can read, code, or be asked about.

Zeno sees that money only after somebody has accepted it in QuickBooks, at
which point it is a posted register entry that a person already coded. The
coding is the work, and by the time the transaction becomes visible the work
is finished.

Staging the account here instead — from a live connection or an imported
statement — puts the lines where the rest of the software can reach them:

* **Coding rules run on arrival.** A descriptor the firm has already decided
  about is filled in before anyone opens the queue.
* **Ledger matching runs before you code.** Each line is compared against the
  register, and anything the books already hold is held back rather than
  posted twice.
* **History is available as evidence.** `qb_suggest_coding` answers a
  descriptor with the rule that matches it, or with how this counterparty has
  actually been coded and how often — a proposal you can read, not a guess you
  have to trust.
* **The assistant works the month.** The queue is addressable through
  [the queue tools](/docs/cloud/tools#the-queue), so an agent codes the batch and
  hands back a plan for review. That is the only road for coding: the console
  shows the result and takes the verdict.
* **What posts carries its own history.** Every entry keeps the run id that
  reverses it and the approval that let it through.

None of that reaches a line in QuickBooks' own queue.

### Running both

If the same account is fed by both, every transaction exists twice over: once
as the entry Zeno posted into the register, and once as a downloaded line
waiting in QuickBooks' **Banking** tab.

QuickBooks will usually notice and offer to match its downloaded line to the
entry Zeno posted, which is the outcome you want — but somebody has to
accept those matches in QuickBooks, one review queue on top of another, and
Zeno cannot do it for them.

<Warning>
  Pick one feed per account. Feeding an account here means turning that
  account's bank feed **off** in QuickBooks. Running both means working every
  transaction twice.
</Warning>

Zeno does not know which accounts QuickBooks is feeding — that is not in the
API either — so it cannot warn you. It is worth checking before connecting a
bank or importing a first statement.

## Teaching it as you go

A coding decision worth making once is worth keeping. Tell the assistant
*always code this vendor here* and it saves a rule with `qb_learn_rule`, so the
next import answers itself — and before saving one it can dry-run the rule
against the pending queue with `qb_test_rule` to see exactly which lines it
would catch. "This catches these 14 lines" is a reviewable proposal; "trust
me" is not. The rules a firm has taught are listed on the console's **Coding
rules** page.

Rules come in two confidences. An **auto** rule fills the coding on arrival. A
**suggest** rule proposes it and waits, which is the right setting for a
descriptor that usually but not always means one thing.

See [firm memory](/docs/cloud/tools#firm-memory) for the tools behind this.

## Cards that are somebody's expenses

A fed card account can be turned into an expense-claim account, after which
every charge on it is a claim that needs a receipt, a cardholder's submission,
and a reviewer's approval before it is eligible for a plan at all. It is the
same queue with a second lifecycle on some of its lines: the **Claims to
review** and **Awaiting cardholder** tabs are where that lifecycle shows. See
[expense claims](/docs/cloud/expenses).
