# Authentication (https://webmetic.de/docs/en/api/authentifizierung)

An API key stands for your whole account. If your CRM fetches yesterday's visits every night, for example, it sends the **Visitor Intelligence** key. Webmetic then returns the companies that visited your websites.

The API has no users, roles, or `Bearer` tokens. Whoever has the key reads all of the account's data.

## What the API checks [#what-the-api-checks]

On the visit endpoints, Webmetic checks every request in this order and stops at the first error:

1. **Header**: If the `Authorization` header is missing, the API answers with `API_KEY_MISSING`.
2. **Format**: If the format is wrong, for example because of a `Bearer` prefix, `API_KEY_INVALID` follows.
3. **Key**: If the key belongs to no account, `API_KEY_NOT_FOUND` follows.
4. **Domain**: If `domain` does not belong to this account, `API_KEY_NOT_AUTHORIZED` follows.

## The three keys [#the-three-keys]

Admins find the keys under [**Menu** > **Integrations** > **API**](https://app.webmetic.de/?menu=api_details). Other users don't see the **API keys** window and ask an admin for the key. If a partner manages your account, the partner decides whether **API** appears in the menu.

| Key | Covers | Plan |
| --- | --- | --- |
| **Visitor Intelligence** | The visit endpoints such as `/company` and `/company-sessions`, contacts (`/contacts/*`), and webhooks (`/webhooks*`) | Every plan |
| **Enrichment** | Every endpoint under `/enrichment/*` | Generate only during the trial, on Growth, and on Enterprise |
| [**Data Layer**](https://webmetic.de/docs/en/data-layer) | Company lookup on your server, for example for the [Matomo plugin](https://webmetic.de/docs/en/integrationen/matomo-plugin) | Matomo plugin: every plan. Your own server: Enterprise |

Webmetic creates the **Visitor Intelligence** key at sign-up. If a card shows the note **No key generated yet.**, click **Generate key**. The **Copy** icon copies the whole key, even while it is masked.

Each key only works on its own endpoints. If you send the **Visitor Intelligence** key to `/enrichment/*`, for example, the API answers with `ENRICHMENT_KEY_NOT_FOUND`.

A key starts with `wmtc_`, followed by 32 letters and digits, an underscore, and an eight-character checksum. All three keys use this format.

The exception is the public demo key `wmtc_demo`, which Webmetic recognizes as a fixed value. It's for testing only, works on every endpoint, and returns invented data. For details, see [Try it without an account](https://webmetic.de/docs/en/api/schnellstart#try-it-without-an-account).

## Key in the header [#key-in-the-header]

Send the key unchanged in the `Authorization` header, without a `Bearer` prefix.

```bash tab="cURL" tab-group="lang"
curl "https://hub.webmetic.de/company?domain=your-website.com&page_size=3" \
  -H "Authorization: wmtc_YOUR_API_KEY"
```

```js tab="JavaScript" tab-group="lang"
const res = await fetch(
  'https://hub.webmetic.de/company?domain=your-website.com&page_size=3',
  { headers: { Authorization: 'wmtc_YOUR_API_KEY' } },
);
const data = await res.json();
```

```python tab="Python" tab-group="lang"
import requests

res = requests.get(
    "https://hub.webmetic.de/company",
    params={"domain": "your-website.com", "page_size": 3},
    headers={"Authorization": "wmtc_YOUR_API_KEY"},
)
data = res.json()
```

On the visit endpoints, `domain` must belong to your account. Enter the domain exactly as it appears under [**Menu** > **Websites**](https://app.webmetic.de/?menu=websites).

With the key of a partner account you also read your customers' domains. For details, see [Partner API](https://webmetic.de/docs/en/partner/partner-api).

<Callout type="warn" title="The key does not belong in the browser">
Don't put your API key into code that runs on your website or in the browser. Whoever has the key reads your account's data and can use credits for contact data.
</Callout>

## New key [#new-key]

If a key has fallen into the wrong hands, generate a new one. The old key stops working at once. This cannot be undone.

1. In the key's card, click **Regenerate**. For three seconds the button asks for confirmation.
2. Click it again within that time. Webmetic shows the new key.

From now on, the API answers requests that use the old key with `API_KEY_NOT_FOUND`.

Enter the new key everywhere the old one was used: in n8n, Make, Zapier, and your own scripts. If you regenerated the **Data Layer** key, enter it in the Matomo plugin too.

Your webhooks keep running, because they belong to the account and not to the key.

You can only regenerate the **Enrichment** key during the trial, on Growth, and on Enterprise.

On Starter and Free it can't be replaced, but an existing key keeps reading your lists. This doesn't apply if your account can't use Enrichment at all, for example after a cancellation (`ACCOUNT_NOT_ELIGIBLE`).

## Key errors [#key-errors]

If something is wrong with the key, the API answers with status `403`. The body has the same shape as every API error:

```json
{
  "detail": {
    "error": "API_KEY_MISSING",
    "message": "Send your API key in the Authorization header."
  }
}
```

Evaluate `detail.error` in your code. The text in `detail.message` is meant for people and can change.

| Code | Meaning |
| --- | --- |
| `API_KEY_MISSING` | The request has no `Authorization` header |
| `API_KEY_INVALID` | The format is wrong, for example because of a `Bearer` prefix or a typo in the key |
| `API_KEY_NOT_FOUND` | No account has this key. This happens after a new key was generated or with the **Enrichment** key |
| `API_KEY_NOT_AUTHORIZED` | The `domain` does not belong to your account or is written differently |
| `ENRICHMENT_KEY_MISSING`, `ENRICHMENT_KEY_INVALID`, `ENRICHMENT_KEY_NOT_FOUND` | The same errors for the **Enrichment** key on `/enrichment/*` |
| `ACCOUNT_NOT_ELIGIBLE` | Your account cannot use Enrichment at the moment, for example after a cancellation |

A request with a valid key can still fail because of the plan. The API returns `PLAN_REQUIRED` in two places only.

Without Growth, Enrichment refuses new lists, new domains, and single lookups. On `/contacts/*`, the error concerns companies that are hidden on the Free plan.

Every other error code is listed under [Errors](https://webmetic.de/docs/en/api/fehler).

## Next steps [#next-steps]

- [Quickstart](https://webmetic.de/docs/en/api/schnellstart): Send your first request and read the response.
- [Errors](https://webmetic.de/docs/en/api/fehler): Every API error code with cause and fix.
- [Rate limits](https://webmetic.de/docs/en/api/anfragelimits): How many requests the visit endpoints accept.
