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

# Step 5: Your API Keys

> Understanding, securing, and managing your API keys

<Note>
  This is Step 5 of 6 in the onboarding journey. [View the full onboarding overview →](/onboarding/overview)
</Note>

## What is an API key?

An **API key** is a unique secret code that identifies your application when it makes requests to the UBN BaaS API.

Think of it like a key card for a secure office building. Without the key card, you can't get through the door. With it, the building's system knows exactly who you are, which areas you're allowed to enter, and logs every door you open. Your API key works the same way. Every request you make is authenticated, attributed to your account, and rate-limited according to your plan.

When you include your API key in a request, our system knows:

* Which partner account the request belongs to
* Whether the request is authorised for the operation being attempted
* How to bill for usage
* How to apply your specific rate limits and permissions

***

## Two types of API keys

You'll have two separate API keys at different points in your journey.

<CardGroup cols={2}>
  <Card title="Sandbox Key" icon="flask">
    **Format:** `ubn_sb_` followed by a random string

    **Example:** `ubn_sb_aBcDeFgH1234567890XyZ`

    **Environment:** sandbox only (`https://api-partner.onecluster.co`)

    Automatically issued when your KYC verification passes. Free to use. No real money moves. No real accounts are created. Use this key to build and test your entire integration.

    You can generate as many sandbox keys as you need, at no cost.
  </Card>

  <Card title="Production Key" icon="building-columns">
    **Format:** `ubn_pk_` followed by a random string

    **Example:** `ubn_pk_aBcDeFgH1234567890XyZ`

    **Environment:** production only (`https://api.onecluster.co`)

    Issued only after your production access request is approved (Step 6). Real money moves. Real accounts are created. Treat this key with extreme care.

    Never use a production key in test or development code.
  </Card>
</CardGroup>

<Warning>
  The key prefix tells you which environment it belongs to. `ubn_sb_` = sandbox. `ubn_pk_` = production. If you're ever unsure which key you're using, check the first 7 characters. Running test code with a production key causes real transactions.
</Warning>

***

## The golden rule: your key is shown only once

When a new API key is generated, it's displayed in full exactly one time, immediately after creation.

**We don't store your full API key.** We store only a **cryptographic hash** of the key: a mathematical fingerprint that lets us verify a key is valid without ever knowing what the key actually is. That means:

* If you copy the key and save it securely at the moment of creation, you're fine
* If you close the window before copying the key, it's gone permanently. You'll need to generate a new one.
* If you contact support and ask us to retrieve your key, we genuinely can't. The full key doesn't exist anywhere in our system.

This design is intentional. Even if our database were compromised, attackers couldn't extract your API keys from our records.

<Warning>
  The moment a new API key is displayed in the portal, copy it immediately and save it in a secure location. You won't see the full key again.
</Warning>

***

## How to store your key safely

Keeping your API key secure is your responsibility. Here are the rules, from most important to least.

### Never put your key in code

If your API key is in your source code, it'll end up in your version control history (Git), and it's a matter of time before it's exposed: whether through a public repository, a leaked code review, or an accidentally shared file.

```javascript theme={null}
// WRONG: never put your key in code
const apiKey = "ubn_sb_aBcDeFgH1234567890XyZ";

fetch("https://api-partner.onecluster.co/api/v1/accounts", {
  headers: { "Authorization": `ApiKey ${apiKey}` }
});
```

```javascript theme={null}
// RIGHT: load from an environment variable
// An environment variable is a value stored in your operating system or
// deployment platform, separate from your code. Your code reads it at
// runtime without ever containing the secret itself.
const apiKey = process.env.UBN_API_KEY;

fetch("https://api-partner.onecluster.co/api/v1/accounts", {
  headers: { "Authorization": `ApiKey ${apiKey}` }
});
```

### Never commit your key to Git

Even if you load the key from an environment variable in your code, you might accidentally commit a `.env` file (a file where environment variables are stored locally) to Git. Prevent this by adding `.env` to your `.gitignore` file:

```bash theme={null}
# .gitignore
.env
.env.local
.env.production
```

### Use a secret manager in production

For production deployments, use a dedicated secret manager rather than environment variables on the server. These services store secrets encrypted, provide audit logs of who accessed what, and let you rotate secrets without redeploying your application.

Recommended options:

