# Authentication

Company API keys, sent from your server over HTTPS in the Authorization header.

Every call sends a company API key as a bearer token, over HTTPS:

```http
GET /v1/training-records?limit=200 HTTP/1.1
Host: api.kapiworks.com
Authorization: Bearer kw_live_…
Accept: application/json
```

This is a company API key, not an OAuth access token. The key decides the company: addresses take no company selector, and a key reads only the company that created it.

## Keep the key on your server

The API is for your server, not for browsers. It sends no CORS headers, and it reads the key only from the `Authorization` header. Browser applications, cookies and keys in web addresses are unsupported.

Send the key only to the API host. Keep it in your secret manager, out of source code, command arguments and logs. The [request samples](https://docs.kapiworks.com/quickstart#3-make-the-first-call) show how for curl, Node and Python.

A key sent in a web address is refused, and the key is revoked at once, because web addresses end up in logs and browser history. The company's owners and admins are told, and the call answers [`key_in_url`](https://docs.kapiworks.com/errors/key_in_url). Ask for a new key and send it only in the header.

## What a key looks like

A key is `kw_live_` (production) or `kw_test_` (Kapi's other environments), then 43 letters, digits, hyphens or underscores, a dot, and an 8-character checksum. The API checks the checksum first, so a mistyped key is refused straight away.

Kapi stores a SHA-256 hash of each key and its last four characters, not the key itself. Works Studio shows the key once, when it is created.

## What the API checks on every call

1. The key is genuine, active and not expired. If not, the call answers [`invalid_token`](https://docs.kapiworks.com/errors/invalid_token). Unknown, expired and revoked keys all get this same answer.
2. If the key is limited to networks, the call comes from one of them. If not, [`ip_not_allowed`](https://docs.kapiworks.com/errors/ip_not_allowed).
3. The key has the [scope](https://docs.kapiworks.com/scopes) the endpoint needs. If not, [`insufficient_scope`](https://docs.kapiworks.com/errors/insufficient_scope), and the `WWW-Authenticate` header names the scope it needs.

Revocation takes effect on the next call. Each response carries an `X-Request-Id`; quote it when you [contact support](https://docs.kapiworks.com/support), and do not send the key.

## HTTP methods

The API is read-only. Every endpoint answers `GET` and `HEAD`; `HEAD` returns the same status and headers without a body. Other methods answer [`method_not_allowed`](https://docs.kapiworks.com/errors/method_not_allowed).
