DocReadi

Delivering documents

Delivering documents

Once a document is ready, DocReadi can get it out to wherever your finance process lives — a bundle dropped on your own server, an email attachment, or a live event pushed to your systems the moment something happens. This chapter covers Connections (the shared credentials DocReadi uses to reach a remote system), Outbox (destinations, scheduled deliveries, and runs), Xero activity (the status of documents you've pushed to Xero), and outbound webhooks. All of these require the Admin role.

Connections, Inbox, Outbox, and Xero activity are grouped under a Sync menu in the top navigation bar, so you can jump straight to whichever direction of document movement you need. On any Sync page, a tab strip across the top gives you the same four destinations (Connections · Inbox · Outbox · Xero activity) plus, on the right of the same row, tabs for the current section's own sub-pages (where it has any).

Connections

Connections (Sync → Connections) is the credential registry shared by both directions of document movement: an Inbox source (see Sending documents in) polls a connection for new documents; an Outbox destination drops a bundle onto one. You set a connection up once and reuse it on either side.

Select + Add connection and choose a kind:

A cloud drive — OneDrive or SharePoint — isn't one of the credential-form kinds above; it's connected separately with a Connect OneDrive / Connect SharePoint button in a Connect a cloud drive panel above the Add connection form. Selecting one sends you to that provider's own sign-in and consent screen — DocReadi never sees your password, only a token it stores encrypted. OneDrive asks for read-write access to your files (so a source can be set to move or delete after pickup, the same as SFTP/S3); a source left in leave-mode only reads. SharePoint asks for the same access across your organisation's sites and, once you've signed in, takes you to a picker to choose a site and then a document library — the connection isn't usable until a library is chosen. If your organisation requires administrator approval for the SharePoint permissions, DocReadi tells you so and names what your Microsoft 365 admin needs to grant; retry the connect once they have.

Each cloud-drive connection shows the connected account (or, for SharePoint, the site and library) instead of a hostname. There's no password field to update — if a token expires or is revoked (the status pill shows Auth Failed), open the connection and select Reconnect to re-authenticate the same connection in place; any Inbox source or Outbox destination already pointed at it keeps working without re-pointing.

SFTP asks for a name, hostname, port (default 22), username, base path, and either a password or an SSH private key (not both). It also requires an expected host-key fingerprint — select Capture from server to connect (without sending any credentials) and read the server's key, which pre-fills the field. Verify that fingerprint against an out-of-band source you trust — a phone call to the server's administrator, your own records, or ssh-keygen -l against a shell you know is genuine — before saving. This fingerprint pin is what stops a network-level attacker from silently swapping in their own server and harvesting your credentials; DocReadi checks the live key against the pinned one on every connection.

S3 asks for bucket, region, access key ID, secret access key, a base path/prefix, and an optional endpoint URL (leave blank for AWS S3; set it for a compatible provider).

WhatsApp asks for the phone number ID and access token from your Meta WhatsApp Business setup, plus an optional toggle that, when on, prompts the sender to pick a document type before DocReadi processes their message.

Email needs no credentials — it's inbound-only. Once created, you add one or more tenant-specific inbox addresses to it as Inbox sources. Because there's nothing to dial out and test, an email connection shows a green Live pill instead of a Test button and status pill.

Testing and connection health

Each connection (other than email) has a Test button that verifies it live: for SFTP, DocReadi connects and lists the base path (re-checking the pinned host key); for S3, it verifies bucket access; for WhatsApp, it pings Meta for your number's status; for OneDrive and SharePoint, it refreshes the token if needed and confirms the drive is reachable. A status pill shows the result:

Status Meaning
Connected The last test succeeded.
Live Email connection — inbound-only, nothing to test.
Not Tested No test has run yet.
Testing A test is in progress.
Auth Failed The credentials were rejected — re-authenticate.
Unreachable DocReadi couldn't reach the host.
Access Denied Connected, but without permission for the path.
Path Not Found Connected, but the configured path doesn't exist.

DocReadi also re-checks SFTP, S3, WhatsApp, OneDrive, and SharePoint connections automatically in the background — roughly once a day when healthy, more often once paused — so a credential that stops working is caught within a day even if nobody clicks Test. Three consecutive Auth Failed results (whether from a manual test or a background check) automatically pause the connection — Inbox polling and Outbox delivery both stop against it, and a banner appears across the app naming the paused connection and prompting you to re-authenticate. Fixing the credentials (or, for a cloud drive, using Reconnect) and running a successful test clears the pause.

Editing and deleting

Editing a connection pre-fills its non-secret fields; leave a password or key field blank to keep the existing one, or fill it in to replace it. A cloud-drive connection (OneDrive, SharePoint) has no password field on its edit page — use Reconnect instead, as described above. Deleting a connection is blocked while an Inbox source or Outbox destination still uses it — resolve those references first. The error lists each blocking Inbox source and Outbox destination by name, and each name links straight to that row, so you don't have to go hunting for it. Past ten of a kind the banner links the first ten and counts the rest as "+N more" — at that point clear the section rather than the individual rows.

Managing a Xero connection

Connecting Xero happens on the Connections page, but everything else about a live Xero connection lives on the Xero activity page (Sync → Xero activity), under its Settings tab. The connection row on the Connections page carries a Manage → link straight to it. The Settings tab holds:

GL accounts that come from Xero are tagged Managed in Xero on the GL accounts page. Their code and name follow Xero — rename an account there and the next sync brings the new name across — and their role follows the Xero account type, re-checked on every sync. DocReadi won't save a different name or role for them: the Edit form shows both read-only, and a CSV import or an API call that tries to change them is refused. You can still set their keywords and switch them active or inactive. A sync deactivates an account that has been archived or deleted in Xero, or moved to an account class DocReadi can't post to, and switches it back on once Xero lists it as active again. A deactivation you make yourself holds unless the account has changed in Xero since the last sync, in which case it follows its status in Xero. Existing defaults and pins are never rewritten; when GL determination skips one, the document's GL postings tab says so (see Postings review).

Sending bank details to Xero

The Send bank details to Xero toggle is off by default. Name, VAT number, address, phone, and the supplier/customer type always transfer when a vendor is sent to Xero; turning this setting on also includes the vendor's primary bank account, which Xero uses for batch payments. Because bank details are sensitive, this stays off unless you turn it on deliberately. It applies to every Xero connection in the workspace.

When supplier invoices push to Xero

The Push to Xero box on the Settings tab holds the push settings. Its When to push supplier invoices dropdown controls what happens to a supplier (AP) invoice:

Below the dropdown, the Send choice decides which documents the connection may push:

Under the Send choice, Include documents flagged as duplicates is off by default: a supplier invoice flagged as a possible duplicate is not pushed, and you're told why. Tick it to push flagged duplicates too. Select Save to apply both choices.

Automatic pushes (Staged on approval and Auto on approval) still happen only when a document is approved, whichever you pick — Any status never makes an unreviewed bill leave on its own. A bill sent before approval carries no account codes, because GL postings are written on approval, and it is marked Sent before approval on Xero activity and in the document's Sent to Xero panel. Under Approved documents only, Push to Xero in the Documents list pushes only the approved invoices among the ones you selected, and a document that isn't approved is not queued — you're told why. DocReadi checks the choice again when the bill is actually sent; if the document is no longer allowed by then, the push is marked rejected with a message saying why.

The push settings only appear once the connection has both the write scope (name matching and Bill creation) and a chosen organisation — a read-only connection shows a Reconnect Xero prompt instead, and a connection whose organisation hasn't been chosen yet asks you to choose one first. The Contact edits toggle sits alongside it: when set to push, editing a Xero-linked counterparty's name, email, or VAT number also updates the matching Xero contact.

Outbox

Outbox (Sync → Outbox in the top navigation bar) is where documents leave DocReadi: destinations, saved delivery rules ("export rules"), and the runs that result from them. The Outbox tabs on the right of the strip switch between Runs, Export rules, and Destinations. The sample invoice on your onboarding checklist never ships through the Outbox, whatever a rule's filter matches — it's a demo document, not real data.

Destinations

An Outbox destination (the Destinations tab) is where a bundle gets dropped. Select + Add destination and choose a kind:

For SFTP, S3, OneDrive, and SharePoint destinations, a Browse… button lets you pick the folder visually rather than typing a path. Each destination has its own Test, Edit, and Delete actions, using the same status-pill vocabulary as Connections. Deleting a destination is blocked while an export rule still points at it — the error lists each blocking export rule by name, linking straight to it. Past ten the banner links the first ten and counts the rest as "+N more" — at that point clear the section rather than the individual rows. A destination's kind is fixed once created — to change it, delete and recreate the destination; re-pointing at a different connection of the same kind (for example, moving to a different OneDrive account) is allowed from Edit.

Saving a destination — whether adding it or editing it — runs the same check as clicking Test, so the status pill shows a result right away instead of sitting at Not Tested until you click Test yourself. If the probe itself fails to run, the save still goes through and the pill just stays untested; it isn't blocked on the test succeeding.

Export rules (saved deliveries)

The Export rules tab holds your saved deliveries. An export rule ties a destination to a bundle format, a Send choice (which document statuses it sends — see below), filters on document type and source, and a trigger:

Choosing which statuses a rule sends

Every export rule has one explicit Send choice:

Under the Send choice, Include documents flagged as duplicates is off by default. While it is off, a document flagged as a possible duplicate (see Comparing a suspected duplicate) is left out, whatever its status, and the run lists it with the document it duplicates. Tick it to send flagged duplicates too. Existing rules were all set to leave duplicates out when this option arrived, so a rule that used to send a flagged duplicate no longer does until you tick the box.

There is no status filter elsewhere on the form: the document type and source filters narrow what the rule matches, and Send decides which statuses go. The Export rules list shows each rule's choice as Sends: … — "Approved only", "Any status", or the statuses by name. A rule with the Report bundle format has no Send choice, because the saved report defines what it contains.

An On approval rule sends each document at the moment it is approved, so Approved documents only and Any status behave the same there. An On approval rule with Only these statuses must include Approved — saving one without it is refused, because it could never send anything.

Rules created before the Send choice existed were each given the choice that names what they already did: a rule with no status filter shows Any status, a rule that sent approved documents shows Approved documents only, and a rule with another status list shows Only these statuses with that list ticked. None of them changed what it sends.

Before saving, the create form shows a live preview of how many documents the current filter and Send choice would match and a sample of filenames, so you can check the filter is right before it goes live. A skip already-delivered option controls whether a document can ship twice — either never re-ship the same document, or re-ship it only if it's been re-extracted since the last delivery.

Some bundle formats can't package every document: the PDF formats need a PDF (or an image), so they can't package a spreadsheet or Word file. A document can also be left out when its source file can't be read. A document that isn't packaged is never counted as delivered. It is checked again on every run and goes out as soon as the reason no longer applies (for example, the document is re-typed or its file can be read again), or when you change the rule's format. The run page lists these documents under "N documents not delivered — they couldn't be packaged", with the reason for each, the Outbox shows "+N not packaged" next to the run, and the Export rules list shows how many matching documents the rule's format can't package. A run where no document could be packaged sends nothing to the destination and ends skipped, with a note on the run page saying why — for example "None of the 3 documents left to deliver can go out as xero_csv", or "No document in this run could be packaged (source files not available); nothing was sent."

Bundle formats

When you set up an export rule, you choose what the bundle actually contains:

An email destination can't be paired with PDF (individual files) — an email carries one attachment, and individual files aren't zipped together. DocReadi blocks saving, editing, or one-off exporting that combination with an explanation; use PDF (clean) instead (it zips a multi-document set into one file) or point per-file drops at a non-email destination.

Runs

The Runs tab is where Outbox opens by default. Every time an export rule fires, it creates a delivery run that moves through a fixed sequence of states:

Status Meaning
queued Waiting to start.
packaging Building the bundle.
ready Bundle built, waiting to hand off to the destination.
delivering Uploading or sending to the destination.
delivered Done — the destination has the bundle.
failed The run couldn't complete; see the run detail for the reason.
skipped Nothing was sent: no document matched, the rule's Send choice left every matching document out, or none of the matching documents could be packaged. The run detail says which.

An export run that fails on a temporary problem — the destination is unreachable, say — goes back to queued and is retried on its own: six attempts in all, the first straight away, then retries after 30 seconds, 2 minutes, 10 minutes, 1 hour and 6 hours. The run detail shows which attempt it is on and when the next try is due. After the sixth failed attempt the run is marked failed. A problem that waiting can't fix — a cloud connection that needs reconnecting, or a bundle too large for the destination — fails the run straight away instead.

The Outbox dashboard shows recent runs with a rolling 24-hour summary (delivered, failed, ready, in-flight). Open a run for its detail — per-document delivery status, a Download bundle button for Download destinations (once the link has expired, the page says Bundle no longer available instead — use Run now on the export rule to build a fresh one), and, on a failed run, a Retry now button that requeues it. A run still in progress (queued, packaging, or delivering) can be cancelled; already-packaged bundles are discarded. On a multi-file bundle, the run detail's per-document table shows when each file actually landed at the destination, not just the run's overall status — and retrying a partially-delivered multi-file run only re-sends the files that haven't landed yet, not ones already delivered.

Documents left out by the rule

A run applies the rule's Send choice and its duplicates choice to every document it considers, including a specific set of documents a run was given rather than a filter. When they leave out documents that matched the rule's other filters, the run page shows a Left out by the rule count and a list of those documents with each one's file name and the reason — for example "Not approved yet (status: Extracted). This rule sends approved documents only." or "Flagged as a duplicate of #INV-1001. This rule leaves duplicates out." The Runs list shows the same count as "+N left out by the rule". This isn't an error: those documents go once their status is one the rule sends, or once you change what the rule sends. A run where the choice left out every matching document is skipped with a note such as "Nothing sent: the 3 matching documents are not approved yet. This rule sends approved documents only."

Selecting Run now while a run for that same export rule is already in flight doesn't start a second one — you're taken to the existing run, and its page shows an Already running notice explaining your click was deduplicated rather than silently doing nothing.

If a filter matches a very large number of documents, DocReadi automatically splits the work into a sequence of runs rather than one enormous one, so you'll sometimes see a run labelled "Part 2 of 3" — they complete independently and each shows its own status.

One-off exports

From any filtered documents list, an Export this set → link opens the one-off export page for that filter. It carries the same Send choice as an export rule, with the number of documents each option would send shown next to it. Approved documents only is preselected; if you came from a list filtered to one status other than approved, an Only <status> option is added and preselected instead. Include documents flagged as duplicates is off unless you tick it. Pick a destination and bundle format, then select Queue export — DocReadi creates a one-time delivery and takes you straight to its run detail. It's useful when you want a bundle right now without setting up a recurring rule.

Xero activity

If your workspace is connected to Xero, Xero activity (in the Sync menu, or the Manage → link on the Xero connection card on the Connections page) shows every document you've pushed to Xero as a Bill and where each push stands. It's a read-and-retry view: you can see the status of every push and re-try the ones that didn't land, but the pushes themselves are started from the Documents list (or by the push-trigger setting on approval).

If Xero isn't connected yet, the page shows a short prompt with a link to Connections instead.

The page has three tabs. Documents is the push list described below. Sync runs shows a history of the reverse-syncs that pull your chart of accounts, tax rates, and contacts back from Xero — newest first. Each row tells you when the sync ran and how long it took, whether it was started by hand (Sync now on the Settings tab) or ran on the daily schedule, the result (ok, partial, or error), and how many accounts, tax rates, and contacts it brought in or updated. When a sync changed accounts, the row shows N account changes from Xero — expand it to see which accounts had a role change, were deactivated, or were reactivated. When a sync fails, the row carries the error so you can see what went wrong. Settings holds the connection's management controls — Sync now, the push-trigger policy, Contact edits, the bank-details toggle, and Test / Reconnect / Choose organisation (see Managing a Xero connection above).

The Documents tab

Each row is one document you've pushed, showing the document number, counterparty, and amount (linked to the document), the push status, how many attempts have been made, when it was pushed or queued, and any error detail. A Sent before approval label next to the status means the bill went to Xero before the document was approved (possible only when the connection's Send choice is Any status). Use the Status filter to narrow the list to one status. If your workspace has more than one Xero connection, a Connection filter also appears so you can look at one organisation at a time. The list shows the most recent pushes first.

