Skip to main content
The Flextell API uses the OAuth 2.0 Authorization Code flow to grant your application access to Flextell resources on behalf of a user. This flow is the recommended approach for server-side applications where you can securely store a client secret.

How the flow works

Three actors are involved:
  • Your app — the application you’re building that needs access to the Flextell API.
  • The end user — the person who owns the Flextell account your app wants to act on behalf of.
  • Flextell’s authorization server — handles authentication and issues tokens.
At a high level: your app redirects the user to Flextell to log in and grant permission. Flextell then redirects back to your app with a short-lived authorization code. Your app exchanges that code for an access token, which it uses to make API requests.
1

Redirect the user to Flextell

Send the user to Flextell’s authorization endpoint. Construct the URL with the required query parameters:
https://dev.flextell.ai/oauth/authorize
response_type
string
required
Must be code. Tells Flextell you are using the Authorization Code flow.
client_id
string
required
Your application’s client ID, issued when you registered your app with Flextell.
redirect_uri
string
required
The URL Flextell will redirect the user back to after they grant (or deny) permission. Must exactly match one of the redirect URIs registered for your app.
scope
string
required
A space-separated list of permissions your app is requesting (e.g., read:contacts write:messages).
state
string
required
A random, unguessable string your app generates. Flextell echoes it back in the redirect so you can verify the response is legitimate and guard against CSRF attacks.
curl --get "https://dev.flextell.ai/oauth/authorize" \
  --data-urlencode "response_type=code" \
  --data-urlencode "client_id=YOUR_CLIENT_ID" \
  --data-urlencode "redirect_uri=https://yourapp.com/callback" \
  --data-urlencode "scope=read:contacts write:messages" \
  --data-urlencode "state=abc123xyz"
Always generate a new state value per authorization request and store it in your session. Verify it matches when Flextell redirects back.
2

User logs in and grants permission

Flextell presents the user with a login screen (if they are not already authenticated) followed by a consent screen listing the permissions your app is requesting.If the user approves, Flextell redirects them to your redirect_uri. If the user denies access, Flextell also redirects back but includes an error parameter instead of a code.
3

Receive the authorization code

After the user grants permission, Flextell redirects to your redirect_uri with an authorization code and your original state value appended as query parameters:
https://yourapp.com/callback?code=AUTH_CODE_HERE&state=abc123xyz
Before proceeding, verify that the state value matches what you sent in step 1.
The authorization code is short-lived (typically a few minutes) and can only be used once. Exchange it for a token immediately.
4

Exchange the code for tokens

Make a POST request from your server to the token endpoint:
https://dev.flextell.ai/oauth/token
grant_type
string
required
Must be authorization_code.
code
string
required
The authorization code received in the redirect.
redirect_uri
string
required
The same redirect_uri you used in step 1. Must match exactly.
client_id
string
required
Your application’s client ID.
client_secret
string
required
Your application’s client secret. Never expose this in client-side code or public repositories.
curl --request POST "https://dev.flextell.ai/oauth/token" \
  --header "Content-Type: application/x-www-form-urlencoded" \
  --data-urlencode "grant_type=authorization_code" \
  --data-urlencode "code=AUTH_CODE_HERE" \
  --data-urlencode "redirect_uri=https://yourapp.com/callback" \
  --data-urlencode "client_id=YOUR_CLIENT_ID" \
  --data-urlencode "client_secret=YOUR_CLIENT_SECRET"
A successful response returns the following JSON:
access_token
string
required
The token your app uses to authenticate API requests. Pass it as a Bearer token in the Authorization header.
token_type
string
required
Always Bearer.
expires_in
number
required
Number of seconds until the access token expires.
refresh_token
string
required
A long-lived token used to obtain a new access token without requiring the user to log in again.
{
  "access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
  "token_type": "Bearer",
  "expires_in": 3600,
  "refresh_token": "def50200abc..."
}
5

Make authenticated API requests

Include the access token as a Bearer token in the Authorization header of every API request:
curl "https://dev.flextell.ai/api/v0.0.1/your-resource" \
  --header "Authorization: Bearer YOUR_ACCESS_TOKEN"

Refreshing an expired token

Access tokens expire after the duration indicated by expires_in. When a token expires, the API returns a 401 Unauthorized response. Use the refresh token to obtain a new access token without requiring the user to log in again. Send a POST request to the token endpoint with grant_type=refresh_token:
curl --request POST "https://dev.flextell.ai/oauth/token" \
  --header "Content-Type: application/x-www-form-urlencoded" \
  --data-urlencode "grant_type=refresh_token" \
  --data-urlencode "refresh_token=YOUR_REFRESH_TOKEN" \
  --data-urlencode "client_id=YOUR_CLIENT_ID" \
  --data-urlencode "client_secret=YOUR_CLIENT_SECRET"
The response has the same shape as the initial token exchange and includes a new access_token and a new refresh_token.
{
  "access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
  "token_type": "Bearer",
  "expires_in": 3600,
  "refresh_token": "def50200xyz..."
}
Replace your stored refresh token with the new one returned in each refresh response. Refresh tokens are rotated on use — the old token is immediately invalidated.
Proactively refresh the access token before it expires (for example, when expires_in is less than 60 seconds away) to avoid 401 errors on in-flight requests.