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

# Authentication

> How to authenticate with the Docyard API

# Authentication

Docyard uses API key authentication for all endpoints. This guide explains how to authenticate as a distributor or collector.

## API Key Authentication

All API requests require authentication headers:

```bash theme={null}
curl -X POST https://api.docyard.io/v1/upload/artifacts \
  -H "X-API-Key: your_api_key" \
  -H "X-API-Secret: your_api_secret" \
  -H "Content-Type: application/json" \
  -d '{ ... }'
```

## Authentication Headers

| Header         | Description     | Example                  |
| -------------- | --------------- | ------------------------ |
| `X-API-Key`    | Your API key    | `dk_live_xxxxxxxxxxxx`   |
| `X-API-Secret` | Your API secret | `dk_secret_xxxxxxxxxxxx` |

## Key Types

### Distributor Keys

Obtained when creating an upload endpoint:

```json theme={null}
{
  "upload endpoint_id": "upload endpoint-abc123",
  "api_key": "dk_live_dist_xxxxxxxxxxxx",
  "api_secret": "dk_secret_dist_xxxxxxxxxxxx"
}
```

**Prefix**: `dk_live_dist_` (production) or `dk_test_dist_` (sandbox)

### Collector Keys

Obtained when creating a dock:

```json theme={null}
{
  "dock_id": "dock-xyz789",
  "api_key": "dk_live_coll_aaaaaaaa",
  "api_secret": "dk_secret_coll_bbbbbbbb"
}
```

**Prefix**: `dk_live_coll_` (production) or `dk_test_coll_` (sandbox)

## Authentication Errors

### Missing Credentials

```json theme={null}
{
  "error": "authentication_required",
  "message": "API key and secret are required"
}
```

### Invalid Key

```json theme={null}
{
  "error": "invalid_api_key",
  "message": "The provided API key is invalid"
}
```

### Invalid Secret

```json theme={null}
{
  "error": "invalid_api_secret",
  "message": "The provided API secret is incorrect"
}
```

### Expired Keys

```json theme={null}
{
  "error": "api_key_expired",
  "message": "The API key has expired. Please rotate your keys."
}
```

### Revoked Keys

```json theme={null}
{
  "error": "api_key_revoked",
  "message": "The API key has been revoked"
}
```

## Key Rotation

Rotate your API keys regularly for security.

### Rotate Distributor Keys

```bash theme={null}
curl -X POST https://api.docyard.io/v1/upload endpoints/upload endpoint-abc123/rotate-keys \
  -H "X-API-Key: dk_live_dist_xxxxxxxxxxxx" \
  -H "X-API-Secret: dk_secret_dist_xxxxxxxxxxxx"
```

**Response:**

```json theme={null}
{
  "new_api_key": "dk_live_dist_yyyyyyyyyyyy",
  "new_api_secret": "dk_secret_dist_yyyyyyyyyyyy",
  "old_key_expires_at": "2026-03-16T10:30:00Z"
}
```

### Rotate Collector Keys

```bash theme={null}
curl -X POST https://api.docyard.io/v1/docks/dock-xyz789/rotate-keys \
  -H "X-API-Key: dk_live_coll_aaaaaaaa" \
  -H "X-API-Secret: dk_secret_coll_bbbbbbbb"
```

## Environment-Based Keys

### Production Keys

```
dk_live_*
```

* Used for real transactions
* Rate limits apply
* Full access

### Test/Sandbox Keys

```
dk_test_*
```

* Used for development
* Higher rate limits available
* Test data only

## Best Practices

### 1. Store Keys Securely

Never commit API keys to version control:

```bash theme={null}
# .gitignore
api_keys.txt
.env
```

Use environment variables:

```bash theme={null}
export DOCYARD_API_KEY="dk_live_xxxxxxxxxxxx"
export DOCYARD_API_SECRET="dk_secret_xxxxxxxxxxxx"
```

### 2. Use Separate Keys Per Environment

```bash theme={null}
# Development
export DOCYARD_API_KEY="dk_test_dist_xxxxxxxxxxxx"

# Production
export DOCYARD_API_KEY="dk_live_dist_xxxxxxxxxxxx"
```

### 3. Rotate Keys Regularly

Set a calendar reminder to rotate keys every 90 days.

### 4. Limit Key Scope

Use the least permissive keys necessary. Distributor keys shouldn't be used for collector actions and vice versa.

## Code Examples

### Node.js

```javascript theme={null}
const docyard = require('docyard-sdk');

const client = new docyard.Client({
  apiKey: process.env.DOCYARD_API_KEY,
  apiSecret: process.env.DOCYARD_API_SECRET
});

// Upload artifact
const artifact = await client.upload endpoint.upload({
  templateId: 'tmpl-abc123',
  locks: {
    policy_number: { value: 'POL-12345678' }
  },
  threshold: 20,
  content: pdfBuffer
});
```

### Python

```python theme={null}
import docyard

client = docyard.Client(
    api_key=os.environ['DOCYARD_API_KEY'],
    api_secret=os.environ['DOCYARD_API_SECRET']
)

# Upload artifact
artifact = client.upload endpoint.upload(
    template_id='tmpl-abc123',
    locks={
        'policy_number': {'value': 'POL-12345678'}
    },
    threshold=20,
    content=pdf_bytes
)
```

### Go

```go theme={null}
import "github.com/docyard/docyard-go"

client := docyard.NewClient(
    os.Getenv("DOCYARD_API_KEY"),
    os.Getenv("DOCYARD_API_SECRET"),
)

// Upload artifact
artifact, err := client.Upload.Upload(&docyard.UploadRequest{
    TemplateID: "tmpl-abc123",
    Locks: map[string]LockValue{
        "policy_number": {Value: "POL-12345678"},
    },
    Threshold: 20,
    Content:   pdfBytes,
})
```

## Rate Limits

Rate limits are applied per API key:

| Endpoint Type        | Limit | Window     |
| -------------------- | ----- | ---------- |
| Upload (distributor) | 100   | per minute |
| Search (collector)   | 300   | per minute |
| Retrieve (collector) | 100   | per minute |

When rate limited, you'll receive:

```json theme={null}
{
  "error": "rate_limit_exceeded",
  "message": "Too many requests. Please retry after 60 seconds.",
  "retry_after": 60
}
```

***

## Next Steps

* **[Errors](/introduction/errors)** - Error handling
* **[API Reference](/api-reference/overview)** - Full API documentation
