This guide will help you understand how to set up a standard refresh token flow for an OAuth app. For more details on which flow to use or how to set up your OAuth app within Kit, please refer to the more general “Authentication” guide. We also offer example OAuth implementations that can be viewed below:
View Oauth2 strategy for Kit on Github
See an example of authenticating with Kit’s OAuth Server in Node.js here

OAuth refresh token flow

1

User initiates install from Kit's App Store

When a user installs your app from the Kit App Store, Kit redirects them to the Authorization URL you’ve configured.
https://example.com/kit/oauth?redirect=https://app.kit.com/apps/1?success=true
From here, your app should present the user a screen to sign in (or sign up).
Kit will append a redirect query parameter to your Authorization URL that you will need to save in order to complete the flow.
2

App requests user's Kit identity

After the user successfully authenticates with your app, redirect them to Kit’s OAuth server to request their identity.
The value supplied to redirect_uri must be one of the Redirect URIs configured in your app’s settings, found on the Distribution tab.
    https://api.kit.com/v4/oauth/authorize?
        client_id=YOUR_CLIENT_ID&
        response_type=code&
        redirect_uri=https://oauth2.example.com/callback&
        state=DEF456
client_id
string
required
Your app’s Client ID
response_type
string
required
code
redirect_uri
string
required
URI to redirect to
scope
string
Default scope is public. Fine-grained access control via scopes coming soon.
state
string
Custom state to pass to the redirect_uri and/or to protect from XSRF
tenant_name
string
Unique, human-readable identifier for a tenant of a multi-tenant app.
Found on the “Authentication” tab in your app settings:Example Kit app configuration
3

Kit prompts user for consent

Kit will present a consent screen that asks the user to grant or refuse your app access to their account.
Kit OAuth page
4

Kit redirects to App OAuth callback with authorization code

If the user grants access, Kit redirects the user back to the redirect_uri you provided when requesting the user’s identity in step 2.

Kit appends a code query param with a temporary authorization code.

Kit also appends a state query param with the same value sent in the authorization request. This check helps verify that the user, not a malicious script, is making the request and reduces the risk of CSRF attacks.
https://oauth2.example.com/callback?
    code=mrApixZzMPnYO28KoeIZxn2mvom1Tx48S9iyrQVYVE8&
    state=DEF456
5

App exchanges authorization code for refresh and access tokens

Your app uses the authorization code provided to obtain a refresh and access token.
    POST https://api.kit.com/v4/oauth/token
With a body like so:
    {
        "client_id": "YOUR_CLIENT_ID",
        "client_secret": "YOUR_CLIENT_SECRET",
        "grant_type": "authorization_code",
        "code": "abc123",
        "redirect_uri": "https://oauth2.example.com/callback"
    }
client_id
string
required
Your app’s Client ID
client_secret
string
required
Your app’s Client Secret
grant_type
string
required
authorization_code
code
string
The code received via the redirect uri query params
redirect_uri
string
The redirect URI the request is coming from (must be one of your app’s redirect URIs)
    curl -X POST https://api.kit.com/v4/oauth/token \
        -H 'Content-Type: application/json' \
        -H 'Accept: application/json' \
        -d '{
            "client_id": "YOUR_CLIENT_ID",
            "client_secret": "YOUR_CLIENT_SECRET",
            "grant_type": "authorization_code",
            "code": "abc123",
            "redirect_uri": "https://oauth2.example.com/callback"
        }'
200: Returns a token
{
    "access_token": "YOUR_ACCESS_TOKEN_HERE",
    "token_type": "Bearer",
    "expires_in": 172800,
    "refresh_token": "YOUR_REFRESH_TOKEN_HERE",
    "scope": "public",
    "created_at": 1710270147
}

Response schema: application/json

access_token
string
required
Access token that can be used to make API requests on behalf of the authenticated user
token_type
string
required
Bearer
expires_in
integer
required
When the access token expire in seconds
refresh_token
string
required
Refresh token that can be used to generate a new access token once this one expires
scope
string
required
The scopes available for the access token
created_at
integer
required
When the access token was created
6

App redirects user back to Kit

Now that the user has completed the OAuth flow, your app must send the the user back to Kit using the redirect parameter provided at the beginning of the flow.

This will ensure the user properly navigates back to your app inside of Kit and registers that the app has been installed.

If you have set up the Redirect URL after install field in your app’s settings, a modal prompting creators to continue their journey on your configured site will appear at this point. See this section in the app details page guide for more details.
example redirect flow
7

App uses access token to make Kit API calls

Your app can now make calls to Kit’s API on behalf of the user by passing a Authorization header with the token as a Bearer value.
    curl -X GET https://api.kit.com/v4/account \
        -H 'Accept: application/json' \
        -H 'Authorization: Bearer YOUR_ACCESS_TOKEN_HERE'
8

App uses refresh token to obtain new access token after expiration

The access token will eventually expire and a new one must be obtained using the refresh token obtained earlier. To do this, make a POST call to https://api.kit.com/v4/oauth/token, with the following body:
    {
        "client_id": "YOUR_CLIENT_ID",
        "grant_type": "refresh_token",
        "refresh_token": "abc123"
    }
client_id
string
required
Your app’s Client ID
grant_type
string
required
refresh_token
refresh_token
string
required
The refresh token
curl -X POST https://api.kit.com/v4/oauth/token \
    -H 'Content-Type: application/json' \
    -H 'Accept: application/json' \
    -d '{
        "client_id": "YOUR_CLIENT_ID",
        "grant_type": "refresh_token",
        "code": "abc123"
    }'
200: Returns a token
    {
        "access_token": "YOUR_NEW_ACCESS_TOKEN_HERE",
        "token_type": "Bearer",
        "expires_in": 7200,
        "refresh_token": "YOUR_NEW_REFRESH_TOKEN_HERE",
        "scope": "public",
        "created_at": 1710271006
    }

Response schema: application/json

access_token
string
required
Access token that can be used to make API requests on behalf of the authenticated user
token_type
string
required
Bearer
expires_in
integer
required
When the access token expire in seconds
refresh_token
string
required
Refresh token that can be used to generate a new access token once this one expires
scope
string
required
The scopes available for the access token
created_at
integer
required
When the access token was created