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

# Create a sandbox access token

> Authenticate sandbox requests and MCP connections with a short-lived sandbox access token instead of your Baseten API key.

A *sandbox access token* is a short-lived credential for working with
sandboxes. Sandbox requests to `/v1/sandboxes` and a sandbox's MCP server
both require a token, not your Baseten API key.

The Baseten CLI and SDKs create and refresh tokens for you. Request one
yourself when your application calls the sandbox API or connects an MCP client
directly.

Your application calls
[`POST /v1/token`](/reference/management-api/sandboxes/create-a-sandbox-access-token)
with its API key and uses the returned token for everything else. A token
expires after 2 hours and can't be renewed.

| Credential | Authenticates |
| - | - |
| Baseten API key | [`POST /v1/token`](/reference/management-api/sandboxes/create-a-sandbox-access-token), to create a token. |
| Sandbox access token | Sandbox and image requests under `/v1/sandboxes`, and a sandbox's MCP server. |

A token carries your [team memberships](/organization/teams), so it isn't
scoped to one sandbox. Creating a token doesn't create a sandbox or grant
additional permissions. Keep both credentials out of agent prompts and out of
code you submit to a sandbox.

The token endpoint is experimental. Create tokens with a
[personal API key](/organization/api-keys#create-an-api-key) or a team API key
with full access.

## Request a token

Call [Create a sandbox access token](/reference/management-api/sandboxes/create-a-sandbox-access-token)
with the `sandboxes` scope:

<Tabs>
  <Tab title="curl">
    ```bash theme={"system"}
    curl --request POST \
      --url https://api.baseten.co/v1/token \
      --header "Authorization: Bearer $BASETEN_API_KEY" \
      --header "Content-Type: application/json" \
      --data '{"scopes": ["sandboxes"]}'
    ```
  </Tab>

  <Tab title="Python">
    ```python theme={"system"}
    import os

    import requests

    response = requests.post(
        "https://api.baseten.co/v1/token",
        headers={"Authorization": f"Bearer {os.environ['BASETEN_API_KEY']}"},
        json={"scopes": ["sandboxes"]},
    )
    response.raise_for_status()
    token = response.json()["token"]
    ```
  </Tab>
</Tabs>

A successful request returns HTTP `200` with the token and its expiration:

```json theme={"system"}
{
  "token": "eyJhbGciOi...",
  "expires_at": "2026-10-01T20:00:00Z"
}
```

A successful request returns HTTP `200` with these fields. Don't record the
token in application logs.

<ResponseField name="token" type="string">
  Short-lived bearer token for sandbox requests and a sandbox's MCP server.
</ResponseField>

<ResponseField name="expires_at" type="string">
  Token expiration time in ISO 8601 format.
</ResponseField>

Send the token in the `Authorization: Bearer <TOKEN>` header of sandbox
requests and of your MCP client's configuration.

## Replace expired tokens

You can't renew a token. Request a new one before the current token's
`expires_at` time. A token can also stop working early if your team
memberships or role change. If a previously valid token is rejected, request a
new one.

A token's expiration is separate from the [sandbox's](/sandboxes/lifecycle):
an expired token doesn't delete the sandbox, and a new token doesn't extend the
sandbox's lifetime.

## Next steps

<CardGroup cols={2}>
  <Card title="Manage sandboxes" icon="server" href="/sandboxes/manage">
    Create, inspect, and delete sandboxes with the Baseten CLI.
  </Card>

  <Card title="Manage sandbox images" icon="box" href="/sandboxes/manage-images">
    Choose a built-in image, or create and version your own.
  </Card>
</CardGroup>
