Authenticate your backend
Use this guide when you need to protect your Orga API key, mint ephemeral tokens, and pass them to browser or mobile clients. You will pull a permanent key from the dashboard, create an authenticated POST request to /v1/realtime/client-secrets, and return the short-lived token plus ICE config to trusted clients.
Prerequisites
- Orga AI account with access to the Developer Platform .
- Backend runtime that can keep secrets (Node, Python, Ruby, etc.).
- Ability to set environment variables (e.g.,
.env, secret manager). - HTTPS access for the endpoint you expose to clients.
1. Get an API key
- Log in to the Orga dashboard and open API Keys.
- Create or copy an existing key (prefixed with
sk_orga_ai_). - Store it in your server’s secret manager or
.envfile:
ORGA_API_KEY=sk_orga_ai_******************************Never embed ORGA_API_KEY in browser or mobile apps. Only your backend should call the Orga REST API.
2. Exchange the key for an ephemeral token
Use your API key to call POST /v1/realtime/client-secrets. The response includes a short-lived JWT plus session metadata.
curl https://api.orga-ai.com/v1/realtime/client-secrets \
-H "Authorization: Bearer $ORGA_API_KEY" \
-H "Content-Type: application/json"Example response:
{
"ephemeralToken": "eyJhbGciOi...",
"ttl": 120
}This token is valid for a few minutes—long enough for a client to start a WebRTC session.
3. Fetch ICE configuration
Immediately fetch ICE servers with the ephemeral token. This keeps TURN credentials and stun URLs aligned.
curl https://api.orga-ai.com/v1/realtime/ice-config \
-H "Authorization: Bearer $EPHEMERAL_TOKEN"Sample response:
{
"iceServers": [
{ "urls": "stun:stun1.l.google.com:19302" },
{
"urls": ["turn:turn.orga-ai.com:3478"],
"username": "6b4c...",
"credential": "0433..."
}
]
}4. Return both values to your client
Wrap the two requests above inside your backend route. A minimal Express example:
import express from 'express';
import fetch from 'node-fetch';
const app = express();
app.get('/api/orga-client-secrets', async (_req, res) => {
try {
const secrets = await fetch('https://api.orga-ai.com/v1/realtime/client-secrets', {
method: 'POST',
headers: { Authorization: `Bearer ${process.env.ORGA_API_KEY}` },
}).then((r) => r.json());
const iceConfig = await fetch('https://api.orga-ai.com/v1/realtime/ice-config', {
headers: { Authorization: `Bearer ${secrets.ephemeralToken}` },
}).then((r) => r.json());
res.json({
ephemeralToken: secrets.ephemeralToken,
iceServers: iceConfig.iceServers,
});
} catch (error) {
console.error('Orga auth error', error);
res.status(500).json({ error: 'Failed to issue client secrets' });
}
});Clients (React, React Native, WebRTC apps) call this endpoint to receive the short-lived credentials.
5. Enforce security controls
| Concern | Recommendation |
|---|---|
| Authorization | Require the caller to include your app’s auth token or session cookie before issuing Orga credentials. |
| Rate limiting | Limit how often a user can request client secrets to prevent token flooding. |
| Transport | Serve /api/orga-client-secrets only over HTTPS. |
| Logging | Avoid logging raw tokens; log request IDs instead. |
6. Summary
| Credential | Lifetime | Where to use it | Header |
|---|---|---|---|
API Key (sk_orga_ai_*) | Long-lived | Server → Orga API | Authorization: Bearer sk_... |
| Ephemeral token | Minutes | Server + Client → Orga realtime endpoints | Authorization: Bearer <JWT> |
Next, connect this endpoint to your SDK:
- React tutorial shows how to call
fetchSessionConfigfrom the client. - Node tutorial shows a reusable proxy built with the Node SDK instead of bare REST.