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

# Authentication

> Authenticate with the Contro Partner API using API keys

## API keys

Every partner account receives two API keys:

| Key type | Prefix | Purpose |
| - | - | - |
| Sandbox | `sk_test_*` | Testing and development - no real charges |
| Production | `sk_live_*` | Live card issuance and transactions |

<Warning>
  Keep your API keys secret. Never expose them in client-side code, public repositories, or logs.
</Warning>

## Making requests

Include your API key in the `x-contro-api-key` header:

<CodeGroup>
  ```bash cURL theme={null}
  curl -X GET https://stg-api.contro.dev/v1/partner/balance \
    -H "x-contro-api-key: sk_test_your_key_here"
  ```

  ```typescript SDK (Node) theme={null}
  import Contro from "@contro/partner-sdk";

  const contro = new Contro({ apiKey: "sk_test_your_key_here" });
  const balance = await contro.balance.retrieve();
  ```

  ```python SDK (Python) theme={null}
  from contro_partner_sdk import Contro

  contro = Contro(api_key="sk_test_your_key_here")
  balance = contro.balance.retrieve()
  ```

  ```typescript TypeScript (fetch) theme={null}
  const response = await fetch("https://stg-api.contro.dev/v1/partner/balance", {
    headers: {
      "x-contro-api-key": "sk_test_your_key_here",
      "Content-Type": "application/json",
    },
  });

  const data = await response.json();
  ```
</CodeGroup>

## Environments

Contro provides two fully isolated environments, each with its own base URL, API keys, and dashboard:

| | Sandbox | Production |
| - | - | - |
| **Base URL** | `https://stg-api.contro.dev/v1` | `https://api.contro.me/v1` |
| **API key prefix** | `sk_test_*` | `sk_live_*` |
| **Dashboard** | [https://partner.contro.dev](https://partner.contro.dev) | [https://partner.contro.me](https://partner.contro.me) |
| **Card provider** | Simulated - no real charges | Live payment network |

* **Sandbox** - use for integration testing. No real funds are moved, cards are not issued to payment networks.
* **Production** - use for live operations. Real cards are issued and funds are debited from your balance.

<Note>
  Sandbox and production data are completely isolated. Cardholders and cards created in sandbox are not visible in production.
</Note>

## IP whitelisting

Restrict API access to specific IP addresses per environment via your dashboard **Settings** page.

* **Sandbox**: Supports `localhost` and `127.0.0.1` in addition to public IPs. An empty list allows all IPs.
* **Production**: Only public IPs are accepted. An empty list allows all IPs.

<Note>
  Changes take effect immediately for all subsequent API requests.
</Note>

## Allowed origins

Control which browser origins can call the Partner API by configuring **allowed origins** in dashboard **Settings**. This enforces CORS for browser-based consumers (e.g., frontend apps using the SDK via `fetch`).

* An empty list bypasses origin checks (all origins allowed).
* Server-to-server requests are unaffected — they don't send an `Origin` header.
* Origins must include the scheme (e.g., `https://app.example.com`).

## Rate limits

The Partner API allows **1,000 requests per minute** per API key.

| Header | Description |
| - | - |
| `X-RateLimit-Limit` | Maximum requests allowed per window |
| `X-RateLimit-Remaining` | Requests remaining in the current window |
| `X-RateLimit-Reset` | Unix timestamp when the window resets |

When you exceed the limit, the API returns `429 Too Many Requests` with a `Retry-After` header indicating how many seconds to wait.

## Key rotation

To rotate an API key, contact the Contro team. A new key will be issued and the old key will remain active for a grace period to allow migration.
