Authentication
Cortex uses API keys to authenticate requests. All API requests must be authenticated and made over HTTPS.
Getting Started
1. Obtain Your API Key
- Sign up at usecortex.co
- Navigate to your Dashboard
- Go to API Keys section
- Click Generate New Key
Your API key will look like this:
ctx_1234567890abcdef1234567890abcdef
2. Making Authenticated Requests
Include your API key in the Authorization header:
POST /v1/search HTTP/1.1
Host: api.usecortex.co
Authorization: Bearer ctx_1234567890abcdef1234567890abcdef
Content-Type: application/json
{
"query": "latest AI developments"
}
Authentication Methods
Bearer Token (Recommended)
The standard and most secure way to authenticate:
import requests
headers = {
'Authorization': 'Bearer ctx_your_api_key_here',
'Content-Type': 'application/json'
}
response = requests.post(
'https://api.usecortex.co/v1/search',
headers=headers,
json={'query': 'your search query'}
)
API Key Header (Alternative)
For clients that don't support Bearer tokens:
headers = {
'X-API-Key': 'ctx_your_api_key_here',
'Content-Type': 'application/json'
}
API Key Types
Standard Keys
Perfect for most applications:
- ✅ Full API access
- ✅ Standard rate limits
- ✅ Basic usage analytics
- 🔄 Manual key rotation
# Generate a standard key
curl -X POST https://api.usecortex.co/v1/auth/keys \
-H "Authorization: Bearer your_master_key" \
-d '{"name": "My App", "type": "standard"}'
Scoped Keys (Pro+)
Keys with limited permissions for enhanced security:
# Generate a scoped key
curl -X POST https://api.usecortex.co/v1/auth/keys \
-H "Authorization: Bearer your_master_key" \
-d '{
"name": "Search Only Bot",
"type": "scoped",
"permissions": ["search", "extract"],
"rate_limit": 1000,
"expires_at": "2025-12-31T23:59:59Z"
}'
Available Scopes:
search- Access to /v1/search endpointextract- Access to /v1/extract endpointsummarize- Access to /v1/summarize endpointvalidate- Access to /v1/validate endpointcache- Access to cache endpointsmonitor- Access to monitoring endpoints
Service Account Keys (Enterprise)
For server-to-server integrations:
# Generate a service account key
curl -X POST https://api.usecortex.co/v1/auth/service-accounts \
-H "Authorization: Bearer your_master_key" \
-d '{
"name": "Production Service",
"environment": "production",
"rate_limit": 10000,
"ip_allowlist": ["192.168.1.0/24", "10.0.0.0/8"]
}'
Key Management
Creating Keys
import cortex
# Initialize with your master key
client = cortex.Client(api_key="your_master_key")
# Create a new key
new_key = client.auth.create_key(
name="My New App",
permissions=["search", "extract"],
rate_limit=2000,
description="Key for my chatbot application"
)
print(f"New API Key: {new_key.key}")
print(f"Key ID: {new_key.id}")
Listing Keys
# List all your keys
keys = client.auth.list_keys()
for key in keys:
print(f"Name: {key.name}")
print(f"Created: {key.created_at}")
print(f"Last Used: {key.last_used_at}")
print(f"Status: {key.status}")
print("---")
Rotating Keys
# Rotate a key (generates new key, keeps old one active for 24h)
rotated_key = client.auth.rotate_key(key_id="key_123")
print(f"New Key: {rotated_key.new_key}")
print(f"Old Key Valid Until: {rotated_key.old_key_expires_at}")
Revoking Keys
# Immediately revoke a key
client.auth.revoke_key(key_id="key_123")
# Schedule revocation
client.auth.revoke_key(
key_id="key_456",
revoke_at="2025-01-15T00:00:00Z"
)
SDK Authentication
Python SDK
import cortex
# Method 1: Direct key
client = cortex.Client(api_key="ctx_your_key_here")
# Method 2: Environment variable
import os
client = cortex.Client(api_key=os.getenv('CORTEX_API_KEY'))
# Method 3: Configuration file
client = cortex.Client.from_config('~/.cortex/config.json')
Node.js SDK
const Cortex = require('@cortex/sdk');
// Method 1: Direct key
const client = new Cortex({
apiKey: 'ctx_your_key_here'
});
// Method 2: Environment variable
const client = new Cortex({
apiKey: process.env.CORTEX_API_KEY
});
// Method 3: Configuration
const client = Cortex.fromConfig('./cortex.config.js');
Go SDK
package main
import (
"os"
"github.com/cortex-ai/go-sdk"
)
func main() {
client := cortex.NewClient(os.Getenv("CORTEX_API_KEY"))
// Use client...
}
Rate Limits & Usage
Rate Limit Headers
Every response includes rate limit information:
HTTP/1.1 200 OK
X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 999
X-RateLimit-Reset: 1640995200
X-RateLimit-Window: 3600
Handling Rate Limits
import time
import requests
def make_request_with_retry(url, data, headers, max_retries=3):
for attempt in range(max_retries):
response = requests.post(url, json=data, headers=headers)
if response.status_code == 429: # Rate limited
reset_time = int(response.headers.get('X-RateLimit-Reset', 0))
wait_time = reset_time - int(time.time())
if wait_time > 0 and attempt < max_retries - 1:
time.sleep(wait_time)
continue
return response
return response
Security Best Practices
🔒 Key Storage
# ✅ Good: Use environment variables
import os
API_KEY = os.getenv('CORTEX_API_KEY')
# ✅ Good: Use secret management
from azure.keyvault.secrets import SecretClient
API_KEY = secret_client.get_secret("cortex-api-key").value
# ❌ Bad: Hard-coded keys
API_KEY = 'ctx_1234567890abcdef' # Never do this!
🔄 Key Rotation
# Rotate keys every 90 days
def rotate_api_keys():
# Generate new key
new_key = client.auth.create_key(name="Production v2")
# Update application configuration
update_app_config(new_key.key)
# Schedule old key deletion after rollout
schedule_key_deletion(old_key_id, delay_days=7)
📊 Monitoring Usage
# Monitor API key usage
usage = client.auth.get_key_usage(key_id="key_123")
if usage.requests_today > usage.daily_limit * 0.8:
send_alert(f"API key approaching rate limit: {usage.requests_today}/{usage.daily_limit}")
Error Handling
Authentication Errors
import cortex
try:
result = client.search("AI developments")
except cortex.AuthenticationError as e:
if e.code == "invalid_api_key":
print("Invalid API key provided")
elif e.code == "api_key_expired":
print("API key has expired")
elif e.code == "api_key_revoked":
print("API key has been revoked")
except cortex.RateLimitError as e:
print(f"Rate limit exceeded. Reset at: {e.reset_time}")
except cortex.PermissionError as e:
print(f"Insufficient permissions: {e.required_scope}")
Common Error Codes
| Code | Description | Solution |
|---|---|---|
invalid_api_key | API key format is invalid | Check key format and regenerate if needed |
api_key_not_found | API key doesn't exist | Verify key exists in dashboard |
api_key_expired | Key has expired | Generate a new key |
api_key_revoked | Key was manually revoked | Create a replacement key |
insufficient_permissions | Key lacks required scope | Use a key with broader permissions |
rate_limit_exceeded | Too many requests | Wait for rate limit reset |
Enterprise Features
SSO Integration (Enterprise)
# SAML SSO configuration
sso_config = {
"provider": "okta",
"entity_id": "https://your-org.okta.com",
"sso_url": "https://your-org.okta.com/app/cortex/sso/saml",
"certificate": "-----BEGIN CERTIFICATE-----..."
}
client.auth.configure_sso(sso_config)
Team Management (Enterprise)
# Create team with role-based access
team = client.auth.create_team(
name="AI Research Team",
members=["user1@company.com", "user2@company.com"],
role="researcher", # researcher, developer, admin
permissions=["search", "extract", "validate"]
)
Migration Guide
From Other APIs
If you're migrating from other search APIs:
# Before (Tavily-style)
headers = {'Api-Key': 'your-tavily-key'}
# After (Cortex)
headers = {'Authorization': 'Bearer ctx_your-cortex-key'}
Updating Existing Applications
- Generate new Cortex API key
- Update authentication headers
- Test in development environment
- Deploy with feature flags
- Monitor usage and errors
- Remove old API credentials
Next: Audit Logs → -