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

# Authentication

> Secure your API requests with authentication

## Authentication Methods

Human Intelligence API supports two authentication methods depending on your use case:

1. **API Key** - For server-to-server integration and general API access
2. **JWT Bearer Token** - For authenticated user sessions and long-lived context

***

## 1. API Key Authentication

Use API keys for server-side integrations where you need to access the API on behalf of your application.

### Request Format

Include your API key in the `X-API-Key` header:

```bash theme={null}
X-API-Key: your_api_key_here
```

### Example Request

```bash theme={null}
curl -X POST https://api.myweave.ai/functions/v1/chat \
  -H "Content-Type: application/json" \
  -H "X-API-Key: your_api_key_here" \
  -d '{
    "message": "Hello",
    "context": {
      "coachId": "coach_xyz789"
    }
  }'
```

### When to Use API Keys

* Server-to-server API calls
* Anonymous user conversations
* General API access without user-specific context
* Third-party integrations

***

## 2. JWT Bearer Token Authentication

Use JWT tokens for authenticated user sessions, enabling long-lived context and personalized experiences.

### Login Flow

#### Step 1: User Login

```bash theme={null}
curl -X POST https://api.myweave.ai/auth/v1/token?grant_type=password \
  -H "Content-Type: application/json" \
  -H "apikey: your_supabase_anon_key" \
  -d '{
    "email": "user@example.com",
    "password": "user_password"
  }'
```

#### Step 2: Receive JWT Token

```json theme={null}
{
  "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "token_type": "bearer",
  "expires_in": 3600,
  "refresh_token": "your_refresh_token_here",
  "user": {
    "id": "user_abc123",
    "email": "user@example.com"
  }
}
```

#### Step 3: Use Bearer Token in Requests

```bash theme={null}
curl -X POST https://api.myweave.ai/functions/v1/chat \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." \
  -H "X-API-Key: your_api_key_here" \
  -d '{
    "message": "Hello, continue our previous conversation",
    "thread_id": "550e8400-e29b-41d4-a716-446655440000",
    "context": {
      "coachId": "coach_xyz789",
      "userId": "user_abc123",
      "isAuthenticated": true
    }
  }'
```

### When to Use JWT Tokens

* User-specific conversations with persistent history
* Accessing user's private threads and data
* Long-lived sessions across multiple requests
* Expert actions requiring coach authentication (e.g., `create_knowledge`)
* Personalized experiences tied to user profiles

### JavaScript/TypeScript Example

```javascript theme={null}
// Step 1: Login and get token
async function login(email, password) {
  const response = await fetch('https://api.myweave.ai/auth/v1/token?grant_type=password', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'apikey': 'your_supabase_anon_key'
    },
    body: JSON.stringify({ email, password })
  });
  
  const { access_token, refresh_token, user } = await response.json();
  
  // Store tokens securely
  localStorage.setItem('access_token', access_token);
  localStorage.setItem('refresh_token', refresh_token);
  
  return { access_token, user };
}

// Step 2: Use token for authenticated requests
async function sendAuthenticatedMessage(message, threadId, coachId, userId) {
  const token = localStorage.getItem('access_token');
  
  const response = await fetch('https://api.myweave.ai/functions/v1/chat', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'Authorization': `Bearer ${token}`,
      'X-API-Key': 'your_api_key_here'
    },
    body: JSON.stringify({
      message,
      thread_id: threadId,
      context: {
        coachId,
        userId,
        isAuthenticated: true
      }
    })
  });
  
  return response;
}
```

### Python Example

```python theme={null}
import requests

# Step 1: Login and get token
def login(email, password):
    url = "https://api.myweave.ai/auth/v1/token?grant_type=password"
    headers = {
        "Content-Type": "application/json",
        "apikey": "your_supabase_anon_key"
    }
    data = {
        "email": email,
        "password": password
    }
    
    response = requests.post(url, headers=headers, json=data)
    result = response.json()
    
    # Store tokens securely
    access_token = result['access_token']
    refresh_token = result['refresh_token']
    
    return access_token, result['user']

# Step 2: Use token for authenticated requests
def send_authenticated_message(token, message, thread_id, coach_id, user_id):
    url = "https://api.myweave.ai/functions/v1/chat"
    headers = {
        "Content-Type": "application/json",
        "Authorization": f"Bearer {token}",
        "X-API-Key": "your_api_key_here"
    }
    data = {
        "message": message,
        "thread_id": thread_id,
        "context": {
            "coachId": coach_id,
            "userId": user_id,
            "isAuthenticated": True
        }
    }
    
    response = requests.post(url, headers=headers, json=data, stream=True)
    return response
```

***

## Long-Lived Sessions & Token Refresh

JWT tokens expire after **1 hour** (3600 seconds). For long-lived sessions, use the refresh token to obtain a new access token without requiring the user to log in again.

### Refreshing Tokens

```bash theme={null}
curl -X POST https://api.myweave.ai/auth/v1/token?grant_type=refresh_token \
  -H "Content-Type: application/json" \
  -H "apikey: your_supabase_anon_key" \
  -d '{
    "refresh_token": "your_refresh_token_here"
  }'
```

