# Authentication

All Verso API requests require authentication using a Bearer token. This guide explains how to obtain and use your API credentials.

## API Key Authentication

Verso uses API key-based authentication. Your API key acts as a Bearer token that must be included in every request.

### Header Format

Include your API key in the `Authorization` header:

```http title="Authorization Header"
Authorization: Bearer YOUR_API_KEY
```

### Example Request

```bash title="Authenticated Request"
curl -X GET "https://api.versohq.io/partners/5/tenants/10/users" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json"
```

## Partner API Keys

Your API key is associated with your **Partner account** and grants access to all tenants you manage.

### How It Works

1. **Partner Account**: Verso creates a partner account for your organization (e.g., Partner ID `5`)
2. **API Key Creation**: Verso generates an API key linked to your Partner ID
3. **Tenant Registration**: You register tenants for each client you serve
4. **Scoped Access**: Every API call requires both `partnerId` and `tenantId` in the URL

### Partner ID Validation

The `partnerId` in the URL **must match** the Partner ID associated with your API key. If there's a mismatch, you'll receive a `403 Forbidden` error.

**Example:**
```bash
# Correct: API key belongs to Partner 5
curl -X GET "https://api.versohq.io/partners/5/tenants/10/employees" \
  -H "Authorization: Bearer YOUR_API_KEY"

# Incorrect: API key belongs to Partner 5, but URL uses Partner 3
curl -X GET "https://api.versohq.io/partners/3/tenants/10/employees" \
  -H "Authorization: Bearer YOUR_API_KEY"
# Returns: 403 Forbidden
```

## Obtaining API Keys

### Development Environment

To access the development environment:

1. Contact your account manager at Verso to create your **Partner account**
2. Receive your credentials:
   - **Partner ID** (e.g., `5`)
   - **API Key** (Bearer token linked to your Partner ID)
   - **Division ID** (default for your tenants)
   - **Payroll ID** (default payroll configuration)
3. Use the base URL: `https://api.versohq.io`

:::tip
Your API key is automatically scoped to your Partner ID. You don't need to manually specify the Partner ID in headers - it's validated from the API key metadata.
:::

### Production Environment

For production access:

1. Complete your integration testing
2. Request production credentials from your account manager
3. Use the production base URL: `https://api.verso.io`

:::warning
Never share your API keys or commit them to version control. Use environment variables to store credentials securely.
:::

## Security Best Practices

### Store Keys Securely

```bash title="Environment Variable"
export VERSO_API_KEY="your-api-key-here"
```

```bash title="Using Environment Variable"
curl -X GET "https://api.versohq.io/partners/5/tenants/10/users" \
  -H "Authorization: Bearer $VERSO_API_KEY"
```

### Key Rotation

- Rotate API keys periodically
- Immediately revoke compromised keys by contacting support
- Use separate keys for development and production

### Network Security

- Always use HTTPS (TLS 1.2+)
- Implement IP allowlisting when possible
- Monitor API usage for anomalies

### API Access Mode

Verso API is designed for **server-to-server** communication. Direct browser calls (from SPAs or frontend JavaScript) are not supported due to CORS restrictions. Always route API calls through your backend server.

## API Routes

All Verso API endpoints follow the partner route pattern:

```
/partners/{partnerId}/tenants/{tenantId}/{resource}
```

**Example:**
```bash
curl -X GET "https://api.versohq.io/partners/5/tenants/10/employees" \
  -H "Authorization: Bearer YOUR_API_KEY"
```

### Route Parameters

| Parameter | Description | Example |
|-----------|-------------|---------|
| `partnerId` | Your partner identifier (must match your API key) | `5` |
| `tenantId` | The tenant (client) you're accessing | `10` |
| `resource` | The API resource (users, employees, payrolls, etc.) | `employees` |

### Access Control

**Partner Validation:**
- The `partnerId` in the URL **must match** your API key's Partner ID
- Mismatch results in `403 Forbidden`

**Tenant Validation:**
- You can only access tenants registered to your partner account
- Create tenants using: `POST /partners/{partnerId}/tenants` (the authenticated partner supplies a stable `externalId`; Verso creates and associates the PayrollEngine tenant)

**Multi-Tenant Isolation:**
- Each tenant's data is completely isolated
- Your API key grants access to all your registered tenants
- Cross-tenant access is not possible

## Error Responses

### 401 Unauthorized

```json
{
  "type": "https://httpproblems.com/http-status/401",
  "title": "Unauthorized",
  "status": 401,
  "detail": "No Authorization Header",
  "instance": "/partners/5/tenants/10/users",
  "trace": {
    "timestamp": "2026-01-07T10:00:00.000Z",
    "requestId": "...",
    "buildId": "...",
    "rayId": "..."
  }
}
```

**Causes:**
- Missing `Authorization` header
- Invalid API key
- Expired API key

### 403 Forbidden

```json
{
  "type": "https://httpproblems.com/http-status/403",
  "title": "Forbidden",
  "status": 403,
  "detail": "Partner ID in path does not match authenticated partner",
  "instance": "/partners/3/tenants/10/users",
  "trace": {
    "timestamp": "2026-01-07T10:00:00.000Z",
    "requestId": "...",
    "buildId": "...",
    "rayId": "..."
  }
}
```

**Common Causes:**

1. **Partner ID mismatch**
   - Problem: `partnerId` in URL doesn't match your API key
   - Solution: Verify your Partner ID with your account manager

2. **No tenant access**
   - Problem: Partner lacks access to the requested tenant
   - Solution: Create the tenant using `POST /partners/{partnerId}/tenants`, or contact Verso Ops to reactivate a deliberately dissociated tenant

3. **Insufficient permissions**
   - Problem: Operation requires admin role
   - Solution: Contact Verso support to verify your API key permissions

4. **Tenant not registered**
   - Problem: Tenant was unregistered or never registered to your partner account
   - Solution: Register the tenant again or contact support

## Next Steps

- [Quickstart](/quickstart) - Run your first payroll
- [Error Handling](/guides/error-handling) - Understanding API errors
- [API Reference](/api) - Explore all endpoints
