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

# Pass user ID

> How to include user id in requests to OpenStack.

To process authorization, analytics, and billing when enabled, every request must include a user identity. This guide shows exactly how to pass it from popular clients and runtimes.

<Warning>
  Avoid PII in user IDs. Prefer stable, pseudonymous strings (e.g., "user\_123"). Avoid spaces and special characters.
</Warning>

## Supported methods

1. Body field `user` — recommended (works with OpenAI‑compatible SDKs)
2. Header `X-Openstack-User` — easy to inject via middleware/proxy
3. URL prefix `/{user}/…` — fallback when body/headers cannot be modified

Base URL and auth for all examples:

* Base URL: `https://api.openstack.ai/v1`
* Header: `Authorization: Bearer $OPENSTACK_API_KEY`

<Tabs>
  <Tab title="Body `user` (recommended)">
    ```bash theme={null}
    POST /v1/chat/completions
    Authorization: Bearer sk-openstack-...
    Content-Type: application/json

    {
    "model": "gpt-5",
    "messages": [{"role": "user", "content": "Write a haiku about routing."}],
    "user": "user_12345"
    }

    ```
  </Tab>

  <Tab title="Header `X-Openstack-User`">
    ```bash theme={null}
    POST /v1/chat/completions
    Authorization: Bearer sk-openstack-...
    X-Openstack-User: user_12345
    Content-Type: application/json

    {
      "model": "gpt-5",
      "messages": [{"role": "user", "content": "Write a haiku about routing."}]
    }
    ```
  </Tab>

  <Tab title="URL prefix `/{user}/...` (fallback)">
    <Info>Use the URL prefix only if you cannot modify body/headers.</Info>

    ```bash theme={null}
    POST https://api.openstack.ai/v1/user_12345/chat/completions
    Authorization: Bearer sk-openstack-...
    Content-Type: application/json

    {
      "model": "gpt-5",
      "messages": [{"role": "user", "content": "Write a haiku about routing."}]
    }

    ```
  </Tab>
</Tabs>

## TypeScript (OpenAI SDK)

<Tabs>
  <Tab title="Body `user`">
    ```ts theme={null}
    import OpenAI from 'openai'

    const client = new OpenAI({
    apiKey: process.env.OPENSTACK_API_KEY,
    baseURL: 'https://api.openstack.ai/v1',
    })

    const resp = await client.chat.completions.create({
    model: 'gpt-5',
    user: 'user_123',
    messages: [{ role: 'user', content: 'Write a haiku about routing.' }],
    })

    ```
  </Tab>

  <Tab title="Header `X-Openstack-User`">
    ```ts theme={null}
    import OpenAI from 'openai'

    const client = new OpenAI({
      apiKey: process.env.OPENSTACK_API_KEY,
      baseURL: 'https://api.openstack.ai/v1',
      defaultHeaders: { 'X-Openstack-User': 'user_123' },
    })

    const resp = await client.chat.completions.create({
      model: 'gpt-5',
      messages: [{ role: 'user', content: 'Hi!' }],
    })
    ```
  </Tab>
</Tabs>

## Python (OpenAI SDK)

<Tabs>
  <Tab title="Body `user`">
    ```python theme={null}
    from openai import OpenAI
    import os

    client = OpenAI(
    api_key=os.environ["OPENSTACK_API_KEY"],
    base_url="https://api.openstack.ai/v1"
    )

    resp = client.chat.completions.create(
    model="gpt-5",
    user="user_123",
    messages=[{"role": "user", "content": "Summarize usage-based billing."}],
    )

    ```
  </Tab>

  <Tab title="Header `X-Openstack-User`">
    ```python theme={null}
    from openai import OpenAI
    import os

    client = OpenAI(
        api_key=os.environ["OPENSTACK_API_KEY"],
        base_url="https://api.openstack.ai/v1",
        default_headers={"X-Openstack-User": "user_123"}
    )

    resp = client.chat.completions.create(
        model="gpt-5",
        messages=[{"role": "user", "content": "Summarize usage-based billing."}],
    )
    ```
  </Tab>
</Tabs>

## Behavior summary

On each request OpenStack extracts the user id (body > header > URL), checks authorization and (if billing is on) balance, and either:

* Returns an assistant message with an authorization/top‑up link (no charge), or
* Forwards the request, meters usage, optionally deducts balance, and streams the model response.

## Best practices

* Use body `user` when possible; header is a great middleware fallback.
* Keep IDs stable across sessions and retries. Avoid PII.
* Ensure your server/edge passes the user on every billable request.

## What makes a good user id

A short, pseudonymous, stable string (e.g., `user_abc123`) that you reuse across sessions and retries. Avoid emails/phone numbers or other PII and keep the id unique within your app or tenant.

<Note>
  If your auth system changes, keep a mapping in your app so you can continue sending a stable id to OpenStack.
</Note>

## Special cases

For guests, mint and persist a random id early. On shared devices, prefer logins; if not, map the device in your system but keep the id stable. Give service/bot accounts dedicated ids rather than reusing human ones.

## Rotation & migration

If you must rotate, maintain a mapping so the effective id you send stays the same. Avoid mid-session changes to prevent fragmented balances and analytics.

## Test & staging users

Label staging/test ids clearly (e.g., `test_alice`) so you can filter them. Keep keys off the browser; use server or edge calls.

## Format recommendations

Use URL‑safe ASCII without spaces, keep it reasonably short (less than 128 chars is a good rule), and treat it as an opaque string—you decide its meaning.

## Privacy & security

Pseudonymous ids reduce risk and compliance scope. Don’t embed sensitive information in ids or metadata. See [Security & compliance](/more/security-compliance) and [Privacy](/privacy) for details.
