> ## Documentation Index
> Fetch the complete documentation index at: https://docs.crewpass.co.uk/llms.txt
> Use this file to discover all available pages before exploring further.

# Authentication

> Authenticate Partner API reads with your API key over TLS.

The Partner API v1 is a read surface. Every request authenticates with a single
credential:

* **An API key**, presented as a Bearer token over TLS. It identifies your
  partner account and carries your granted scopes.

There is no request body to sign on a read, so reads are **not** signed; the
Bearer key over TLS is the only credential you need.

## API keys

Keys are issued by CrewPass and look like:

| Prefix       | Meaning                                       |
| ------------ | --------------------------------------------- |
| `cpk_live_…` | Live key, operates on production data.        |
| `cpk_test_…` | Test-mode key, operates on test-flagged data. |

Present the key as a Bearer token (preferred) or in the `X-Partner-API-Key`
header:

```http theme={null}
Authorization: Bearer cpk_live_xxxxxxxxxxxxxxxxxxxxxxxx
```

Your granted scopes are **derived from your CrewPass plan**, so you do not manage
a separate API permission set. Call
[`GET /api/v2/partners/me`](/api-reference/overview) to see your identity and
full granted-scope list. It is the first call any partner makes.

<Warning>
  Keep your API key server-side. Never embed it in a browser or mobile app. Public
  read-only widget keys (`cppk_*`) are a separate surface and are not accepted here.
</Warning>

## Calling a read endpoint

Every v1 read takes the same Bearer header and nothing else:

<CodeGroup>
  ```bash cURL theme={null}
  curl -sS https://partners.crewpass.co.uk/api/v2/employers/me/vessels \
    -H "Authorization: Bearer $CPK_KEY"
  ```

  ```python Python theme={null}
  import httpx

  resp = httpx.get(
      "https://partners.crewpass.co.uk/api/v2/employers/me/vessels",
      headers={"Authorization": f"Bearer {CPK_KEY}"},
  )
  resp.raise_for_status()
  ```

  ```javascript Node theme={null}
  const resp = await fetch(
    "https://partners.crewpass.co.uk/api/v2/employers/me/vessels",
    { headers: { Authorization: `Bearer ${CPK_KEY}` } },
  );
  ```
</CodeGroup>

A missing or invalid key returns
[`invalid_api_key`](/errors/invalid_api_key). Calls are still rate-limited per
partner (see [Rate limits](/rate-limits)) and recorded in your audit log.

<Note>
  Outbound **webhook** deliveries are signed by CrewPass so you can verify they are
  genuine; see [Webhooks](/webhooks) for how to verify a delivery signature.
</Note>
