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

# API Keys

> Manage API credentials for server-to-server Yativo Crypto integrations

API keys are the recommended authentication method for Yativo Crypto integrations. They let your server authenticate programmatically without user sessions, and can be scoped to the minimum permissions your integration requires.

<Warning>
  2FA must be enabled on your account before you can create API keys. All key management operations require a current TOTP code in the `X-2FA-Token` header.
</Warning>

***

## Crypto-Relevant Permissions

| Permission     | What It Unlocks                                                        |
| -------------- | ---------------------------------------------------------------------- |
| `read`         | Read balances, transaction history, asset info, analytics              |
| `write`        | Create accounts, add wallets, configure gas stations, manage customers |
| `transactions` | Initiate sends, execute swaps, fund cards                              |
| `webhooks`     | Create and manage webhook subscriptions                                |

For most Yativo Crypto server integrations, you'll want `read`, `write`, and `transactions` at minimum.

***

## Create an API Key

**POST** `/apikey/create`

<ParamField header="X-2FA-Token" type="string" required>
  Current 6-digit TOTP code from your authenticator app.
</ParamField>

<ParamField body="name" type="string" required>
  A descriptive name (e.g., "Crypto Backend — Production").
</ParamField>

<ParamField body="permissions" type="array" required>
  Array of permission scopes.
</ParamField>

<ParamField body="expires_in_days" type="number">
  Days until expiry. Omit for a non-expiring key.
</ParamField>

```bash cURL theme={null}
curl -X POST https://crypto-api.yativo.com/api/v1/apikey/create \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "X-2FA-Token: 123456" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Crypto Backend — Production",
    "permissions": ["read", "write", "transactions", "webhooks"],
    "expires_in_days": 365
  }'
```

```json Response theme={null}
{
  "id": "key_01abc123",
  "name": "Crypto Backend — Production",
  "api_key": "yvk_live_...",
  "api_secret": "yvs_live_...",
  "permissions": ["read", "write", "transactions", "webhooks"],
  "expires_at": "2027-03-26T10:00:00Z",
  "created_at": "2026-03-26T10:00:00Z"
}
```

<Warning>
  The `api_secret` is only shown once. Store it in your secrets manager immediately.
</Warning>

***

## Authenticate with an API Key

**Method 1: Exchange for Bearer token (recommended for production)**

```bash theme={null}
curl -X POST https://crypto-api.yativo.com/api/v1/apikey/token \
  -H "Content-Type: application/json" \
  -d '{
    "api_key": "yvk_live_...",
    "api_secret": "yvs_live_..."
  }'
```

Use the returned `access_token` as `Authorization: Bearer {token}` on all subsequent requests. Refresh it before expiry using the same endpoint.

**Method 2: Header-based (for simpler integrations)**

```bash theme={null}
curl -X POST https://crypto-api.yativo.com/api/v1/transactions/send-funds \
  -H "X-API-Key: yvk_live_..." \
  -H "X-API-Secret: yvs_live_..." \
  -H "Content-Type: application/json" \
  -d '{ ... }'
```

***

## Server-to-Server Pattern

Here's a complete server-to-server setup using the Bearer token method with auto-refresh:

```typescript theme={null}
import { YativoCrypto } from '@yativo/sdk';

// The SDK handles token exchange and refresh automatically
const yativo = new YativoCrypto({
  apiKey: process.env.YATIVO_API_KEY!,
  apiSecret: process.env.YATIVO_API_SECRET!,
  // environment: 'sandbox', // uncomment for sandbox
});

// All methods are authenticated automatically
const accounts = await yativo.accounts.list();
const balance = await yativo.balance.check({ asset_id: 'asset_01xyz' });
```

Without the SDK:

```typescript theme={null}
class YativoClient {
  private token: string | null = null;
  private expiresAt = 0;
  private baseUrl = 'https://crypto-api.yativo.com/api';

  constructor(
    private apiKey: string,
    private apiSecret: string
  ) {}

  async getHeaders(): Promise<Record<string, string>> {
    const token = await this.getToken();
    return {
      'Authorization': `Bearer ${token}`,
      'Content-Type': 'application/json',
    };
  }

  private async getToken(): Promise<string> {
    if (this.token && Date.now() < this.expiresAt - 60_000) {
      return this.token;
    }
    const res = await fetch(`${this.baseUrl}/apikey/token`, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ api_key: this.apiKey, api_secret: this.apiSecret }),
    });
    const { access_token, expires_in } = await res.json();
    this.token = access_token;
    this.expiresAt = Date.now() + expires_in * 1000;
    return access_token;
  }
}
```

***

## Key Management

| Operation          | Endpoint                                                |
| ------------------ | ------------------------------------------------------- |
| List all keys      | `GET /apikey/list`                                      |
| Get a key          | `GET /apikey/{id}`                                      |
| Revoke a key       | `POST /apikey/{id}/revoke` (requires `X-2FA-Token`)     |
| Rotate secret      | `POST /apikey/{id}/rotate` (requires `X-2FA-Token`)     |
| Update permissions | `PUT /apikey/{id}/permissions` (requires `X-2FA-Token`) |

For full endpoint documentation, see the [API Keys reference](/yativo/api-keys).

***

## Best Practices for Crypto Integrations

<Accordion title="Use separate keys per environment">
  Create dedicated API keys for sandbox and production. Never use a production key for testing.
</Accordion>

<Accordion title="Scope permissions minimally">
  A key used only for reading balances and transaction history should only have `read`. Only grant `transactions` to services that actually initiate transfers.
</Accordion>

<Accordion title="Rotate keys on a schedule">
  Rotate API secrets periodically (e.g., every 90 days) and immediately if you suspect a key has been exposed. The `rotate` endpoint generates a new secret without requiring you to delete and recreate the key.
</Accordion>

<Accordion title="Store secrets in environment variables">
  Never hardcode API keys in source code. Use environment variables or a secrets manager and inject at runtime.
</Accordion>
