Partner API Authentication
Learn how to authenticate requests to the CHeKT Partner API
Partner API Authentication
The Partner API uses OAuth 2.0 for authentication with two different flows depending on the endpoint. This guide explains how to set up authentication and make authorized API calls.
Two APIs, Two Auth Methods
Partner API and Partner Event API have different authentication methods. This document covers Partner API authentication. For Partner Event API authentication, see the Event API documentation.
Overview
The Partner API requires different authentication methods based on the endpoint:
| Endpoint | Authentication Method |
|---|---|
/partner/v1/dealers/connect | OAuth 2.0 Authorization Code Flow |
| All other endpoints | OAuth 2.0 Client Credentials Grant (M2M) |
Step 1: Register Auth Application
Before you can use the Partner API, you must register an Auth Application with CHeKT to obtain credentials for M2M (Machine-to-Machine) authentication.
Registration Requirements
Contact CHeKT support to register your Auth Application. You will need to provide:
- Application Name: Your platform or company name
- Public Key: Your RSA public key for JWT signing verification
- Additional Information: Platform details, integration scope, and technical contact
What You Receive
After registration, you will receive:
- Client ID: Your application identifier
- Secret Key: Your private secret for signing assertions
- Auth Server URL: The token endpoint for authentication
Keep Credentials Secure
- Store your secret key securely - never commit it to version control
- Treat credentials like passwords
- Rotate keys periodically for enhanced security
Step 2: Dealer Connection Flow
The /partner/v1/dealers/connect endpoint requires a special authentication flow to establish the relationship between dealers on both platforms.
OAuth 2.0 Authorization Code Flow
This endpoint uses the Authorization Code Flow to authenticate users and exchange dealer information between platforms.
Separate Auth Application Required
You need a second Auth Application specifically for the Authorization Code Flow. Contact CHeKT support to register this additional application.
Authorization Code Flow Steps
1. User Authorization Request
Redirect the user to CHeKT's authorization endpoint:
GET https://auth.chekt.com/oauth/authorize?
response_type=code&
client_id=YOUR_CLIENT_ID&
redirect_uri=YOUR_REDIRECT_URI&
scope=dealer:connect&
state=RANDOM_STATE_STRING
2. User Grants Permission
The user logs in to CHeKT and authorizes your application to access their dealer information.
3. Receive Authorization Code
CHeKT redirects back to your redirect_uri with an authorization code:
GET https://yourapp.com/callback?
code=AUTHORIZATION_CODE&
state=RANDOM_STATE_STRING
4. Exchange Code for Access Token
Make a POST request to exchange the authorization code for an access token:
curl -X POST https://auth.chekt.com/oauth/token \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=authorization_code" \
-d "code=AUTHORIZATION_CODE" \
-d "client_id=YOUR_CLIENT_ID" \
-d "client_secret=YOUR_CLIENT_SECRET" \
-d "redirect_uri=YOUR_REDIRECT_URI"
Response:
{
"access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
"token_type": "Bearer",
"expires_in": 3600,
"refresh_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..."
}
5. Call Dealer Connect API
Use the access token to call the dealer connect endpoint:
curl -X POST https://api.chekt.com/partner/v1/dealers/connect \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"partner_dealer_id": "your_dealer_id",
"dealer_name": "Dealer Name"
}'
Step 3: M2M Authentication for All Other Endpoints
Once dealers are connected, all other Partner API endpoints use OAuth 2.0 Client Credentials Grant with JWT assertion tokens.
Authentication Flow
sequenceDiagram
participant Partner as Your Platform
participant Auth as CHeKT Auth Server
participant API as Partner API
Partner->>Partner: Create JWT Assertion Token
Partner->>Partner: Sign with M2M Secret
Partner->>Auth: POST /oauth/token (with assertion)
Auth->>Auth: Verify signature
Auth->>Partner: Return access_token
Partner->>API: API Request (Bearer token)
API->>Partner: API Response
Create JWT Assertion Token
1. Build JWT Claims
Create a JWT with the following claims:
{
"iss": "YOUR_CLIENT_ID",
"sub": "YOUR_CLIENT_ID",
"aud": "https://auth.chekt.com",
"exp": 1234567890,
"iat": 1234567800,
"jti": "unique-jwt-id"
}
2. Sign with M2M Secret Key
Sign the JWT using your M2M secret key (RS256 algorithm):
// Node.js example
const jwt = require('jsonwebtoken');
const assertion = jwt.sign(
{
iss: 'YOUR_CLIENT_ID',
sub: 'YOUR_CLIENT_ID',
aud: 'https://auth.chekt.com',
exp: Math.floor(Date.now() / 1000) + 300, // 5 minutes
iat: Math.floor(Date.now() / 1000),
jti: generateUniqueId()
},
YOUR_SECRET_KEY,
{ algorithm: 'RS256' }
);
# Python example
import jwt
import time
import uuid
assertion = jwt.encode(
{
"iss": "YOUR_CLIENT_ID",
"sub": "YOUR_CLIENT_ID",
"aud": "https://auth.chekt.com",
"exp": int(time.time()) + 300, # 5 minutes
"iat": int(time.time()),
"jti": str(uuid.uuid4())
},
YOUR_SECRET_KEY,
algorithm="RS256"
)
Exchange Assertion for Access Token
Request:
curl -X POST https://auth.chekt.com/oauth/token \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer" \
-d "assertion=YOUR_JWT_ASSERTION"
Response:
{
"access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
"token_type": "Bearer",
"expires_in": 3600
}
Make API Requests
Include the access token in the Authorization header:
curl -X GET https://api.chekt.com/partner/v1/sites \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json"
Token Management
Token Expiration
Access tokens expire after a period (typically 1 hour). When a token expires:
- You'll receive a
401 Unauthorizedresponse - Generate a new JWT assertion and request a new access token
Token Caching
Cache access tokens and reuse them until they expire to minimize authentication requests. Generate a new token only when the current one expires.
Refresh Strategy
Implement automatic token refresh in your application:
// Example refresh logic
let accessToken = null;
let tokenExpiry = 0;
async function getAccessToken() {
// Check if current token is still valid
if (accessToken && Date.now() < tokenExpiry) {
return accessToken;
}
// Generate new assertion and get new token
const assertion = createJWTAssertion();
const response = await fetch('https://auth.chekt.com/oauth/token', {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: `grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer&assertion=${assertion}`
});
const data = await response.json();
accessToken = data.access_token;
tokenExpiry = Date.now() + (data.expires_in * 1000) - 60000; // Refresh 1 min early
return accessToken;
}
Request Headers
Required Headers
All Partner API requests must include:
Authorization: Bearer YOUR_ACCESS_TOKEN
Content-Type: application/json
Optional Headers
x-partner-trace-id (Recommended)
Include a UUID to track requests across systems:
x-partner-trace-id: 550e8400-e29b-41d4-a716-123456789000
This helps with debugging and monitoring.
Authentication Errors
Common Error Responses
401 Unauthorized
{
"error": "unauthorized",
"error_description": "The access token expired"
}
Solution: Generate a new access token
403 Forbidden
{
"error": "insufficient_scope",
"error_description": "The access token does not have the required scope"
}
Solution: Verify your Auth Application has the correct permissions
400 Bad Request
{
"error": "invalid_grant",
"error_description": "Invalid JWT assertion"
}
Solution: Check JWT signing and claims
Security Best Practices
Complete Authentication Example
Here's a complete example of authenticating and making an API call:
const jwt = require('jsonwebtoken');
const axios = require('axios');
// Configuration
const CLIENT_ID = process.env.CHEKT_CLIENT_ID;
const SECRET_KEY = process.env.CHEKT_SECRET_KEY;
const AUTH_SERVER = 'https://auth.chekt.com';
const API_BASE = 'https://api.chekt.com';
// Generate JWT assertion
function createAssertion() {
return jwt.sign(
{
iss: CLIENT_ID,
sub: CLIENT_ID,
aud: AUTH_SERVER,
exp: Math.floor(Date.now() / 1000) + 300,
iat: Math.floor(Date.now() / 1000),
jti: require('crypto').randomUUID()
},
SECRET_KEY,
{ algorithm: 'RS256' }
);
}
// Get access token
async function getAccessToken() {
const assertion = createAssertion();
const response = await axios.post(
`${AUTH_SERVER}/oauth/token`,
new URLSearchParams({
grant_type: 'urn:ietf:params:oauth:grant-type:jwt-bearer',
assertion: assertion
}),
{
headers: { 'Content-Type': 'application/x-www-form-urlencoded' }
}
);
return response.data.access_token;
}
// Make API request
async function listSites() {
const accessToken = await getAccessToken();
const response = await axios.get(
`${API_BASE}/partner/v1/sites`,
{
headers: {
'Authorization': `Bearer ${accessToken}`,
'Content-Type': 'application/json',
'x-partner-trace-id': require('crypto').randomUUID()
}
}
);
return response.data;
}
// Usage
listSites()
.then(sites => console.log('Sites:', sites))
.catch(error => console.error('Error:', error.response?.data || error.message));
Next Steps
Now that you understand authentication, explore the Partner API endpoints:
Next Steps
Support
For authentication issues or questions:
- Email: support@chekt.com
- Documentation: developer.chekt.com
- Check the Partner API Overview for general API information