Skip to content

Authentication

All /v1/* endpoints require a Bearer API key.

API Keys

API keys use the plabs_ prefix and are passed in the Authorization header:

bash
curl https://persona-labsvoice-api-production.up.railway.app/v1/agents \
  -H "Authorization: Bearer plabs_your_key_here"

Creating Keys

bash
curl -X POST https://persona-labsvoice-api-production.up.railway.app/v1/keys \
  -H "Authorization: Bearer $PH0NY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Production Key",
    "expiresInDays": 90
  }'

WARNING

The raw key is only returned once at creation time. Store it securely.

Listing Keys

bash
curl https://persona-labsvoice-api-production.up.railway.app/v1/keys \
  -H "Authorization: Bearer $PH0NY_API_KEY"

Rotating Keys

bash
curl -X POST https://persona-labsvoice-api-production.up.railway.app/v1/keys/key_id/rotate \
  -H "Authorization: Bearer $PH0NY_API_KEY"

Returns a new key and revokes the old one.

Revoking Keys

bash
curl -X DELETE https://persona-labsvoice-api-production.up.railway.app/v1/keys/key_id \
  -H "Authorization: Bearer $PH0NY_API_KEY"

BYOK (Bring Your Own Key)

Pass provider API keys as headers to use your own accounts directly. BYOK requests bypass platform credit metering.

HeaderProvider
X-Provider-Key-ElevenLabsElevenLabs (TTS/STT)
X-Provider-Key-OpenAIOpenAI (LLM)
X-Provider-Key-AnthropicAnthropic (LLM)
X-Provider-Key-CartesiaCartesia (TTS/STT)
X-Provider-Key-DeepgramDeepgram (STT)
X-Provider-Key-FishAudioFish Audio (TTS)
X-Provider-Key-InworldInworld (TTS)
X-Provider-Key-ResembleAIResemble AI (TTS)
X-Provider-Key-GroqGroq (LLM/STT)
X-Provider-Key-HuggingFaceHugging Face (TTS)

Example:

bash
curl -X POST https://persona-labsvoice-api-production.up.railway.app/v1/synthesize \
  -H "Authorization: Bearer $PH0NY_API_KEY" \
  -H "X-Provider-Key-ElevenLabs: sk_your_elevenlabs_key" \
  -H "Content-Type: application/json" \
  -d '{"text": "Hello", "provider": "elevenlabs", "voiceId": "your_voice"}'

Stored Provider Keys

You can also store provider keys server-side so they are used automatically:

bash
# Store a key
curl -X POST https://persona-labsvoice-api-production.up.railway.app/v1/provider-keys \
  -H "Authorization: Bearer $PH0NY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"provider": "elevenlabs", "apiKey": "sk_..."}'

# List stored keys
curl https://persona-labsvoice-api-production.up.railway.app/v1/provider-keys \
  -H "Authorization: Bearer $PH0NY_API_KEY"

# Verify a key works
curl -X POST https://persona-labsvoice-api-production.up.railway.app/v1/provider-keys/elevenlabs/verify \
  -H "Authorization: Bearer $PH0NY_API_KEY"

# Delete a stored key
curl -X DELETE https://persona-labsvoice-api-production.up.railway.app/v1/provider-keys/elevenlabs \
  -H "Authorization: Bearer $PH0NY_API_KEY"

Response Headers

Every authenticated response includes usage information:

HeaderDescription
X-Request-IdUnique request identifier for debugging
X-Usage-CurrentCredits used this billing period
X-Usage-LimitCredit limit for your tier
X-Usage-RemainingCredits remaining
X-Usage-Bypassedtrue if BYOK key was used (no credits deducted)
X-Provider-UsedWhich provider handled the request

Rate Limits

Per-key rate limiting is applied to all /v1/* routes. When you hit the limit:

  • 429 Too Many Requests response
  • X-RateLimit-Limit — requests allowed per window
  • X-RateLimit-Remaining — requests left in current window
  • Retry-After — seconds until the window resets

Portal Authentication

The Developer Portal (/portal/*) uses session-based authentication via Better Auth (phone OTP). Portal routes are not accessible with API keys.

Built by Persona Labs.