# Partner API (https://webmetic.de/docs/en/partner/partner-api)

The Partner API connects your own system to your [partner area](https://webmetic.de/docs/en/partner).

The endpoints sit under `https://hub.webmetic.de`, like the rest of the [API](https://webmetic.de/docs/en/api). They are also part of the [API reference](https://webmetic.de/docs/en/api/referenz/partner/create-customer), where you can try each endpoint in the Playground.

In the Playground you need the key of your partner account. The partner endpoints reject the prefilled [demo key](https://webmetic.de/docs/en/api/schnellstart#try-it-without-an-account) with status `403`. With your key every request is real: `POST /partner/create-customer` creates a real customer, and `DELETE` really removes a website.

## Access [#access]

The Partner API needs an account with a partner area. How to become a partner is described under [Partners](https://webmetic.de/docs/en/partner).

The Partner API uses the **Visitor Intelligence** key of your partner account, not a separate partner key. Only admins find it under [**Menu** > **Integrations** > **API**](https://app.webmetic.de/?menu=api_details).

Send the key unchanged in the `Authorization` header, without a `Bearer` prefix. [Authentication](https://webmetic.de/docs/en/api/authentifizierung) describes its format and errors.

If the key belongs to an account without a partner area, the API answers with `NOT_A_PARTNER`.

When you regenerate the key, the old one stops working. This affects your partner requests and the requests for your own visit data.

Requests to the partner endpoints cost no credits.

## Endpoints [#endpoints]

| Method and path | Purpose | Requests per minute |
|---|---|---|
| [`POST /partner/create-customer`](https://webmetic.de/docs/en/api/referenz/partner/create-customer) | Create a customer | 10 |
| [`GET /partner/customers`](https://webmetic.de/docs/en/api/referenz/partner/customers) | List customers | 60 |
| [`GET /partner/customers/CUSTOMER_ACCOUNT_ID`](https://webmetic.de/docs/en/api/referenz/partner/customers-account-id) | Get one customer | 60 |
| [`POST /partner/customers/CUSTOMER_ACCOUNT_ID/websites`](https://webmetic.de/docs/en/api/referenz/partner/customers-account-id-websites) | Add a website | 30 |
| [`DELETE /partner/customers/CUSTOMER_ACCOUNT_ID/websites/DOMAIN`](https://webmetic.de/docs/en/api/referenz/partner/customers-account-id-websites-domain) | Remove a website | 30 |

The limits apply per endpoint. If you exceed a limit, the API answers with status `429`, and you repeat the request after a pause.

## New customer [#new-customer]

`POST /partner/create-customer` creates an account for your customer and takes a JSON body with these fields:

| Field | Type | Required | Description |
|---|---|---|---|
| `email` | String | yes | Email address of the first user. It must not belong to any Webmetic account yet |
| `website` | String | yes | Domain or full address of the website |
| `whitelabel` | Boolean | no | `true` creates a [white-label customer](https://webmetic.de/docs/en/partner/white-label). Default is `false` |

Webmetic cuts `website` down to the main domain and stores it in lower case. `https://www.Customer-Example.com/pricing` becomes `customer-example.com`, and so does `shop.customer-example.com`.

```bash tab="cURL"
curl -X POST "https://hub.webmetic.de/partner/create-customer" \
  -H "Authorization: wmtc_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"email": "contact@customer-example.com", "website": "customer-example.com", "whitelabel": true}'
```

```js tab="JavaScript"
const res = await fetch('https://hub.webmetic.de/partner/create-customer', {
  method: 'POST',
  headers: {
    Authorization: 'wmtc_YOUR_API_KEY',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    email: 'contact@customer-example.com',
    website: 'customer-example.com',
    whitelabel: true,
  }),
});
const customer = await res.json();
```

```python tab="Python"
import requests

res = requests.post(
    "https://hub.webmetic.de/partner/create-customer",
    headers={"Authorization": "wmtc_YOUR_API_KEY"},
    json={
        "email": "contact@customer-example.com",
        "website": "customer-example.com",
        "whitelabel": True,
    },
)
customer = res.json()
```

The response contains the login details of the new account:

```json
{
  "account_id": "CUSTOMER_ACCOUNT_ID",
  "email": "contact@customer-example.com",
  "password": "pX7kTq2mWb9R",
  "api_key": "wmtc_CUSTOMER_API_KEY",
  "status": "partner_trial",
  "account_type": "partner_customer",
  "website": "customer-example.com",
  "whitelabel": true
}
```

The account has one user with the Admin role and a random password. Store the password right away, because Webmetic never returns it a second time.

Because Webmetic sends no login details when you create a customer through the API, you pass the email address and password on to your customer yourself.

Your customer can sign in with them at once, also on your [white-label domain](https://webmetic.de/docs/en/partner/white-label-domain).

You invoice the new customer. A white-label customer sees the features you turn on under [Choose features for customers](https://webmetic.de/docs/en/partner/funktionen-fuer-kunden).

Through the API you set `whitelabel` only at creation, and later you change the value on the customer page in the dashboard.

Data only arrives once the tracking code with the customer's account ID runs on their website. How to hand over the code is described under [Add customers](https://webmetic.de/docs/en/partner/kunden-anlegen).

## Customer list and single customer [#customer-list-and-single-customer]

`GET /partner/customers` returns all customers of your partner account, newest first. The list also includes customers you created in the dashboard.

| Parameter | Type | Default | Description |
|---|---|---|---|
| `limit` | Integer | `100` | Customers per page, 1 to 500 |
| `offset` | Integer | `0` | How many customers the response skips |

`count` is the number of customers on this page, `total` the number of all customers. To page on, raise `offset` by `limit` until `offset` reaches `total`.

```json
{
  "customers": [
    {
      "account_id": "CUSTOMER_ACCOUNT_ID",
      "account": "customer-example",
      "email": "contact@customer-example.com",
      "status": "partner_trial",
      "account_type": "partner_customer",
      "api_key": "wmtc_CUSTOMER_API_KEY",
      "websites": ["customer-example.com"],
      "usage": [],
      "whitelabel": true,
      "created_at": "2026-10-22T09:14:03.512000"
    }
  ],
  "count": 1,
  "total": 1,
  "limit": 100,
  "offset": 0,
  "partner_account_id": "YOUR_ACCOUNT_ID"
}
```

`GET /partner/customers/CUSTOMER_ACCOUNT_ID` returns one customer with the same fields. For an unknown account ID and for another partner's customer the API answers the same way: `404` with `CUSTOMER_NOT_FOUND`.

## Customer fields [#customer-fields]

| Field | Description |
|---|---|
| `account_id` | The customer's account ID |
| `account` | Name of the website without its ending, set at creation |
| `email` | Email address of the first user, otherwise `null` |
| `status` | State of the account. A customer created through the API has `partner_trial`. If Webmetic invoices the customer, other values occur, for example `trial` |
| `account_type` | Who invoices: `partner_customer` means you, `partner_direct` means Webmetic |
| `api_key` | The customer's own API key |
| `websites` | The customer's domains in the stored spelling |
| `usage` | Monthly volume per billing period, empty for new customers |
| `whitelabel` | Whether the customer is a white-label customer. This only takes effect while you invoice them |
| `created_at` | Time of creation in ISO 8601 without a time zone |

Base your logic on `account_type`, not on `status`, because `account_type` is the field that says who invoices.

An entry in `usage` contains these fields, among others:

| Field | Description |
|---|---|
| `period` | Billing period as `YYYY-MM-DD_YYYY-MM-DD` |
| `company_count` | Companies identified in the period so far |
| `estimate` | Companies expected for 30 days. Only in the running period |
| `confidence` | Reliability of the estimate from `excellent` to `very_low`, or `no_data`. Only in the running period |

The dashboard also shows a customer's account ID and API key under [**Menu** > **Partner area** > **Customers**](https://app.webmetic.de/?menu=partner_customers), on the customer page under **Account details**.

## Customer websites [#customer-websites]

`POST /partner/customers/CUSTOMER_ACCOUNT_ID/websites` adds a website, with the body `{"website": "customer-example.com"}`. Webmetic cuts the value down to the main domain, as at creation.

If the customer already has this domain or another Webmetic account uses it, the API answers with `409`. This also applies to subdomains, because Webmetic collects them under the main domain, see [Track subdomains](https://webmetic.de/docs/en/installation/sonderfaelle#track-subdomains).

`DELETE /partner/customers/CUSTOMER_ACCOUNT_ID/websites/DOMAIN` removes a domain, written exactly as `websites` shows it.

Webmetic only removes the entry and deletes no visit data. The account stays in place, even when it has no website left.

Both endpoints answer with the full list:

`{"account_id": "CUSTOMER_ACCOUNT_ID", "websites": ["customer-example.com"]}`

## Your customers' visit data [#your-customers-visit-data]

With your key you read the visit data of every domain listed in `websites` of one of your customers. This covers `/company-sessions`, `/company`, `/company_nace`, `/session`, `/session_user_data`, `/intensive-visits`, `/returning-visits` and `/new-visits`.

You get the same data as with the customer's key. Parameters, paging and responses are the same as in the [API reference](https://webmetic.de/docs/en/api/referenz/visitor-intelligence/company-sessions).

The same limit of one request per second per endpoint applies, along with these rules:

- Pass `domain` exactly in the stored spelling: without `https://`, without `www.`, in the same upper and lower case. Otherwise the API answers with `403` and `API_KEY_NOT_AUTHORIZED`.
- `/company` accepts `domain` several times and merges the companies of several customers. The response does not say which customer a company belongs to.
- The limits of the customer's account apply. If Webmetic invoices the customer and they are on the Free plan, some companies are hidden.
- After you remove a domain, requests for it answer with `API_KEY_NOT_AUTHORIZED`, with your key and with the customer's.

Your key does not reach contacts and Enrichment, so for [Contacts](https://webmetic.de/docs/en/api/referenz/contacts/search) you use the customer's own `api_key`.

Searching for contacts needs the contacts setup in the customer's dashboard. Unlocking an email address or phone number costs their credits.

[Enrichment](https://webmetic.de/docs/en/api/referenz/enrichment/company) uses the Enrichment key of the account in question.

## Errors [#errors]

Errors have the same format as in the rest of the API, for example status `404` for an unknown account ID:

```json
{
  "detail": {
    "error": "CUSTOMER_NOT_FOUND",
    "message": "No customer with this account id."
  }
}
```

Check the code in `detail.error`. The English text in `detail.message` is meant for people and can change. For details, see [Errors](https://webmetic.de/docs/en/api/fehler).

| Status | `detail.error` | Meaning |
|---|---|---|
| `400` | `INVALID_WEBSITE` | No domain with a valid ending, for example `localhost` or an IP address |
| `403` | `API_KEY_MISSING` | No `Authorization` header |
| `403` | `API_KEY_INVALID` | Wrong format, for example a `Bearer` prefix |
| `403` | `API_KEY_NOT_FOUND` | The key does not exist, for example because a new one was generated |
| `403` | `NOT_A_PARTNER` | The key belongs to an account without a partner area |
| `404` | `CUSTOMER_NOT_FOUND` | Unknown account ID or another partner's customer |
| `404` | `WEBSITE_NOT_FOUND` | The customer does not have this domain |
| `409` | `EMAIL_ALREADY_EXISTS` | A Webmetic account already uses the email address |
| `409` | `WEBSITE_ALREADY_EXISTS` | At creation: another Webmetic account uses the website. When adding: the customer already has it, or another Webmetic account uses it |
| `422` | `VALIDATION_ERROR` | A required field is missing, the email address is invalid, or `limit` or `offset` is out of range. The `errors` list names each problem |
| `429` | `RATE_LIMITED` | More requests per minute than the endpoint accepts. Wait and repeat the request |
| `500` | `INTERNAL_ERROR` | Error at Webmetic. Repeat the request later |

## Limitations [#limitations]

- The Partner API sends no webhooks, so you fetch new data per domain. Webhooks exist per Webmetic account. For details, see [Webhooks](https://webmetic.de/docs/en/api/webhooks).
- You set up the white-label domain, branding and features for customers in the dashboard.
- You change who invoices a customer on the customer page in the dashboard.
- Only the response at creation contains a customer's password.

## Next steps [#next-steps]

- [Add customers](https://webmetic.de/docs/en/partner/kunden-anlegen): Hand over the tracking code with the customer's account ID.
- [Manage customers](https://webmetic.de/docs/en/partner/kunden-verwalten): Check monthly volume, billing and users of your customers in the dashboard.
- [Authentication](https://webmetic.de/docs/en/api/authentifizierung): Look up the key format and every key error.
