Authentication
Trading Card API offers two authentication methods to fit your use case: OAuth 2.0 for production applications and Personal Access Tokens for simpler integrations. This guide will walk you through both options.
🔐 Authentication Overview
Choose the authentication method that best fits your needs:
OAuth 2.0 Client Credentials Flow
Best for production applications and multi-user systems:
- Secure OAuth flow - Industry standard for server-to-server authentication
- Short-lived tokens - Tokens expire after 24 hours for enhanced security
- Automatic refresh - Seamlessly refresh tokens as needed
- Scoped access - Control permissions with OAuth scopes
Use OAuth when:
- Building production applications
- Creating multi-user systems
- Need granular permission control
- Require token refresh capabilities
Personal Access Tokens (PAT)
Simplified authentication for development and trusted applications:
- Quick setup - Generate tokens instantly from your dashboard
- Long-lived - Tokens remain valid until manually revoked
- Direct usage - No OAuth flow required, use token immediately
- Perfect for scripts - Ideal for automation, testing, and integrations
Use PAT when:
- Developing and testing locally
- Building personal scripts or automation
- Integrating with GPT/AI assistants
- Creating trusted single-user applications
New to the API? Start with a Personal Access Token for the easiest setup. You can always switch to OAuth later for production deployments.
🔐 OAuth 2.0 Authentication
Follow these steps to set up OAuth authentication for production applications.
Step 1: Create an Account
- Visit api.tradingcardapi.com/register
- Fill out the registration form with your details
- Verify your email address
- Log in to your new account
Step 2: Create an Application
Once logged in, create an application to get your credentials:
- Navigate to Applications in your dashboard
- Click Create New Application
- Fill out the application details:
- Name: Your application name
- Description: Brief description of your app
- Type: Choose "Machine-to-Machine" for server applications
- Save your application
You'll receive:
- Client ID: Public identifier for your application
- Client Secret: Private key (keep this secure!)
Never expose your client secret in client-side code or public repositories. Store it securely as an environment variable.
Understanding OAuth Scopes
Before requesting an access token, you need to understand OAuth scopes. Scopes control what actions your application can perform and what data it can access.
Available Scopes
The Trading Card API supports five OAuth scopes:
Read Scopes (control data visibility):
read:published- Access published content only (recommended for public apps)read:draft- Access published and draft contentread:all-status- Access all content regardless of status (for admin tools)
Modification Scopes:
write- Create and update resourcesdelete- Delete resources (admin tools only)
Choosing Scopes
Request only the scopes your application needs:
- Public card browser →
read:published - Collection management app →
read:published write - Content management system →
read:draft write - Admin dashboard →
read:all-status write delete
See the Authorization and OAuth Scopes guide for detailed information about each scope, status-based filtering, and security best practices.
Step 3: Get an Access Token
Use the client credentials flow to obtain an access token:
HTTP Request
POST https://api.tradingcardapi.com/oauth/token
Content-Type: application/json
{
"grant_type": "client_credentials",
"client_id": "your_client_id",
"client_secret": "your_client_secret",
"scope": "read:published write"
}
cURL Example
curl -X POST "https://api.tradingcardapi.com/oauth/token" \
-H "Content-Type: application/json" \
-d '{
"grant_type": "client_credentials",
"client_id": "your_client_id",
"client_secret": "your_client_secret",
"scope": "read:published write"
}'
Response
{
"token_type": "Bearer",
"expires_in": 86400,
"access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9...",
"scope": "read write"
}
Step 4: Make Authenticated Requests
Include the access token in the Authorization header of your API requests:
GET https://api.tradingcardapi.com/cards
Authorization: Bearer your_access_token
Accept: application/vnd.api+json
Content-Type: application/vnd.api+json
OAuth Code Examples
PHP
<?php
class TradingCardAPI {
private $clientId;
private $clientSecret;
private $accessToken;
private $baseUrl = 'https://api.tradingcardapi.com';
public function __construct($clientId, $clientSecret) {
$this->clientId = $clientId;
$this->clientSecret = $clientSecret;
}
public function authenticate() {
$response = $this->request('POST', '/oauth/token', [
'grant_type' => 'client_credentials',
'client_id' => $this->clientId,
'client_secret' => $this->clientSecret,
'scope' => 'read:published write'
]);
$this->accessToken = $response['access_token'];
return $this->accessToken;
}
public function getCards($params = []) {
return $this->request('GET', '/cards', $params);
}
private function request($method, $endpoint, $data = []) {
$url = $this->baseUrl . $endpoint;
$headers = [
'Accept: application/vnd.api+json',
'Content-Type: application/json'
];
if ($this->accessToken) {
$headers[] = 'Authorization: Bearer ' . $this->accessToken;
}
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
if ($method === 'POST') {
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
} elseif ($method === 'GET' && !empty($data)) {
$url .= '?' . http_build_query($data);
curl_setopt($ch, CURLOPT_URL, $url);
}
$response = curl_exec($ch);
curl_close($ch);
return json_decode($response, true);
}
}
// Usage
$api = new TradingCardAPI('your_client_id', 'your_client_secret');
$api->authenticate();
$cards = $api->getCards(['page[limit]' => 10]);
JavaScript (Node.js)
const axios = require('axios');
class TradingCardAPI {
constructor(clientId, clientSecret) {
this.clientId = clientId;
this.clientSecret = clientSecret;
this.baseUrl = 'https://api.tradingcardapi.com';
this.accessToken = null;
}
async authenticate() {
try {
const response = await axios.post(`${this.baseUrl}/oauth/token`, {
grant_type: 'client_credentials',
client_id: this.clientId,
client_secret: this.clientSecret,
scope: 'read:published write'
});
this.accessToken = response.data.access_token;
return this.accessToken;
} catch (error) {
throw new Error(`Authentication failed: ${error.response.data.message}`);
}
}
async getCards(params = {}) {
return this.request('GET', '/cards', params);
}
async request(method, endpoint, params = {}) {
const headers = {
'Accept': 'application/vnd.api+json',
'Content-Type': 'application/json'
};
if (this.accessToken) {
headers['Authorization'] = `Bearer ${this.accessToken}`;
}
try {
const config = {
method,
url: `${this.baseUrl}${endpoint}`,
headers
};
if (method === 'GET') {
config.params = params;
} else {
config.data = params;
}
const response = await axios(config);
return response.data;
} catch (error) {
throw new Error(`API request failed: ${error.response.data.message}`);
}
}
}
// Usage
async function example() {
const api = new TradingCardAPI('your_client_id', 'your_client_secret');
await api.authenticate();
const cards = await api.getCards({ 'page[limit]': 10 });
console.log(cards);
}
Python
import requests
import json
class TradingCardAPI:
def __init__(self, client_id, client_secret):
self.client_id = client_id
self.client_secret = client_secret
self.base_url = 'https://api.tradingcardapi.com'
self.access_token = None
def authenticate(self):
url = f"{self.base_url}/oauth/token"
data = {
'grant_type': 'client_credentials',
'client_id': self.client_id,
'client_secret': self.client_secret,
'scope': 'read:published write'
}
response = requests.post(url, json=data)
response.raise_for_status()
token_data = response.json()
self.access_token = token_data['access_token']
return self.access_token
def get_cards(self, params=None):
return self.request('GET', '/cards', params)
def request(self, method, endpoint, params=None):
url = f"{self.base_url}{endpoint}"
headers = {
'Accept': 'application/vnd.api+json',
'Content-Type': 'application/json'
}
if self.access_token:
headers['Authorization'] = f'Bearer {self.access_token}'
if method == 'GET':
response = requests.get(url, headers=headers, params=params)
else:
response = requests.post(url, headers=headers, json=params)
response.raise_for_status()
return response.json()
# Usage
api = TradingCardAPI('your_client_id', 'your_client_secret')
api.authenticate()
cards = api.get_cards({'page[limit]': 10})
print(cards)
🎫 Personal Access Token (PAT) Authentication
Personal Access Tokens provide a simpler authentication method perfect for development, testing, automation scripts, and GPT/AI integrations.
What is a Personal Access Token?
A Personal Access Token (PAT) is a long-lived authentication token that you can generate instantly from your dashboard. Unlike OAuth, there's no complex flow—just generate a token and start making requests immediately.
Generating a Personal Access Token
- Log in to your account at api.tradingcardapi.com
- Navigate to Account Settings → API Tokens
- Click Generate New Token
- Give your token a descriptive name (e.g., "Development", "Production Script", "GPT Integration")
- Select the scopes/permissions needed
- Click Create Token
- Copy the token immediately - it won't be shown again!
Personal Access Tokens are only displayed once during creation. Store it securely in your password manager or environment variables. If you lose it, you'll need to generate a new one.
Using a Personal Access Token
Simply include your PAT in the Authorization header of your requests:
GET https://api.tradingcardapi.com/cards
Authorization: Bearer YOUR_PERSONAL_ACCESS_TOKEN
Accept: application/vnd.api+json
Quick Start with cURL
# No OAuth flow needed - use your PAT directly
curl -X GET "https://api.tradingcardapi.com/cards?page[limit]=10" \
-H "Authorization: Bearer YOUR_PERSONAL_ACCESS_TOKEN" \
-H "Accept: application/vnd.api+json"
PAT Code Examples
PHP with PAT
<?php
class TradingCardAPI {
private $personalAccessToken;
private $baseUrl = 'https://api.tradingcardapi.com';
public function __construct($personalAccessToken) {
$this->personalAccessToken = $personalAccessToken;
}
public function getCards($params = []) {
return $this->request('GET', '/cards', $params);
}
private function request($method, $endpoint, $data = []) {
$url = $this->baseUrl . $endpoint;
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url . ($method === 'GET' && $data ? '?' . http_build_query($data) : ''));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Authorization: Bearer ' . $this->personalAccessToken,
'Accept: application/vnd.api+json',
'Content-Type: application/vnd.api+json'
]);
if ($method !== 'GET' && $data) {
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
}
$response = curl_exec($ch);
curl_close($ch);
return json_decode($response, true);
}
}
// Usage - No authentication flow needed!
$api = new TradingCardAPI(getenv('TRADING_CARD_API_PAT'));
$cards = $api->getCards(['page[limit]' => 10]);
print_r($cards);
JavaScript with PAT
const axios = require('axios');
class TradingCardAPI {
constructor(personalAccessToken) {
this.pat = personalAccessToken;
this.baseUrl = 'https://api.tradingcardapi.com';
}
async getCards(params = {}) {
return this.request('GET', '/cards', params);
}
async request(method, endpoint, data = {}) {
const config = {
method,
url: this.baseUrl + endpoint,
headers: {
'Authorization': `Bearer ${this.pat}`,
'Accept': 'application/vnd.api+json',
'Content-Type': 'application/vnd.api+json'
}
};
if (method === 'GET') {
config.params = data;
} else {
config.data = data;
}
const response = await axios(config);
return response.data;
}
}
// Usage - No authentication flow needed!
const api = new TradingCardAPI(process.env.TRADING_CARD_API_PAT);
const cards = await api.getCards({ 'page[limit]': 10 });
console.log(cards);
Python with PAT
import requests
import os
class TradingCardAPI:
def __init__(self, personal_access_token):
self.pat = personal_access_token
self.base_url = 'https://api.tradingcardapi.com'
def get_cards(self, params=None):
return self.request('GET', '/cards', params)
def request(self, method, endpoint, data=None):
url = self.base_url + endpoint
headers = {
'Authorization': f'Bearer {self.pat}',
'Accept': 'application/vnd.api+json',
'Content-Type': 'application/vnd.api+json'
}
if method == 'GET':
response = requests.get(url, headers=headers, params=data)
else:
response = requests.request(method, url, headers=headers, json=data)
response.raise_for_status()
return response.json()
# Usage - No authentication flow needed!
api = TradingCardAPI(os.getenv('TRADING_CARD_API_PAT'))
cards = api.get_cards({'page[limit]': 10})
print(cards)
Comparison: OAuth vs Personal Access Token
| Feature | OAuth 2.0 Client Credentials | Personal Access Token |
|---|---|---|
| Setup Complexity | Higher - Create app, implement flow | Lower - Generate token instantly |
| Best For | Production applications | Development, testing, scripts |
| Token Lifetime | Short-lived (24 hours) | Long-lived (until revoked) |
| Refresh | Automatic refresh supported | Manual rotation required |
| Security Model | OAuth flow with client secret | Static bearer token |
| Ideal Use Cases | Multi-user apps, production systems | Personal scripts, testing, automation |
| Scope Management | Full OAuth scope support | Token-level permissions |
| Revocation | Revoke via OAuth flow | Instant revocation from dashboard |
Managing Personal Access Tokens
Viewing Your Tokens
- Go to Account Settings → API Tokens
- See all your active tokens with their names and creation dates
- Last used date helps identify unused tokens
Revoking Tokens
Revoke tokens immediately if:
- You suspect a token has been compromised
- The token is no longer needed
- You're rotating tokens for security
To revoke:
- Go to Account Settings → API Tokens
- Click Revoke next to the token
- Confirm revocation
For enhanced security, rotate your PATs periodically (every 90 days recommended). Generate a new token, update your applications, then revoke the old one.
PAT Security Best Practices
1. Store Tokens Securely
Never hardcode tokens in your code:
// ❌ BAD - Never do this!
$api = new TradingCardAPI('pat_abc123def456...');
// ✅ GOOD - Use environment variables
$api = new TradingCardAPI(getenv('TRADING_CARD_API_PAT'));
Use environment variables:
# .env file
TRADING_CARD_API_PAT=pat_your_token_here
Load from environment:
// Node.js with dotenv
require('dotenv').config();
const pat = process.env.TRADING_CARD_API_PAT;
# Python with python-dotenv
from dotenv import load_dotenv
import os
load_dotenv()
pat = os.getenv('TRADING_CARD_API_PAT')
2. Never Commit Tokens to Version Control
Add .env to your .gitignore:
# .gitignore
.env
.env.local
*.env
Create an example file without actual tokens:
# .env.example
TRADING_CARD_API_PAT=your_pat_here
3. Use Separate Tokens for Different Environments
- Development: One token for local development
- Staging: Different token for staging environment
- Production: Dedicated token for production (consider OAuth instead)
- CI/CD: Separate token for automated testing
4. Rotate Tokens Regularly
Set a schedule for token rotation:
- High-security apps: Every 30 days
- Standard apps: Every 90 days
- Low-risk scripts: Every 180 days
5. Monitor Token Usage
Regularly review your active tokens:
- Check last used dates
- Revoke unused tokens
- Investigate unexpected activity
For production applications with multiple users, OAuth 2.0 is recommended over Personal Access Tokens. PATs are best suited for single-user applications, development, testing, and automation scripts.
Troubleshooting PAT Authentication
Invalid Token Error
{
"error": "invalid_token",
"error_description": "The access token provided is invalid"
}
Solutions:
- Verify token is copied correctly (no extra spaces)
- Check token hasn't been revoked
- Ensure token has required permissions
- Generate a new token if needed
Token Permissions Error
{
"error": "insufficient_scope",
"error_description": "The request requires higher privileges"
}
Solutions:
- Generate new token with required scopes
- Check token permissions in dashboard
- Use OAuth if fine-grained scope control needed
🔄 Token Management
Token Expiration
Access tokens typically expire after 24 hours. When a token expires, you'll receive a 401 Unauthorized response.
Automatic Refresh
Implement automatic token refresh in your application:
async function makeAuthenticatedRequest(api, endpoint, params) {
try {
return await api.request('GET', endpoint, params);
} catch (error) {
if (error.response && error.response.status === 401) {
// Token expired, refresh and retry
await api.authenticate();
return await api.request('GET', endpoint, params);
}
throw error;
}
}
🔒 Security Best Practices
Environment Variables
Store credentials as environment variables:
# .env file
TRADING_CARD_API_CLIENT_ID=your_client_id
TRADING_CARD_API_CLIENT_SECRET=your_client_secret
// Load from environment
const clientId = process.env.TRADING_CARD_API_CLIENT_ID;
const clientSecret = process.env.TRADING_CARD_API_CLIENT_SECRET;
Token Storage
- Server-side: Store tokens in memory or secure cache (Redis)
- Never store tokens in client-side code or local storage
- Rotate credentials periodically for enhanced security
Rate Limiting
- Implement exponential backoff for rate limit responses
- Cache responses to reduce API calls
- Monitor usage to stay within limits
❌ Common Issues
Invalid Client Credentials
{
"error": "invalid_client",
"error_description": "Client authentication failed"
}
Solution: Verify your client ID and secret are correct.
Expired Token
{
"error": "invalid_token",
"error_description": "The access token provided is expired"
}
Solution: Request a new token using the authentication flow.
Insufficient Scope
{
"error": "insufficient_scope",
"error_description": "The request requires higher privileges"
}
Solution: Request appropriate scopes when getting your token.
🚀 Next Steps
Now that you have authentication set up:
💡 Testing Your Setup
Use this quick test to verify your authentication:
# 1. Get a token
curl -X POST "https://api.tradingcardapi.com/oauth/token" \
-H "Content-Type: application/json" \
-d '{"grant_type":"client_credentials","client_id":"YOUR_ID","client_secret":"YOUR_SECRET","scope":"read"}'
# 2. Test the token
curl -X GET "https://api.tradingcardapi.com/cards?page[limit]=1" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Accept: application/vnd.api+json"
If you see card data in the response, your authentication is working correctly!