Authentication
Learn how authentication works in the API
Authentication Overview
The API uses JWT (JSON Web Token) based authentication to secure all endpoints for B2B integrations. This section covers the complete authentication flow and how to manage tokens in server-to-server environments.
Authentication Flow for B2B Integration
- API Key Setup: Obtain API credentials (username and password) from your account dashboard
- Token Exchange: Exchange API credentials for access and refresh tokens
- Server-to-Server Calls: Use the access token in the Authorization header
- Automated Refresh: Implement automatic token refresh in your backend services
- Token Revocation: Invalidate tokens when rotating credentials or ending sessions
Token Types
Access Token
- Purpose: Used to authenticate API requests
- Lifetime: 1 hour
- Usage: Include in Authorization header as
Bearer {token}
Refresh Token
- Purpose: Used to obtain new access and refresh token pairs
- Lifetime: 7 days
- Usage: Send to
/auth/refreshendpoint
IP Whitelisting
If your account has IP whitelist entries configured, API requests (including login and token refresh) must originate from a whitelisted IP address. Requests from non-whitelisted IPs will receive a 403 Forbidden response. If no whitelist entries are configured, all IPs are allowed.
Headers Required
All protected endpoints require the following header:
Authorization: Bearer {your_access_token}Response Format
Success Responses
All authentication endpoints return responses wrapped in a standard envelope:
{
"success": true,
"data": {
// response data
}
}Error Responses
{
"error": {
"name": "UnauthorizedError",
"code": "UNAUTHORIZED",
"message": "Invalid credentials"
}
}Common Error Codes
| Status | Error Name | Code | Description |
|---|---|---|---|
| 400 | ValidationException | VALIDATION_FAILURE | Missing or invalid request fields |
| 400 | SyntaxError | SYNTAX_ERROR | Invalid JSON in request body |
| 401 | UnauthorizedError | UNAUTHORIZED | Invalid credentials or expired token |
| 403 | ForbiddenError | FORBIDDEN | IP address not authorized |
Quick Start for B2B Integration
- Authenticate with your API credentials
- Extract the
access_tokenfrom thedataobject in the response - Store tokens securely in your backend infrastructure
- Use the token in subsequent server-to-server API calls
- Implement automatic token refresh before expiration
Example Implementation
# Step 1: Login and get tokens
curl -X POST {{host}}/auth/login \
-H "Content-Type: application/json" \
-d '{
"username": "your_api_username",
"password": "your_api_password"
}'
# Response:
# {
# "success": true,
# "data": {
# "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
# "refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
# "access_expires_at": "2024-01-15T10:30:00Z",
# "refresh_expires_at": "2024-01-22T09:30:00Z",
# "client_id": 123456
# }
# }
# Step 2: Use access token for API calls
curl -X GET {{host}}/api/v1/products \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." \
-H "Content-Type: application/json"
# Step 3: Refresh token when needed (before access token expires)
curl -X POST {{host}}/auth/refresh \
-H "Content-Type: application/json" \
-d '{
"refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}'class APIAuth {
private $host;
private $accessToken;
private $refreshToken;
private $accessExpiresAt;
public function __construct($host) {
$this->host = $host;
}
public function login($username, $password) {
$data = json_encode([
'username' => $username,
'password' => $password
]);
$context = stream_context_create([
'http' => [
'method' => 'POST',
'header' => 'Content-Type: application/json',
'content' => $data
]
]);
$response = file_get_contents($this->host . '/auth/login', false, $context);
$result = json_decode($response, true);
if ($result && $result['success']) {
$tokenData = $result['data'];
$this->accessToken = $tokenData['access_token'];
$this->refreshToken = $tokenData['refresh_token'];
$this->accessExpiresAt = strtotime($tokenData['access_expires_at']);
// Store tokens securely (database, cache, etc.)
$this->storeTokens();
return true;
}
return false;
}
public function makeAuthenticatedRequest($url, $method = 'GET', $data = null) {
// Check if token needs refresh (5 minutes before expiry)
if ($this->shouldRefreshToken()) {
$this->refreshAccessToken();
}
$headers = [
'Authorization: Bearer ' . $this->accessToken,
'Content-Type: application/json'
];
$context = [
'http' => [
'method' => $method,
'header' => implode("\r\n", $headers)
]
];
if ($data && in_array($method, ['POST', 'PUT', 'PATCH'])) {
$context['http']['content'] = json_encode($data);
}
$response = file_get_contents($url, false, stream_context_create($context));
return json_decode($response, true);
}
private function shouldRefreshToken($bufferMinutes = 5) {
return (time() + ($bufferMinutes * 60)) >= $this->accessExpiresAt;
}
private function refreshAccessToken() {
$data = json_encode(['refresh_token' => $this->refreshToken]);
$context = stream_context_create([
'http' => [
'method' => 'POST',
'header' => 'Content-Type: application/json',
'content' => $data
]
]);
$response = file_get_contents($this->host . '/auth/refresh', false, $context);
$result = json_decode($response, true);
if ($result && $result['success']) {
$tokenData = $result['data'];
$this->accessToken = $tokenData['access_token'];
$this->refreshToken = $tokenData['refresh_token'];
$this->accessExpiresAt = strtotime($tokenData['access_expires_at']);
$this->storeTokens();
}
}
private function storeTokens() {
// Store in your preferred secure storage
// Examples: database, Redis, encrypted file
$_SESSION['api_access_token'] = $this->accessToken;
$_SESSION['api_refresh_token'] = $this->refreshToken;
$_SESSION['api_expires_at'] = $this->accessExpiresAt;
}
}
// Usage example
$auth = new APIAuth('{{host}}');
$auth->login('your_api_username', 'your_api_password');
// Make authenticated API calls
$products = $auth->makeAuthenticatedRequest('{{host}}/api/v1/products');
$categories = $auth->makeAuthenticatedRequest('{{host}}/api/v1/categories');Authentication Endpoints
- API Authentication - Exchange API credentials for tokens
- Token Refresh - Get new access tokens automatically
- Token Revocation - Invalidate tokens for security
Advanced Topics
For production applications, see our comprehensive guides on:
- Token Management - Best practices for storing and refreshing tokens
- Security Considerations - Security patterns and credential protection