A bookkeeping platform is defined as much by what it connects to as by what it computes. This page lists every external service production code actually calls, what it is for, and what happens when it fails.
Making Tax Digital is not a REST API with a token. It is a REST API with a token plus a set of fraud prevention headers that describe, truthfully, the network path between the taxpayer's browser and HMRC. Getting those headers right on modern serverless infrastructure is the part most vendors underestimate.
HMRC requires headers identifying the client's public address and port and the vendor's own public address. This is a genuinely awkward requirement for any application hosted on modern edge infrastructure, and it is worth showing the whole sequence, because it is a fair sample of how technical decisions get made here.
A diagnostic endpoint was deployed purely to print what the infrastructure actually sees. The assumed path, browser to database platform, was wrong. The real path has two intermediaries: a content delivery network and a cloud provider in front of the runtime.
The client address was obtainable. The client's source port was not, because what the platform exposes is the gateway's listening port, not the browser's ephemeral one. And the outbound address of the runtime changed on every invocation, so it could never be a fixed vendor value.
On that stack, compliant headers were not achievable. Not difficult: not achievable. The diagnostic endpoint was then removed, because an unauthenticated endpoint making outbound calls is not something to leave lying around once it has done its job.
Rather than guess at an interpretation, the two specific questions were put to HMRC's software developer support: what is accepted when the source port genuinely cannot be obtained, and what is the accepted pattern for a vendor address on dynamic serverless egress.
A single fixed-address relay sits in the path for HMRC API calls only. It gives a stable vendor address and one known hop, and it forwards the browser-collected client values faithfully. Everything else in the platform stays where it is.
The client address and port it forwards are trusted only when a shared secret matches on a constant-time comparison, and they are format-validated before use. Values that fail are ignored rather than passed on. The OAuth token exchange deliberately does not go through the relay, because the client secret must never transit that box.
It is a small feature. It is also a complete demonstration of the operating method: measure rather than assume, accept an unwelcome finding, ask the authority rather than invent an interpretation, fix narrowly, and treat your own infrastructure as untrusted. If you are deciding whether to trust a piece of software with your books, that method is most of what you actually want to know about the people who wrote it.
| Service | Purpose | Position |
|---|---|---|
| Finexer | Open banking account information, and payment initiation for Pay by Bank | TaxChad operates as an agent under Finexer's own regulatory permissions for account information. TaxChad holds no permissions of its own and never holds client money. Integration is built, feeds are moving to live customers, and a webhook monitor runs hourly. |
| Companies House | Company details, officers and filing deadlines | Independent controller, not a subprocessor. Swept twice daily so deadlines stay current without manual entry. |
| Stripe | Subscription billing | Card details never touch TaxChad infrastructure. |
| GoCardless | Direct debit collection of subscription fees | Money movement screens are reserved to the owner access tier rather than available to every operator. |
| AWS Textract | Document text extraction from statements and receipts | Region pinned to London. Output always reviewed by a human before posting. |
| AI gateway | Document extraction and speech to text for voice capture | Named in the privacy policy and the subprocessor register. Never used for an accounting judgement. |
| Amazon S3 | Off-site encrypted backups | A separate cloud account from the production platform, so a compromise of one is not a compromise of both. |
| Exchange rate sources | Daily rates, with a secondary source as fallback | A freshness monitor raises an alert if rates go stale, and HMRC's own monthly rates are refreshed separately. |
| Postcode and mapping lookups | Address completion and mileage distances | Mapping is reached through a gateway rather than a direct account, and both are on the register. |
| Email delivery | Transactional and notification email | Allowlisted templates only, rate limited, with a send log and bounce handling. |
Bank data can also arrive with no live connection at all: format-aware importers for Wise, Monzo, Lloyds, Mettle, Virgin Money and Capital on Tap, gateway exports from Stripe, PayPal and Shopify, plus generic CSV, OFX and PDF. That matters commercially, because it means a customer can be onboarded and made useful before any open banking consent exists.
Scheduled work calls the application over HTTPS with a secret held in the database vault, and the target host is a vault value rather than a hardcoded string. Without the secret, the endpoint refuses.
| Job | Schedule | What it does |
|---|---|---|
| Platform backup | 01:00 and 02:00 | Two London-time-guarded jobs so the encrypted off-site snapshot lands at 02:00 local all year |
| Ledger invariant sweep | 03:20 nightly | Replays the invariant suite across the live ledger |
| FX daily ingest | 17:00 daily | Pulls the day's rates from the primary source |
| FX freshness monitor | 17:30 daily | Raises an alert if rates did not land |
| HMRC token expiry watch | 05:45 daily | Flags authorisations about to lapse before a filing deadline does |
| HMRC sandbox keepalive | Weekly | Keeps the test environment credentials alive between releases |
| Companies House sweep | 02:45 and 14:45 | Refreshes company details and statutory deadlines |
| Obligation reminders | 06:00 daily | Tells clients and the practice what is due |
| Recurring invoices | 07:00 daily | Generates invoices from schedules, atomically |
| Invoice reminders | 08:15 daily | Chases unpaid sales invoices |
| Receipt matching | 04:10 daily | Matches uploaded receipts to bank lines |
| Fiscal year creation | 02:15 daily | Opens the next period before anyone needs it |
| Payroll billing | Monthly | Meters and bills reviewed payroll runs |
| Finexer webhook monitor | Hourly | Detects a bank feed that has gone quiet, rather than waiting for a customer to notice |
| HMRC monthly rates | 1st of month | Refreshes the published rates some returns require |
An automated path that cannot prove it should run does not run. A missing secret, an unverified webhook or an absent credential produces a refusal, not a best-effort attempt.
Rate limiting is retried politely. Server errors on filing endpoints are not, because filing the same return twice is worse than filing it late.
The failure mode that hurts is not an error, it is a feed that quietly stops. Hence a webhook monitor, a rate freshness monitor, a token expiry watch and a nightly ledger sweep: four jobs whose only purpose is to notice nothing happening.
Every automated input has a manual equivalent. If a feed stops, a statement can be imported. If extraction fails, rows can be typed. Nothing in the filing path depends on a single integration being available.