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

# API Keys

> Create, manage, and revoke user API keys for programmatic authentication with the Sawmills platform using JWT tokens and REST API calls.

API keys provide a secure way to authenticate with the Sawmills platform. This guide covers how to create, manage, and use API keys for programmatic access to Sawmills services.

## Overview

Sawmills supports two types of API keys:

* **User API Keys**: Personal API keys that can be created by individual users for their own use
* **Organization API Keys**: System-level API keys for organization-wide access (currently only used by Sawmills itself)

This documentation focuses on **User API Keys**, which are the most commonly used for individual authentication.

## Obtaining Your JWT Token

Before creating API keys, you need to obtain a JWT token from the Sawmills UI. This token is used to authenticate your requests to the API.

### Method 1: Using Chrome DevTools

1. **Log in to Sawmills**: Open [https://app.sawmills.ai](https://app.sawmills.ai) in Chrome
2. **Open DevTools**: Press `F12` or right-click and select "Inspect"
3. **Go to Network Tab**: Click on the "Network" tab in DevTools
4. **Filter Requests**: In the filter box, type "api" to see API requests
5. **Find a Request**: Look for any request to `api.sawmills.ai` (you may need to navigate around the UI to trigger API calls)
6. **Check Headers**: Click on the request and look at the "Request Headers" section
7. **Copy the Token**: Find the `Authorization` header and copy the JWT token (the part after "Bearer ")

### Method 2: Using Application Storage

1. **Log in to Sawmills**: Open [https://app.sawmills.ai](https://app.sawmills.ai) in Chrome
2. **Open DevTools**: Press `F12` or right-click and select "Inspect"
3. **Go to Application Tab**: Click on the "Application" tab
4. **Check Local Storage**: In the left sidebar, expand "Local Storage" and click on the Sawmills domain
5. **Find Token**: Look for keys containing "token", "jwt", or "auth" and copy the JWT value

<Note>
  **Token Expiration**: JWT tokens expire after a certain period. If you get authentication errors, you may need to refresh the page and obtain a new token.
</Note>

## Creating a User API Key

### Prerequisites

* You must be authenticated with a valid Sawmills account
* You must have appropriate permissions to create API keys in your organization
* You need a JWT token from the Sawmills UI (see [Obtaining Your JWT Token](#obtaining-your-jwt-token) below)

### API Endpoint

```http theme={null}
POST /v1/user-api-keys
```

### Request Body

```json theme={null}
{
  "label": "My API Key"
}
```

**Parameters:**

* `label` (optional): A human-readable name for your API key (max 255 characters)

### Response

```json theme={null}
{
  "api_key": {
    "id": "123e4567-e89b-12d3-a456-426614174000",
    "organization_id": "org_123",
    "user_id": "user_456",
    "label": "My API Key",
    "status": "ACTIVE",
    "created_at": "2024-01-15T10:30:00Z",
    "updated_at": "2024-01-15T10:30:00Z",
    "last_used_at": null,
    "value": "sk_test.abc123def456.xyz789uvw012"
  },
  "opaque_key": "sk_test.abc123def456.xyz789uvw012"
}
```

<Warning>
  **Important**: The `opaque_key` and `value` fields are only returned once when the API key is created. Store this value securely as it cannot be retrieved later.
</Warning>

### Example: Creating an API Key with cURL

```bash theme={null}
curl -X POST "https://api.sawmills.ai/v1/user-api-keys" \
  -H "Authorization: Bearer YOUR_JWT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "label": "Production API Key"
  }'
```

<Note>
  **JWT Token**: Replace `YOUR_JWT_TOKEN` with the JWT token you obtain from the Sawmills UI. See [Obtaining Your JWT Token](#obtaining-your-jwt-token) for instructions.
</Note>

### Example: Creating an API Key with JavaScript

```javascript theme={null}
const response = await fetch('https://api.sawmills.ai/v1/user-api-keys', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer YOUR_JWT_TOKEN', // Replace with JWT from UI
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    label: 'My Application Key'
  })
});

const data = await response.json();
console.log('API Key created:', data.opaque_key);
```

## Managing API Keys

### Listing Your API Keys

```http theme={null}
GET /v1/user-api-keys
```

**Query Parameters:**

* `page` (optional): Page number for pagination (default: 1)
* `limit` (optional): Number of keys per page (default: 20, max: 100)
* `include_revoked` (optional): Include revoked keys in results (default: false)

### Getting a Specific API Key

```http theme={null}
GET /v1/user-api-keys/{id}
```

### Revoking an API Key

```http theme={null}
DELETE /v1/user-api-keys/{id}
```

<Note>
  Revoking an API key immediately invalidates it and prevents any further use. This action cannot be undone.
</Note>

## Security Best Practices

### Storage

* Store API keys in environment variables or secure key management systems
* Never commit API keys to version control
* Use different API keys for different environments (development, staging, production)

### Rotation

* Regularly rotate your API keys
* Use short-lived keys when possible
* Revoke unused or compromised keys immediately

## Error Handling

### Common Error Responses

**401 Unauthorized**

```json theme={null}
{
  "code": "UNAUTHENTICATED",
  "message": "user not authenticated"
}
```

**403 Forbidden**

```json theme={null}
{
  "code": "PERMISSION_DENIED",
  "message": "insufficient permissions"
}
```

**404 Not Found**

```json theme={null}
{
  "code": "NOT_FOUND",
  "message": "api key not found"
}
```

**400 Bad Request**

```json theme={null}
{
  "code": "INVALID_ARGUMENT",
  "message": "invalid request parameters"
}
```

## Troubleshooting

### API Key Not Working

1. **Check the format**: Ensure your API key follows the correct format
2. **Verify environment**: Make sure you're using the correct environment prefix
3. **Check status**: Ensure the API key is active and not revoked
4. **Verify scopes**: Confirm the API key has the required permissions

### Common Issues

**"Invalid API key format"**

* Check that the API key is correctly formatted
* Verify the key is complete and not truncated

**"API key revoked"**

* The API key has been revoked and cannot be used
* Create a new API key to continue

**"Invalid API key credentials"**

* The API key is malformed or corrupted
* Verify the key was copied correctly without extra characters

## Next Steps

Once you have created an API key, you can use it to obtain access tokens for authenticating with other Sawmills services. See [Obtaining Tokens](/docs/tokens) for more information.
