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 v1 reads do not use a request signature. Request signing (HMAC) returns for the v2 write surface, which is described below and is currently disabled.

API keys

Keys are issued by CrewPass and look like:
PrefixMeaning
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:
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 to see your identity and full granted-scope list. It is the first call any partner makes.
Keep your API key server-side. Never embed it in a browser or mobile app. Public read-only widget keys (cppk_*) are a separate, future surface and are not accepted here.

Calling a read endpoint

Every v1 read takes the same Bearer header and nothing else:
curl -sS https://partners.crewpass.co.uk/api/v2/employers/me/vessels \
  -H "Authorization: Bearer $CPK_KEY"
A missing or invalid key returns invalid_api_key. Calls are still rate-limited per partner (see Rate limits) and recorded in your audit log.

Request signing (v2 write surface)

Mutating endpoints (vessel attach, crew placements, background-check issuance) are deferred to v2 and are not part of this release. When they ship, each mutating request is signed with an HMAC-SHA256 body signature so the body and timing are provably genuine and not replayed. The scheme uses three headers and binds a single-use nonce into the signature:
HeaderValue
X-CrewPass-TimestampUnix time in seconds. Must be within ±300s of server time.
X-CrewPass-NonceA unique, single-use token per request.
X-CrewPass-Signaturev1=<hex(hmac_sha256(secret, "{timestamp}.{nonce}." + body))>
This is documented now so integrators can plan ahead; it is not required for any v1 read.
import hashlib, hmac, time, uuid

def signed_headers(api_key: str, secret: str, body: bytes = b"") -> dict[str, str]:
    ts = str(int(time.time()))
    nonce = uuid.uuid4().hex
    msg = f"{ts}.{nonce}.".encode() + body
    sig = hmac.new(secret.encode(), msg, hashlib.sha256).hexdigest()
    return {
        "Authorization": f"Bearer {api_key}",
        "Content-Type": "application/json",
        "X-CrewPass-Timestamp": ts,
        "X-CrewPass-Nonce": nonce,
        "X-CrewPass-Signature": f"v1={sig}",
    }
Outbound webhook deliveries are signed by CrewPass with a separate scheme so you can verify they are genuine. That is unrelated to request signing; see Webhooks for how to verify a delivery signature.