Developer documentation
Overview
What the proxy does, what it deliberately does not do, and how a request travels through it.
What this is
Xero Proxy holds one OAuth connection to a Xero organisation and fans it out to as many downstream applications as you like, each with its own revocable API key. Xero sees a single connected app; you see one credential per integration, scoped and auditable.
- A one-to-one passthrough: paths, query strings, headers and bodies are forwarded unchanged, and Xero's status codes, bodies and rate-limit headers come back verbatim.
- Three independent restrictions on every key: which organisations it may reach, which scopes it holds, and which network addresses it may call from.
- Deny by default: a method and path that is not in the route table never reaches Xero.
- Token refresh is single-flight across every container, so fifty concurrent callers hitting an expired token produce exactly one refresh.
The request lifecycle
- 1.Credential: the bearer token is parsed, the key looked up by its public ID and the secret verified against its hash. There is no cache, so a revocation applies to the very next request.
- 2.Network scope: if the key carries an allowlist, the calling address must match it.
- 3.Route mapping: the method and path are resolved against the route table. An unmapped route is denied and logged.
- 4.Tenant selection: a single-organisation key has its Xero-Tenant-Id filled in; a multi-organisation key must state one, and it must be in the key's own set.
- 5.Permission scope: the required scope must be in the intersection of what the key was granted and what the connection currently holds.
- 6.Replay and budget: an account may have read caching, idempotent writes or a quota policy turned on. A request answered from a stored read or a recorded write stops here and spends nothing; otherwise the policy decides whether this key may spend what is left.
- 7.Forward: the request is streamed to Xero with a valid access token, and the response streamed straight back.
Every step is a hard gate. A request that fails any of them never reaches Xero, and the refusal is logged with the reason.
What it does not do
- It does not transform payloads. There is no schema mapping layer to fall out of date, and a response is Xero's own bytes unless this page says otherwise.
- It does not absorb Xero's rate limiting. Xero's 429s pass through with
Retry-Afterintact, so your existing backoff keeps working exactly as it did against Xero directly. - It does not decide anything about your traffic on your behalf. Caching, quota governance, idempotent writes, body capture, deferred execution and completion callbacks are each off until an account turns them on, and an account that turns none of them on gets a pure passthrough.
- It does not call anywhere you did not ask it to. The only addresses it will send to are ones an account owner registered in the dashboard, for Xero event fan-out, alert notifications and completion callbacks. A proxied request cannot name a destination, and every registered URL must be public https.
- It does not hold data it was not asked to hold. Request and response bodies are stored only by the features you enable, always encrypted at rest, always with a stated expiry.