The Authorization Code Grant is a standard OAuth 2.0 flow that enables secure user authentication and authorization. This flow allows applications to obtain an access_token by first receiving an authorization code after the user logs in. The process works as follows:

  1. Your application redirects the user to authenticate with their Smokeball credentials
  2. Upon successful authentication, Smokeball returns an authorization code to your redirect URI
  3. Your application exchanges this code for an access_token that can be used to make authenticated API requests

This is the recommended OAuth 2.0 flow when you need to access the Smokeball API on behalf of a specific user.

Request User Authorization

Direct the user to https://auth.smokeball.com/oauth2/authorize with the following parameters:

Example:

curl -X GET 'https://auth.smokeball.com/oauth2/authorize?response_type=code&client_id=xxxxx&redirect_uri=https://xxxxxxxx'
response_type
string
required

Must be set to “code” for Authorization Code flow. Determines the OAuth 2.0 grant type being requested.

client_id
string
required

The client identifier issued during application registration. Used to identify the application making the authorization request.

redirect_uri
string
required

The URI where the authorization server will send the authorization code. Must match one of the pre-registered redirect URIs.

state
string

An opaque value used to maintain state between request and callback. Helps prevent CSRF attacks in the OAuth flow.

This parameter is optional.

scope
string

The requested scope of access (space-delimited strings). Defines the permissions being requested by the application.

This parameter is optional. Leaving it empty will ensure that all assigned scopes are automatically included in the access token.

The user will be directed to a login page where they will need to use their Smokeball credentials to login.

If authorized, the user will be redirected to:

https://your_redirect_uri?code=xxxxx

The response returns a one time use code that is valid for five minutes.

See AWS Cognito Authorization Endpoint Documentation for more information.

Request an Access Token

Once you have obtained an authorization code, you can now use it to get an access_token which may be used to make requests to the API.

Make a POST request to https://auth.smokeball.com/oauth2/token with the following parameters and headers:

curl --request POST \
  --url https://auth.smokeball.com/oauth2/token \
  --header "Authorization: Basic Y2xpZW50X2lkOmNsaWVudF9zZWNyZXQ=" \
  --header "Content-Type: application/x-www-form-urlencoded" \
  --data-urlencode "grant_type=authorization_code" \
  --data-urlencode "client_id=xxxx" \
  --data-urlencode "redirect_uri=https://xxxxx" \
  --data-urlencode "code=the code acquired from step 1"

The Authorization header must be the string “Basic” followed by your client_id and client_secret with a colon : in between, Base64 Encoded. For example, client_id:client_secret is Y2xpZW50X2lkOmNsaWVudF9zZWNyZXQ=

Sample Response

HTTP/1.1 200 OK
Content-Type: application/json

{ 
 "refresh_token":"dn43ud8uj32nk2je", 
 "access_token":"dmcxd329ujdmkemkd349r",
 "token_type":"Bearer", 
 "expires_in":3600
}
refresh_token
string

A token used to obtain a new access token when the current one expires.

By default, the returned refresh_token is valid for 30 days. If you require a longer expiration period, please contact us to discuss your specific needs.

access_token
string

The access token used to authenticate API requests.

By default, the returned access_token is valid for 60 minutes.

token_type
string

The type of token issued (typically "Bearer").

Indicates how the token should be presented in API requests.

expires_in
number

The lifetime of the access token in seconds.

After expiration, a new token must be obtained.

Important: The refresh token expiry is not returned in the above response. Your application is responsible for monitoring the expiration of the refresh token and prompting the user to re-authenticate when it expires. This ensures continuous access to the application without interruptions. See AWS Cognito Token Endpoint Documentation for more information

The use of id_token to make API requests has been deprecated. API requests can now also be made using the access_token.

For further information, see migration section below for migrating from id_token to access_token.

Please note that the id_token will continue to work for the time being and no immediate action is required.

PKCE (Proof Key for Code Exchange)

PKCE is an extension of the Authorization Code Grant flow, designed for mobile and single-page applications where storing a client secret securely is difficult. It ensures a more secure flow by requiring a dynamically generated code verifier and code challenge. It is recommended that all authorization code flows are authorized using PKCE and it is required for all public api clients, which do not have a client secret.

Generate a Code Verifier and Code Challenge

To initiate the PKCE flow, you must generate a code_verifier, which is a random string, and a code_challenge, which is derived by hashing the code_verifier using SHA-256 and then Base64-URL encoding it.

using System;
using System.Security.Cryptography;
using System.Text;

class PKCEGenerator
{
    public static void Main()
    {
        string codeVerifier = GenerateCodeVerifier();
        string codeChallenge = GenerateCodeChallenge(codeVerifier);

        Console.WriteLine("Code Verifier: " + codeVerifier);
        Console.WriteLine("Code Challenge: " + codeChallenge);
    }

    // Generate a random code verifier
    private static string GenerateCodeVerifier()
    {
        var randomBytes = new byte[32]; // 32-byte random string
        using (var rng = RandomNumberGenerator.Create())
        {
            rng.GetBytes(randomBytes);
        }
        return Base64UrlEncode(randomBytes);
    }

    // Create code challenge using SHA256
    private static string GenerateCodeChallenge(string codeVerifier)
    {
        using (var sha256 = SHA256.Create())
        {
            byte[] challengeBytes = sha256.ComputeHash(Encoding.UTF8.GetBytes(codeVerifier));
            return Base64UrlEncode(challengeBytes);
        }
    }

