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

# Per-user attribution

> See cost and usage per customer by tagging calls with a user id.

If you serve many end-users, tag each call with **your** user id. Orbitrage then
breaks down cost, usage, and flow graphs per customer — inside one project. It's
your own data about your own users.

## One user per process

```python theme={null}
import orbitrage
orbitrage.init(api_key, user_id=current_user.id)
```

## A multi-tenant server

Set the user at the start of each request, then build the client.

<CodeGroup>
  ```python Python (FastAPI) theme={null}
  import os, orbitrage
  orbitrage.init(os.environ["ORBITRAGE_API_KEY"])

  from fastapi import FastAPI, Request
  from openai import OpenAI
  app = FastAPI()

  @app.post("/chat")
  def chat(request: Request, body: dict):
      orbitrage.set_user(body["user_id"])     # tag this request's calls
      client = OpenAI()                        # construct AFTER set_user
      resp = client.chat.completions.create(
          model="minimax-m3",
          messages=body["messages"],
      )
      return resp.choices[0].message.content
  ```

  ```typescript Node.js (Express) theme={null}
  import { orbitrage } from "orbitrage";
  await orbitrage.init({ apiKey: process.env.ORBITRAGE_API_KEY });

  import express from "express";
  import OpenAI from "openai";
  const app = express();

  app.post("/chat", express.json(), async (req, res) => {
    await orbitrage.withAssociationProperties({ user_id: req.body.userId }, async () => {
      const resp = await new OpenAI().chat.completions.create({
        model: "minimax-m3",
        messages: req.body.messages,
      });
      res.send(resp.choices[0].message.content);
    });
  });
  ```
</CodeGroup>

<Warning>
  In Python, construct the `OpenAI()` client **after** `set_user()` — already-built
  clients keep their original headers. Node's `withAssociationProperties` scopes
  the user to the block, so any client built inside it is tagged.
</Warning>

## What you get

In the dashboard, filter any workflow by end-user to see:

* spend and call volume per customer,
* their per-run flow graph,
* and churn / frustration signals in the [Intelligence layer](/concepts/intelligence).

<Note>
  Set only `x-orbitrage-end-user-id` (what `user_id` does). Never send
  `x-orbitrage-user-id` — that's the gateway's account identity and returns 403.
</Note>
