Authentication
The Quantaprice API uses OAuth2 with API keys. You first exchange your API key for an access token, then use that token for API calls.
Creating an API Key
- Sign in to account.quantaprice.com
- Select your tenant from the dashboard
- Navigate to the API Keys section
- Click Create API Key
- Enter a descriptive name for the key (e.g., "Production Server", "Development")
- Click Create
The client_secret is only shown once when created. Copy it immediately and store it securely. If you lose the secret, you'll need to create a new API key.
API Key Components
When you create an API key, you receive two values:
| Component | Description | Example |
|---|---|---|
client_id | 24-character hexadecimal identifier | a1b2c3d4e5f6a1b2c3d4e5f6 |
client_secret | 64-character hexadecimal secret | 0123456789abcdef... |
The client_id is always visible in the Account Portal. The client_secret is only shown once at creation time.
Authentication Flow
Step 1: Exchange API Key for Access Token
Use the OAuth2 client_credentials grant to exchange your API key for a JWT access token:
curl -X POST "https://login.quantaprice.com/oauth2/token" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=client_credentials" \
-d "client_id=your_client_id" \
-d "client_secret=your_client_secret"
Response:
{
"access_token": "eyJhbGciOiJSUzI1NiIs...",
"token_type": "Bearer",
"expires_in": 3600
}
The access token is valid for 1 hour (3600 seconds).
Step 2: Use Access Token for API Calls
Include the access token in the Authorization header:
curl -X GET "https://api.quantaprice.com/api/v1/prices?sku=PRODUCT-001" \
-H "Authorization: Bearer eyJhbGciOiJSUzI1NiIs..." \
-H "Content-Type: application/json"
Code Examples
JavaScript/TypeScript
const CLIENT_ID = process.env.QUANTAPRICE_CLIENT_ID;
const CLIENT_SECRET = process.env.QUANTAPRICE_CLIENT_SECRET;
const TOKEN_URL = "https://login.quantaprice.com/oauth2/token";
const API_URL = "https://api.quantaprice.com/api/v1";
// Cache for access token
let accessToken: string | null = null;
let tokenExpires = 0;
async function getAccessToken(): Promise<string> {
// Return cached token if still valid (with 60s buffer)
if (accessToken && Date.now() < tokenExpires - 60000) {
return accessToken;
}
const response = await fetch(TOKEN_URL, {
method: "POST",
headers: { "Content-Type": "application/x-www-form-urlencoded" },
body: new URLSearchParams({
grant_type: "client_credentials",
client_id: CLIENT_ID,
client_secret: CLIENT_SECRET
})
});
if (!response.ok) {
throw new Error(`Token request failed: ${response.status}`);
}
const data = await response.json();
accessToken = data.access_token;
tokenExpires = Date.now() + (data.expires_in * 1000);
return accessToken;
}
async function getPrices(sku: string) {
const token = await getAccessToken();
const response = await fetch(`${API_URL}/prices?sku=${sku}`, {
headers: {
"Authorization": `Bearer ${token}`,
"Content-Type": "application/json"
}
});
return response.json();
}
Python
import os
import time
import requests
CLIENT_ID = os.environ.get("QUANTAPRICE_CLIENT_ID")
CLIENT_SECRET = os.environ.get("QUANTAPRICE_CLIENT_SECRET")
TOKEN_URL = "https://login.quantaprice.com/oauth2/token"
API_URL = "https://api.quantaprice.com/api/v1"
# Token cache
_access_token = None
_token_expires = 0
def get_access_token():
global _access_token, _token_expires
# Return cached token if still valid (with 60s buffer)
if _access_token and time.time() < _token_expires - 60:
return _access_token
response = requests.post(TOKEN_URL, data={
"grant_type": "client_credentials",
"client_id": CLIENT_ID,
"client_secret": CLIENT_SECRET
})
response.raise_for_status()
data = response.json()
_access_token = data["access_token"]
_token_expires = time.time() + data["expires_in"]
return _access_token
def get_prices(sku):
token = get_access_token()
response = requests.get(
f"{API_URL}/prices",
params={"sku": sku},
headers={
"Authorization": f"Bearer {token}",
"Content-Type": "application/json"
}
)
response.raise_for_status()
return response.json()
Token Refresh
Access tokens expire after 1 hour. Your application should:
- Cache the token - Don't request a new token for every API call
- Track expiration - Store the
expires_invalue and refresh before it expires - Handle 401 errors - If you receive a 401, request a new token and retry
Managing API Keys
Viewing Keys
In the Account Portal, you can view all API keys for your tenant. Each key shows its client_id, name, creation date, and last usage time. The client_secret is never displayed after creation.
Revoking Keys
To revoke an API key:
- Go to the API Keys section in the Account Portal
- Find the key you want to revoke
- Click the Revoke button
- Confirm the action
Revoked keys are immediately invalidated. Any access tokens issued from that key will also stop working.
Security Best Practices
- Never commit API keys to version control. Use environment variables or a secrets manager.
- Use separate keys for different environments. Create distinct keys for development, staging, and production.
- Rotate keys periodically. Create a new key, update your applications, then revoke the old key.
- Revoke unused keys. Remove keys that are no longer needed.
- Monitor key usage. Check the "Last Used" timestamp in the Account Portal to identify inactive keys.
- Cache tokens appropriately. Request new tokens only when needed, not on every API call.
Error Responses
| Status Code | Description |
|---|---|
401 Unauthorized | Invalid API key, expired token, or missing authorization |
403 Forbidden | Valid token but insufficient permissions for the resource |
Example error response:
{
"error": "invalid_client",
"error_description": "Invalid client credentials"
}