Complete Xero Authorization (OAuth Callback)
GET/xero/auth/callback
Called by the merchant's browser, not by an integrator (note: no /api prefix). This is the redirect URI registered with Xero: after the merchant approves SKU.io on Xero's consent screen (opened from the authorization_url returned by Generate OAuth URL), Xero redirects the browser here. No bearer token.
Query parameters sent by Xero
code(required) — authorization code.state— the value SKU.io put on the authorization URL (<app url>~<tenant id>_<nonce>). The tenant prefix identifies the workspace; the nonce must be one this workspace issued, unexpired (30 minutes) and not yet used, otherwise the connection is refused.
Behaviour: exchanges the code for tokens. On a first connection SKU.io creates the Xero integration and starts downloading accounts, tax rates (auto-mapping the certain matches) and tracking categories in the background (first_run=1). When the workspace already has a Xero integration (re-authorization), its tokens are replaced and the integration is reactivated (first_run=0). A failed code exchange leaves no half-created integration behind.
Response: always a 302 redirect to the workspace's own host at /v2/integrations/xero/callback, a small page that notifies the window that opened the popup and closes:
- success:
?success=true&instance_id=7&first_run=1 - failure:
?success=false&error_message=...(missing code, invalid/expired/used state, token exchange failure).
Authentication: none (public redirect target, secured by the single-use state).
Request
Responses
- 302
- 401
- 403
- 429
Found
Response Headers
Unauthenticated — the bearer token is missing, revoked, expired, or malformed. Never retry automatically; fix the credential. See the Errors guide.
Forbidden — the token lacks a required scope, the endpoint is not available to API tokens, or the user behind the token lacks the permission. A human must adjust the token scopes or user permissions; do not retry.
Rate limited — platform limit is 1,000 requests/min; individual tokens may carry lower limits. Honor the Retry-After header before retrying. See the Rate Limits guide.