OAuth2 Flows
There are two ways to get a token, depending on whose data you're touching.
Server-to-server: client_credentials
This is what you'll use for the Payments API — creating, listing, capturing, and cancelling payments as a merchant. It requires a confidential application (is_confidential: true).
curl -X POST https://dev.gladys.the-all.io/api/v1/oauth/token \
-d grant_type=client_credentials \
-d client_id=<your client id> \
-d client_secret=<your client secret> \
-d scope=payments:create
The requested scope(s) must be a subset of what your application was registered with. No refresh token is issued for this grant — just request a new access token when the current one expires.
User-delegated: authorization_code with PKCE
Use this when you need a specific Gladys user's permission — for example, reading their profile (profile:read) or wallet balance (wallet:read). PKCE is mandatory for every application, confidential or not, and only S256 is supported (plain is rejected).
- Send the user to
/oauth/authorizewithresponse_type=code, yourclient_id,redirect_uri, thescope(s) you want, astate, and your PKCEcode_challenge+code_challenge_method=S256. The user must already be signed in to Gladys — this is a browser redirect, not a server-to-server call. - The user approves or denies on a consent screen. If they've already approved this exact set of scopes before, they're redirected straight back with no extra prompt.
- You receive an authorization code at your
redirect_uri(?code=...&state=...), valid for 5 minutes and usable exactly once. - Exchange the code for a token at
/oauth/tokenwithgrant_type=authorization_code, thecode, yourredirect_uriagain, and thecode_verifierthat matches the challenge from step 1.
curl -X POST https://dev.gladys.the-all.io/api/v1/oauth/token \
-d grant_type=authorization_code \
-d client_id=<your client id> \
-d client_secret=<your client secret> \
-d code=<the code from the redirect> \
-d redirect_uri=<same redirect_uri as step 1> \
-d code_verifier=<your PKCE verifier>
This grant does issue a refresh token. Refreshing rotates both tokens — the old refresh token is single-use, and a refreshed token's scopes can only stay the same or narrow, never widen.
Scopes
| Scope | Grants |
|---|---|
payments:create | Create payment intents |
payments:capture | Capture or cancel a payment |
payments:read | List and read payment intents |
payments:refund | Refund a captured payment |
profile:read | The user's name and masked contact details |
wallet:read | The user's wallet balance |
Discovery, introspection, and revocation
GET /.well-known/oauth-authorization-server— RFC 8414 metadata, if your OAuth library can configure itself from a discovery document.POST /oauth/introspect— check whether a token is still active. Confidential clients only.POST /oauth/revoke— revoke an access or refresh token you hold.