API Keys & Authentication
API keys are the primary method for authenticating with the Synvo API. This section covers how to create, manage, and use API keys to access all Synvo API endpoints securely.
Authentication Methods
The Synvo API supports API Key Authentication:
- API Key Authentication
- Header:
X-API-Key: <your_api_key> - Best for server-to-server communication
- Easy to manage and rotate
- Header:
Base URL
https://api.synvo.aiList API Keys
Returns all API keys for the authenticated user, showing their status and usage information.
Endpoint: GET /user/api_keys/list
Example Request
curl -X GET "https://api.synvo.ai/user/api_keys/list" \
-H "X-API-Key: ${API-KEY}"import requests
api_key = "<API_KEY>"
url = "https://api.synvo.ai/user/api_keys/list"
headers = {"X-API-Key": api_key}
response = requests.get(url, headers=headers, timeout=30)
response.raise_for_status()
print(response.json())const api_key = "<API_KEY>";
const response = await fetch("https://api.synvo.ai/user/api_keys/list", {
method: "GET",
headers: {
"X-API-Key": apiKey,
},
});
if (!response.ok) {
throw new Error(`Request failed: ${response.status}`);
}
console.log(await response.json());Example Response
{
"success": true,
"items": [
{
"key_id": "key_abc123xyz",
"name": "Production API Key",
"status": "ACTIVE",
"created_at": "2024-01-15T10:30:00Z",
"last_used_at": "2024-01-16T14:22:00Z"
},
{
"key_id": "key_def456uvw",
"name": "Development Key",
"status": "ACTIVE",
"created_at": "2024-01-10T09:15:00Z",
"last_used_at": "2024-01-15T16:45:00Z"
},
{
"key_id": "key_ghi789rst",
"name": "Old Testing Key",
"status": "REVOKED",
"created_at": "2024-01-01T12:00:00Z",
"last_used_at": "2024-01-05T10:30:00Z"
}
]
}API Key Status Values
ACTIVE- Key is active and can be usedREVOKED- Key has been permanently disabledDISABLED- Key is temporarily disabledUNKNOWN- Status cannot be determined
Response Codes
200- API keys retrieved successfully401- Unauthorized
Create API Key
Generates a new API key for programmatic access. Important: The plaintext key is only shown once during creation.
Endpoint: POST /user/api_keys/create
Content-Type: application/x-www-form-urlencoded
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
name | string | No | Optional display name for the key |
Example Request
curl -X POST "https://api.synvo.ai/user/api_keys/create" \
-H "X-API-Key: ${API-KEY}" \
-H "Content-Type: application/x-www-form-urlencoded" \
--data-urlencode "name=My API Key"import requests
api_key = "<API_KEY>"
url = "https://api.synvo.ai/user/api_keys/create"
data = {"name": "My API Key"}
headers = {"X-API-Key": api_key}
response = requests.post(url, data=data, headers=headers, timeout=30)
response.raise_for_status()
result = response.json()
# Save this API key securely - it won't be shown again!
print(f"New API Key: {result['api_key']}")const api_key = "<API_KEY>";
const params = new URLSearchParams({ name: "My API Key" });
const response = await fetch("https://api.synvo.ai/user/api_keys/create", {
method: "POST",
headers: {
"X-API-Key": apiKey,
},
body: params,
});
if (!response.ok) {
throw new Error(`Request failed: ${response.status}`);
}
const result = await response.json();
// Save this API key securely - it won't be shown again!
console.log("New API Key:", result.api_key);Example Response
{
"success": true,
"key_id": "key_new123xyz",
"api_key": "sk_live_abcdef123456789..."
}:::warning Important Security Notice
The api_key field contains the actual API key and is only shown once during creation. Make sure to save it securely immediately. You cannot retrieve the plaintext key again after this response.
:::
Response Codes
200- API key created successfully400- Bad request (invalid parameters)401- Unauthorized
Getting Started
Step 1: Create Your First API Key
- Using the Dashboard: Log into your Synvo dashboard and navigate to API Keys
- Using the API: Use an existing session token to create a new API key via the
/user/api_keys/createendpoint
Step 2: Secure Storage
Store your API key securely:
- Environment Variables: Store in environment variables (recommended)
- Secure Vaults: Use services like AWS Secrets Manager, Azure Key Vault
- Configuration Files: Store in encrypted configuration files (not recommended for production)
Step 3: Test Your API Key
# Test with a simple file list request
curl -X GET "https://api.synvo.ai/file/list?path=/" \
-H "X-API-Key: sk_live_your_api_key_here"import requests
import os
# Load API key from environment variable
api_key = os.getenv("SYNVO_API_KEY")
# Test the API key
response = requests.get(
"https://api.synvo.ai/file/list",
params={"path": "/"},
headers={"X-API-Key": api_key}
)
if response.status_code == 200:
print("✅ API key is working!")
print(f"Found {len(response.json()['items'])} items")
else:
print(f"❌ API key test failed: {response.status_code}")// Load API key from environment variable
const apiKey = process.env.SYNVO_API_KEY;
// Test the API key
try {
const response = await fetch("https://api.synvo.ai/file/list?path=/", {
method: "GET",
headers: {
"X-API-Key": apiKey
}
});
if (response.ok) {
const data = await response.json();
console.log("✅ API key is working!");
console.log(`Found ${data.items.length} items`);
} else {
console.log(`❌ API key test failed: ${response.status}`);
}
} catch (error) {
console.log(`❌ API key test error: ${error.message}`);
}API Key Management
Key Management Class
import requests
import os
from datetime import datetime
class SynvoAPIKeyManager:
def __init__(self, auth_token):
"""Initialize with existing auth token (from dashboard login)"""
self.auth_token = auth_token
self.base_url = "https://api.synvo.ai"
self.headers = {"X-API-Key": auth_token}
def list_keys(self):
"""List all API keys"""
response = requests.get(
f"{self.base_url}/user/api_keys/list",
headers=self.headers
)
response.raise_for_status()
return response.json()["items"]
def create_key(self, name=None):
"""Create a new API key"""
data = {}
if name:
data["name"] = name
response = requests.post(
f"{self.base_url}/user/api_keys/create",
data=data,
headers=self.headers
)
response.raise_for_status()
return response.json()
def get_active_keys(self):
"""Get only active API keys"""
keys = self.list_keys()
return [key for key in keys if key["status"] == "ACTIVE"]
def find_key_by_name(self, name):
"""Find API key by name"""
keys = self.list_keys()
return next((key for key in keys if key.get("name") == name), None)
# Usage example
manager = SynvoAPIKeyManager("your-dashboard-token")
# List all keys
keys = manager.list_keys()
print(f"You have {len(keys)} API keys")
# Create a new key
new_key = manager.create_key("Production API Key")
print(f"Created new key: {new_key['api_key']}")
# Find active keys
active_keys = manager.get_active_keys()
print(f"Active keys: {len(active_keys)}")class SynvoAPIKeyManager {
constructor(authToken) {
this.authToken = authToken;
this.baseUrl = "https://api.synvo.ai";
this.headers = {
"X-API-Key": authToken
};
}
async listKeys() {
const response = await fetch(`${this.baseUrl}/user/api_keys/list`, {
method: "GET",
headers: this.headers
});
if (!response.ok) {
throw new Error(`Failed to list keys: ${response.status}`);
}
const data = await response.json();
return data.items;
}
async createKey(name = null) {
const formData = new FormData();
if (name) {
formData.append("name", name);
}
const response = await fetch(`${this.baseUrl}/user/api_keys/create`, {
method: "POST",
headers: this.headers,
body: formData
});
if (!response.ok) {
throw new Error(`Failed to create key: ${response.status}`);
}
return await response.json();
}
async getActiveKeys() {
const keys = await this.listKeys();
return keys.filter(key => key.status === "ACTIVE");
}
async findKeyByName(name) {
const keys = await this.listKeys();
return keys.find(key => key.name === name) || null;
}
}
// Usage example
const manager = new SynvoAPIKeyManager("your-dashboard-token");
// List all keys
const keys = await manager.listKeys();
console.log(`You have ${keys.length} API keys`);
// Create a new key
const newKey = await manager.createKey("Production API Key");
console.log(`Created new key: ${newKey.api_key}`);
// Find active keys
const activeKeys = await manager.getActiveKeys();
console.log(`Active keys: ${activeKeys.length}`);Security Best Practices
1. Key Storage
- Never commit API keys to version control
- Use environment variables for local development
- Use secure secret management for production
- Rotate keys regularly (every 90 days recommended)
2. Key Usage
- Use different keys for different environments (dev, staging, prod)
- Implement key rotation without service interruption
- Monitor key usage and set up alerts for unusual activity
- Revoke unused keys immediately
3. Network Security
- Use HTTPS only - API keys should never be sent over HTTP
- Implement IP restrictions if possible
- Use API gateways for additional security layers
- Log API key usage for audit trails
Environment Setup Examples
.env File
# .env file (never commit this!)
SYNVO_API_KEY=sk_live_your_api_key_here
SYNVO_BASE_URL=https://api.synvo.ai
# Different keys for different environments
SYNVO_DEV_API_KEY=sk_dev_your_dev_key_here
SYNVO_PROD_API_KEY=sk_live_your_prod_key_hereDocker
# Dockerfile
FROM node:18-alpine
# Set environment variables
ENV SYNVO_API_KEY=""
ENV NODE_ENV=production
COPY . /app
WORKDIR /app
RUN npm install
# Run with: docker run -e SYNVO_API_KEY=sk_live_... myapp
CMD ["npm", "start"]Kubernetes
# kubernetes-secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: synvo-api-secret
type: Opaque
data:
api-key: <base64-encoded-api-key>
---
# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp
spec:
template:
spec:
containers:
- name: myapp
image: myapp:latest
env:
- name: SYNVO_API_KEY
valueFrom:
secretKeyRef:
name: synvo-api-secret
key: api-keyError Handling
Authentication Errors
{
"error": "Invalid API key",
"code": "INVALID_API_KEY"
}{
"error": "API key has been revoked",
"code": "API_KEY_REVOKED"
}Error Codes
INVALID_API_KEY- API key format is invalid or not recognizedAPI_KEY_REVOKED- API key has been permanently disabledAPI_KEY_EXPIRED- API key has expired (if expiration is enabled)API_KEY_SUSPENDED- API key is temporarily suspendedRATE_LIMITED- Too many requests with this API key
Handling Authentication Errors
import requests
from requests.exceptions import HTTPError
def make_authenticated_request(api_key, endpoint, **kwargs):
"""Make an authenticated request with proper error handling"""
headers = {"X-API-Key": api_key}
try:
response = requests.get(
f"https://api.synvo.ai{endpoint}",
headers=headers,
**kwargs
)
response.raise_for_status()
return response.json()
except HTTPError as e:
if e.response.status_code == 401:
error_data = e.response.json()
error_code = error_data.get("code", "UNKNOWN")
if error_code == "INVALID_API_KEY":
raise ValueError("API key is invalid. Please check your key.")
elif error_code == "API_KEY_REVOKED":
raise ValueError("API key has been revoked. Please create a new one.")
else:
raise ValueError(f"Authentication failed: {error_data.get('error')}")
else:
raise
# Usage
try:
result = make_authenticated_request("your-api-key", "/file/list")
print("Request successful!")
except ValueError as e:
print(f"Authentication error: {e}")
except Exception as e:
print(f"Other error: {e}")async function makeAuthenticatedRequest(apiKey, endpoint, options = {}) {
const response = await fetch(`https://api.synvo.ai${endpoint}`, {
...options,
headers: {
"X-API-Key": apiKey,
...options.headers
}
});
if (!response.ok) {
if (response.status === 401) {
const errorData = await response.json();
const errorCode = errorData.code || "UNKNOWN";
switch (errorCode) {
case "INVALID_API_KEY":
throw new Error("API key is invalid. Please check your key.");
case "API_KEY_REVOKED":
throw new Error("API key has been revoked. Please create a new one.");
default:
throw new Error(`Authentication failed: ${errorData.error}`);
}
} else {
throw new Error(`Request failed: ${response.status}`);
}
}
return await response.json();
}
// Usage
try {
const result = await makeAuthenticatedRequest("your-api-key", "/file/list");
console.log("Request successful!");
} catch (error) {
console.log(`Error: ${error.message}`);
}Rate Limiting
API keys are subject to rate limiting based on your plan:
- Free Tier: 100 requests per hour
- Pro Tier: 1,000 requests per hour
- Enterprise: Custom limits
Rate Limit Headers
The API returns rate limit information in response headers:
X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 999
X-RateLimit-Reset: 1642694400Handling Rate Limits
import time
import requests
def make_request_with_retry(api_key, endpoint, max_retries=3):
"""Make request with automatic retry on rate limit"""
headers = {"X-API-Key": api_key}
for attempt in range(max_retries):
response = requests.get(
f"https://api.synvo.ai{endpoint}",
headers=headers
)
if response.status_code == 429: # Rate limited
reset_time = int(response.headers.get("X-RateLimit-Reset", 0))
wait_time = max(reset_time - int(time.time()), 1)
print(f"Rate limited. Waiting {wait_time} seconds...")
time.sleep(wait_time)
continue
response.raise_for_status()
return response.json()
raise Exception("Max retries exceeded")async function makeRequestWithRetry(apiKey, endpoint, maxRetries = 3) {
const headers = { "X-API-Key": apiKey };
for (let attempt = 0; attempt < maxRetries; attempt++) {
const response = await fetch(`https://api.synvo.ai${endpoint}`, {
method: "GET",
headers
});
if (response.status === 429) {
const resetTime = parseInt(response.headers.get("X-RateLimit-Reset") || "0");
const waitTime = Math.max(resetTime - Math.floor(Date.now() / 1000), 1);
console.log(`Rate limited. Waiting ${waitTime} seconds...`);
await new Promise(resolve => setTimeout(resolve, waitTime * 1000));
continue;
}
if (!response.ok) {
throw new Error(`Request failed: ${response.status}`);
}
return await response.json();
}
throw new Error("Max retries exceeded");
}