API Key Authentication
API Keys are used by Agents (developers) to authenticate API requests.
Overview
ZhenRent uses Bearer token authentication with API keys for all agent-side requests.
Authorization: Bearer zr_live_your_api_key_here
API Key Format: zr_{environment}_{random_string}
zr_live_*- Production keyszr_test_*- Test environment keys (coming soon)
Creating an API Key
Step 1: Access Dashboard
- Log in to ZhenRent Dashboard
- Navigate to API Keys section
- Click Create New Key
Step 2: Configure Key
Key Configuration:
| Setting | Description | Recommendation |
|---|---|---|
| Key Name | Descriptive identifier | Use environment name (e.g., "Production", "Development") |
| Permissions | API access scope | Grant minimum required permissions |
| IP Whitelist | Allowed IP addresses (optional) | Use for production keys |
| Expiration | Auto-expiration date (optional) | Set for temporary keys |
Available Permissions:
task:create- Create new taskstask:read- Query tasks and resultstask:cancel- Cancel pending taskswebhook- Receive webhook notifications
Example Configuration:
Name: Production API
Permissions: task:create, task:read
IP Whitelist: 203.0.113.0/24
Expiration: None
Step 3: Save Key Securely
After creation, your API key is displayed once. Copy and store it securely.
Your API Key:
zr_live_l2HqGwGQVq0pUKshFM2AZiHfFX6LK
Warning: This key provides full access to your account. Store it like a password.
Using API Keys
In HTTP Requests
Include the API key in the Authorization header:
curl "https://www.zhenrent.com/api/v1/tasks" \
-H "Authorization: Bearer zr_live_your_api_key"
In Python
import os
import requests
API_KEY = os.getenv("ZHENRENT_API_KEY")
BASE_URL = "https://www.zhenrent.com/api/v1"
headers = {
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json"
}
response = requests.get(f"{BASE_URL}/tasks", headers=headers)
In JavaScript/Node.js
const API_KEY = process.env.ZHENRENT_API_KEY;
const BASE_URL = 'https://www.zhenrent.com/api/v1';
const response = await fetch(`${BASE_URL}/tasks`, {
headers: {
'Authorization': `Bearer ${API_KEY}`,
'Content-Type': 'application/json'
}
});
In Go
package main
import (
"net/http"
"os"
)
func main() {
apiKey := os.Getenv("ZHENRENT_API_KEY")
req, _ := http.NewRequest("GET", "https://www.zhenrent.com/api/v1/tasks", nil)
req.Header.Set("Authorization", "Bearer "+apiKey)
client := &http.Client{}
resp, _ := client.Do(req)
defer resp.Body.Close()
}
Security Best Practices
1. Use Environment Variables
Never hardcode API keys in your source code.
Bad (Insecure):
API_KEY = "zr_live_l2HqGwGQVq0pUKshFM2AZiHfFX6LK" # Never do this!
Good (Secure):
import os
API_KEY = os.getenv("ZHENRENT_API_KEY")
Set environment variable:
# Linux/Mac
export ZHENRENT_API_KEY="zr_live_your_key"
# Windows
set ZHENRENT_API_KEY=zr_live_your_key
2. Use .env Files (Local Development)
# .env
ZHENRENT_API_KEY=zr_live_your_key_here
Python (.env loading):
from dotenv import load_dotenv
load_dotenv()
API_KEY = os.getenv("ZHENRENT_API_KEY")
JavaScript (.env loading):
require('dotenv').config();
const API_KEY = process.env.ZHENRENT_API_KEY;
3. Add .env to .gitignore
Prevent accidental commits:
# .gitignore
.env
.env.local
.env.production
*.pem
4. Rotate Keys Regularly
Recommended schedule:
- Production keys: Every 90 days
- Development keys: Every 180 days
- After team member departure: Immediately
Rotation process:
- Create new API key
- Update application configuration
- Test with new key
- Delete old key
5. Use Different Keys per Environment
| Environment | Key Prefix | Purpose |
|---|---|---|
| Development | zr_test_* | Local testing |
| Staging | zr_live_* | Pre-production testing |
| Production | zr_live_* | Live traffic |
Never use production keys in development.
6. Implement IP Whitelisting
For production keys, restrict access to known IP addresses:
Dashboard → API Keys → Edit → IP Whitelist
203.0.113.0/24
Benefits:
- Prevents unauthorized access even if key is leaked
- Reduces attack surface
- Compliance requirement for some industries
7. Monitor API Key Usage
Check usage statistics regularly:
Dashboard → API Keys → Usage Statistics
Warning signs:
- Unexpected traffic spikes
- Requests from unknown IPs
- Unusual error rates
- Off-hours activity
8. Implement Key Validation
Verify API key format before making requests:
import re
def validate_api_key(key):
"""Validate ZhenRent API key format"""
pattern = r'^zr_(live|test)_[A-Za-z0-9\-_]{32}$'
if not re.match(pattern, key):
raise ValueError("Invalid API key format")
return True
# Usage
try:
validate_api_key(API_KEY)
except ValueError as e:
print(f"Error: {e}")
exit(1)
Managing Multiple Keys
Use Case: Multiple Applications
Create separate keys for each application:
Key 1: E-commerce Platform (task:create, task:read)
Key 2: Analytics Dashboard (task:read only)
Key 3: Mobile Backend (task:create, task:read, webhook)
Benefits:
- Granular permission control
- Easy to revoke specific app access
- Better audit trail
Key Naming Convention
Use descriptive names:
Format: {App}-{Environment}-{Purpose}
Examples:
- MainApp-Production-API
- Analytics-Staging-ReadOnly
- MobileBackend-Dev-Testing
Troubleshooting
Error: 401 Unauthorized
Cause: Invalid or missing API key
Solutions:
-
Check key format
# Correct
headers = {"Authorization": "Bearer zr_live_abc123"}
# Wrong (missing "Bearer")
headers = {"Authorization": "zr_live_abc123"} -
Verify key is active
Dashboard → API Keys → Status -
Check for typos
# Print key (first 10 chars only for security)
print(f"Using key: {API_KEY[:10]}...") -
Ensure key hasn't expired
Dashboard → API Keys → Expiration Date
Error: 403 Forbidden
Cause: Insufficient permissions
Solution: Add required permission to API key
Dashboard → API Keys → Edit → Permissions → Add "task:create"
Error: 429 Rate Limit Exceeded
Cause: Too many requests
Solution: Implement exponential backoff
import time
def api_request_with_retry(url, max_retries=3):
for attempt in range(max_retries):
response = requests.get(url, headers=headers)
if response.status_code == 429:
retry_after = int(response.headers.get('Retry-After', 60))
print(f"Rate limited. Retrying after {retry_after}s...")
time.sleep(retry_after)
continue
return response
raise Exception("Max retries exceeded")
API Key Lifecycle
Creation
User creates key → Platform generates random string → Key saved (hashed)
Storage
Platform: SHA-256 hash stored in database
Client: Plain text stored in environment variable
Validation
Client sends key → Platform hashes → Compares with stored hash → Grants/Denies access
Revocation
User deletes key → Hash removed from database → All requests with that key fail
Rate Limits
API keys have usage limits to prevent abuse:
| Tier | Requests/Minute | Requests/Day |
|---|---|---|
| Free | 100 | 10,000 |
| Paid | 1,000 | 100,000 |
| Enterprise | Custom | Custom |
Rate limit headers (included in every response):
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 87
X-RateLimit-Reset: 1680261600
Next Steps
- JWT Authentication - For worker mobile apps
- Security Best Practices - Advanced security guide
- Quick Start - Start building
- API Reference - Complete API documentation