While a push is still working its way through — a row sitting at pending or pushing — the page updates those rows on its own every few seconds, so you'll see them move to pushed, failed, or needs a contact without refreshing. A small "Auto-updating…" note appears while this is happening and disappears once everything has settled. If a push stays in flight for a long time the live updates pause and the page shows a refresh link to pick them back up.

The Status column tells you where each push is:

Status Meaning What to do
ready to push Created by the Push: staged on approval setting and held for your review. Select Push now to queue it, or Remove to discard it (the document stays manually pushable).
pending Queued, waiting for the push to run. Nothing — watch for it to move to pushed.
pushing The push is in progress. Nothing — wait for it to finish.
pushed The Bill was created in Xero. Nothing. A Bill … ↗ link opens it directly in Xero.
needs a contact The supplier couldn't be matched to a Xero contact automatically. Select Resolve contact on the row (see below) — you no longer need to open the document.
rejected Xero declined the Bill (a data problem it reported back). Read the error under Detail, correct the document, then Retry.
failed The push kept hitting a technical error and stopped retrying. Read the error under Detail, then Retry once the cause is resolved.

A push that hits a temporary error — Xero is briefly unavailable, or the connection drops — goes back to pending and is retried on its own: six attempts in all, the first straight away, then retries after 30 seconds, 2 minutes, 10 minutes, 1 hour and 6 hours. After the sixth failed attempt it is marked failed. Every attempt for the same document carries the same reference, and Xero recognises a repeat of that reference for 24 hours, so a retry gets back a Bill Xero already made rather than creating a second. When Xero asks DocReadi to slow down, the push waits as long as Xero says and that wait doesn't count as an attempt.