| Platform         | Secret manager                                                     |
| ---------------- | ------------------------------------------------------------------ |
| AWS              | AWS Secrets Manager or AWS Systems Manager Parameter Store         |
| Google Cloud     | Google Secret Manager                                              |
| Azure            | Azure Key Vault                                                    |
| Any platform     | HashiCorp Vault                                                    |
| Vercel / Netlify | Built-in environment variable management in the platform dashboard |

***

## How to use your key in every request

Include your API key in the `Authorization` header of every API request. The format is `ApiKey` followed by a space and then your key.

```bash theme={null}
curl https://api-partner.onecluster.co/api/v1/accounts \
  -H "Authorization: ApiKey ubn_sb_your_key_here" \
  -H "Content-Type: application/json"
```

In JavaScript (Node.js):

```javascript theme={null}
const response = await fetch("https://api-partner.onecluster.co/api/v1/accounts", {
  method: "GET",
  headers: {
    "Authorization": `ApiKey ${process.env.UBN_API_KEY}`,
    "Content-Type": "application/json"
  }
});
```

In Python:

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

response = requests.get(
    "https://api-partner.onecluster.co/api/v1/accounts",
    headers={
        "Authorization": f"ApiKey {os.environ['UBN_API_KEY']}",
        "Content-Type": "application/json"
    }
)
```

<Note>
  Every request that modifies data (POST, PUT, DELETE) also requires an **idempotency key** in the `Idempotency-Key` header. An idempotency key is a unique string you generate per request that prevents duplicate operations if your network retries a request. See the [API Reference: Authentication](/api-reference/authentication) page for details.
</Note>

***

## Key rotation

**Key rotation** means generating a new API key and retiring the old one. It's a security practice, like changing the locks on an office when an employee leaves. Rotate your API keys:

* Every 90 days as routine security hygiene
* Immediately when a team member with key access leaves your organisation
* Immediately when you suspect a key may have been exposed

### The 72-hour grace period

When you rotate a key, the old key doesn't stop working immediately. It remains valid for a **72-hour grace period**: 3 days during which both the old key and the new key are accepted.

This gives you time to:

1. Generate the new key
2. Update your production environment with the new key
3. Redeploy your application
4. Confirm the new key is working correctly
5. Let the old key expire naturally at the end of the 72 hours

<Tip>
  The 72-hour grace period is designed to prevent downtime during rotation. Use it, but don't rely on it as a permanent state. Both keys being valid simultaneously doubles your exposure window. Complete the rotation as quickly as possible after generating the new key.
</Tip>

### How to rotate a key

Rotate keys from the portal at [ubn-ui.onecluster.co](https://ubn-ui.onecluster.co). Open the **API Keys** page, click **Rotate** next to the key you want to rotate, and the new key value is displayed once. Copy it immediately. You won't see it again.

***

## Key revocation

**Key revocation** immediately and permanently invalidates an API key. Unlike rotation (which has a 72-hour grace period), revocation takes effect instantly. Use it when:

* You believe your key has been leaked or compromised
* You find your key in a public Git repository
* A team member left your organisation and may have retained a copy of the key
* You receive a security alert about suspicious usage on your account

<Warning>
  Revocation is immediate and irreversible. Any system still using the revoked key will fail instantly. Before revoking a key in production, make sure you have a replacement key ready to deploy. If you need to revoke immediately due to a security incident, accept the brief downtime and prioritise security.
</Warning>

### How to revoke a key

Revoke keys from the portal at [ubn-ui.onecluster.co](https://ubn-ui.onecluster.co). Open the **API Keys** page, click **Revoke** next to the affected key, and confirm. The key stops working instantly.

***

## Managing keys

All key management happens in the portal at [ubn-ui.onecluster.co](https://ubn-ui.onecluster.co):

* **List all keys:** see every key on your account, with metadata (created, last used, status). Full key values are never shown after creation, only prefixes and IDs.
* **Generate a new key:** the full key value is displayed once at creation.
* **Rotate a key:** generates a new key and starts the 72-hour grace period on the old key.
* **Revoke a key:** immediately and permanently invalidates a key.

***

You now have your sandbox API key and you know how to use it safely. Start building and testing your integration. When you're ready to handle real transactions, move on to Step 6.

[Continue to Step 6: Go Live →](/onboarding/go-live)
