Skip to main content

Authentication

Every request needs an X-Api-Key header:

curl -H "X-Api-Key: $KAMEE_API_KEY" "https://kamee.fit/api/plans"

There is no OAuth, no bearer token, and no signing. The key is compared in constant time, so a wrong key takes the same time to reject as a nearly-right one.

Keep the key server-side

Treat the key like a password:

  • Store it in an environment variable or a secrets manager, never in source control.
  • Call the API from your backend. Never put the key in browser JavaScript, a mobile app binary, or anything else a user can read.
  • Do not put it in a URL — it belongs in the header, where it stays out of logs and Referer headers.

By default the API sends no CORS headers, so a browser fetch will fail anyway. That is deliberate. Calling from a browser covers the proxy pattern.

What you should know about the current key model

Being straight with you: keys are not currently per-partner. There is one key shared by every integrator. That has two consequences worth planning around:

  • There is no self-serve issuance or revocation. Getting or replacing a key means contacting PLACEHOLDER_CONTACT.
  • Rotation is global. When the key rotates, it rotates for everyone at once. Read your key from configuration you can change without a redeploy, so a rotation is a config change rather than a release.

Per-partner keys are on the roadmap. Until then, build for a key that can change out from under you: read it at request time rather than caching it at process start, and make a 401 a loud, alerting failure rather than a silent empty list.

When authentication fails

A missing, malformed, or wrong key returns 401:

{"error": "Unauthorized."}

401 always means the key. It is never a rate limit and never a signal to back off and retry — retrying with the same key will fail identically. Treat it as a configuration error and alert on it.

Full list of responses: Errors.