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

# Authentication

> How to authenticate with the thinnestAI API and secure your integrations.

# Authentication

thinnestAI uses API keys for programmatic access and Auth0 for dashboard authentication. This guide covers how to authenticate your API requests, set up OAuth integrations, and secure your endpoints.

## API Key Authentication

Every API request to thinnestAI must include a valid API key. API keys are scoped to your account and have full access to all your resources.

### Getting Your API Key

1. Sign in to the [thinnestAI Dashboard](https://app.thinnest.ai).
2. Go to **Settings > API Keys**.
3. Click **Generate API Key**.
4. Copy and store the key securely. It will only be shown once.

### Using Your API Key

Include the key in the `Authorization` header of every request:

```bash theme={null}
curl https://api.thinnest.ai/agents \
  -H "Authorization: Bearer your-api-key-here"
```

Or set it as an environment variable:

```bash theme={null}
THINNESTAI_API_KEY=your-api-key-here
```

Then reference it in your requests:

```bash theme={null}
curl https://api.thinnest.ai/agents \
  -H "Authorization: Bearer $THINNESTAI_API_KEY"
```

### API Key Best Practices

* **Never commit API keys to source control.** Use environment variables or a secrets manager.
* **Rotate keys regularly.** You can generate a new key and revoke the old one from the dashboard.
* **Use separate keys for development and production.** This limits the blast radius if a key is compromised.
* **Monitor usage.** Check the dashboard for unexpected API activity.

### Revoking a Key

1. Go to **Settings > API Keys**.
2. Find the key you want to revoke.
3. Click **Revoke**. The key is immediately invalidated.

Revoking a key does not affect your agents, phone numbers, or any other resources. It only stops future API requests using that key.

## Dashboard Authentication (Auth0)

The thinnestAI Dashboard uses Auth0 for user authentication. When you sign up or log in at [app.thinnest.ai](https://app.thinnest.ai), you're authenticating through Auth0.

### Supported Login Methods

* **Email + Password** — Standard email/password registration
* **Google OAuth** — Sign in with your Google account
* **GitHub OAuth** — Sign in with your GitHub account

### Team Access

If you're working with a team, you can invite members from **Settings > Team**:

1. Click **Invite Member**.
2. Enter their email address.
3. Choose a role:
   * **Admin** — Full access to all settings, billing, and agents
   * **Editor** — Can create and modify agents, but no billing access
   * **Viewer** — Read-only access to agents and call logs

The invited user receives an email and can sign up or sign in to access your workspace.

## OAuth Integrations

Some agent tools require OAuth authentication to access third-party services on behalf of your users. thinnestAI handles the OAuth flow for you.

### Google OAuth (Gmail, Calendar, Sheets)

To let your agents send emails, manage calendars, or access spreadsheets, you need to connect a Google account:

1. Go to your agent's **Tools** tab.
2. Click **Add Tool** and select a Google tool (Gmail, Calendar, or Sheets).
3. Click **Connect Google Account**.
4. You'll be redirected to Google's OAuth consent screen.
5. Grant the requested permissions.
6. You're redirected back to thinnestAI with the connection active.

Your agent can now use Google tools on behalf of the connected account.

### Required Google OAuth Scopes

| Tool                | Scopes                                  |
| ------------------- | --------------------------------------- |
| **Gmail**           | `gmail.send`, `gmail.readonly`          |
| **Google Calendar** | `calendar.events`, `calendar.readonly`  |
| **Google Sheets**   | `spreadsheets`, `spreadsheets.readonly` |

### Disconnecting OAuth

To disconnect a Google account:

1. Go to **Settings > Integrations**.
2. Find the Google connection.
3. Click **Disconnect**.

This revokes thinnestAI's access to the connected Google account. Agents using Google tools will stop working until a new account is connected.

## Webhook Authentication

If you're receiving webhooks from thinnestAI (e.g., call events, campaign updates), you can verify the authenticity of incoming requests.

### Webhook Signatures

Every webhook request from thinnestAI includes a signature header:

```
X-ThinnestAI-Signature: sha256=abc123...
```

Verify it using your webhook secret:

```python theme={null}
import hmac
import hashlib

def verify_webhook(payload: bytes, signature: str, secret: str) -> bool:
    expected = hmac.new(
        secret.encode(),
        payload,
        hashlib.sha256
    ).hexdigest()
    return hmac.compare_digest(f"sha256={expected}", signature)
```

```javascript theme={null}
const crypto = require('crypto');

function verifyWebhook(payload, signature, secret) {
  const expected = crypto
    .createHmac('sha256', secret)
    .update(payload)
    .digest('hex');
  return signature === `sha256=${expected}`;
}
```

### Getting Your Webhook Secret

1. Go to **Settings > Webhooks**.
2. Create or edit a webhook endpoint.
3. Copy the **Signing Secret**.

## Embedded Chat Widget Authentication

When embedding the chat widget on your website, the agent ID is public. To restrict who can use the widget, enable **Allowed Origins**:

1. Go to your agent's **Settings > Embed**.
2. Add your website domain(s) to **Allowed Origins**:
   ```
   https://www.yoursite.com
   https://app.yoursite.com
   ```
3. Save. The widget will only load on pages served from these domains.

### Authenticated Widget Sessions

For logged-in users on your website, you can pass user identity to the widget so the agent knows who it's talking to:

```html theme={null}
<script
  src="https://app.thinnest.ai/embed.js"
  data-agent-id="agent_abc123"
  data-user-id="user_12345"
  data-user-name="Jane Smith"
  data-user-email="jane@example.com"
  data-user-hash="hmac-signature-here"
  async
></script>
```

The `data-user-hash` is an HMAC-SHA256 signature of the user ID, signed with your webhook secret. This prevents users from impersonating others:

```python theme={null}
import hmac
import hashlib

user_hash = hmac.new(
    webhook_secret.encode(),
    user_id.encode(),
    hashlib.sha256
).hexdigest()
```

## API Rate Limits

To protect the platform, API requests are rate-limited per account:

| Endpoint            | Limit               |
| ------------------- | ------------------- |
| Agent CRUD          | 60 requests/minute  |
| Chat/Conversation   | 120 requests/minute |
| Call triggers       | 30 requests/minute  |
| Knowledge upload    | 20 requests/minute  |
| All other endpoints | 60 requests/minute  |

When you exceed a rate limit, the API returns a `429 Too Many Requests` response with a `Retry-After` header:

```json theme={null}
{
  "error": "rate_limit_exceeded",
  "message": "Too many requests. Please retry after 30 seconds.",
  "retry_after": 30
}
```

## Security Recommendations

1. **Use HTTPS for all API calls.** The API rejects plain HTTP requests.
2. **Store keys in environment variables** or a secrets manager — never hardcode them.
3. **Restrict embed widget origins** to your own domains.
4. **Verify webhook signatures** to ensure requests are genuinely from thinnestAI.
5. **Rotate API keys** periodically, especially if team members leave.
6. **Use the principle of least privilege** when assigning team roles.
7. **Monitor your usage dashboard** for unexpected activity.

## Error Responses

| Status Code             | Meaning                                |
| ----------------------- | -------------------------------------- |
| `401 Unauthorized`      | Missing or invalid API key             |
| `403 Forbidden`         | Valid key but insufficient permissions |
| `429 Too Many Requests` | Rate limit exceeded                    |

If you receive a `401`, double-check that:

* The API key is included in the `Authorization` header
* The key hasn't been revoked
* The header format is `Bearer your-key-here` (note the space after "Bearer")
