# Xero HubSpot integration

*Xero → HubSpot*

**In short:** A Xero HubSpot integration keeps sales and finance looking at the same customer: closed-won HubSpot deals become Xero contacts and sales invoices, and Xero invoice status, amount due, payments, and credit notes flow back onto the HubSpot record. Done properly it is not a nightly export - it is an idempotent pipeline that matches on a stored Xero ContactID rather than a company name, derives tax types instead of copying rates, and stays inside Xero's 60-calls-per-minute ceiling.

## What a Xero to HubSpot integration actually does

HubSpot is where the customer relationship lives - the company, the contacts, the pipeline, the quote, the moment a deal is marked closed-won. Xero is where that relationship becomes money: a contact record, a sales invoice, a payment, a credit note, an overdue balance sitting in aged receivables.

Between those two systems there is almost always a person. Someone reads the closed-won deal, opens Xero, retypes the company, picks the accounts, sets the tax rate, and issues the invoice. Later, someone else answers the question sales keeps asking: has this customer actually paid? Nobody in HubSpot can see it, so finance gets pinged, or an aged-receivables report gets pasted into a spreadsheet once a month.

A Xero to HubSpot integration removes both halves of that. Closed deals turn into correctly coded Xero invoices without re-keying, and invoice status, amount due, due date, and payments flow back onto the HubSpot record so account owners see payment reality without ever being given access to your ledger.

## What data moves

| Xero object / event | Becomes in HubSpot | Notes |
| --- | --- | --- |
| Contact (customer) | Company | Matched on stored ContactID, not name - Xero enforces unique contact names |
| Contact person on a Xero contact | Contact, associated to the company | HubSpot keys contacts on email; Xero does not treat email as unique |
| Sales invoice (ACCREC) | Invoice object or deal properties | Invoice number, total, due date, currency, and status surfaced to the owner |
| Invoice status change | Deal or company property | DRAFT, SUBMITTED, AUTHORISED, PAID, VOIDED kept current |
| Payment / amount due | Deal or company property | Drives paid, part-paid, and overdue states without exposing Xero |
| Credit note | Property update plus deal note | Reduces the recognised amount and explains why |
| Overdue balance | Company property | Can trigger a HubSpot workflow to pause outreach or alert the owner |

In the other direction, HubSpot **companies** and **contacts** become Xero **contacts**, closed-won **deals** become **sales invoices**, and HubSpot **line items** map to Xero **line items** with an ItemCode, AccountCode, and TaxType. Product SKUs in the HubSpot product library are mapped once to Xero item codes and revenue accounts, along with any tracking categories you report on. After that, nobody maps them again by hand.

## The details that break naive syncs

A marketplace connector or a Zapier scenario gets you a contact sync and leaves the expensive parts on your desk:

- **Contact matching.** Xero requires a unique contact Name per organisation and will reject a second contact with the same name outright. HubSpot happily holds two companies called the same thing at different domains. Without a stored cross-system ID and an agreed match key, you either create duplicates or fail on write.
- **Tax types are not tax rates.** Xero uses organisation- and region-specific TaxType codes, and the correct one depends on the customer's country and VAT registration, not on a percentage in HubSpot. HubSpot line items have no tax concept at all, so tax has to be derived by the pipeline.
- **Line amount types.** A Xero invoice is Exclusive, Inclusive, or NoTax. Send tax-inclusive HubSpot amounts as exclusive lines and every invoice is wrong by the VAT amount - and Xero recalculates line tax itself, so totals silently diverge from the deal amount.
- **Discounts and rounding.** HubSpot computes a deal amount from line items and discounts in its own way. Xero applies percentage discounts per line and rounds per line. The mapping has to reproduce the intended total rather than force one number to match.
- **Rate limits.** Xero allows roughly 60 API calls per minute and 5,000 per day per organisation, with a low concurrency ceiling. HubSpot meters requests in ten-second windows with daily caps that vary by subscription tier, and the Search API is stricter still. A bulk update on either side will trip a limit unless the pipeline batches, throttles, and backs off.
- **Delta versus full sync.** Re-reading every contact and invoice nightly burns your entire Xero daily budget for nothing. The pipeline reads only what changed, using the If-Modified-Since header on Xero and incremental search on hs_lastmodifieddate in HubSpot.
- **Ordering and partial failures.** An invoice cannot post before its contact exists. And a batch of invoices posted to Xero must be sent so that per-record validation errors come back individually rather than failing the whole batch, with each failed record retried on its own.
- **Reopened deals.** A closed-won deal can be moved back. An authorised Xero invoice cannot be un-issued - it needs a credit note. The pipeline has to know the difference and never quietly delete accounting history.

## How we build and run it

We treat this as a pipeline, not a scheduled export. Changes are read from HubSpot and Xero on a schedule and by webhook, validated, transformed into the mapping agreed with you and your accountant, and written to the other system with the right contact link, account codes, tax types, and currency.

