xuly.io

OAuth2 setup

For public apps that need users to grant xuly.io access without pasting API keys.

If you're building an app that acts on behalf of xuly.io users — a BI dashboard, a Slack bot, a Zapier-style integration — OAuth2 is the right auth model. For internal scripts or one-off automations, use an API key instead.

Register your app

Go to Settings → OAuth apps (Business plan and above) and click New app. You'll need:

  • A display name and logo (shown to users on the consent screen).
  • A redirect URL — we only redirect to URLs you register explicitly.
  • A set of scopes you want to request — keep it minimal for better consent rates.

On creation you receive a client ID (safe to embed in frontends) and a client secret (never embed in frontends).

The authorization flow

xuly.io implements the standard Authorization Code Flow with PKCE.

Step 1 — Send user to the authorize URL

https://app.xuly.io/oauth/authorize?
  response_type=code
  &client_id=<your_client_id>
  &redirect_uri=<your_redirect>
  &scope=stats:read%20integrations:read
  &state=<random_csrf_token>
  &code_challenge=<pkce_challenge>
  &code_challenge_method=S256

Step 2 — Exchange the code for tokens

POST https://api.xuly.io/oauth/token
Content-Type: application/x-www-form-urlencoded

grant_type=authorization_code
&code=<code_from_redirect>
&redirect_uri=<same_as_before>
&client_id=<your_client_id>
&client_secret=<your_client_secret>
&code_verifier=<pkce_verifier>

You get back an access token (valid 1h), a refresh token (valid 30 days, single-use), and a user context describing which workspace the user authorised.

Step 3 — Call the API

GET https://api.xuly.io/v1/stats
Authorization: Bearer <access_token>

Refreshing tokens

POST https://api.xuly.io/oauth/token
grant_type=refresh_token&refresh_token=<refresh>&client_id=...&client_secret=...

Refresh tokens are single-use — each refresh returns a fresh pair. The old refresh token is invalidated immediately, so save the new one.

Scopes

Request the narrowest scopes you need. Users are more likely to approve minimal-access apps.

  • stats:read — read aggregated stats
  • integrations:read, integrations:write
  • campaigns:read, campaigns:write
  • invoices:read, invoices:write
  • webhooks:manage