Authentication
Learn how to authenticate with the ACME Company API using API keys and bearer tokens.
The ACME Company API uses multiple authentication methods to ensure secure access to your data. Choose the method that best fits your use case and security requirements.
Authentication Methods
API Key Authentication
The simplest way to authenticate with the ACME Company API is using an API key passed in the request header.
Header format:
X-API-Key: your_api_key_here
Example request:
curl -X GET "https://api.acme.com/v1/pets" \
-H "X-API-Key: pk_live_51H9X2LKjI8mZ2gH8vK3nR7..."
# Using cURL with API key
curl -X GET "https://api.acme.com/v1/pets" \
-H "X-API-Key: pk_live_51H9X2LKjI8mZ2gH8vK3nR7..." \
-H "Content-Type: application/json"
// Using JavaScript fetch with API key
const response = await fetch('https://api.acme.com/v1/pets', {
headers: {
'X-API-Key': 'pk_live_51H9X2LKjI8mZ2gH8vK3nR7...',
'Content-Type': 'application/json'
}
});
const pets = await response.json();
# Using Python requests with API key
import requests
headers = {
'X-API-Key': 'pk_live_51H9X2LKjI8mZ2gH8vK3nR7...',
'Content-Type': 'application/json'
}
response = requests.get(
'https://api.acme.com/v1/pets',
headers=headers
)
pets = response.json()
// Using Go with API key
package main
import (
"fmt"
"io"
"net/http"
)
func main() {
client := &http.Client{}
req, _ := http.NewRequest("GET", "https://api.acme.com/v1/pets", nil)
req.Header.Add("X-API-Key", "pk_live_51H9X2LKjI8mZ2gH8vK3nR7...")
req.Header.Add("Content-Type", "application/json")
resp, err := client.Do(req)
if err != nil {
fmt.Println("Error:", err)
return
}
defer resp.Body.Close()
body, _ := io.ReadAll(resp.Body)
fmt.Println(string(body))
}
Bearer Token Authentication (JWT)
For more secure applications, use JWT bearer tokens obtained through the authentication endpoint.
Header format:
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
Authentication flow:
- Obtain a token by calling the
/auth/loginendpoint - Include the token in the
Authorizationheader for subsequent requests - Refresh the token before it expires (tokens are valid for 1 hour)
Endpoint: POST /auth/login
Request body:
{
"username": "your_username",
"password": "your_password"
}
Example request:
curl -X POST "https://api.acme.com/v1/auth/login" \
-H "Content-Type: application/json" \
-d '{
"username": "john.doe",
"password": "secure_password_123"
}'
const loginResponse = await fetch('https://api.acme.com/v1/auth/login', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
username: 'john.doe',
password: 'secure_password_123'
})
});
const { token, user, expiresIn } = await loginResponse.json();
console.log('Token expires in:', expiresIn, 'seconds');
import requests
login_data = {
'username': 'john.doe',
'password': 'secure_password_123'
}
response = requests.post(
'https://api.acme.com/v1/auth/login',
json=login_data
)
auth_info = response.json()
token = auth_info['token']
expires_in = auth_info['expiresIn']
Successful response:
{
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"user": {
"id": 123,
"username": "john.doe",
"email": "john.doe@acme.com"
},
"expiresIn": 3600
}
Getting Your API Credentials
Creating an API Key
API keys are perfect for server-side applications and testing. They don't expire but should be kept secure.
- Log in to your Pet Store dashboard at dashboard.acme.com
- Navigate to Settings → API Keys
- Click "Generate New API Key"
- Give your key a descriptive name (e.g., "Production Server", "Development Testing")
- Copy the key immediately - it won't be shown again
- Store the key securely in your environment variables
API key format:
- Live keys:
pk_live_...(for production use) - Test keys:
pk_test_...(for development and testing)
Security warning: Never commit API keys to version control or expose them in client-side code. Store them as environment variables or in secure key management systems.
Creating User Accounts
For JWT authentication, you'll need a user account:
- Register at the Pet Store platform or have an admin create your account
- Verify your email address if required
- Use your username and password with the
/auth/loginendpoint - Store the returned JWT token securely in your application
Security Best Practices
Protecting Your Credentials
Store credentials in environment variables, not in your code:
Development (.env file):
# .env file (never commit this!)
PETSTORE_API_KEY=pk_test_51H9X2LKjI8mZ2gH8vK3nR7...
PETSTORE_USERNAME=john.doe
PETSTORE_PASSWORD=secure_password_123
PETSTORE_BASE_URL=https://api.acme.com/v1
Usage in code:
// Load from environment variables
const apiKey = process.env.PETSTORE_API_KEY;
const username = process.env.PETSTORE_USERNAME;
const password = process.env.PETSTORE_PASSWORD;
// Never do this:
// const apiKey = "pk_live_51H9X2LKjI8mZ2gH8vK3nR7..."; ❌
Production deployment:
- Use your hosting platform's environment variable settings
- Consider using secret management services (AWS Secrets Manager, Azure Key Vault, etc.)
- Rotate credentials regularly
Error Responses
Common Authentication Errors
| Status Code | Error Code | Description | Solution |
|---|---|---|---|
401 | INVALID_API_KEY | API key is invalid or malformed | Check your API key format and regenerate if needed |
401 | EXPIRED_TOKEN | JWT token has expired | Re-authenticate to get a fresh token |
401 | INVALID_CREDENTIALS | Username/password combination is incorrect | Verify credentials and account status |
403 | INSUFFICIENT_PERMISSIONS | Account lacks required permissions | Contact support to upgrade your account |
429 | RATE_LIMIT_EXCEEDED | Too many requests in time window | Wait for rate limit reset or upgrade plan |
Example error response:
{
"code": "EXPIRED_TOKEN",
"message": "The provided JWT token has expired",
"details": {
"expired_at": "2024-01-15T14:30:00Z",
"current_time": "2024-01-15T15:45:00Z"
}
}
Handling Errors Gracefully
async function handleApiError(response) {
const errorData = await response.json();
switch (errorData.code) {
case 'EXPIRED_TOKEN':
// Attempt to refresh token
console.log('Token expired, refreshing...');
return await refreshToken();
case 'RATE_LIMIT_EXCEEDED':
// Wait and retry
const retryAfter = response.headers.get('Retry-After') || 60;
console.log(`Rate limited, waiting ${retryAfter}s`);
await new Promise(resolve => setTimeout(resolve, retryAfter * 1000));
return 'retry';
case 'INVALID_API_KEY':
// This requires manual intervention
throw new Error('API key is invalid. Please check your configuration.');
default:
throw new Error(`API Error: ${errorData.message}`);
}
}
Testing Authentication
Quick Test Commands
Verify your authentication is working:
# Test API key authentication
curl -X GET "https://api.acme.com/v1/pets" \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-w "Status: %{http_code}
"
# Expected: Status 200 with pet data
# Test JWT authentication
curl -X POST "https://api.acme.com/v1/auth/login" \
-H "Content-Type: application/json" \
-d '{
"username": "your_username",
"password": "your_password"
}' \
-w "Status: %{http_code}
"
# Expected: Status 200 with token data
# Test protected endpoint with JWT
TOKEN="your_jwt_token_here"
curl -X GET "https://api.acme.com/v1/users" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-w "Status: %{http_code}
"
# Expected: Status 200 with user data
Authentication setup complete! You're now ready to start making authenticated requests to the ACME Company API. Check out our Getting Started guide for your first API calls.
What's next?
- Getting Started - Make your first API calls
- ACME Company API Reference - Explore all available endpoints
- Error Handling - Learn robust error handling patterns
- Rate Limits - Understand API usage limits and optimization