---
updatedAt: 2026-10-13T20:52:48.000Z
agentTools:
  projectIndex: https://docs.cybrid.xyz/llms.txt
---

# API Keys

Generate and manage API key pairs for secure access to the Cybrid platform.

## Set up your Organization and Bank

Before interacting with the Cybrid API, create an Organization and Bank through the dashboard.

After logging in, you are guided through three steps:

1. **Name your Organization** — this represents your business or project within the Cybrid platform.
2. **Create a Bank** — a Bank is a digital representation of a financial institution in the Cybrid ecosystem. Enter a descriptive name and configure your Bank settings.
3. **Generate an API key pair** — click **Generate** to create a Client ID and Client Secret for secure API communication. Add an [IP allowlist](#restrict-access-with-an-ip-allowlist) on this step to restrict the credentials to specific source IPs. Cybrid requires an IP allowlist on production credentials. Keys generated in this step expire after 90 days; see [Key expiry](#key-expiry).

## Store your Client Secret

Once generated, the Client ID and Client Secret display on screen. Hover over the Client Secret to reveal it, and use the copy buttons on the right to copy each value.

<Image align="center" src="https://files.readme.io/cf43829-Screenshot_2023-07-27_at_3.36.19_PM.webp" alt="Cybrid dashboard showing a generated API key pair with Client ID and Client Secret fields" />

> ⚠️ Save your Client Secret immediately
>
> The secret displays only once. If you navigate away without saving it, you must generate a new key pair.

## Generate new keys

To generate new keys at any time:

1. Navigate to the **Developers** tab in the Cybrid dashboard.
2. Click **Generate New Key** in the top-right corner.
3. Select either **Organization** keys or **Bank** keys.
4. Choose when the key expires: 30, 60, 90, 180, or 365 days.
5. Add an [IP allowlist](#restrict-access-with-an-ip-allowlist) to restrict the new credentials to specific source IPs. Cybrid requires an IP allowlist on production credentials.

This lets you rotate credentials or manage keys across multiple projects. After you confirm the new key is working, remove the old key pair from the Developers tab so it can no longer be used.

You cannot delete the only active key pair for an Organization or Bank: the **Delete** option appears only when another active key pair exists. Generate the replacement key first, then delete the old one.

API keys are managed only in the dashboard. Access tokens issued for an Organization or Bank API key can list and get applications, but cannot create, update, or delete them.

### Key expiry

Each new Organization and Bank key has an expiry date, shown in the **Expires** column on the **Developers** tab and returned as `expires_at` on the application (`null` for keys that do not expire). Once a key expires, it can no longer issue access tokens: `POST /oauth/token` returns `403` with `{"error": "unauthorized_client", "error_description": "The client application has expired."}`. Access tokens issued before the expiry stay valid until their own expiry. Generate a replacement key before the current one expires to avoid downtime.

## Bank-specific API credentials

When managing multiple banks under a single organization, each bank requires its own API credentials (`client_id` and `client_secret`). The access token generated from these credentials is scoped to a specific bank — all API actions (such as creating customers) run under that bank. The `bank_guid` parameter in API requests is ignored; the access token determines bank context.

To generate credentials for a specific bank:

1. In the Cybrid portal, use the top-left selector to choose the bank you want to generate credentials for.
2. Navigate to the **Developers** tab.
3. Generate new credentials for that bank.

This ensures API requests are scoped to the intended bank. To delete a bank's key, select that bank with the same selector before opening the **Developers** tab.

## Restrict access with an IP allowlist

Each Bank or Organization Application can carry an **IP allowlist** — a list of public IPv4 addresses or CIDR ranges that are permitted to use the credentials. Requests from any other source IP are rejected. An empty allowlist means unrestricted access. The dashboard does not block saving an empty list, but Cybrid requires an allowlist on production credentials.

### Limits and accepted values

* Up to 3 entries per Application.
* IPv4 only. IPv6 addresses are rejected at validation.
* Format: a single address (e.g. `203.0.113.5`) or a CIDR range (e.g. `198.51.100.0/24`). The example values shown are RFC 5737 documentation-range placeholders and will be rejected at validation — substitute the real public addresses from your environment.
* Must be a public address. Private (RFC 1918), loopback, link-local, multicast, reserved, CGNAT, documentation (RFC 5737), and benchmarking ranges are rejected at validation.

### Where to configure it

* **Onboarding wizard** — the **Generate an API key pair** step on first login.
* **Generate Bank Key** form — on the **Developers** tab when creating a new Application.
* **Edit Application** form — on the **Developers** tab to update an existing Application.

The **Developers** tab also lists each Bank Application's current entries in an **IP Allowlist** column.

### When changes take effect

The allowlist is checked when you request a token from `POST /oauth/token`, embedded in the access token at issuance, and enforced on every API call. Edits apply on the **next token issuance** — access tokens already in flight continue to enforce the list they were issued with. After updating an allowlist, request a fresh token before retrying from a new IP.

> ⚠️ Validate in a non-production Application first
>
> Pinning to the wrong egress IP can lock your integration out of the Cybrid API. Confirm the source IP from your production environment before applying the allowlist there. Serverless and container platforms often use dynamic outbound IPs by default; route their traffic through a static egress IP (for example, a NAT gateway) before you add it to the allowlist.

### Clear the allowlist

To remove all restrictions, delete every entry in the **Edit Application** form on the **Developers** tab.

### Denied request behavior

When a request arrives from a source IP that is not in the allowlist, Cybrid returns `403 Forbidden`. The body depends on where the request was rejected.

Token requests to `POST /oauth/token`:

```json Response
{"error": "ip_not_allowed", "error_description": "IP address not in allowlist"}
```

API calls with an access token that carries an allowlist:

```json Response
{"status": 403, "error_message": "IP address not in allowlist", "message_code": "ip_not_allowed"}
```

Map `ip_not_allowed` in your error handling to distinguish it from scope or rate-limit errors.

### Scope

IP allowlists apply to **Bank** and **Organization** Applications, and to customer tokens generated via [POST `/api/customer_tokens`](https://docs.cybrid.xyz/reference/createcustomertoken). By default (`inherit_ip_allowlist: true`), a customer token inherits the allowlist of the Bank key that creates it. You can also pass `ip_allowlist` to add entries; the token is restricted to the combined list. Send `inherit_ip_allowlist: false` with no `ip_allowlist` to issue an unrestricted customer token. The inherited list is copied when the token is created, so later changes to the Bank key's allowlist do not affect tokens already issued.

## Handle "Signature has expired" errors

If you receive a `Signature has expired` error with status 401 (`authentication_failed`), your access token has expired. To resolve this, generate a new token using your existing API credentials.

You do **not** need to recycle or rotate your API key or Client Secret for this error. If the token request itself fails with `unauthorized_client` and `The client application has expired.`, the API key has expired; see [Key expiry](#key-expiry). Rotating secrets is only necessary if you suspect they have been compromised or as part of periodic security hygiene — not for normal token expiration.