# Authentication

> Every request needs an API key, sent as a Bearer token in the Authorization header.

Page: https://developers.zactonz.com/apis/authentication/

Every endpoint on `api.zactonz.com` requires an API key. Send it on each request in the `Authorization` header using the Bearer scheme:

```text
Authorization: Bearer YOUR_API_KEY
```

There are no other credentials, sessions or signatures to manage.

## Example

```bash
curl "https://api.zactonz.com/qr/enc/?content=https://zactonz.com" \
  -H "Authorization: Bearer YOUR_API_KEY"
```

```php
<?php
$ch = curl_init('https://api.zactonz.com/qr/enc/?content=' . rawurlencode('https://zactonz.com'));
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER     => ['Authorization: Bearer YOUR_API_KEY'],
]);
$result = json_decode(curl_exec($ch), true);
```

Every reference page's samples include the header.

## Getting a key

Create an account in the [API console](https://developers.zactonz.com/console/signup) and issue a key for each product you use. A key is scoped to the product it was created for, so a QR key cannot call Screenshot; calls outside that scope are rejected with `403`. Keeping one key per product means a leaked key can be rotated or revoked without touching your other integrations.

The console shows a new key once. Rotating a key issues a replacement and keeps the old one working for seven days, or stops it immediately if you choose. Revoking a key stops it at once.

## Checking a key

`GET /auth/me/` with the Bearer header returns the key's product, state, plan and the quota remaining today and this month. Use it to confirm a rollout before you switch traffic.

```bash
curl "https://api.zactonz.com/auth/me/" \
  -H "Authorization: Bearer YOUR_API_KEY"
```

## Rejected requests

| status | Meaning |
|---|---|
| `401` | The `Authorization` header is missing, malformed, or the key is not recognised. |
| `403` | The key is valid but not licensed for this endpoint. |
| `406` | The key has expired. Contact support to renew it. |

The reply body follows the usual shape, with the reason in `message`:

```json
{ "status": 401, "message": "Missing or invalid API key" }
```

## Existing integrations

Translator and Mail Verifier also accept the key as a `key` form field. That form is kept so current integrations keep working; new code should send the header. The retired video endpoints take `key` as a query parameter only.

## Keep keys server-side

A key sent from browser JavaScript is visible to anyone who opens the developer tools. Call the APIs from your own backend and proxy the result to the browser. Rotate a key through support if it is ever exposed.
