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

# Authenticating API Requests

> Every Proxy, Unified API and MCP request carries two things: your API key, and the connection ID of the account to act on.

Every request to the Proxy, Unified API or MCP needs two values:

| Header | Value | What it does |
| - | - | - |
| `Authorization` | `Bearer YOUR_API_KEY` | Identifies your workspace. Used for access control, rate limiting and billing. |
| `BU-Connection-Id` | `conn_abc123` | Picks which connected account the request acts on. |

```bash theme={null}
curl https://proxy.bundleup.io/user \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "BU-Connection-Id: conn_abc123"
```

The [Platform API](/docs/api-reference/introduction) and the [code exchange](/docs/api-reference/auth/exchange-code) only need the `Authorization` header, since they don’t act on a specific account.

## How BundleUp checks a request

Before anything reaches the provider:

1. The API key is looked up. Missing or unknown → `401` (on the Unified API, a missing key is a `400` validation error).
2. The connection is looked up and must belong to **the same workspace** as the API key. Missing, unknown, deleted or from another workspace → `400 connection_invalid` (on the Unified API, `404`).
3. The connection’s [rate limit](/docs/guides/proxy/rate-limits) is checked. Over the limit → `429`.

If a check fails, nothing is sent to the provider.

There’s no separate permission per connection: any API key in a workspace can use any connection in that workspace. Keep your connection-to-user mapping in your own database, and make sure your code only uses the connection that belongs to the current user.

## Your `Authorization` header is replaced

BundleUp removes your `Authorization` header and sets the provider’s one, containing the user’s access token, before forwarding. Your API key is never sent to the provider. `BU-` headers are also removed.

## Single-token form

Some clients can only send one credential and can’t add a second header. Model-hosted MCP (OpenAI’s and Anthropic’s MCP connectors) is the common case. For those, join the API key and connection ID with a dot:

```http theme={null}
Authorization: Bearer YOUR_API_KEY.conn_abc123
```

BundleUp splits the value on the first `.`. API keys and connection IDs never contain a dot, so this is unambiguous. If you also send `BU-Connection-Id`, the header wins.

This form works on the Proxy and MCP. The Unified API always requires the `BU-Connection-Id` header. See [Using MCP clients](/docs/guides/mcp/clients).

## With the SDKs

The SDKs take the API key once and the connection ID per call:

<CodeGroup>
  ```typescript JavaScript theme={null}
  const client = new BundleUp(process.env.BUNDLEUP_API_KEY);

  const proxy = client.proxy('conn_abc123');
  const unify = client.unify('conn_abc123');
  const mcp = client.mcp('conn_abc123');
  ```

  ```python Python theme={null}
  client = BundleUp(os.environ["BUNDLEUP_API_KEY"])

  proxy = client.proxy("conn_abc123")
  unify = client.unify("conn_abc123")
  mcp = client.mcp("conn_abc123")
  ```

  ```ruby Ruby theme={null}
  client = BundleUp::Client.new(ENV['BUNDLEUP_API_KEY'])

  proxy = client.proxy('conn_abc123')
  unify = client.unify('conn_abc123')
  mcp = client.mcp('conn_abc123')
  ```
</CodeGroup>

## Errors

| Status | Body | Cause |
| - | - | - |
| `401` | `{"status": 401, "message": "Not authorized"}` | Missing or unknown API key. |
| `400` | `{"code": "connection_invalid", "message": "Missing or invalid connection ID", "status": 400}` | Missing connection ID, or not in this workspace. |
| `429` | `{"code": "rate_limit", "message": "Too many requests", "status": 429}` | Over 100 requests in 60 seconds on this connection. |

The Unified API uses a different error envelope. See the [errors reference](/docs/api-reference/errors).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.