---
seo_title: Private API Keys — X-API-Key Header Authentication | EnConvert
meta_desc: Authenticate server-to-server with sk_ private keys in the X-API-Key header. Full access to sync, async, and batch endpoints like POST /v1/convert/json-to-xml.
keywords: x-api-key header authentication, private api key sk_ prefix, server-to-server api authentication, restrict api key to specific endpoints, api key sha-256 hashed storage, api key rotation without downtime, curl x-api-key example, 403 forbidden allowed_endpoints
---

# Private API Keys (X-API-Key Authentication)

Private keys (`sk_`) authenticate server-to-server requests to the Enconvert API: include the key in the `X-API-Key` header on every request, with no token exchange or session management required. They grant full access to all endpoints — synchronous and asynchronous conversions, batch processing, job status polling, and webhooks — and conversion responses return a `presigned_url` for downloading the converted file. Use them in any environment where the key can be kept confidential.

## Header Format

Include your private key in the `X-API-Key` header with every request:

```
X-API-Key: sk_your_private_key
```

Private keys always begin with the `sk_` prefix. You can generate and manage your keys from the Enconvert dashboard.

## Usage

Private keys grant access to all API endpoints and features, including:

- All synchronous and asynchronous conversion endpoints
- Batch processing
- Job status polling and webhook notifications
- File uploads and URL-based conversions

No token exchange or session management is required. Simply include the key in each request.

## Example: File Conversion

Convert a JSON file to XML using a private key:

### cURL

```bash
curl -X POST https://api.enconvert.com/v1/convert/json-to-xml \
  -H "X-API-Key: sk_your_private_key" \
  -F "file=@data.json"
```

### Response

```json
{
  "presigned_url": "https://econverter.nyc3.cdn.digitaloceanspaces.com/...",
  "object_key": "live/files/12345/json-to-xml/data_20250202_120530123.xml",
  "filename": "data_20250202_120530123.xml",
  "file_size": 1024,
  "conversion_time_seconds": 0.45
}
```

- `presigned_url` -- A temporary, downloadable URL for retrieving the converted file.
- `object_key` -- The storage path of the converted file (e.g., `live/files/12345/json-to-xml/...`). This is not a URL.
- `filename` -- The generated filename for the converted file.
- `file_size` -- The size of the output file in bytes.
- `conversion_time_seconds` -- The time taken to complete the conversion.

## Endpoint Restrictions

By default, a private key has access to all API endpoints. You can optionally restrict a key to specific endpoints using the **allowed_endpoints** setting in your dashboard.

When `allowed_endpoints` is configured, the key will only be able to call the listed endpoints. Requests to any other endpoint will be rejected with a `403 Forbidden` error.

Example configuration:

```json
{
  "allowed_endpoints": [
    "/v1/convert/url-to-pdf",
    "/v1/convert/json-to-xml",
    "/v1/convert/html-to-pdf"
  ]
}
```

This is useful when you want to issue a key with limited scope, for example, a key that can only perform PDF conversions.

## Security

- **Hashed storage:** Private keys are stored on the server as SHA-256 hashes. The plaintext key is displayed only once at creation time. If you lose it, you must generate a new key.
- **Key rotation:** You can create multiple keys and revoke old ones at any time from the dashboard without downtime.
- **Environment variables:** Store your key in an environment variable (e.g., `ENCONVERT_API_KEY`) rather than hardcoding it in your source code.

<div class="alert alert-warning">
<strong>Do not use private keys in client-side code.</strong> The API detects the <code>Origin</code> header sent by browsers and will reject requests made with a private key from a browser environment. For client-side integrations, use a <a href="public-keys-jwt">public key with JWT</a> instead.
</div>

## Frequently asked questions

### How do I authenticate API requests with the X-API-Key header?

Include your private key in the `X-API-Key` header on every request, for example `X-API-Key: sk_your_private_key`. Private keys always begin with the `sk_` prefix, and no token exchange or session management is required.

### Can I restrict a private API key to specific endpoints?

Yes. Configure the `allowed_endpoints` setting for the key in your dashboard, listing paths such as `/v1/convert/url-to-pdf`. Requests to any endpoint not on the list are rejected with a `403 Forbidden` error.

### Why does my sk_ private key get rejected from a browser?

The API detects the `Origin` header sent by browsers and rejects requests made with a private key from a browser environment. For client-side integrations, use a public key with JWT instead.

### What happens if I lose my private API key?

Private keys are stored on the server as SHA-256 hashes, and the plaintext key is displayed only once at creation time — if you lose it, you must generate a new key. You can create multiple keys and revoke old ones from the dashboard without downtime.

### How should I store my API key securely?

Store the key in an environment variable (e.g., `ENCONVERT_API_KEY`) rather than hardcoding it in your source code, and never use it in client-side code such as browsers or mobile apps.
