---
sidebar_position: 2
title: Client Authentication
description: Learn how to generate secure Agent JWT Tokens on your backend for the Firetell Client SDK.
---

# Client Authentication

To authorize frontend WebRTC clients safely, your backend server must generate a temporary **Agent JWT Token** representing that agent, which is then passed to the frontend client to initialize the `FiretellClient`.

> [!WARNING]
> **NEVER hardcode your Master API Key (`sk-...`) in frontend client-side code.**
>
> Exposing your master API Key gives anyone full access to provision phone numbers, configure billing, and read call records for your entire workspace.

---

## Generating the Agent JWT Token (Backend)

To generate the JWT token on your backend server using your Firetell API Key credentials, you must sign the token using the **HS256** algorithm with your API Key's secret (`sk-...`) as the signing key.

### How to Obtain API Key Credentials from Firetell Console

To generate Agent JWT tokens, your backend needs both the **API Key SID** and the **API Key Secret**:

1. Log in to the [Firetell Console](https://console.firetell.com).
2. Select your workspace from the dashboard.
3. Navigate to **Workspace Settings** → **API Keys** in the left sidebar.
4. Click **Create API Key** (or select an existing key).
5. Copy both of the following credentials:
   - **API Key SID** (starts with `sid-`, e.g. `sid-your_api_key_sid`): The public key identifier, used as the `iss` (Issuer) claim in your JWT.
   - **API Key Secret** (starts with `sk-`, e.g. `sk-your_api_key_secret`): The secret key, used as the signing secret for HS256.

:::caution
The **API Key Secret** (`sk-...`) is **only shown once** at the time of creation. Store it securely on your backend server (e.g., in environment variables) and never share it or commit it to version control.
:::

### JWT Claims & Structure

- **Algorithm:** `HS256`
- **Signing Key (Secret):** Your Firetell API Key secret (starts with `sk-`, e.g. `sk-your_api_key_secret`)
- **Standard Claims:**
  - `iss` (Issuer): Your API Key SID (starts with `sid-`, e.g. `sid-your_api_key_sid`)
  - `sub` (Subject): Depends on the audience type (see below)
  - `aud` (Audience): `'agent-api'` or `'client-api'`
  - `exp` (Expiration): The expiration timestamp (e.g. 24 hours from generation)
- **Custom Claims:**
  - `domain`: Your full workspace domain (e.g. `"yourcompany.firetell.app"`)

#### Audience Types

| Audience | `sub` requirement | Use case |
| --- | --- | --- |
| `agent-api` | Must be the **username of an existing, active agent** in your workspace | WebRTC agent clients (call center agents, support reps) |
| `client-api` | Can be **any identifier** you define (e.g. user ID, session ID) | End-user clients (customers, anonymous callers) |

### Code Examples

#### Agent API Token

Generate a token for a call center agent. The `sub` must match an existing, active agent username in your workspace.

##### Node.js (using `jsonwebtoken`)

```javascript
const jwt = require("jsonwebtoken");

const apiKeySid = "sid-your_api_key_sid"; // From Firetell Console (API Key SID)
const apiKeySecret = "sk-your_api_key_secret"; // From Firetell Console (API Key Secret)
const workspaceDomain = "yourcompany.firetell.app"; // Your full workspace domain
const agentUsername = "agent_123"; // Must be an existing, active agent username

const token = jwt.sign(
  {
    domain: workspaceDomain,
  },
  apiKeySecret,
  {
    algorithm: "HS256",
    expiresIn: "24h",
    issuer: apiKeySid,
    subject: agentUsername,
    audience: "agent-api",
  },
);

console.log(token); // Send this token to the frontend client SDK
```

##### Python (using `PyJWT`)

```python
import jwt
from datetime import datetime, timedelta

api_key_sid = 'sid-your_api_key_sid'
api_key_secret = 'sk-your_api_key_secret'
workspace_domain = 'yourcompany.firetell.app'
agent_username = 'agent_123'  # Must be an existing, active agent username

payload = {
    'domain': workspace_domain,
    'iss': api_key_sid,
    'sub': agent_username,
    'aud': 'agent-api',
    'exp': datetime.utcnow() + timedelta(hours=24)
}

token = jwt.encode(payload, api_key_secret, algorithm='HS256')
print(token) # Send this token to the frontend client SDK
```

---

#### Client API Token

Generate a token for an end-user client. The `sub` can be any custom identifier you define.

##### Node.js (using `jsonwebtoken`)

```javascript
const jwt = require("jsonwebtoken");

const apiKeySid = "sid-your_api_key_sid";
const apiKeySecret = "sk-your_api_key_secret";
const workspaceDomain = "yourcompany.firetell.app";
const userId = "user_abc"; // Any custom identifier you define

const token = jwt.sign(
  {
    domain: workspaceDomain,
  },
  apiKeySecret,
  {
    algorithm: "HS256",
    expiresIn: "24h",
    issuer: apiKeySid,
    subject: userId,
    audience: "client-api",
  },
);

console.log(token); // Send this token to the frontend client
```

##### Python (using `PyJWT`)

```python
import jwt
from datetime import datetime, timedelta

api_key_sid = 'sid-your_api_key_sid'
api_key_secret = 'sk-your_api_key_secret'
workspace_domain = 'yourcompany.firetell.app'
user_id = 'user_abc'  # Any custom identifier you define

payload = {
    'domain': workspace_domain,
    'iss': api_key_sid,
    'sub': user_id,
    'aud': 'client-api',
    'exp': datetime.utcnow() + timedelta(hours=24)
}

token = jwt.encode(payload, api_key_secret, algorithm='HS256')
print(token) # Send this token to the frontend client
```

#### PHP (using `firebase/php-jwt`)

```php
<?php
require 'vendor/autoload.php';
use Firebase\JWT\JWT;

$apiKeySid = 'sid-your_api_key_sid';         // From Firetell Console (API Key SID)
$apiKeySecret = 'sk-your_api_key_secret';     // From Firetell Console (API Key Secret)
$workspaceDomain = 'yourcompany.firetell.app'; // Your full workspace domain
$agentUsername = 'agent_123';                 // The active agent username

$payload = [
    'domain' => $workspaceDomain,
    'iss' => $apiKeySid,
    'sub' => $agentUsername,
    'aud' => 'agent-api',
    'exp' => time() + (24 * 60 * 60) // e.g. token expires in 24 hours
];

$token = JWT::encode($payload, $apiKeySecret, 'HS256');
echo $token; // Send this token to the frontend client SDK
```