    // Base64 URL Encoding (removes padding, uses '-' and '_')
    private static string Base64UrlEncode(byte[] bytes)
    {
        return Convert.ToBase64String(bytes)
            .Replace("+", "-")
            .Replace("/", "_")
            .TrimEnd('=');
    }
}

Request Authorization Code for Access Token

Direct the user to https://auth.smokeball.com/oauth2/authorize with the following parameters:

curl --request GET \
  --url "https://auth.smokeball.com/oauth2/authorize?response_type=code&client_id=xxxxx&redirect_uri=https://your_redirect_uri&code_challenge_method=S256&code_challenge=your_code_challenge"
response_type
string
required

Must be set to “code” for Authorization Code flow.

Determines the OAuth 2.0 grant type being requested.

client_id
string
required

The client identifier issued during application registration.

Used to identify the application making the authorization request.

redirect_uri
string
required

The URI where the authorization server will send the authorization code.

Must match one of the pre-registered redirect URIs.

code_challenge
string
required

The PKCE code challenge derived from the code verifier.

Generated using the S256 code challenge method.

code_challenge_method
string
required

The hash method used to generate the code challenge (must be “S256”).

Ensures secure PKCE implementation for authorization flow.

state
string

An opaque value used to maintain state between request and callback.

Helps prevent CSRF attacks in the OAuth flow.

This parameter is optional.

scope
string

The requested scope of access (space-delimited strings). Defines the permissions being requested by the application.

This parameter is optional. Leaving it empty will ensure that all assigned scopes are automatically included in the access token.

For Smokeball API, only S256 method is allowed for code_challenge_method

The user will be directed to the login page, and if authorized, redirected back with a code.

Exchange Authorization Code for Access Token

After receiving the authorization code, use it along with the code_verifier to request an access token:

curl --request POST \
  --url https://auth.smokeball.com/oauth2/token \
  --header "Content-Type: application/x-www-form-urlencoded" \
  --data-urlencode "grant_type=authorization_code" \
  --data-urlencode "client_id=xxxxx" \
  --data-urlencode "code=authorization_code_from_previous_step" \
  --data-urlencode "redirect_uri=https://your_redirect_uri" \
  --data-urlencode "code_verifier=your_code_verifier"
grant_type
string
required

Must be set to “authorization_code” for this flow.

Specifies the OAuth 2.0 grant type being used.

client_id
string
required

The client identifier issued during application registration.

Must match the client_id used in the authorization request.

code
string
required

The authorization code received from the authorization server.

This is the code obtained in the previous authorization step.

redirect_uri
string
required

The same redirect URI that was used in the authorization request.

Must exactly match the previous URI for security validation.

code_verifier
string
required

The original PKCE code verifier that was used to generate the code_challenge.

Used to prove possession of the authorization code.

client_secret
string
required

The client secret for confidential clients.

Required if the client is configured with a secret.

You will receive an access token that can be used to authenticate API requests.

Refreshing an Access Token

You can use the refresh_token returned in the previous request to continuously retrieve a valid access_token for use with the API. To exchange a refresh_token for an access_token, make the following request:

  curl -X POST 'https://auth.smokeball.com/oauth2/token' \
    --header 'Authorization: Basic Y2xpZW50X2lkOmNsaWVudF9zZWNyZXQ=' \
    --header 'Content-Type: application/x-www-form-urlencoded' \
    --data-urlencode 'grant_type=refresh_token' \
    --data-urlencode 'client_id=xxxxxx' \
    --data-urlencode 'refresh_token=xxxxxx'
Authorization
string
required

Basic Authentication header containing base64-encoded client_id:client_secret.

Example: Basic Y2xpZW50X2lkOmNsaWVudF9zZWNyZXQ=

Content-Type
string
required

Must be application/x-www-form-urlencoded for token endpoints.

grant_type
string
required

Must be refresh_token for this flow.

Determines the OAuth2 grant type being used.

client_id
string
required

The client identifier issued during registration.

Must match the client ID used in the Basic Auth header.

refresh_token
string
required

Previously issued refresh token.

Used to obtain new access tokens without re-authentication.

Sample Response

HTTP/1.1 200 OK
Content-Type: application/json

{
 "access_token":"dmcxd329ujdmkemkd349r",
 "token_type":"Bearer", 
 "expires_in":3600
}
access_token
string
required

The access token used to authenticate API requests.

By default, the returned access_token is valid for 60 minutes.

token_type
string
required

The type of token issued (typically "Bearer").

Indicates how the token should be presented in API requests.

expires_in
number
required

The lifetime of the access token in seconds.

After expiration, a new token must be obtained.

See AWS Cognito User Pool OAuth 2.0 Grants for more information

Migrating from Id Token to Access Token

The use of id_token to make API requests has been deprecated. We will be phasing out issuing an id_token when you request a token in the future.

If you have been using an id_token for your API requests, no immediate action is required. You will be contacted with instructions for transitioning to the access_token. You can also contact us via this link and provide us with a list of endpoints that you need access to so we can verify that your access_token is appropriately configured with the necessary permissions.

Note: When you transition to access_token you will no longer require to include the scope query parameter in your user authorization requests. Please remember to omit scope=openid from your requests to https://auth.smokeball.com/oauth2/authorize, to ensure seamless operation.