> ## Documentation Index
> Fetch the complete documentation index at: https://developers.readyforcommerce.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Authentication

> Call the API with an API key of your organization: how to create it, send it, keep it safe and replace it.

Every call to the API carries an API key of your organization, as a Bearer token in the `Authorization` header:

```text theme={null}
Authorization: Bearer $RFC_API_KEY
```

A key belongs to one organization and reaches that organization alone, within the permissions it was created with.

## Create a key

The organization's owner, or a person the owner allows, creates keys in the app, in **Settings › API and connections ›
API keys**. A key has:

* **A name,** which says what uses it, such as *Sales reports*.
* **What it may do:** **Read only** (it sees everything and changes nothing), **Full access** (it sees and changes
  everything a key may) or **Custom** (you tick what it may do in each area). Either way, a key never holds more than
  the person who creates it.
* **When it expires:** at most 365 days after it is created.

The key is shown **once**, when it is created: copy it then. Production keys start with `rfc_key_`. The app keeps
only a fingerprint of the key, never the key itself, and its list shows each key by its start and its last four
characters.

An organization holds at most 50 live keys, neither revoked nor expired. Give each program its own key, so
you can replace or revoke one without stopping the others.

> [!WARNING]
>
> Treat a key like a password. Keep it out of your code, your repository and anything that runs in a
> browser or on a customer's device: read it from an environment variable or a secret store, as
> every example of this site does with `RFC_API_KEY`. If a key leaks, revoke it at once in **API
> keys**.

## Check a key

[Get the calling credential](https://developers.readyforcommerce.com/api-reference/core-get-credential.md) answers who the key is: its organization, its name,
its expiry, its permissions, its limits and the calls it may still make. It counts against no limit, so it is the
call to make first, and whenever a program starts.

```bash curl theme={null}
curl https://app.readyforcommerce.com/api/v1/credential \
  --header "Authorization: Bearer $RFC_API_KEY"
```

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

import requests

response = requests.get(
    "https://app.readyforcommerce.com/api/v1/credential",
    headers={"Authorization": f"Bearer {os.environ['RFC_API_KEY']}"},
)
print(response.json())
```

```php PHP theme={null}
<?php
$curl = curl_init('https://app.readyforcommerce.com/api/v1/credential');
curl_setopt_array($curl, [
    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('RFC_API_KEY')],
    CURLOPT_RETURNTRANSFER => true,
]);
echo curl_exec($curl);
```

```javascript JavaScript theme={null}
const response = await fetch('https://app.readyforcommerce.com/api/v1/credential', {
  headers: { Authorization: `Bearer ${process.env.RFC_API_KEY}` },
});
console.log(await response.json());
```

The answer's `org.id` is the `orgId` of every other path: `/api/v1/orgs/{orgId}/…`.

## What a key may do

* **Its own organization alone.** A path under another organization's id answers as if the key did not exist.
* **The permissions it was created with, and no more.** A permission added to the app later, such as a new feature's
  or a module the organization activates later, never joins an existing key, even a **Full access** one. Create a new
  key to use it.
* **Never what only a person does.** Deleting or transferring the organization, its people and roles, its modules, its
  card and payments, and its API keys and AI connections stay in the app. A key that calls one gets `403
  core.human_only`.

## When a call is refused

| Answer | Code | What it means | What to do |
| - | - | - | - |
| `401` | `core.invalid_credential` | The key is unknown, revoked or expired, or belongs to another organization. All four answer the same, so the answer tells nothing about other keys. | Check that the program sends the right key, and that it is still live in **API keys**. |
| `403` | `core.forbidden` | The key lacks the permission the call needs; `params.permission` names it. | Create a key that holds it: an existing key's permissions never grow. |

Retrying either call unchanged answers the same: fix the key first. Every error's shape is in
[Errors](https://developers.readyforcommerce.com/errors.md).

## Expiry and rotation

A key stops working at its expiry. The organization's owner is told 30, 7, 1 days before it, by
email and in the app.

To replace a key without stopping your program:

**1. Create the new key**

In **Settings › API and connections › API keys**, with the permissions your program needs.

**2. Deploy it**

Put the new key where your program reads it, and check it with [Get the calling
credential](https://developers.readyforcommerce.com/api-reference/core-get-credential.md).

**3. Revoke the old key**

Revoke it in the same list. A revoked key is refused from its very next call.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.