Xero and Plaid integration
Xero tracks every accounting transaction. Plaid connects to the actual bank. Bringing the two together means your bank account in Xero always matches what the bank sees, without manual reconciliation. Payments you record in Xero as accounts payable can move out through Plaid as real ACH transfers, and bank transactions from Plaid flow back into Xero to close the loop. ml-connector handles the different authentication and data models on each side so the two stay aligned.
What moves between them
The main flow runs in both directions. Bank transactions from Plaid sync into Xero's bank transaction endpoint on a schedule controlled by Plaid webhook events, so every deposit, check, and fee appears in Xero as a bank transaction awaiting reconciliation. Outbound, payment records created in Xero with instructions to move through Plaid trigger an ACH or wire transfer request to Plaid, which initiates the transfer at the bank and returns a transfer ID that ml-connector records back in Xero for tracking. Payment amounts and descriptions stay within Plaid's limits (10-15 characters for transfer descriptions depending on transfer type).
How ml-connector handles it
ml-connector stores Xero's OAuth2 refresh token encrypted and refreshes the access token when a call returns 401. For Plaid, it stores the per-user item access tokens encrypted and validates every incoming webhook signature using ES256 JWT and a public key fetched from Plaid's JWK endpoint, rejecting any signature older than 5 minutes or using a different algorithm. When Plaid webhooks signal new transactions, ml-connector fetches the full transaction batch via the transactions/sync endpoint, maps each transaction to the appropriate Xero bank account using the Plaid item ID, and posts it as a Xero bank transaction. When an Xero payment is marked for Plaid, ml-connector constructs the transfer description within Plaid's character limits, calls the Transfers API with an idempotency key, and stores the resulting transfer ID in Xero. Both systems are polled on a schedule for reconciliation status, and retries respect Xero's 5 concurrent call limit and Plaid's rate limits.
A real-world example
A growing professional services firm uses Xero for accounting and maintains operating accounts at three different banks via Plaid. Before the integration, the finance manager logged into each bank portal daily, downloaded transactions, and manually entered them into Xero, a process that took 45 minutes and was error-prone. Payments approved in Xero were printed and mailed or initiated manually through the bank portal. With Xero and Plaid connected, new transactions appear in Xero within minutes of hitting the bank account, and the finance team approves payments in Xero without touching the bank portal. Monthly reconciliation now takes 15 minutes instead of three hours.
What you can do
- Sync bank transactions from Plaid into Xero so your accounts reconcile without manual entry.
- Initiate ACH and wire transfers from Xero payment records through Plaid, with transfer status tracked back in Xero.
- Validate Plaid webhook signatures using ES256 JWT and reject unsigned or stale webhook events.
- Refresh Xero OAuth2 access tokens transparently and handle Xero's tenant-specific organization headers.
- Map Plaid transactions to Xero bank accounts by item ID, with full audit trails on every transaction and transfer.
Questions
- How do bank transactions flow from Plaid into Xero?
- Plaid publishes webhooks when new transactions are available. ml-connector receives the webhook, validates the ES256 signature, and fetches the full transaction batch via the transactions/sync endpoint. Each transaction is posted to Xero as a bank transaction, mapped to the correct Xero bank account by the Plaid item ID. Xero then surfaces the transaction in its bank reconciliation view.
- What happens when I initiate a transfer in Xero through Plaid?
- You create a payment record in Xero marked for Plaid execution. ml-connector reads the payment, formats the description to fit Plaid's 10-15 character limit (depending on transfer type), and calls the Plaid Transfers API with an idempotency key to initiate the ACH or wire transfer. The transfer ID is stored in Xero for tracking and audit purposes.
- How does ml-connector handle authentication for both systems?
- Xero uses OAuth2 with a 30-minute access token and 60-day refresh token; ml-connector stores the refresh token encrypted and refreshes the access token on 401 responses. Plaid uses API key authentication and per-user item access tokens obtained via the Link flow; ml-connector stores both encrypted and validates every webhook using ES256 JWT signature verification with Plaid's public key.
Related integrations
More Xero integrations
Other systems that connect to Plaid
Connect Xero and Plaid
Free to use. Add your credentials, ping your real systems, and see if we fit.
Get started