Skip to main content

Overview

The token exchange endpoint converts an authorization code into access tokens and ID tokens. This is the second step in the OAuth 2.0 authorization code flow, after receiving the authorization code from the authorization URL.

Endpoint

method
string
default:"POST"
POST
url
string
{SCALEKIT_ENVIRONMENT_URL}/oauth/token

Request Headers

Content-Type
string
required
Must be application/x-www-form-urlencoded

Request Parameters

grant_type
string
required
OAuth grant type. Use authorization_code for exchanging authorization codes.
code
string
required
The authorization code received from the authorization callback. This code is single-use and expires after a short period.
client_id
string
required
Your Scalekit application client ID from the Dashboard.
client_secret
string
required
Your Scalekit application client secret from the Dashboard.
redirect_uri
string
required
The same redirect URI used in the authorization request. Must match exactly.

Request Examples

    Response

    access_token
    string
    required
    JWT access token for making authenticated API requests on behalf of the user.
    token_type
    string
    required
    Always Bearer for OAuth 2.0 flows.
    expires_in
    integer
    required
    Number of seconds until the access token expires.
    id_token
    string
    required
    JWT ID token containing user identity information. Decode this token to access user claims.
    refresh_token
    string
    Refresh token for obtaining new access tokens. Only returned if offline_access scope was requested.
    scope
    string
    Space-separated list of granted OAuth scopes.

    Response Example

    {
      "access_token": "eyJhbGciOiJSUzI1NiIsImtpZCI6InNua181Ok4OTEyMjU2NiIsInR5cCI6IkpXVCJ9...",
      "token_type": "Bearer",
      "expires_in": 3600,
      "id_token": "eyJhbGciOiJSUzI1NiIsImtpZCI6InNua181Ok4OTEyMjU2NiIsInR5cCI6IkpXVCJ9...",
      "refresh_token": "v1.refresh_token_abc123...",
      "scope": "openid email profile"
    }
    

    ID Token Claims

    The ID token is a JWT that contains user identity information. Decode the token to access these claims:
    sub
    string
    required
    Unique identifier for the user (subject). Use this as the user ID in your application.
    email
    string
    User’s email address. Only present if email scope was requested.
    email_verified
    boolean
    Whether the email address has been verified.
    name
    string
    User’s full name. Only present if profile scope was requested.
    given_name
    string
    User’s first name.
    family_name
    string
    User’s last name.
    picture
    string
    URL of the user’s profile picture.
    iss
    string
    required
    Token issuer (your Scalekit environment URL).
    aud
    string
    required
    Token audience (your client_id).
    iat
    integer
    required
    Token issued at timestamp (Unix epoch).
    exp
    integer
    required
    Token expiration timestamp (Unix epoch).

    Decoded ID Token Example

    {
      "sub": "usr_2bqMbGm3qjJqXtEDzaUg6K1UiEr",
      "email": "[email protected]",
      "email_verified": true,
      "name": "Jane Doe",
      "given_name": "Jane",
      "family_name": "Doe",
      "picture": "https://example.com/photo.jpg",
      "iss": "https://your-org.scalekit.dev",
      "aud": "your_client_id",
      "iat": 1704067200,
      "exp": 1704070800
    }
    

    Error Responses

    error
    string
    Error code indicating the type of error.
    error_description
    string
    Human-readable description of the error.

    Common Errors

    Error CodeDescriptionSolution
    invalid_grantAuthorization code is invalid, expired, or already usedRequest a new authorization code
    invalid_clientClient authentication failedVerify client_id and client_secret
    invalid_requestMissing or invalid required parametersCheck all parameters are included
    unsupported_grant_typeInvalid grant_type parameterUse authorization_code for this flow
    redirect_uri_mismatchRedirect URI doesn’t match authorization requestEnsure redirect_uri matches exactly

    Error Response Example

    {
      "error": "invalid_grant",
      "error_description": "Authorization code has expired or is invalid"
    }
    

    Security Considerations

    Critical Security Practices:
    1. Token Validation: Always validate tokens before trusting their contents. Verify the signature, issuer, audience, and expiration.
    2. Secure Storage: Store tokens securely. Never expose access tokens or refresh tokens in URLs, logs, or client-side code.
    3. Client Secret: Never expose your client_secret in client-side code. This exchange must happen server-side.
    4. HTTPS Only: Always use HTTPS for token exchange to prevent token interception.
    5. Code Reuse: Authorization codes are single-use. Attempting to reuse a code may indicate an attack.
    6. Expiration: Check token expiration times and refresh tokens before they expire.

    Token Validation

    Always validate tokens before using them:
    // Example token validation (Node.js)
    import jwt from 'jsonwebtoken'
    import jwksClient from 'jwks-rsa'
    
    const client = jwksClient({
      jwksUri: `${process.env.SCALEKIT_ENVIRONMENT_URL}/.well-known/jwks.json`
    })
    
    function getKey(header, callback) {
      client.getSigningKey(header.kid, (err, key) => {
        const signingKey = key.publicKey || key.rsaPublicKey
        callback(null, signingKey)
      })
    }
    
    // Validate ID token
    jwt.verify(idToken, getKey, {
      issuer: process.env.SCALEKIT_ENVIRONMENT_URL,
      audience: process.env.SCALEKIT_CLIENT_ID
    }, (err, decoded) => {
      if (err) {
        console.error('Token validation failed:', err)
        return
      }
      
      // Token is valid, use decoded claims
      console.log('User ID:', decoded.sub)
      console.log('Email:', decoded.email)
    })
    

    Next Steps

    Session Management

    Manage user sessions and validate tokens

    Logout

    Implement secure logout functionality

    Build docs developers (and LLMs) love