Authentication
The SellerCockpit API uses API keys for authentication. Each API key has specific scopes that determine which resources it can access and what operations it can perform.
Creating API Keys
API keys are created through the SellerCockpit web application:
- Navigate to Settings → API Keys
- Click Create API Key
- Provide a name and optional description
- Select the appropriate scopes for your use case
- Choose key type (Personal or Shared)
- Optionally set an expiration date
- Click Create
Important: The full API key is shown only once during creation. Store it securely - you won’t be able to retrieve it again.
API Key Format
API keys follow this format:
sellercockpit_live_abcdefghijklmnopqrstuvwxyz012345- Prefix:
sellercockpit_(identifies the service) - Environment:
live_ortest_(production vs sandbox) - Random Part: 32 alphanumeric characters (unique identifier)
Only the first 24 characters are stored in the UI for identification purposes. The full key is hashed using SHA-256 and stored securely.
Authentication Header
Include your API key in every request using the Authorization header with the Bearer scheme:
Authorization: Bearer sellercockpit_live_abcdefghijklmnopqrstuvwxyz012345Example Requests
Using cURL:
curl https://your-project.supabase.co/functions/v1/api-v1-contacts \ -H "Authorization: Bearer sellercockpit_live_abcdefghijklmnopqrstuvwxyz012345" \ -H "Content-Type: application/json"Using JavaScript (fetch):
const response = await fetch( 'https://your-project.supabase.co/functions/v1/api-v1-contacts', { headers: { 'Authorization': 'Bearer sellercockpit_live_abcdefghijklmnopqrstuvwxyz012345', 'Content-Type': 'application/json' } });
const data = await response.json();Using Python (requests):
import requests
headers = { 'Authorization': 'Bearer sellercockpit_live_abcdefghijklmnopqrstuvwxyz012345', 'Content-Type': 'application/json'}
response = requests.get( 'https://your-project.supabase.co/functions/v1/api-v1-contacts', headers=headers)
data = response.json()API Key Scopes
Scopes control what operations an API key can perform. Use the principle of least privilege - only grant the scopes necessary for your integration.
Available Scopes
| Scope | Description |
|---|---|
read:all | Read access to all resources |
write:all | Write access to all resources (create, update, delete) |
read:organizations | Read organization data only |
write:organizations | Create, update, delete organizations |
read:contacts | Read contact data only |
write:contacts | Create, update, delete contacts |
read:deals | Read deal data only |
write:deals | Create, update, delete deals |
read:activities | Read activity logs only |
write:activities | Create activities (calls, emails, meetings, notes) |
read:tasks | Read task data only |
write:tasks | Create, update, delete tasks |
admin:all | Full administrative access (use with caution) |
Scope Hierarchy
Some scopes provide hierarchical access:
admin:all- Grants all permissions (equivalent to all scopes combined)read:all- Grants read access to all resourceswrite:all- Grants write access to all resources
Example: If a key has read:all, it can access read:contacts, read:deals, etc. without needing each individual scope.
Recommended Scope Combinations
Read-only integration (analytics, reporting):
["read:all"]Full integration (sync, automation):
["read:all", "write:all"]Contact sync only:
["read:contacts", "write:contacts", "read:organizations"]Deal pipeline automation:
["read:deals", "write:deals", "read:contacts"]Activity logging only:
["write:activities"]Key Types
Personal Keys
- Associated with a specific user
- Ideal for individual automation scripts or personal projects
- Automatically revoked when user leaves the company
Shared Keys
- Shared across the team
- Ideal for company-wide integrations (e.g., Zapier, n8n)
- Persist independently of individual user accounts
API Key Lifecycle
Active Keys
- Keys are active immediately after creation
- Can be temporarily disabled by setting
is_activetofalse - No requests are processed for inactive keys
Expiration
- Keys can have an optional expiration date
- Expired keys return
API_KEY_EXPIREDerror (401) - Set expiration for temporary integrations or testing
Revocation
- Keys can be permanently revoked at any time
- Revoked keys cannot be reactivated
- Create a new key if you need access again
IP Allowlisting
Restrict API key usage to specific IP addresses or CIDR ranges for enhanced security.
Configuration
- Navigate to Settings → API Keys
- Click the Globe icon on an existing key
- Enter allowed IP addresses or CIDR ranges (one per line)
- Click Save Allowlist
Supported Formats
| Format | Example | Description |
|---|---|---|
| IPv4 | 192.168.1.100 | Single IPv4 address |
| IPv4 CIDR | 10.0.0.0/24 | IPv4 subnet (256 addresses) |
| IPv4 CIDR | 172.16.0.0/16 | IPv4 subnet (65,536 addresses) |
| IPv6 | ::1 | IPv6 loopback |
| IPv6 | 2001:db8::1 | Single IPv6 address |
| IPv6 CIDR | 2001:db8::/32 | IPv6 subnet |
Behavior
- Empty allowlist: All IPs are permitted (default)
- Configured allowlist: Only listed IPs can use the key
- Requests from non-allowed IPs receive
IP_NOT_ALLOWEDerror (403)
Example Allowlist
# Production servers10.0.0.0/24192.168.1.50
# Office network172.16.0.0/16
# IPv6 support2001:db8::/32API Key Rotation
Rotate API keys without service interruption using grace periods.
Why Rotate Keys?
- Security best practice: Regular rotation limits exposure if keys are compromised
- Compliance requirements: Many security frameworks mandate periodic key rotation
- Team changes: Rotate when team members with access leave
How It Works
- Click the Rotate icon on an existing key
- Select a grace period (how long the old key remains valid)
- Click Rotate Key
- Copy the new API key (shown only once!)
- Update your applications with the new key
- Old key automatically expires after grace period
Grace Period Options
| Duration | Use Case |
|---|---|
| 1 hour | Quick updates, single application |
| 6 hours | Small team, fast deployment |
| 24 hours | Recommended for most use cases |
| 48 hours | Multiple applications, staged rollout |
| 7 days | Large enterprise, complex deployments |
What Gets Inherited
The new key automatically inherits from the old key:
- ✅ Scopes (permissions)
- ✅ IP allowlist (if configured)
- ✅ Key type (personal/shared)
- ✅ Name and description
Grace Period Behavior
During the grace period:
- Both keys work - Old and new keys are valid
- Old key shows “In Rotation” badge in the UI
- Countdown visible - Shows when old key expires
- After expiration, old key returns
API_KEY_EXPIREDerror
Security Best Practices
Storage
- Never commit API keys to version control (Git, SVN, etc.)
- Store keys in environment variables or secure key management systems
- Use
.envfiles with.gitignorefor local development - Use platform-specific secret storage for production (AWS Secrets Manager, HashiCorp Vault, etc.)
Usage
- Use HTTPS only - Never send API keys over unencrypted HTTP
- Rotate keys regularly - Use the built-in rotation feature for zero-downtime key changes
- Configure IP allowlists - Restrict production keys to known server IPs
- Use specific scopes - Don’t use
admin:allunless absolutely necessary - Monitor usage - Check the API key dashboard for unexpected activity
- Revoke immediately - If a key is compromised, revoke it immediately
Environment Variables Example
.env file (never commit this):
SELLERCOCKPIT_API_KEY=sellercockpit_live_abcdefghijklmnopqrstuvwxyz012345SELLERCOCKPIT_BASE_URL=https://your-project.supabase.co/functions/v1Node.js usage:
require('dotenv').config();
const apiKey = process.env.SELLERCOCKPIT_API_KEY;const baseUrl = process.env.SELLERCOCKPIT_BASE_URL;Python usage:
import osfrom dotenv import load_dotenv
load_dotenv()
api_key = os.getenv('SELLERCOCKPIT_API_KEY')base_url = os.getenv('SELLERCOCKPIT_BASE_URL')Error Responses
Missing API Key
curl https://your-project.supabase.co/functions/v1/api-v1-contactsResponse (401):
{ "error": { "code": "UNAUTHORIZED", "message": "Missing API key. Include it in the Authorization header as \"Bearer <your_api_key>\"" }}Invalid API Key
curl https://your-project.supabase.co/functions/v1/api-v1-contacts \ -H "Authorization: Bearer invalid_key_format"Response (401):
{ "error": { "code": "INVALID_API_KEY", "message": "Invalid API key format" }}Insufficient Permissions
# Trying to create a contact with a read-only API keycurl -X POST https://your-project.supabase.co/functions/v1/api-v1-contacts \ -H "Authorization: Bearer sellercockpit_live_readonly123..." \ -H "Content-Type: application/json" \ -d '{"name": "John Doe"}'Response (403):
{ "error": { "code": "INSUFFICIENT_PERMISSIONS", "message": "This action requires the \"write:contacts\" scope" }}Revoked or Expired Key
Response (401):
{ "error": { "code": "API_KEY_REVOKED", "message": "This API key has been revoked" }}or
{ "error": { "code": "API_KEY_EXPIRED", "message": "This API key has expired" }}IP Not Allowed
When an IP allowlist is configured and the request comes from an unlisted IP:
Response (403):
{ "error": { "code": "IP_NOT_ALLOWED", "message": "Request IP (203.0.113.50) is not in the API key's allowlist" }}To resolve this error:
- Navigate to Settings → API Keys
- Click the Globe icon on the affected key
- Add your server’s IP address to the allowlist
- Click Save Allowlist
Monitoring API Key Usage
Track API key usage in the SellerCockpit web application:
- Last used: Timestamp of the most recent request
- Last IP: IP address of the most recent request
- Request count: Total number of requests made with this key
- Usage stats: Requests per day, week, and month
This helps identify:
- Unused keys that should be revoked
- Unexpected usage patterns that may indicate compromise
- Performance bottlenecks in your integrations