For a rejected or failed push, the Detail column carries the error Xero or DocReadi returned — select it to expand the full message. A Retry button on those rows re-queues the push, so you don't have to go back to the document to try again. When one or more pushes have failed, a banner at the top of the page also offers Retry all failed to re-queue every failed push at once.

If a connection can't push at all — because you still need to choose its Xero organisation, or it was paused after repeated failures — a banner at the top of the tab explains the problem and links to the Settings tab where you fix it.

Resolving a contact

When a push shows needs a contact, DocReadi couldn't be sure which Xero contact the supplier is (a close-but-not-exact name match, or a supplier that isn't in Xero yet). A banner reads "Waiting for a contact decision: N", and each of those rows has a Resolve contact button that opens a small panel right on the page — you don't have to open the document:

Once you resolve the contact, the push is re-queued automatically.

Reviewing staged pushes

If your workspace's push setting is Push: staged on approval (see above), approved AP invoices land here with a ready to push status instead of going straight to Xero. When one or more rows are staged, a banner at the top of the page reads "Ready to push to Xero: N". From there you can:

Reviewing staged pushes requires the Admin role, same as the rest of this chapter.

If you haven't pushed anything to Xero yet, the tab shows a short "No pushes yet" note.

Outbound webhooks

Settings → Integrations → Webhooks pushes a signed HTTP request to your own endpoint the moment something happens in DocReadi — an alternative to polling the API for changes.

