> ## Documentation Index
> Fetch the complete documentation index at: https://docs.zeplo.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Authentication

> Authenticate your API requests using session cookies or API keys.

# Authentication

The Zeplo API supports two authentication methods depending on your use case.

## API Key Authentication

Use API keys for external integrations and the REST API v1 endpoints. Every request must include your API key and channel ID.

### Getting Your API Key

**1. Open API Keys Settings**

Navigate to **Settings > API Keys** in your Zeplo dashboard at [app.zeplo.ai](https://app.zeplo.ai).

**2. Create a New Key**

Click **Create Key**, enter a descriptive name, select the required permissions, and set your rate and monthly limits.

**3. Copy Your Credentials**

Copy the API key (`zeplo_ak_...`) and secret (`zeplo_as_...`). The secret is shown only once.

**4. Store Securely**

Save both values in your environment variables or a secrets manager. Never commit them to source control.

### Using Your API Key

**JavaScript/TypeScript**

```typescript theme={null}
import { ZeploClient } from '@zeplo/sdk';

const zeplo = new ZeploClient({
  apiKey: process.env.ZEPLO_API_KEY,
  apiSecret: process.env.ZEPLO_API_SECRET,
  channelId: process.env.ZEPLO_CHANNEL_ID,
});

// All SDK methods automatically include auth headers
const contacts = await zeplo.contacts.list();
```

**Python**

```python theme={null}
from zeplo import ZeploClient

client = ZeploClient(
    api_key=os.environ["ZEPLO_API_KEY"],
    api_secret=os.environ["ZEPLO_API_SECRET"],
    channel_id=os.environ["ZEPLO_CHANNEL_ID"],
)

# All client methods automatically include auth headers
contacts = client.contacts.list()
```

**cURL**

```bash theme={null}
curl https://zeplo.ai/api/v1/contacts \
  -H "x-api-key: zeplo_ak_abc123..." \
  -H "x-api-secret: zeplo_as_abc123..." \
  -H "x-channel-id: 647015955153740"
```

### Required Headers

| Header | Required | Description |
| - | - | - |
| `x-api-key` | Yes | Your API key (`zeplo_ak_...`) |
| `x-api-secret` | Yes | Your API secret key (`zeplo_as_...`) |
| `x-channel-id` | Yes | The WhatsApp channel ID to operate on |

> [!WARNING]
>
> Never expose your API key in client-side JavaScript or mobile apps. All API calls should be made from your backend server. Use environment variables to store credentials.

## Session-Based Authentication

Use session-based auth for internal dashboard operations. Login via `POST /api/auth/login` to receive a session cookie.

```bash theme={null}
curl -X POST https://zeplo.ai/api/auth/login \
  -H "Content-Type: application/json" \
  -d '{
    "username": "admin@example.com",
    "password": "your_password"
  }'
```

The response sets a `connect.sid` cookie used for subsequent requests.

## Environment Variables

**JavaScript/TypeScript**

Create a `.env` file:

```bash theme={null}
ZEPLO_API_KEY=zeplo_ak_abc123...
ZEPLO_API_SECRET=zeplo_as_abc123...
ZEPLO_CHANNEL_ID=647015955153740
```

Access in your code:

```typescript theme={null}
const zeplo = new ZeploClient({
  apiKey: process.env.ZEPLO_API_KEY,
  apiSecret: process.env.ZEPLO_API_SECRET,
  channelId: process.env.ZEPLO_CHANNEL_ID,
});
```

**Python**

Create a `.env` file:

```bash theme={null}
ZEPLO_API_KEY=zeplo_ak_abc123...
ZEPLO_API_SECRET=zeplo_as_abc123...
ZEPLO_CHANNEL_ID=647015955153740
```

Access in your code:

```python theme={null}
import os
from dotenv import load_dotenv

load_dotenv()

client = ZeploClient(
    api_key=os.environ["ZEPLO_API_KEY"],
    api_secret=os.environ["ZEPLO_API_SECRET"],
    channel_id=os.environ["ZEPLO_CHANNEL_ID"],
)
```

## Rate Limiting

| Plan | Requests/min | Monthly Limit |
| - | - | - |
| Free | 20 | 1,000 |
| Starter | 60 | 10,000 |
| Professional | 120 | 50,000 |
| Enterprise | 300 | Unlimited |

> [!NOTE]
>
> Rate limit headers are included in every API response: `X-RateLimit-Limit`, `X-RateLimit-Remaining`, and `X-RateLimit-Reset`.

## Error Handling

When authentication fails, the API returns a `401` status code:

```json Response theme={null}
{
  "error": "Unauthorized",
  "message": "Invalid or missing API key",
  "code": "AUTH_INVALID_KEY"
}
```

| Status Code | Error Code | Description |
| - | - | - |
| 401 | `AUTH_INVALID_KEY` | Invalid or missing API key |
| 401 | `AUTH_INVALID_CHANNEL` | Channel ID not found or unauthorized |
| 401 | `AUTH_EXPIRED_SESSION` | Session cookie has expired |
| 403 | `AUTH_INSUFFICIENT_PERMISSIONS` | API key lacks required permissions |
| 429 | `RATE_LIMIT_EXCEEDED` | Too many requests, retry after `X-RateLimit-Reset` |


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.