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

# Authentication: API keys, scopes, and idempotency

> Create API keys in the dashboard, authenticate programmatic requests with Bearer tokens, and understand scope and idempotency requirements.

Remitflex has two authentication modes:

| Mode              | Used for                                                                               | Header                                                 |
| ----------------- | -------------------------------------------------------------------------------------- | ------------------------------------------------------ |
| **Dashboard JWT** | Login, signup, API key management, admin ops                                           | `Authorization: Bearer <accessToken>`                  |
| **API key**       | Payment routes, payment links, swaps, cNGN, local fiat, rates, customers, transactions | `Authorization: Bearer rmf_live_...` or `rmf_test_...` |

This guide covers **API keys** for programmatic integrations. Dashboard login uses email OTP and JWT — see your dashboard app for that flow.

## Creating an API key

API keys are created in the [Remitflex Dashboard](https://dashboard.remitflex.io) after you log in. Keys cannot be created via the public API using another API key.

<Steps>
  <Step title="Log in to the dashboard">
    Complete email + OTP login to receive a short-lived access JWT.
  </Step>

  <Step title="Open API Keys">
    Navigate to **Settings → API Keys** and click **Create new key**.
  </Step>

  <Step title="Choose environment and access">
    Select **test** or **live**, then **read**, **write** (full access), or both. See [Key scopes](#key-scopes) below.
  </Step>

  <Step title="Copy the key immediately">
    The full key is shown **once** at creation. Store it in a secrets manager or environment variable.
  </Step>
</Steps>

Key format:

```
rmf_live_  LLLLLLLL  SSSSSSSSSSSSSSSSSSSSSSSS
prefix(9)  lookup(8)  secret(24)
```

Display in the dashboard: `rmf_live_••••••••<last4>`.

## Using your API key

Send the key as a Bearer token on every business API request:

<CodeGroup>
  ```bash curl theme={null}
  curl --request GET \
    --url https://api.remitflex.io/v1/transactions \
    --header "Authorization: Bearer $REMITFLEX_API_KEY"
  ```

  ```javascript JavaScript theme={null}
  const response = await fetch("https://api.remitflex.io/v1/transactions", {
    headers: {
      Authorization: `Bearer ${process.env.REMITFLEX_API_KEY}`,
    },
  });
  const { data } = await response.json();
  ```

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

  response = requests.get(
      "https://api.remitflex.io/v1/transactions",
      headers={"Authorization": f"Bearer {os.environ['REMITFLEX_API_KEY']}"},
  )
  data = response.json()["data"]
  ```
</CodeGroup>

## Key types: test vs live

| Type     | Prefix      | Use case                            |
| -------- | ----------- | ----------------------------------- |
| **Test** | `rmf_test_` | Development and integration testing |
| **Live** | `rmf_live_` | Production transactions             |

<Warning>
  Never use a live key in source code, client-side apps, or CI logs. Revoke compromised keys immediately from the dashboard.
</Warning>

## Key scopes

Secret API keys use a simple **read / write** model. Scopes are enforced on API-key requests. Dashboard JWT sessions have full access to business routes.

| Scope       | Access                                                                                                                   |
| ----------- | ------------------------------------------------------------------------------------------------------------------------ |
| `api:read`  | List and fetch all business resources (customers, transactions, routes, links, swaps, cNGN, local fiat, rates, webhooks) |
| `api:write` | Create and mutate those resources (**implies read**)                                                                     |

New keys should use only these scopes. Existing keys with older product scopes (`transfers:*`, `collections:*`, `offramps:*`, etc.) still work — RemitFlex treats any legacy write as full write, and any legacy read as full read.

**Publishable keys** (`rmf_pk_*`) are embed-safe and receive only `collections:read` (pay-page / embed reads). They cannot create or mutate resources — use a secret key or dashboard JWT for writes.

Default for backend integrations: **full access** (`api:read` + `api:write`).

## Idempotency

Mutating requests authenticated with an **API key** (`POST`, `PUT`, `PATCH`, `DELETE`) require an `Idempotency-Key` header. See [Idempotency](/api-reference/idempotency) for details.

JWT requests from the dashboard do **not** require idempotency keys.

## JWT-only routes

These routes require a dashboard access token, not an API key:

* `/v1/auth/*` — register, login, OTP, refresh, logout
* `/v1/api-keys/*` — create, list, revoke keys
* `/v1/admin/ops/*` — RemitFlex internal ops only (not a merchant API)

Webhook endpoint CRUD (`/v1/webhooks`) accepts **JWT or** API keys with `api:read` / `api:write`. See [Webhooks](/guides/webhooks).

## Error responses

```json theme={null}
{
  "status": "error",
  "message": "Invalid API key"
}
```

| HTTP  | Typical cause                                                               |
| ----- | --------------------------------------------------------------------------- |
| `401` | Missing, invalid, expired, or revoked API key                               |
| `403` | Valid key but missing required scope (`Missing required scopes: api:write`) |
| `400` | Missing `Idempotency-Key` on a mutating API-key request                     |

## Security best practices

<Tip>
  Store keys in environment variables (`REMITFLEX_API_KEY`) or a secrets manager — never commit them to git.
</Tip>

* Use separate keys per environment and per service.
* Rotate keys periodically; revoke old keys after migration.
* Use test keys (`rmf_test_`) for all local and CI workflows.
