# Authentication

> How to send your API key, whom it acts as, where it works and what the API answers when it is wrong.

Running tasks and reading your jobs, files and account need an API key; reading the task catalogue, vocabularies, concepts, recipes, the error catalogue and the service metadata does not. Keys start with `rf_live_`.

## Sending the key

Preferred:

```http
Authorization: Key rf_live_…
```

Also accepted, with the same effect:

```http
Authorization: Bearer rf_live_…
x-api-key: rf_live_…
```

Send exactly one. Use HTTPS; a request over plain HTTP is refused.

```bash
curl -s "$REFABRIC_API/tasks" -H "Authorization: Key $REFABRIC_API_KEY"
```

```python
import os, requests
s = requests.Session()
s.headers["Authorization"] = f"Key {os.environ['REFABRIC_API_KEY']}"
s.get("https://api.refabric.com/v1/tasks").raise_for_status()
```

## Who a key acts as

A key is owned by a Refabric **user** and acts **as that user**:

- credits are charged to that user's balance;
- permissions (plan, features) are that user's;
- files uploaded or produced with the key belong to that user, and the user sees them in the app.

A key's [scopes](https://docs.refabric.com/setting-up/get-your-api-key#scopes) define what it may do, within its user's permissions.

## Where keys work

Keys work on the public endpoints listed in the [Platform API](https://docs.refabric.com/api-reference/platform) only.
Any other endpoint refuses a key:

```json
HTTP 403
{ "error": { "code": "session_required", "type": "permission",
             "message": "this route needs a signed-in session; an API key cannot call it",
             "field": null, "retryable": false,
             "request_id": "req_…" } }
```

This includes key management itself: creating, rolling and revoking keys needs you signed in to
the panel, so a leaked key cannot mint new keys.

A key sent from a browser (a request with an `Origin` header) is refused on every endpoint with
`403 api_key_not_allowed_here` — see [Never from a browser](#never-from-a-browser).

## Failures

| Situation | HTTP | `error.type` | `error.code` |
|---|---|---|---|
| no key on an endpoint that needs one | 401 | `authentication` | `unauthenticated` |
| malformed, revoked or expired key | 401 | `authentication` | `invalid_api_key` |
| key lacks the scope | 403 | `permission` | `scope_missing` |
| endpoint not public | 403 | `permission` | `session_required` |
| key sent from a browser | 403 | `permission` | `api_key_not_allowed_here` |
| plan without API access | 403 | `permission` | `api_access_not_included` |
| user's plan does not allow the task | 403 | `permission` | `permission_denied` |

Reads that need no key check a key you send with them, the same way: an invalid key answers
`401 invalid_api_key`, and a key sent from a browser `403 api_key_not_allowed_here`. Send a key to
those reads only from your server, or send none.

The live list is `GET /v1/errors` ([Errors](https://docs.refabric.com/task-apis/errors/task-errors#the-codes)).

## Never from a browser

Keys are server-side secrets. Do not put them in web pages, mobile apps or any code a user can
read. A key sent from a browser is refused with `403 api_key_not_allowed_here`, whatever the
endpoint. See [Security](https://docs.refabric.com/api-reference/platform/security).
