API Keys Guide¶
This guide covers everything you need to know about creating, managing, and using API keys in R Commerce.
Overview¶
API keys provide secure, long-lived authentication for service-to-service communication. Unlike JWT tokens which are designed for user sessions, API keys are ideal for:
- Backend service integrations
- Webhook handlers
- ETL and data synchronization processes
- Third-party integrations
- Automated scripts and tools
Creating API Keys¶
Basic Creation¶
Create an API key using the CLI:
Output:
✅ API Key created successfully!
Key: aB3dEfGh.sEcReTkEy123456789abcdef1234567
Prefix: aB3dEfGh
Scopes: read
Created: 2026-01-15T10:30:00Z
Expires: Never
⚠️ IMPORTANT: Store this key securely. It will not be shown again!
Creating with Specific Scopes¶
Specify scopes during creation:
Creating with Expiration¶
Set an expiration date for enhanced security:
rcommerce api-key create \
--name "Temporary Integration" \
--scopes "orders:read" \
--expires "2026-12-31T23:59:59Z"
Creating with Rate Limits¶
Limit the number of requests per minute:
rcommerce api-key create \
--name "Limited Access Key" \
--scopes "products:read" \
--rate-limit 100
Managing API Keys¶
Listing All Keys¶
View all API keys in your system:
Output:
┌──────────┬──────────────────────┬─────────────────┬─────────┬──────────────────────┐
│ Prefix │ Name │ Scopes │ Status │ Last Used │
├──────────┼──────────────────────┼─────────────────┼─────────┼──────────────────────┤
│ aB3dEfGh │ Product Sync Service │ products:write │ Active │ 2026-01-20T14:30:00Z │
│ Xy9ZaBcD │ Mobile App Backend │ read │ Active │ 2026-01-20T15:45:00Z │
│ Mn7OpQrS │ Old Integration │ write │ Revoked │ 2026-01-10T09:00:00Z │
└──────────┴──────────────────────┴─────────────────┴─────────┴──────────────────────┘
Viewing Key Details¶
Get detailed information about a specific key:
Output:
API Key Details
===============
Prefix: aB3dEfGh
Name: Product Sync Service
Scopes: products:read, products:write
Status: Active
Created: 2026-01-15T10:30:00Z
Created By: admin@example.com
Expires: Never
Rate Limit: 1000 req/min
Last Used: 2026-01-20T14:30:00Z
Last Used IP: 203.0.113.42
Revoked: -
Revoke Reason: -
Revoking API Keys¶
Revoke a key to immediately disable it:
Output:
✅ API Key revoked successfully
Prefix: aB3dEfGh
Revoked at: 2026-01-20T16:00:00Z
Reason: Key compromised
Note: Revoked keys cannot be reactivated. Create a new key if needed.
Deleting API Keys¶
Permanently delete a key from the system:
Confirmation:
⚠️ WARNING: This action cannot be undone!
Are you sure you want to delete API key 'aB3dEfGh'? [y/N]: y
✅ API Key deleted successfully
Note: It's recommended to revoke keys before deletion to maintain an audit trail.
Using API Keys¶
In HTTP Requests¶
Include the API key in the Authorization header:
curl -X GET "https://api.rcommerce.app/api/v1/products" \
-H "Authorization: Bearer aB3dEfGh.sEcReTkEy123456789abcdef1234567"
Or without the Bearer prefix:
curl -X GET "https://api.rcommerce.app/api/v1/products" \
-H "Authorization: aB3dEfGh.sEcReTkEy123456789abcdef1234567"
In JavaScript/TypeScript¶
const API_KEY = process.env.RCOMMERCE_API_KEY;
async function getProducts() {
const response = await fetch('https://api.rcommerce.app/api/v1/products', {
headers: {
'Authorization': `Bearer ${API_KEY}`,
'Content-Type': 'application/json'
}
});
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
return await response.json();
}
In Python¶
import os
import requests
API_KEY = os.environ.get('RCOMMERCE_API_KEY')
BASE_URL = 'https://api.rcommerce.app'
headers = {
'Authorization': f'Bearer {API_KEY}',
'Content-Type': 'application/json'
}
# Get products
response = requests.get(f'{BASE_URL}/api/v1/products', headers=headers)
products = response.json()
# Create an order
order_data = {
'customer_id': '123e4567-e89b-12d3-a456-426614174000',
'items': [
{'product_id': '123e4567-e89b-12d3-a456-426614174001', 'quantity': 2}
]
}
response = requests.post(f'{BASE_URL}/api/v1/orders', json=order_data, headers=headers)
In Go¶
package main
import (
"net/http"
"os"
)
func main() {
apiKey := os.Getenv("RCOMMERCE_API_KEY")
req, err := http.NewRequest("GET", "https://api.rcommerce.app/api/v1/products", nil)
if err != nil {
panic(err)
}
req.Header.Set("Authorization", "Bearer "+apiKey)
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
// Process response...
}
In PHP¶
<?php
$apiKey = getenv('RCOMMERCE_API_KEY');
$ch = curl_init('https://api.rcommerce.app/api/v1/products');
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Authorization: Bearer ' . $apiKey,
'Content-Type: application/json'
]);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);
$products = json_decode($response, true);
?>
Security Best Practices¶
1. Store Keys Securely¶
Use Environment Variables:
Never: - ❌ Hardcode keys in source code - ❌ Commit keys to version control - ❌ Log keys or include them in error messages - ❌ Share keys via email or chat
2. Use Minimal Scopes¶
Grant only the permissions necessary:
# Good: Specific access
rcommerce api-key create --name "Product Viewer" --scopes "products:read"
# Avoid: Broad access when not needed
rcommerce api-key create --name "Product Viewer" --scopes "read"
3. Rotate Keys Regularly¶
Establish a key rotation schedule:
# 1. Create new key
rcommerce api-key create --name "Product Sync - Q1 2026" --scopes "products:write"
# 2. Update your application with the new key
# 3. Test the new key
# 4. Revoke the old key
rcommerce api-key revoke <old_prefix> --reason "Scheduled rotation"
Recommended Rotation Schedule: - Production keys: Every 90 days - Staging keys: Every 180 days - Development keys: As needed
4. Monitor Key Usage¶
Regularly check key activity:
# List keys with last used information
rcommerce api-key list
# Get detailed usage for a specific key
rcommerce api-key get <prefix>
Watch for:
- Keys that haven't been used in a long time (candidates for revocation)
- Unexpected IP addresses in last_used_ip
- Sudden spikes in usage
5. Use Separate Keys for Different Environments¶
# Development
rcommerce api-key create --name "Dev - Product Sync" --scopes "products:write"
# Staging
rcommerce api-key create --name "Staging - Product Sync" --scopes "products:write"
# Production
rcommerce api-key create --name "Prod - Product Sync" --scopes "products:read"
6. Set Appropriate Rate Limits¶
Protect your system from accidental abuse:
# High-volume service
rcommerce api-key create --name "Data Sync" --scopes "write" --rate-limit 10000
# Low-volume webhook
rcommerce api-key create --name "Webhook Handler" --scopes "orders:write" --rate-limit 100
# Occasional script
rcommerce api-key create --name "Daily Report" --scopes "read" --rate-limit 60
7. Revoke Compromised Keys Immediately¶
If a key is compromised:
# 1. Revoke immediately
rcommerce api-key revoke <prefix> --reason "Compromised - accidentally committed to GitHub"
# 2. Create a new key
rcommerce api-key create --name "Replacement Key" --scopes "<same_scopes>"
# 3. Update your application
# 4. Review access logs for unauthorized usage
Use Case Examples¶
Example 1: Read-Only API Key for Mobile App¶
Scenario: A mobile app needs to display products but shouldn't modify data.
# Create the key
rcommerce api-key create \
--name "Mobile App - Production" \
--scopes "products:read" \
--rate-limit 1000
Usage in mobile app:
// React Native example
const API_KEY = Config.RCOMMERCE_API_KEY; // From environment
async function fetchProducts() {
const response = await fetch(`${API_URL}/api/v1/products`, {
headers: {
'Authorization': `Bearer ${API_KEY}`
}
});
return await response.json();
}
Security considerations: - Mobile apps can't securely store API keys - Consider using a backend proxy or JWT authentication for production mobile apps - This example is suitable for internal/enterprise apps
Example 2: Webhook Handler API Key¶
Scenario: A payment gateway sends webhooks that need to update orders.
# Create the key with minimal required scopes
rcommerce api-key create \
--name "Payment Gateway Webhook" \
--scopes "orders:read,orders:write,payments:read,payments:write,webhooks:write" \
--rate-limit 500
Webhook handler implementation:
from flask import Flask, request
import os
app = Flask(__name__)
API_KEY = os.environ.get('RCOMMERCE_API_KEY')
def verify_webhook_signature(payload, signature):
# Verify the webhook signature from payment gateway
pass
@app.route('/webhooks/payment', methods=['POST'])
def handle_payment_webhook():
# Verify webhook authenticity
signature = request.headers.get('X-Webhook-Signature')
if not verify_webhook_signature(request.data, signature):
return 'Invalid signature', 401
# Process webhook
event = request.json
if event['type'] == 'payment.success':
# Update order using R Commerce API
order_id = event['data']['order_id']
update_data = {
'payment_status': 'paid',
'transaction_id': event['data']['transaction_id']
}
response = requests.patch(
f'https://api.rcommerce.app/api/v1/orders/{order_id}',
json=update_data,
headers={'Authorization': f'Bearer {API_KEY}'}
)
if response.ok:
return 'OK', 200
return 'Failed to update order', 500
return 'Event ignored', 200
Example 3: Inventory Management Integration¶
Scenario: A warehouse management system needs to sync inventory levels.
# Create the key
rcommerce api-key create \
--name "WMS Integration" \
--scopes "inventory:read,inventory:write,products:read,orders:read" \
--rate-limit 5000
Sync script:
import requests
import os
from datetime import datetime
API_KEY = os.environ.get('RCOMMERCE_API_KEY')
BASE_URL = 'https://api.rcommerce.app'
HEADERS = {'Authorization': f'Bearer {API_KEY}'}
def sync_inventory():
# Get all products from R Commerce
response = requests.get(f'{BASE_URL}/api/v1/products', headers=HEADERS)
products = response.json()
for product in products:
# Get current inventory from WMS
wms_stock = get_wms_stock(product['sku'])
# Update R Commerce inventory
if wms_stock != product['inventory_quantity']:
requests.put(
f'{BASE_URL}/api/v1/inventory/{product["id"]}',
json={'quantity': wms_stock},
headers=HEADERS
)
print(f"Updated {product['sku']}: {product['inventory_quantity']} -> {wms_stock}")
def get_wms_stock(sku):
# Query your WMS for current stock level
pass
if __name__ == '__main__':
print(f"Starting inventory sync at {datetime.now()}")
sync_inventory()
print("Sync complete")
Example 4: Multi-Service Architecture¶
Scenario: Multiple microservices need different levels of access.
# Product Service - manages product catalog
rcommerce api-key create \
--name "Service: Product Manager" \
--scopes "products:write,inventory:read" \
--rate-limit 2000
# Order Service - processes orders
rcommerce api-key create \
--name "Service: Order Processor" \
--scopes "orders:write,customers:read,products:read,payments:write" \
--rate-limit 5000
# Notification Service - sends emails
rcommerce api-key create \
--name "Service: Notifications" \
--scopes "orders:read,customers:read" \
--rate-limit 1000
# Analytics Service - generates reports
rcommerce api-key create \
--name "Service: Analytics" \
--scopes "read,reports:write" \
--rate-limit 500
Troubleshooting¶
401 Unauthorized¶
Cause: Invalid or missing API key
Solutions: 1. Verify the API key is included in the Authorization header 2. Check that the key hasn't been revoked:
3. Ensure the key hasn't expired403 Forbidden¶
Cause: Insufficient permissions for the requested operation
Solutions: 1. Check your key's scopes:
2. Verify the endpoint requires the scopes you have 3. Create a new key with appropriate scopes if needed429 Too Many Requests¶
Cause: Rate limit exceeded
Solutions: 1. Check your key's rate limit:
2. Implement exponential backoff in your client 3. Request a higher rate limit if needed:# Create a new key with higher limit
rcommerce api-key create --name "High Volume Key" --scopes "write" --rate-limit 10000
Key Not Working After Creation¶
Cause: There might be a delay or the key wasn't copied correctly
Solutions: 1. Verify you copied the full key including the prefix and dot 2. Check for extra whitespace 3. Ensure you're using the correct environment (dev/staging/prod)
Configuration Options¶
In config.toml¶
[security]
# Length of the key prefix (default: 8)
api_key_prefix_length = 8
# Length of the secret portion (default: 32)
api_key_secret_length = 32
# Default rate limit for new keys (optional)
api_key_default_rate_limit = 1000
Next Steps¶
- Scopes Reference - Complete scope documentation
- Authentication - Authentication methods
- CLI Reference - All CLI commands
- Error Codes - Error handling reference