
# Run your first completion

This page sends one chat completion through the gateway, walks through
what came back, and points at the things you'll come back to.

## Send the request

Set your key in an environment variable so it doesn't end up in shell
history:

```bash
export LOWROUTER_API_KEY="sk-lr-..."
```

Then call the gateway:

```bash
curl https://api.lowrouter.ai/v1/chat/completions \
  -H "Authorization: Bearer $LOWROUTER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "auto/mistralai/mistral-large-2512",
    "messages": [
      {"role": "user", "content": "In one sentence, what is a vector database?"}
    ]
  }'
```

An `auto/<creator>/<model>` ID names the model you want and leaves the
route to us: among the providers and regions serving it, LowRouter
prefers EU-sovereign routes, then the lowest-carbon one (modeled from
annual grid averages — see the
[methodology](../sustainable-ai/methodology)). You get the same model
either way — only where it runs is decided for you.

The `model` field is required. You can name the route yourself
instead, for example `openai/openai/gpt-4.1/global` or
`anthropic/anthropic/claude-haiku-4.5/global`, pinning a region with a
UN/LOCODE as the fourth segment (e.g.
`vertex/anthropic/claude-opus-4.6/sg-sin`), or call an alias you can
repoint later without changing code. See
[routing](../models/routing). Custom auto-routing policies (like a
per-key carbon budget) are coming soon.

## What comes back

The response is OpenAI-shaped. The fields you'll use most are:

```json
{
  "id": "chatcmpl-01J9...",
  "object": "chat.completion",
  "created": 1714150000,
  "model": "openai/openai/gpt-4.1",
  "choices": [
    {
      "index": 0,
      "message": {
        "role": "assistant",
        "content": "A vector database stores …"
      },
      "finish_reason": "stop"
    }
  ],
  "usage": {
    "prompt_tokens": 18,
    "completion_tokens": 26,
    "total_tokens": 44,
    "cost": 0.000034,
    "currency": "EUR",
    "remaining_balance": 9.87
  },
  "lowrouter_metadata": {
    "provider": "openai",
    "region": "eu-west",
    "energy_wh": 0.0021,
    "carbon_gco2e": 0.00057,
    "carbon_intensity_gco2_per_kwh": 45.0,
    "estimation_methodology": "parameter-based",
    "routing_mode": "auto",
    "routing_reason": "lowest_carbon_intensity",
    "fallback_occurred": false,
    "providers_attempted": ["openai"]
  }
}
```

The OpenAI-compatible parts (`id`, `choices`, `usage`, …) follow the
standard OpenAI Chat Completions shape. LowRouter adds three billing
fields to `usage`:

- **`cost`** — what this request cost, in `currency`. This is the
  per-request figure: attribute it to a user, tenant, or workflow
  without scraping a dashboard or maintaining your own price table.
- **`currency`** — ISO-4217 code for `cost` and `remaining_balance`
  (`EUR`).
- **`remaining_balance`** — your credit balance after this request.

Costs are billed in integer micros (millionths of a euro) and rounded
up to the next micro, so a request never bills below what it cost us.
On very small requests that rounding is visible: the amount you are
charged can exceed the exact computed cost by up to €0.000001.

The `lowrouter_metadata` block carries the LowRouter-specific fields:

- **`provider`** — which upstream actually served the request.
- **`region`** — the region the upstream served from.
- **`energy_wh`** and **`carbon_gco2e`** — the energy and carbon
  estimate for this request. Read
  [methodology](../sustainable-ai/methodology) before quoting these
  numbers anywhere.
- **`routing_mode`**, **`routing_reason`**, **`fallback_occurred`**,
  and **`providers_attempted`** — the routing trace: how the model was
  picked and whether a fallback was used.

To look up the full record for a request later, open its transaction
on the dashboard.

## Stream the response

For interactive UIs, set `"stream": true` and read Server-Sent Events:

```bash
curl https://api.lowrouter.ai/v1/chat/completions \
  -H "Authorization: Bearer $LOWROUTER_API_KEY" \
  -H "Content-Type: application/json" \
  -N \
  -d '{
    "model": "auto/mistralai/mistral-large-2512",
    "stream": true,
    "messages": [{"role": "user", "content": "Count to 5 slowly"}]
  }'
```

The stream is a Server-Sent Events stream in the same format the
OpenAI streaming API uses, so any OpenAI-compatible SDK consumes it
unchanged. See [integrations](../integrations/) for per-SDK snippets.

Streaming does not cost you cost attribution. The final chunk before
`data: [DONE]` carries `lowrouter_metadata` and a `usage` object with
the same `cost`, `currency`, and `remaining_balance` fields the
non-streaming response returns:

```json
{
  "object": "chat.completion.chunk",
  "choices": [],
  "usage": {
    "cost": 0.000034,
    "currency": "EUR",
    "remaining_balance": 9.87
  },
  "lowrouter_metadata": { "provider": "openai", "...": "..." }
}
```

Token counts appear exactly once across the stream. If the upstream
provider already sent a usage chunk with `prompt_tokens` /
`completion_tokens` / `total_tokens`, this final chunk carries the
money fields only rather than restating them — so read tokens from
whichever chunk carries them, and cost from the final one.

If a stream is cut short — you cancel it, your client times out, or
the connection drops — you are still billed for the tokens the
provider generated before the cut. Those requests are marked
`interrupted` on the dashboard, in the CSV export, and on the
generation record, so you can reconcile them against your own logs.

## Things that might surprise you

- **The `model` in the response is the resolved four-segment ID**,
  not necessarily the string you sent. If you sent an `auto/` or
  `alias/` ID, the response tells you which route actually ran.
- **`usage` reflects upstream tokens**, which may include caching
  discounts (for providers that support them). The credits charged on
  your dashboard match this `usage`.
- **The carbon estimate is absent on requests we couldn't classify**,
  e.g. a model whose parameter count is unknown. The dashboard shows
  the same record without an eco number rather than a fabricated one.

## If it didn't work

A 401, 402, or 404 here almost always means a key, balance, or
model-id problem. The [errors reference](../guides/errors) lists every
payload the gateway returns, with the one-line fix for each.

## Next

[Tour the dashboard →](dashboard-tour)
