# API Authentication

Solo's API uses API key authentication. Generate API keys in Settings → API Keys and use them to authenticate all API requests.

## Authentication Method

### Bearer Token

All API requests require a Bearer token in the Authorization header:

```bash
Authorization: Bearer <your-api-key>
```

### API Key Format

API keys are long, random strings:
- **Format**: Random alphanumeric string
- **Length**: 64+ characters
- **Unique**: Each key is unique
- **Secret**: Keep keys private

## Getting an API Key

### Generate a Key

1. **Go to Settings → API Keys**
2. **Click "Generate New Key"**
3. **Enter key name**: Descriptive name (e.g., "Workflow Integration" or "n8n Integration")
4. **Click "Generate"**
5. **Copy key**: Save immediately (shown only once)

### Key Information

Each API key includes:
- **Key name**: Your label for the key
- **Key value**: The actual API key (Bearer token)
- **Created date**: When key was created
- **Last used**: Last time key was used
- **Usage count**: Number of requests made

## Using API Keys

### Request Headers

Include the API key in the Authorization header:

```bash
curl -X GET https://solomail.io/api/v1/identity \
  -H "Authorization: Bearer <your-api-key>"
```

### JavaScript Example

```javascript
const apiKey = 'your-api-key-here'

fetch('https://solomail.io/api/v1/identity', {
  headers: {
    'Authorization': `Bearer ${apiKey}`,
    'Content-Type': 'application/json'
  }
})
```

### Python Example

```python
import requests

api_key = 'your-api-key-here'
headers = {
    'Authorization': f'Bearer {api_key}',
    'Content-Type': 'application/json'
}

response = requests.get(
    'https://solomail.io/api/v1/identity',
    headers=headers
)
```

## Authentication Errors

### Invalid API Key

**Status**: `401 Unauthorized`

```json
{
  "error": "Invalid API key"
}
```

**Solutions**:
- Verify API key is correct (no extra spaces)
- Check key hasn't been revoked
- Generate a new key if needed

### Missing API Key

**Status**: `401 Unauthorized`

```json
{
  "error": "API key required"
}
```

**Solutions**:
- Include Authorization header
- Use Bearer token format
- Verify header name is correct

### Expired or Revoked Key

**Status**: `401 Unauthorized`

```json
{
  "error": "API key has been revoked"
}
```

**Solutions**:
- Generate a new API key
- Check key hasn't been revoked
- Verify key is still active

## Rate Limits

### Rate Limit Headers

API responses include rate limit information:

```
X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 999
X-RateLimit-Reset: 1640995200
```

### Rate Limits by Plan

| Plan | Requests/Day |
|------|--------------|
| **Free** | 100 |
| **Solopreneur** | 1,000 |
| **Small Business** | 10,000 |
| **Enterprise** | Unlimited |

### Rate Limit Exceeded

**Status**: `429 Too Many Requests`

```json
{
  "error": "Rate limit exceeded",
  "retry_after": 3600
}
```

**Solutions**:
- Wait for rate limit reset
- Upgrade your plan for higher limits
- Optimize API usage

## Security Best Practices

### Protect Your Keys

- **Never share keys**: Keep keys private
- **Don't commit to git**: Never commit keys to version control
- **Use environment variables**: Store keys securely
- **Rotate regularly**: Generate new keys periodically

### Key Management

- **One key per integration**: Separate keys for different systems
- **Name descriptively**: Use clear key names
- **Revoke unused keys**: Remove keys you're not using
- **Monitor usage**: Watch for unusual activity

### Access Control

- **Limit permissions**: Only grant necessary permissions
- **Review regularly**: Check who has access
- **Revoke promptly**: Remove access when no longer needed
- **Monitor activity**: Watch for suspicious usage

- **Monitor activity**: Watch for suspicious usage

## Identity Scoping

User API keys are bound to a single Solo Identity. All API responses and mutations apply only to resources owned by that identity.

### What This Means

- **Agents, conversations, tasks, plans, and work orders** are only accessible when they belong to your identity
- **Cross-identity access** returns `404 Not Found` — this is intentional and protects other users' data
- **Identity override blocked**: You cannot pass a different `identityId` in a request body or query parameter when using a user-scoped key

### Example Error Responses

**404 — Resource not owned by your identity:**
```json
{
  "error": "Not Found",
  "message": "Resource not found or access denied"
}
```

**403 — Attempted identity override:**
```json
{
  "error": "Forbidden",
  "message": "Identity ID does not match authenticated identity"
}
```

## Next Steps

- Explore [API Endpoints](./endpoints.md)
- Learn about [Webhooks](./webhooks.md)
- See [API Examples](./examples.md)

---

**Version**: 1.1  
**Last Updated**: July 2026