### Response

```json theme={null}
{
  "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "token_type": "bearer",
  "expires_in": 3600,
  "refresh_token": "new_refresh_token_here"
}
```

### Automatic Token Refresh (JavaScript)

```javascript theme={null}
class AuthManager {
  constructor(apiKey, supabaseAnonKey) {
    this.apiKey = apiKey;
    this.supabaseAnonKey = supabaseAnonKey;
    this.accessToken = null;
    this.refreshToken = null;
    this.tokenExpiry = null;
  }
  
  async login(email, password) {
    const response = await fetch('https://api.myweave.ai/auth/v1/token?grant_type=password', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'apikey': this.supabaseAnonKey
      },
      body: JSON.stringify({ email, password })
    });
    
    const data = await response.json();
    this.setTokens(data.access_token, data.refresh_token, data.expires_in);
    return data.user;
  }
  
  setTokens(accessToken, refreshToken, expiresIn) {
    this.accessToken = accessToken;
    this.refreshToken = refreshToken;
    this.tokenExpiry = Date.now() + (expiresIn * 1000);
    
    // Store in localStorage
    localStorage.setItem('access_token', accessToken);
    localStorage.setItem('refresh_token', refreshToken);
    localStorage.setItem('token_expiry', this.tokenExpiry.toString());
  }
  
  async refreshTokenIfNeeded() {
    // Refresh 5 minutes before expiry
    if (this.tokenExpiry && Date.now() > (this.tokenExpiry - 300000)) {
      await this.refreshAccessToken();
    }
  }
  
  async refreshAccessToken() {
    const response = await fetch('https://api.myweave.ai/auth/v1/token?grant_type=refresh_token', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'apikey': this.supabaseAnonKey
      },
      body: JSON.stringify({ refresh_token: this.refreshToken })
    });
    
    const data = await response.json();
    this.setTokens(data.access_token, data.refresh_token, data.expires_in);
  }
  
  async makeAuthenticatedRequest(url, options = {}) {
    await this.refreshTokenIfNeeded();
    
    return fetch(url, {
      ...options,
      headers: {
        ...options.headers,
        'Authorization': `Bearer ${this.accessToken}`,
        'X-API-Key': this.apiKey
      }
    });
  }
}

// Usage
const auth = new AuthManager('your_api_key', 'your_supabase_anon_key');
await auth.login('user@example.com', 'password');

// Make authenticated requests
const response = await auth.makeAuthenticatedRequest(
  'https://api.myweave.ai/functions/v1/chat',
  {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ message: 'Hello', context: { coachId: 'coach_123' }})
  }
);
```

***

## Getting Your API Key

<Steps>
  <Step title="Request Access">
    Email [support@myweave.ai](mailto:support@myweave.ai?subject=API%20Key%20Request) with your use case and integration plans
  </Step>

  <Step title="Receive API Key">
    Our team will review your request and send you an API key within 24 hours
  </Step>

  <Step title="Start Building">
    Use your API key in the `X-API-Key` header for all requests
  </Step>
</Steps>

***

## Authentication Comparison

| Feature                | API Key                | JWT Bearer Token           |
| ---------------------- | ---------------------- | -------------------------- |
| **Use Case**           | Server-to-server       | User sessions              |
| **Expiration**         | Never (unless revoked) | 1 hour (refresh available) |
| **User Context**       | Anonymous or app-level | User-specific              |
| **Thread Persistence** | Limited                | Full conversation history  |
| **Required For**       | All API calls          | Authenticated actions      |
| **Security Level**     | Server-side only       | Client + Server            |
| **Refresh Mechanism**  | N/A                    | Refresh token              |

## Security Best Practices

<Warning>
  Never expose your API key in client-side code or public repositories.
</Warning>

* **Store securely**: Keep API keys in environment variables
* **Server-side only**: Make API calls from your backend, not frontend
* **Rotate regularly**: Update keys periodically for enhanced security
* **Monitor usage**: Track API calls for suspicious activity
* **Use HTTPS**: Always make requests over secure connections

## Rate Limiting

All API endpoints are rate limited per API key to ensure fair usage and system stability:

| Period     | Limit           |
| ---------- | --------------- |
| Per minute | 60 requests     |
| Per hour   | 1,000 requests  |
| Per day    | 10,000 requests |

### Rate Limit Headers

Each API response includes rate limit information:

```
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 45
X-RateLimit-Reset: 1640000000
```

### Handling Rate Limits

When rate limits are exceeded, you'll receive a `429 Too Many Requests` response:

```json theme={null}
{
  "error": "Rate limit exceeded",
  "message": "Too many requests. Please try again later.",
  "retryAfter": 60
}
```

Implement exponential backoff in your application to handle rate limits gracefully.

## CORS Support

All endpoints support Cross-Origin Resource Sharing (CORS) with the following headers:

* `Access-Control-Allow-Origin: *`
* `Access-Control-Allow-Headers: authorization, x-client-info, apikey, content-type`

This allows you to make requests from browser-based applications, though we recommend using a backend proxy to keep your API key secure.