The pipeline is idempotent: every deal, invoice, and payment carries a stable identifier and the resolved cross-system ID, so a retry, a redelivered webhook, or a re-run never issues the same invoice twice. Xero webhooks only tell you that a contact or invoice changed, not what changed, so the pipeline fetches and reconciles rather than trusting the notification. It runs on cloud-native, fully EU-hosted AWS infrastructure, so customer, deal, and invoice data never leaves the EU - which keeps your DPA / AVV and your GDPR obligations clean.

And then we keep it running. Monitoring, alerting, incident response, and - critically - watching Xero endpoint and rate-limit changes, OAuth refresh-token rotation, and HubSpot property and pipeline changes are our responsibility under contract. Your sales-to-finance handoff stops depending on anyone remembering to check it.

## When this integration is worth building

If you issue a handful of invoices a month and someone retypes them into Xero in ten minutes, the marketplace app or plain manual work is genuinely fine, and we will tell you so. The integration earns its place when invoice volume climbs, when your product catalogue and revenue accounts need real line-level coding, when sales keeps asking finance who has paid, when you invoice in more than one currency, or when duplicate Xero contacts have already started to accumulate. At that point a managed pipeline costs less than the reconciliation and clean-up it replaces.

## Frequently asked questions

### Does HubSpot not already have a Xero app in its marketplace?

It does, and for a small team that raises a few straightforward invoices a month it can be enough. The marketplace app syncs contacts and surfaces invoices against a deal, but the mapping it gives you is fixed: your product catalogue, revenue accounts, tracking categories, tax treatment, and deal-stage rules are yours, not its. Once invoices need line-level account and tax coding, or once payment status has to drive HubSpot workflows, you are back to filling the gap by hand.

### How do you match a HubSpot company to a Xero contact without creating duplicates?

This is the part that quietly breaks. Xero enforces a unique contact Name per organisation and does not treat email as a key, while HubSpot deduplicates companies on domain and contacts on email. Two records that look identical to a human are different records to both systems. We agree a match key up front - VAT number, domain, or a customer number written into the Xero ContactNumber field - then store the resolved Xero ContactID on the HubSpot company so every later sync matches on a stable ID instead of guessing on a name.

### Do you create invoices in Xero as drafts or as authorised?

Whichever your finance team wants to own. A draft invoice is still editable and reversible, which suits businesses where someone reviews before sending. An authorised invoice is a committed accounting document and can only be undone with a credit note, so it suits high-volume, low-touch billing. We usually start with drafts during the first weeks, confirm the totals and coding match what your accountant expects, then switch to authorised once the mapping has proved itself.

### How do you handle multi-currency deals and tax rates?

Separately, because the two systems treat both differently. HubSpot stores a deal in its own currency and converts to your company currency at a rate you maintain for reporting; Xero applies its own dated exchange rate when the invoice is issued, and multi-currency is only available on higher Xero plans. We invoice in the transaction currency and let Xero own the rate, so your ledger stays authoritative. Tax is derived, not copied - the correct Xero TaxType comes from the customer's country and VAT status, since HubSpot line items carry no equivalent concept.

### Who operates the integration after it goes live?

We do. The pipeline runs on cloud-native, fully EU-hosted infrastructure that we monitor. If Xero revises an endpoint or its rate limits, or a Xero refresh token stops rotating, or HubSpot changes a property or pipeline, that is our problem to fix under contract - not something your sales team discovers because invoices stopped appearing on deals. You get a named owner, alerting, incident response, and a DPA / AVV that keeps your GDPR obligations clean.

## Related integrations

- [HubSpot ↔ QuickBooks](https://seamless.engineering/integrations/hubspot-quickbooks/): HubSpot QuickBooks integration
- [Business Central ↔ HubSpot](https://seamless.engineering/integrations/business-central-hubspot/): Business Central HubSpot integration
- [GoCardless ↔ Xero](https://seamless.engineering/integrations/gocardless-xero/): GoCardless Xero integration
- [HubSpot ↔ Intercom](https://seamless.engineering/integrations/hubspot-intercom/): HubSpot Intercom integration
- [HubSpot ↔ Mailchimp](https://seamless.engineering/integrations/hubspot-mailchimp/): HubSpot Mailchimp integration
- [HubSpot ↔ Pipedrive](https://seamless.engineering/integrations/hubspot-pipedrive/): HubSpot Pipedrive integration

## Browse by system

- [All Xero integrations](https://seamless.engineering/integrations/xero/)
- [All HubSpot integrations](https://seamless.engineering/integrations/hubspot/)
- [HubSpot API changelog](https://seamless.engineering/api-changelog/hubspot/): 8 breaking changes and 2 deprecations in the last 90 days

## Request a scoping call

Need this integration built and permanently operated? Tell us which systems connect and what data has to move. Fixed-price scoping quote within 48 hours.

- Email: hello@seamless.engineering
- Contact form: https://seamless.engineering/#contact
