Skip to main content
ClearLine uses OAuth 2.0 for secure API authentication. Choose your authentication flow below and get your first access token in minutes.
New to OAuth2? No worries! Just follow the code examples for your integration type - most developers are authenticated within 5 minutes.

Which Authentication Flow Do I Need?

Security Rule: Never use Client Credentials Flow in mobile or browser apps. Client secrets must remain on secure servers only.

Get Your Access Token

Authorization Code Flow with PKCE

Best for: Mobile apps, web applications, any app where users log in with their ClearLine credentials

Generate PKCE Challenge

Create a code verifier and challenge for security.
// Generate code_verifier (43-128 characters)
const codeVerifier = generateRandomString(64);

// Generate code_challenge
const codeChallenge = base64UrlEncode(sha256(codeVerifier));

function generateRandomString(length) {
  const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~';
  let result = '';
  const randomValues = crypto.getRandomValues(new Uint8Array(length));
  for (let i = 0; i < length; i++) {
    result += chars[randomValues[i] % chars.length];
  }
  return result;
}
Important: Save the code_verifier! You’ll need it in Step 3 to exchange the authorization code for tokens.

Redirect User to Login

Send the user to ClearLine’s login page using the GET /Account/Login endpoint.
const authUrl = new URL('https://logintest.clearline.me/Account/Login');
authUrl.searchParams.append('ReturnUrl', '/connect/authorize/callback');
authUrl.searchParams.append('response_type', 'code');
authUrl.searchParams.append('client_id', 'your-client-id');
authUrl.searchParams.append('scope', 'clearline_api openid profile');
authUrl.searchParams.append('redirect_uri', 'myapp://auth-callback');
authUrl.searchParams.append('code_challenge', codeChallenge);
authUrl.searchParams.append('code_challenge_method', 'S256');
authUrl.searchParams.append('state', generateRandomString(32)); // CSRF protection

// Redirect user
window.location.href = authUrl.toString();
The user logs in and authorizes your app. ClearLine redirects back to your redirect_uri with an authorization code:
myapp://auth-callback?code=AUTH_CODE_HERE&state=...

Exchange Code for Access Token

Trade the authorization code for an access token using the POST /connect/token endpoint.
curl -X POST https://logintest.clearline.me/connect/token \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -H "Authorization: Basic $(echo -n 'client_id:client_secret' | base64)" \
  -d "grant_type=authorization_code" \
  -d "code=AUTH_CODE_FROM_CALLBACK" \
  -d "redirect_uri=myapp://auth-callback" \
  -d "code_verifier=YOUR_CODE_VERIFIER"
Response:
access_token
string
required
JWT access token - include in Authorization: Bearer {token} header for all API requests
token_type
string
required
Always “Bearer”
expires_in
integer
required
Token lifetime in seconds (typically 3600 = 1 hour)
refresh_token
string
Use to obtain new access tokens without re-authenticating the user
scope
string
required
Granted scopes (e.g., “clearline_api openid profile”)
You’re authenticated! Use the access_token in your API requests. See Using Your Access Token below.

Using Your Access Token

Once you have an access token, include it in the Authorization header of all API requests:
GET https://public-api-demo.clearline.me/v2/pos/{posSystemId}/settings/lookup
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
Content-Type: application/json

Token Lifecycle

Active Token (0-3600 seconds)

Use your token normally for API requests. It’s valid and working.
Best practice: Refresh your token proactively before it expires.
if (tokenExpiresAt < Date.now() + 300000) {
  // Refresh 5 minutes before expiry
  await refreshAccessToken();
}
Authorization Code Flow: Use your refresh_token to get a new access token without re-authenticating the user.Client Credentials Flow: Request a new token using the same process as before.
If you receive a 401 Unauthorized error, your token is invalid. Re-authenticate from the beginning.Common causes: token manually revoked, credentials changed, or security policy violation.

OAuth Scopes

Request the appropriate scopes based on your integration needs:
ScopeDescriptionTypical Use
clearline_apiGeneral API access for user applicationsUser-facing apps
pos_integrationFull POS integration (transactions, loyalty, coupons)POS terminals
coupons_integrationCoupon-specific integration accessCoupon providers
openidUser identity information (required for user auth)User-facing apps
profileUser profile data (name, email, etc.)User-facing apps
Request multiple scopes by separating them with spaces:
scope=clearline_api openid profile

Environments

ClearLine provides three environments for different stages of development:
EnvironmentAuth Base URLPurpose
Testlogintest.clearline.meDevelopment and integration testing
Demologindemo.clearline.meClient demonstrations and UAT
Productionlogin.clearline.meLive production environment
Don’t mix up Auth and API URLs!
  • Authentication/Token requests: login*.clearline.me (OAuth endpoints)
  • API business requests: public-api-*.clearline.me (with your Bearer token)
See API Environments for complete environment configuration details.

Troubleshooting

Cause: Authorization codes expire quickly (typically 5 minutes) or have already been used.Solution:
  • Request a new authorization code by redirecting the user to login again
  • Ensure you exchange the code immediately after receiving it
  • Verify you’re not reusing the same code (codes are single-use only)
Cause: Your client_id or client_secret is incorrect, or the Basic Auth header is malformed.Solution:
  • Verify credentials in the ClearLine Admin Portal
  • Ensure Basic Auth header format: Basic {base64(client_id:client_secret)}
  • Check for spaces or special characters in your credentials
  • Test your base64 encoding: client_id:client_secret should encode properly
Cause: Missing code_verifier parameter when exchanging authorization code (PKCE flow).Solution:
  • Save the code_verifier before redirecting to login
  • Include it in the token request body
  • The verifier must exactly match the one used to generate code_challenge
Cause: Your client is not configured for the grant type you’re trying to use.Solution:
  • Contact ClearLine support to verify your client configuration
  • Ensure you’re using the correct flow for your client type:
    • User apps → Authorization Code Flow
    • POS/server apps → Client Credentials Flow
Cause: You’re requesting a scope that doesn’t exist or your client isn’t authorized for.Solution:
  • Use valid scopes: clearline_api, pos_integration, coupons_integration, openid, profile
  • Check scope spelling and formatting (lowercase, underscore-separated)
  • Verify your client has permission for the requested scopes in Admin Portal

Security Best Practices

Protect Client Secrets

Never expose client_secret in:
  • Mobile app code
  • Browser JavaScript
  • Public repositories
  • Client-side storage
Always store secrets only on secure servers with proper encryption.

Validate State Parameter

Always validate the state parameter in OAuth callbacks to prevent CSRF attacks.
if (callbackState !== originalState) {
  throw new Error('CSRF attack detected');
}

Use HTTPS Only

Always use HTTPS for:
  • Redirect URIs
  • Token endpoints
  • All API requests
HTTP is not supported in production environments.

Implement Proactive Token Refresh

Don’t wait for 401 errors - refresh tokens before they expire:
// Refresh 5 min before expiry
if (expiresAt < Date.now() + 300000) {
  await refreshToken();
}

Next Steps