Authentication
ZeroVoice supports two authentication methods: JWT bearer tokens and API keys.
JWT Bearer Tokens
Login
POST /auth/login
Content-Type: application/json
{
"email": "user@company.com",
"password": "your-password"
}
Response:
{
"access_token": "eyJ...",
"refresh_token": "rft_...",
"token_type": "bearer",
"expires_in": 900
}
Using the token
curl -H "Authorization: Bearer eyJ..." \
https://your-instance/api/v1/calls/live
Token details
| Property | Value |
|---|---|
| Algorithm | HS256 (local) or RS256 (external ZeroApp) |
| TTL | 15 minutes (hard limit) |
| Issuer | https://auth.zeroapp.dev |
| Audience | zerovoice |
Refreshing tokens
POST /auth/refresh
Content-Type: application/json
{
"refresh_token": "rft_..."
}
Refresh tokens use one-time rotation: each use invalidates the previous token and returns a new pair. Replaying a used refresh token revokes the entire token family (theft detection).
API Keys
For service-to-service or agent integrations, use API keys instead of JWT tokens.
Creating an API key
POST /api/v1/api-keys
Authorization: Bearer <admin-token>
Content-Type: application/json
{
"name": "MCP Bridge",
"expires_in_days": 90
}
Using API keys
curl -H "X-API-Key: zvk_..." \
https://your-instance/api/v1/contacts
Key management
- Keys can be listed, revoked, and auto-expire
- Revoked keys are purged nightly
- Keys inherit the creating user's org scope
Rate Limits
| Scope | Limit |
|---|---|
| General API | 200 requests/min per tenant |
| Auth endpoints | 10 requests/min per IP |
| Webhook endpoints | 30 requests/min per tenant |
Rate limit headers are returned on every response:
X-RateLimit-Limit: 200
X-RateLimit-Remaining: 195
X-RateLimit-Reset: 1719006000
Retry-After: 12
Multi-tenant isolation
Every authenticated request is scoped to the user's org_id. Tenant isolation is enforced at the query level — there is no way to access another organization's data through the API.