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

# Authentication

> How to pass your API key to the SDK and override the base URL.

The Spine API uses API keys sent as the `X-API-KEY` request header. The
SDK adds the header for you on every request — you just need to give it
a key.

## Passing the key

<CodeGroup>
  ```python Environment variable (preferred) theme={"theme":{"light":"github-light","dark":"tokyo-night"}}
  # Shell:
  # export SPINE_API_KEY=sk_spine_...

  from spine import SpineClient

  with SpineClient() as client:
      ...
  ```

  ```python Explicit argument theme={"theme":{"light":"github-light","dark":"tokyo-night"}}
  from spine import SpineClient

  with SpineClient(api_key="sk_spine_...") as client:
      ...
  ```
</CodeGroup>

<Warning>
  Never commit keys to source control. Use your deployment platform's
  secret manager (AWS Secrets Manager, 1Password, Doppler, etc.) and
  inject them at runtime.
</Warning>

If no key is provided and `SPINE_API_KEY` is unset, `SpineClient()`
raises `ValueError` immediately — before any network call.

## Key rotation

Keys revoked in the dashboard stop working on the next request; you'll
see `AuthenticationError` raised from the SDK. Roll new keys through
your secret store before revoking the old one so running processes
don't break mid-run.

## Overriding the base URL

Point the SDK at a staging or enterprise deployment via `base_url` (or
the `SPINE_BASE_URL` env var):

```python theme={"theme":{"light":"github-light","dark":"tokyo-night"}}
client = SpineClient(base_url="https://staging.getspine.ai")
```

The SDK appends `/v1` automatically, so pass the host without the API
prefix.

## Injecting your own HTTP client

For advanced cases (custom proxies, SSL contexts, test doubles), pass a
pre-configured `httpx.Client` or `httpx.AsyncClient`. The SDK still
applies the `X-API-KEY` and `User-Agent` headers — your client does not
need to set them.

```python theme={"theme":{"light":"github-light","dark":"tokyo-night"}}
import httpx
from spine import SpineClient

transport = httpx.HTTPTransport(proxy="http://corp-proxy:8080")
http_client = httpx.Client(transport=transport, base_url="https://api.getspine.ai/v1")

with SpineClient(http_client=http_client) as client:
    ...
```

When you inject a client, the SDK does **not** close it on `__exit__` —
that's your responsibility.
