---
seo_title: API Key Authentication — X-API-Key & JWT Bearer | EnConvert
meta_desc: Authenticate with the Enconvert API using X-API-Key private keys (sk_) or exchange a public key (pk_) for a JWT via POST /v1/auth/token. Compare both methods.
keywords: api key authentication x-api-key header, jwt bearer token api authentication, public key client-side api auth, sk_ vs pk_ api keys, rest api authentication methods, server-to-server api key authentication, exchange public key for jwt token, file conversion api authentication
---

# API Key Authentication — X-API-Key and JWT Bearer Tokens

The Enconvert API supports two authentication methods: private keys (`sk_`) sent in the `X-API-Key` header for server-to-server integrations, and public keys (`pk_`) exchanged for a short-lived JWT bearer token via `POST /v1/auth/token` for client-side (browser) use. Private keys grant full access to all endpoints, while public keys are restricted to whitelisted domains and authenticate requests with an `Authorization: Bearer <token>` header. This page compares both flows so you can choose the method that matches your integration scenario.

## Overview

| Method | Key Prefix | Use Case | Auth Header |
|---|---|---|---|
| Private Keys | `sk_` | Server-to-server | `X-API-Key: sk_...` |
| Public Keys + JWT | `pk_` | Client-side (browsers) | `Authorization: Bearer <token>` |

## Private Keys

Private keys are intended for **server-side applications** where your API key can be kept secret. They provide full access to all API endpoints and features.

- **Header:** `X-API-Key: sk_your_private_key`
- **Access:** Full access to all endpoints, including sync and async operations, batch processing, and all conversion types.
- **Security:** Keys are stored as SHA-256 hashes on the server. The plaintext key is shown only once at creation time.

```bash
curl -X POST https://api.enconvert.com/v1/convert/url-to-pdf \
  -H "X-API-Key: sk_your_private_key" \
  -H "Content-Type: application/json" \
  -d '{"url": "https://example.com"}'
```

<div class="alert alert-warning">
<strong>Security Warning:</strong> Never use private keys (<code>sk_</code>) in client-side code such as browsers or mobile apps. The API detects the <code>Origin</code> header sent by browsers and will reject requests made with private keys from browser environments. Use public keys with JWT for client-side integrations instead.
</div>

For full details, see [Private Keys](private-keys).

## Public Keys + JWT

Public keys are designed for **client-side applications** running in browsers. Because the key is visible to end users, it cannot grant direct API access. Instead, the public key is exchanged for a short-lived JWT token, which is then used to authenticate subsequent requests.

- **Step 1:** Exchange your public key (`pk_`) for a JWT token via `POST /v1/auth/token`.
- **Step 2:** Use the JWT token in the `Authorization: Bearer <token>` header for API requests.
- **Step 3:** Refresh the token automatically before it expires using `POST /v1/auth/refresh`.
- **Domain whitelisting:** Public keys are restricted to requests originating from whitelisted domains, configured in your dashboard.

```javascript
// Step 1: Exchange public key for a short-lived JWT
const { token } = await fetch("https://api.enconvert.com/v1/auth/token", {
  method: "POST",
  headers: {
    "X-API-Key": "pk_live_your_public_key",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({}),
}).then((res) => res.json());

// Step 2: Convert URL to PDF using the JWT
const { presigned_url } = await fetch("https://api.enconvert.com/v1/convert/url-to-pdf", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${token}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ url: "https://example.com" }),
}).then((res) => res.json());

// Step 3: Download the PDF
window.open(presigned_url);

```

For full details, see [Public Keys + JWT](public-keys-jwt).

## Choosing the Right Method

- **Building a backend service, script, or internal tool?** Use a **private key** (`sk_`). It is simpler and gives full access.
- **Building a browser-based app or widget?** Use a **public key** (`pk_`) with JWT. It keeps your credentials safe and restricts access to whitelisted domains.

## Frequently asked questions

### How do I authenticate to a REST API with an X-API-Key header?

Send your private key in the `X-API-Key` header on every request, for example `X-API-Key: sk_your_private_key`. Private keys grant full access to all endpoints — including sync and async operations, batch processing, and all conversion types — with no token exchange required.

### What is the difference between sk_ and pk_ API keys?

Keys with the `sk_` prefix are private keys for server-to-server use and provide full API access via the `X-API-Key` header. Keys with the `pk_` prefix are public keys for client-side (browser) apps: they cannot call the API directly and must first be exchanged for a short-lived JWT via `POST /v1/auth/token`.

### Can I use my private API key (sk_) in a browser or mobile app?

No. The API detects the `Origin` header sent by browsers and rejects requests made with private keys from browser environments. Use a public key (`pk_`) with the JWT flow for client-side integrations instead.

### How do I get a JWT bearer token for client-side API authentication?

Exchange your public key (`pk_`) for a JWT by calling `POST /v1/auth/token` with the key in the `X-API-Key` header. Use the returned token in the `Authorization: Bearer <token>` header on API requests, and refresh it before expiry via `POST /v1/auth/refresh`.

### Which authentication method should I choose for my integration?

Use a private key (`sk_`) for backend services, scripts, or internal tools — it is simpler and gives full access. Use a public key (`pk_`) with JWT for browser-based apps or widgets, since it keeps credentials safe and restricts access to whitelisted domains.
