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

# WebSocket Authentication

> Authenticate your WebSocket connection and manage session state

## Authentication Flow

Authentication happens in two steps: connection-level authentication via query parameter and session-level authentication via WebSocket message.

### Connection Authentication

Connect to the secure WebSocket endpoint without API key in URL:

```
wss://data.quantcite.com/api/v1/ws
```

**Security Enhancement:** API keys are no longer exposed in URLs for better security.

### Session Authentication

After connecting, send an authentication message to establish your session:

**Request:**

```json theme={null}
{
  "type": "authenticate",
  "api_key": "YOUR_API_KEY"
}
```

**Success Response:**

```json theme={null}
{
  "type": "welcome",
  "session_id": "860a5a96-0da4-4154-9d13-a79d07121758",
  "user_id": "cb88461f-421a-4ac8-9722-afe248a40ae6",
  "user_tier": "premium",
  "message": "Authenticated successfully as premium user",
  "authentication": {
    "api_key": "demo_key...",
    "status": "authenticated"
  }
}
```

## Authentication Errors

### Invalid API Key

```json theme={null}
{
  "type": "error",
  "error": "Authentication failed",
  "code": 4001
}
```

### API Key Not Found

```json theme={null}
{
  "type": "authentication_error",
  "error": "api_key_not_found", 
  "message": "The provided API key was not found"
}
```

### Account Suspended

```json theme={null}
{
  "type": "authentication_error",
  "error": "account_suspended",
  "message": "Your account has been suspended. Contact support."
}
```

## User Tiers

Different tiers provide different access levels:

| Tier       | Rate Limit     | Monthly Messages | Max Connections | Data Limit |
| ---------- | -------------- | ---------------- | --------------- | ---------- |
| Basic      | 600 req/min    | 10,000           | 5               | 50GB       |
| Premium    | 1,200 req/min  | 100,000          | 20              | 50GB       |
| Developer  | 1,000 req/min  | 50,000           | 15              | 50GB       |
| Enterprise | 10,000 req/min | 1,000,000        | 100             | 50GB       |

## Session Management

### Session State

After authentication, your session maintains:

* **User ID** - Unique identifier for your account
* **Tier Information** - Your current subscription tier
* **Usage Statistics** - Real-time data consumption tracking
* **Active Subscriptions** - Currently subscribed trading pairs
* **Connection Metadata** - Connection time, IP, etc.

### Session Persistence

Sessions are maintained as long as:

* WebSocket connection remains active
* API key remains valid
* Account remains in good standing
* Data limits are not exceeded

### Multiple Connections

You can maintain multiple WebSocket connections up to your tier limit:

* Each connection requires separate authentication
* Data usage is shared across all connections
* Rate limits apply per API key, not per connection

## Security Best Practices

<CardGroup cols={2}>
  <Card title="API Key Security" icon="key">
    * Never expose API keys in client-side code
    * Use environment variables for key storage
    * Rotate keys regularly
    * Monitor for unauthorized usage
  </Card>

  <Card title="Connection Security" icon="shield">
    * Use secure WebSocket connections (WSS) in production
    * Implement proper error handling
    * Log authentication events
    * Monitor for suspicious activity
  </Card>
</CardGroup>

## Code Examples

### Python Authentication

```python theme={null}
import asyncio
import websockets
import json

async def authenticate():
    uri = "wss://data.quantcite.com/api/v1/ws"
    
    async with websockets.connect(uri) as websocket:
        # Send authentication message
        auth_msg = {
            "type": "authenticate",
            "api_key": "demo_key_123"
        }
        await websocket.send(json.dumps(auth_msg))
        
        # Wait for authentication response
        response = await websocket.recv()
        auth_data = json.loads(response)
        
        if auth_data.get("type") == "welcome":
            print(f"Authenticated as user: {auth_data['user_id']}")
            print(f"Session ID: {auth_data['session_id']}")
            print(f"Tier: {auth_data['user_tier']}")
        else:
            print(f"Authentication failed: {auth_data['error']}")

asyncio.run(authenticate())
```

### JavaScript Authentication

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

const ws = new WebSocket('wss://data.quantcite.com/api/v1/ws');

ws.on('open', () => {
    // Send authentication message
    const authMsg = {
        type: 'authenticate',
        api_key: 'demo_key_123'
    };
    ws.send(JSON.stringify(authMsg));
});

ws.on('message', (data) => {
    const message = JSON.parse(data.toString());
    
    if (message.type === 'welcome') {
        console.log(`Authenticated as user: ${message.user_id}`);
        console.log(`Session ID: ${message.session_id}`);
        console.log(`Tier: ${message.user_tier}`);
    } else if (message.type === 'error') {
        console.error(`Authentication failed: ${message.error}`);
    }
});
```

<Note>
  Always handle authentication errors gracefully and implement retry logic with exponential backoff for temporary failures.
</Note>
