API Reference

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:

EndpointAuthentication Method
/partner/v1/dealers/connectOAuth 2.0 Authorization Code Flow
All other endpointsOAuth 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 Unauthorized response
  • 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: