Exports reference
Export is the last stage: approved invoices leave inletAP and become bills in your ledger, or rows in a file your ledger can import. This page describes what is sent, what the statuses mean, and what happens when a posting fails.
Export is a deliberate act. Approving an invoice marks it ready and nothing more; somebody — or, in time, a schedule — starts the batch.
Connector kinds
| Kind | What it is | Availability |
|---|---|---|
quickbooks_online | A direct connection to a QuickBooks Online company. Approved invoices are created as Bills. | Every plan, including the free one |
xero | A direct connection to a Xero organization. Approved invoices are created as ACCPAY bills, with the source PDF attached where the invoice arrived with one. | Every plan, including the free one — in limited release while it is new |
csv | A CSV whose columns you define yourself, downloaded from the export batch. | Every plan |
sftp | The same CSV, pushed to an SFTP destination. Set up by us with you — there is no self-serve screen for it yet. | Pro and above |
The Xero connector is in limited release while it is new. No plan excludes it, but inletAP is an uncertified Xero app and the pool of connections we may hold is capped on Xero's side, so a new connection can be refused for a reason that is ours rather than yours. If that happens you are told so in words, at the moment you try to connect, rather than being sent to Xero for an authorization we could not use.
There is a second cap at your end, and we cannot see it: a Xero organization may connect at most two uncertified apps at a time. If Xero itself refuses the connection and says you have reached that limit, disconnect an app you no longer use — in Xero, under Settings → Connected apps — and try again. Nothing is wrong with your inletAP workspace, and reconnecting on its own will not clear it.
How many ledgers may receive bills
Connecting a ledger is never capped. Switching Post approved bills here on is, and the cap is counted across QuickBooks and Xero together:
| Plan | Ledgers that may be switched on |
|---|---|
| Free | 2 |
| Starter | 3 |
| Growth | 5 |
| Pro, Enterprise | Unlimited |
Past the cap the switch is refused with a sentence naming your plan. Turn one ledger off, or upgrade, then switch the next one on.
There is no property management system connector. AppFolio, Buildium, Yardi and Rent Manager are not built — no connector, and no ready-made column set for any of them either. What you have instead is a generic CSV: you set the columns to match whatever your system's import expects, once. It is less magical than a direct connector and it works everywhere, which on balance is a fair trade.
That paragraph is about export — bills leaving inletAP for another system. Data coming the other way is a separate thing and works differently: at setup you can upload a file you exported from your own system and load your properties, units, vendors and entities from it, mapping your columns to ours once. See importing your data. It is still a file you produce yourself, not a connection — there is no live link to a property management system in either direction.
Connector states
| State | Meaning | What to do |
|---|---|---|
connected | Working. Batches can be posted. | Nothing. |
action_required | The connection has been rejected and cannot be renewed on its own — typically because the stored authorization was revoked or expired at the ledger's end. | Reconnect the company. Nothing posts until you do. |
disconnected | No live connection. | Connect it, or export by CSV in the meantime. |
A batch you aim at a named ledger is refused before it is queued if that connection is not connected — or, for QuickBooks, if the company on the other end cannot hold bills at all. A connection that is not connected is left out of an ordinary run entirely. One clear sentence at the point of clicking is better than a batch full of parked invoices twenty minutes later.
Runs, batches and items
One export is a run. A run holds one batch per destination: post to QuickBooks and Xero together and that run has two batches, each with its own status. Inside a batch there is one item per invoice per destination, and the item is what carries an outcome — the ledger's id for the bill it became, or the reason it did not.
Export history shows each batch and the run it belongs to, and offers two retries. Retry replays that one batch. Retry the whole run re-queues only the batches of the run that failed, so a ledger that already took the bill is never asked twice.
Export statuses
Batches and the items inside them share the same four statuses.
| Status | Meaning |
|---|---|
pending | Queued. It also covers the gaps between scheduled attempts, so a pending batch may have a post in flight. |
processing | A worker is running it now. |
succeeded | Every bill posted and every one settled at the amount the invoice states. |
failed | The batch did not complete. Its documents move to failed_export. |
failed means "something needs a person", not "nothing posted". A batch reads failed when any invoice is parked, when any post is still waiting on a retry, and when a bill posted but the ledger settled it at a different total from the invoice. That last one is a posted bill: the batch says so, the row names both figures, and the bill is not unposted.
Each run of a batch records an attempt, with its start time, end time and any error payload. A batch that failed twice has two attempts against it, which is how you tell "it failed once and worked" from "it has been failing all week".
What is written to a ledger
Each approved document becomes one bill in each ledger it is sent to. The fields differ by ledger, so each connector page carries its own table: the one below is QuickBooks, and connecting Xero holds the Xero table, in its section "What a posted bill looks like".
A QuickBooks bill
| On the bill | From the invoice |
|---|---|
| Vendor | Your vendor, through its mapping to a QuickBooks vendor |
| Transaction date and due date | The invoice date and due date |
| Document number | The invoice number, truncated to the length QuickBooks allows |
| Lines | The extracted line items, each against the GL account its code maps to; where extraction found no line items, one line built from the document total |
| Class | The property, where the QuickBooks company tracks classes |
| Tax | Outside the US, the purchase tax code on the document, where tax is stated. In the US, an extra bill line described "Sales tax", coded to your sales tax expense account or to the largest line's account |
| Private note | A marker identifying the inletAP document it came from |
| A/P account | Your mapped Accounts payable account, when one is set |
| Currency | The invoice currency, sent only when it differs from the company's home currency |
| The document itself | The source PDF, uploaded to QuickBooks and attached to the bill |
The document records the external ID that comes back, so "where did this end up" always has an answer. The reverse is also true: the marker written into the bill's private note identifies the inletAP document, which is what makes reconciliation possible in both directions.
A split invoice on a bill
Where an invoice has been split across properties, the bill carries one line per allocation rather than one line per printed line item:
- The GL account is the allocation's own code.
- The class is the allocation's property, on that line. Class is a per-line field on a QuickBooks bill, which is what makes property splitting possible at all.
- The description is the vendor's own line text with the property name alongside it, so somebody opening the bill in QuickBooks can see which building each line is for.
- The location, if you use locations, is a header field for the whole bill and cannot vary by line.
Where the properties belong to ownership entities with separate companies, the document posts as one bill per company. See posting to several companies.
Several checks run before any network call, and each of them parks the invoice rather than posting something wrong:
- The vendor has no QuickBooks mapping.
- A GL code resolves to no account.
- Line items do not add up to the invoice subtotal.
- The invoice states tax, the company is outside the US, and no tax code is mapped to carry it.
- The bill would settle at a figure other than the stated total.
- The invoice is in a currency the QuickBooks company cannot hold.
Each parks with a message naming the figures involved. Posting a bill that is short by the tax is the kind of error nobody finds until a vendor chases the balance.
What the CSV contains
The default columns are the ones most ledgers ask for:
"invoice_no","vendor","due_date","amount","property","gl_code","status"
Every cell is quoted, including the header row, which keeps a vendor name containing a comma from becoming two columns.
The mapping is configurable. A column has a header, written verbatim to row one, and a source: the document record — its id, its status, its vendor or its property — or any extracted field by name. That last option is the escape hatch that stops the list being closed: if your ledger wants the purchase order number in column three, it can have it.
Change the mapping in Exports → CSV mapping to match your ledger's import template, rather than editing files after the fact. A CSV that imports cleanly on the first attempt at month end is worth ten minutes of setup in a quiet week.
One row per invoice, or one row per allocation
How many rows a split invoice becomes is a setting: CSV export rows, on Settings → Split coding. It matters the moment you split an invoice across properties. Its two choices are below, with the value the wire and the API use in brackets.
| Setting | What a row is | Use it when |
|---|---|---|
One row per invoice (document) | One row per invoice | The default, and correct for every workspace that does not split. |
One row per property (allocation) | One row per allocation | You split invoices and your ledger needs each property's share on its own row. |
The default is document so that an existing downstream import keeps working byte-for-byte. Nobody's month end breaks because a new setting appeared.
The reason to change it is simple: a document-granularity row has one property cell, and a three-way split has three properties. One cell cannot honestly hold them, so it is written as the literal MULTIPLE and the batch carries a warning saying which invoices did that — a wrong CSV that imports cleanly is worse than one that does not. At allocation granularity each allocation becomes its own row, repeating the invoice-level values, which is the shape every ledger's import expects for a distribution. A mapping may hold up to 64 columns, and only an admin or a controller can change it.
At allocation granularity these column sources become available alongside the document ones:
| Source | What it writes |
|---|---|
allocation_property | The property this row is coded to. |
allocation_entity | That property's ownership entity. |
allocation_gl_code | The GL code on this allocation. |
allocation_amount | This allocation's amount. |
allocation_percent | Its share of the line it splits. |
allocation_seq | Its position within the split. |
allocation_of | The printed line the split belongs to. |
The rendered file is kept on the batch and stays downloadable, including when an SFTP delivery afterwards fails.
Retries
Only a failed batch can be retried. A batch that is pending, processing or already succeeded is refused, with the reason.
A retry is a replay rather than a second post. The idempotency key minted for the first attempt is reused, so the ledger recognizes the repeat and returns the original bill instead of creating another one. This is the single most important behavior in the export path: the failure mode it prevents is paying a vendor twice. Xero's own API does not refuse a repeated bill number, so there the defense is entirely ours — export failures sets out how it works.
Transient faults — throttling, a timeout, an internal error at the far end — are retried on a backoff of a few seconds, up to a small fixed number of attempts. Faults that cannot succeed unchanged, such as a rejected account reference, are parked immediately with the code recorded, because retrying them only burns your rate limit.
A failed export leaves its documents in failed_export. Fix the cause and retry the batch: a document that posts goes straight to exported. You can also move a failed_export invoice back to approved by hand, which puts it in the next batch instead of this one.
A document can reach more than one destination in a single run — one bill per connected ledger that is switched on, and one bill per company where a split spans several companies of one kind — and those posts succeed or fail independently. Two posted and one parked is the partially_exported status. It needs no split at all: two ledgers are enough. A retry re-runs the batch, and a bill that already holds the ledger's own id is skipped rather than posted again, so only the outstanding destination is attempted and the ones that succeeded are never touched. See export failures.
Where to go next
- Connecting QuickBooks — the connection itself, step by step.
- Connecting Xero — the same, and what a posted Xero bill carries.
- Month-end export — the routine this reference sits underneath.
- Export failures — when a batch will not go.
- Invoice statuses — what
exported,partially_exportedandfailed_exportmean for a document. - Posting to several companies — one invoice, several companies, several bills.