Select Create webhook after entering an Endpoint URL (must be https://) and an optional Description. The endpoint URL is checked against DocReadi's outbound-request safety rules both when you save it and again on every delivery.

When a webhook is created, its signing secret is shown exactly once — copy it immediately, since DocReadi doesn't store it in a form you can retrieve later. Use it to verify each delivery: DocReadi signs the request body with HMAC-SHA256 and sends it in the X-DocReadi-Signature header (t=<timestamp>,v1=<signature>), alongside X-DocReadi-Event-Id and X-DocReadi-Event-Type headers. Recompute the signature on your end and compare it before trusting the payload; reject anything with a timestamp too far in the past to guard against a replayed request.

The Add Webhook form has an "Events to send" checklist, grouped by area: Documents (document.approved, document.rejected, document.failed, and duplicate-related events), Counterparties (counterparty.candidate_created, counterparty.confirmed), Validation (validation_error.raised), Inbox activity, Outbox delivery outcomes, and Xero push events. Leave every box unchecked to receive all events — that's the default when you create a webhook. Check one or more boxes to receive only those event types instead.

Each webhook in the table shows how many events it's subscribed to (All events, or N of 17 events). Select that summary to expand the same checklist inline and adjust the subscription, then select Save events. The Test button (see below) always sends its synthetic event regardless of your event selection, so you can confirm the endpoint is wired up correctly even on a narrowly filtered webhook.

The sample invoice on your onboarding checklist never fires an event — nothing it does should show up in a system watching for real activity.

If the document carries reviewer answers to your workspace's review requirements, a document event's payload includes them under review_responses — one entry per answer, with the requirement's label and kind, who answered it and when, and either the typed value or the confirmed snapshot. The key is left out entirely when the document has no answers. See /api/docs-guide for the exact field list.

Use the per-webhook Test link to send a synthetic test event to your endpoint and confirm it's wired up correctly, and Recent deliveries to see the last 200 delivery attempts across all your webhooks — event type, target URL, status, status code, and the next retry time for anything still failing. A delivery that keeps failing is retried on a lengthening backoff — six attempts in all: the first straight away, then retries after 30 seconds, 2 minutes, 10 minutes, 1 hour and 6 hours (about 7 hours end to end). The Tries column shows how many of the six have been used. After the sixth failure DocReadi gives up on that particular event and marks it Dead-letter. Select Delete to remove a webhook; deleting cancels anything still pending for it.

Pausing and resuming

Each webhook's status pill reads Active or Paused. Select Pause to stop it without deleting it — useful while your endpoint is down for maintenance or you're mid-migration to a new receiver. While a webhook is paused:

The Test button is hidden while a webhook is paused, since a paused webhook shouldn't be receiving anything, synthetic or otherwise.

Rotating the signing secret

Select Rotate secret to generate a new signing secret for a webhook — useful if the current one has leaked or you're doing routine credential hygiene. The new secret is shown once, the same way it is when you first create a webhook, so copy it immediately.

The old secret keeps working for 24 hours after rotation. During that window, every delivery carries a second header, X-DocReadi-Signature-Previous, signed with the old secret over the same body — X-DocReadi-Signature always carries the new (current) secret. This gives you a window to update your receiver instead of having to swap both ends at the exact same instant. While the window is open, that webhook's row shows Previous secret accepted until <date> (<relative time>), so you can see at a glance which webhooks still need their receiver updated.

Rotating a second time inside that window ends it early: only one previous secret is ever kept, so the confirmation dialog warns you that rotating now replaces the still-valid old secret with the one you are rotating away from today, rather than promising a fresh 24-hour window on top of the existing one.

See /api/docs-guide for the full event catalogue and payload shapes if you're integrating programmatically.


Previous: Reports and exports. Next: Billing and credits.

Looking for the developer/API reference? See /api/docs-guide. Can't find an answer? Email [email protected].