# How to Configure the Biohub Platform API Client with Proper Authentication Tokens

> Configure the Biohub Platform API client using environment variables, factory function tokens, or Jupyter login. The SDK automatically validates and adds your authentication token for secure API access.

- Repository: [Biohub/esm](https://github.com/Biohub/esm)
- Tags: how-to-guide
- Published: 2026-05-30

---

**You can authenticate the Biohub Platform API client by setting the `ESM_API_KEY` environment variable, passing a `token` argument directly to factory functions, or using the interactive Jupyter login widget, with the SDK automatically validating the token and attaching it as a Bearer header to every request.**

The Biohub (`esm`) Python SDK provides seamless access to the Biohub Platform inference API (formerly Forge). To configure the Biohub Platform API client with proper authentication tokens, you can leverage environment variables, explicit parameters, or interactive widgets, with the underlying implementation in [`esm/sdk/base_forge_client.py`](https://github.com/Biohub/esm/blob/main/esm/sdk/base_forge_client.py) handling Bearer token formatting automatically.

## Authentication Methods Overview

The SDK supports three distinct approaches for supplying credentials, all converging on the same underlying validation logic.

According to the source code in [`esm/sdk/__init__.py`](https://github.com/Biohub/esm/blob/main/esm/sdk/__init__.py), the factory functions `client()`, `esmc_client()`, and `esmfold2_client()` attempt to read from the `ESM_API_KEY` environment variable by default via `os.environ.get("ESM_API_KEY", "")`. These functions also accept explicit `token` parameters that bypass environment lookup. Additionally, the Jupyter widget interface in [`esm/widgets/views/login.py`](https://github.com/Biohub/esm/blob/main/esm/widgets/views/login.py) provides an interactive alternative that can optionally persist tokens to the environment.

## Method 1: Environment Variable Configuration

The simplest approach uses shell environment variables. Set `ESM_API_KEY` before launching your Python interpreter, and the factory functions will detect it automatically.

First, export your token in the shell:

```bash
export ESM_API_KEY="sk_live_XXXXXXXXXXXXXXXX"

```

Then instantiate the client without explicit arguments:

```python
from esm.sdk import client

esm3 = client(model="esm3-small-2024-03")   # URL defaults to https://biohub.ai

protein = esm3.encode(input="MALWMRLLPLLALLALAVPDPAAA")

```

The `client()` function reads `os.environ.get("ESM_API_KEY", "")` and forwards the value to the underlying Forge client class during construction.

## Method 2: Explicit Token Arguments

For scenarios requiring multiple tokens or temporary credentials, pass the `token` parameter directly to bypass environment variable lookup.

```python
from esm.sdk import client

my_token = "sk_live_XXXXXXXXXXXXXXXX"
esm3 = client(
    model="esm3-small-2024-03",
    url="https://biohub.ai",
    token=my_token,
)

```

This method immediately forwards the token to the `_BaseForgeInferenceClient` constructor in [`esm/sdk/base_forge_client.py`](https://github.com/Biohub/esm/blob/main/esm/sdk/base_forge_client.py), where it is stored for subsequent request header generation.

## Method 3: Interactive Jupyter Login Widget

For notebook environments, the SDK provides a UI component in [`esm/widgets/views/login.py`](https://github.com/Biohub/esm/blob/main/esm/widgets/views/login.py) that handles token input and optional environment persistence.

Initialize the widget interface:

```python
from esm.widgets.views.login import create_login_ui
from esm.widgets.utils.types import ClientInitContainer

container = ClientInitContainer()
login_ui = create_login_ui(container)
display(login_ui)          # Show the UI in a notebook

```

After pasting the token and clicking **Login**, the widget optionally writes to `os.environ["ESM_API_KEY"]` and prepares `container.client_init_callback`. Retrieve the configured client:

```python
client = container.client_init_callback()
result = client.encode(input="MALWMRLLPLLALLALAVPDPAAA")

```

## Token Validation and HTTP Header Construction

Authentication enforcement occurs in the `_BaseForgeInferenceClient` class within [`esm/sdk/base_forge_client.py`](https://github.com/Biohub/esm/blob/main/esm/sdk/base_forge_client.py). During initialization, the constructor validates the token:

```python

# From esm/sdk/base_forge_client.py

if token == "":
    raise RuntimeError(
        "Please provide a token to connect to Forge/Biohub Platform via token=YOUR_API_TOKEN_HERE"
    )

```

Once validated, every HTTP request prepares the authorization header through the `prepare_request()` method, which merges `Authorization: Bearer <token>` into the request headers. This ensures consistent authentication across all inference calls without manual header management.

## Testing Configuration

The test suite in [`tests/oss_pytests/test_oss_client.py`](https://github.com/Biohub/esm/blob/main/tests/oss_pytests/test_oss_client.py) demonstrates the expected environment variable pattern for continuous integration:

```python
import os
from esm.sdk import client

API_TOKEN = os.environ.get("ESM_API_KEY", "")
URL = os.environ.get("URL")
esm3_client = client(model="esm3-small-2024-03", url=URL, token=API_TOKEN)

```

Configure your CI environment with both `ESM_API_KEY` and `URL` variables to match this pattern.

## Summary

- **Environment Variable**: Set `ESM_API_KEY` in your shell, and `esm.sdk` factory functions automatically detect and forward the token to the Biohub Platform API.
- **Explicit Parameter**: Pass `token=` directly to `client()`, `esmc_client()`, or `esmfold2_client()` to override environment settings.
- **Jupyter Widget**: Use `create_login_ui()` from [`esm/widgets/views/login.py`](https://github.com/Biohub/esm/blob/main/esm/widgets/views/login.py) for interactive token input with optional environment persistence.
- **Validation**: The `_BaseForgeInferenceClient` raises a clear `RuntimeError` if the token is empty, and automatically formats the `Authorization: Bearer` header for all requests.
- **Source Files**: Key implementation resides in [`esm/sdk/__init__.py`](https://github.com/Biohub/esm/blob/main/esm/sdk/__init__.py) (factory functions) and [`esm/sdk/base_forge_client.py`](https://github.com/Biohub/esm/blob/main/esm/sdk/base_forge_client.py) (validation and header construction).

## Frequently Asked Questions

### What format should the API token be in?

The token should be a string value that the Biohub Platform issued for your account. The SDK automatically prefixes it with `Bearer ` in the HTTP `Authorization` header, so you should provide only the raw token value without the "Bearer" prefix.

### What happens if I forget to provide a token?

If the token resolves to an empty string (neither provided via environment variable nor explicit argument), the `_BaseForgeInferenceClient` constructor raises a `RuntimeError` with the message: "Please provide a token to connect to Forge/Biohub Platform via token=YOUR_API_TOKEN_HERE".

### Can I use the same token for different model clients?

Yes. The same authentication token works across different model-specific factory functions. You can instantiate multiple clients (e.g., `client()` for ESM3, `esmc_client()` for ESMC) using the identical token value, as authentication is account-based rather than model-specific.

### How do I update a token in a running Jupyter session without restarting the kernel?

Set `os.environ["ESM_API_KEY"] = "new_token_value"` directly in your notebook cell, then instantiate a new client. Alternatively, re-run the `create_login_ui()` widget to input a new token interactively, which will update the environment variable if the persistence checkbox is selected.