Ir al contenido
AtheronDEVELOPERS
← API reference

Token: swap a code

Swaps the code from the redirect for an ID token, an access token and, with offline_access, a refresh token.

Inicie sesión para ver su propio ID de cliente de prueba en los ejemplos.

POST https://accounts.aton-network.org/oauth/token

When to use it

On your server, in the route your redirect address points at, straight after checking state.

Authentication

client_secret_basic (preferred), client_secret_post, private_key_jwt, or none for a public app. See Secrets and certificates.

Parameters

NameInTypeRequiredLimitsWhat it is
grant_typeformstringyesauthorization_codeThis grant.
codeformstringyesThe code from the redirect. 60 seconds, once.
redirect_uriformstringyesThe same redirect address the authorize request used.
code_verifierformstringyes43 to 128 charactersThe verifier whose challenge you sent to authorize.
client_idformstringnoRequired for a public app, and with client_secret_post.
client_secretformstringnoOnly with client_secret_post. Prefer HTTP Basic.
client_assertion_typeformstringnourn:ietf:params:oauth:client-assertion-type:jwt-bearerWith private_key_jwt.
client_assertionformstringnoA JWT signed with your certificate's private key: iss and sub your client ID, aud the token endpoint, exp at most ten minutes ahead, a jti used once.

Request

# Swap the code from the redirect for tokens, on your server. HTTP Basic carries your client ID and
# secret; the verifier proves this is the browser that started the sign-in.
curl https://accounts.aton-network.org/oauth/token \
  -u "$ATHERON_CLIENT_ID:$ATHERON_CLIENT_SECRET" \
  -d grant_type=authorization_code \
  -d code="$CODE" \
  -d redirect_uri=https://app.example.com/callback \
  -d code_verifier="$VERIFIER"

Response

http
HTTP 200
content-type: application/json
cache-control: no-store

{
  "access_token": "eyJhbGciOiJFUzI1NiIsInR5cCI6ImF0K2p3dCJ9...",
  "token_type": "Bearer",
  "expires_in": 900,
  "scope": "openid profile email offline_access",
  "id_token": "eyJhbGciOiJFUzI1NiIsImtpZCI6IjIwMjYtMTAtMDEiLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJodHRwczovL2FjY291bnRzLmF0b24tbmV0d29yay5vcmciLCJzdWIiOiI5YTZk...",
  "refresh_token": "ath_rt_6Qm9..."
}

Errors

HTTPerrorCauseFix
400invalid_requestA parameter is missing or malformed: no PKCE, PKCE with plain, a bad max_age, prompt=none combined with another prompt, or a token request that is not form encoded.Send every required parameter once, PKCE with S256, and form-encode the token request.
401invalid_clientYour app could not be authenticated: a wrong or expired secret, a revoked or expired certificate, a bad client_assertion (aud must be the token endpoint, exp at most ten minutes ahead, jti new), a public app sending a secret, or the app is suspended.Check the credential on the app's Credentials page and its expiry. Rotate without downtime: add a new one, deploy, then revoke the old.
400invalid_grantThe code or refresh token cannot be used: the code expired (60 seconds) or was used, it was issued to another client, the redirect_uri or code_verifier does not match, a refresh token was used twice, access was withdrawn, or the tester was removed.Start the sign-in again. Swap each code once, straight away, with the same redirect_uri and the verifier you kept.
400unsupported_grant_typegrant_type is not authorization_code or refresh_token.Use one of the two.
429rate_limitedOver your quota for this bucket, this minute or this day.Wait the Retry-After seconds. Requests over the limit still count, so a retry loop keeps you over it.

Good to know

  • The body must be application/x-www-form-urlencoded. JSON is refused with invalid_request.
  • Check the ID token before you trust it: signature (ES256, from the keys), iss, aud is your client ID, exp, and nonce.
  • A refresh token comes back only when you asked for offline_access and the person agreed.

Security

  • Never call this from a browser with a secret. A public app sends client_id and its PKCE verifier only.
  • Send an assertion or a secret, never both.

Pregunte a Atlas

Asistente de IA

Pregunte lo que quiera sobre Iniciar sesión con Atheron, la API o el portal. La respuesta sale de nuestra documentación, con enlaces a las páginas usadas.