# Endpoints

Every DirectInference request goes to one host with one key. This page is the full URL map across all three API surfaces plus the account & billing REST API. Each surface has a dedicated guide with request and response detail — the links are below each table.

## Base URL and authentication

The advertised, API-only host is `https://api.directinference.com`. Every endpoint sits under the zero-knowledge DI base path `/di`. The authentication header is the one your client already uses for that vendor — point it at DirectInference and pass an `llm_live_…` key.

| Surface | Base URL | Auth header |
| --- | --- | --- |
| OpenAI-compatible | `https://api.directinference.com/di/v1` | `Authorization: Bearer llm_live_…` |
| Anthropic Messages | `https://api.directinference.com/di` — _the SDK appends `/v1/messages`_ | `x-api-key: llm_live_…` (or `Authorization: Bearer`) |
| Gemini | `https://api.directinference.com/di` — _the SDK appends `/v1beta/models/…`_ | `x-goog-api-key: llm_live_…` (or `?key=` / `Authorization: Bearer`) |

Full per-surface auth detail — including the header each SDK sets for you — is in [Authentication](https://docs.directinference.com/authentication/).

:::note[Hosts and the legacy root path]
`api.directinference.com` is the advertised host; use it for new integrations. The same API is also served at `app.directinference.com` for existing integrations. The surfaces also answer at the root (without the `/di` prefix) for older clients, but new integrations should use the `…/di` base shown here — it is the zero-knowledge surface where any `model` id resolves and is echoed back.
:::

## OpenAI-compatible

| Method | Endpoint | Purpose |
| --- | --- | --- |
| `POST` | `https://api.directinference.com/di/v1/chat/completions` | Chat Completions. Stream with `"stream": true`. |
| `POST` | `https://api.directinference.com/di/v1/responses` | Responses API (served statelessly). |
| `GET` | `https://api.directinference.com/di/v1/models` | List the DI Model — `di-fusion`, `di-saver`, `di-max`. |

Request and response detail, including tools, vision, structured output, and supported parameters, is in the [OpenAI-compatible](https://docs.directinference.com/openai/) guide.

## Anthropic Messages

| Method | Endpoint | Purpose |
| --- | --- | --- |
| `POST` | `https://api.directinference.com/di/v1/messages` | Messages API. Stream with `"stream": true`. |
| `POST` | `https://api.directinference.com/di/v1/messages/count_tokens` | Count tokens for a Messages request. |
| `GET` | `https://api.directinference.com/di/v1/models` | List models. `client.models.list()` reads this in the Anthropic models shape. |

Full detail — `tool_use`, streaming, `cache_control`, and the response envelope — is in the [Anthropic Messages](https://docs.directinference.com/anthropic/) guide.

## Gemini

The model and method live in the URL path — `models/{model}:method` — not the body. Any `{model}` id (for example `gemini-2.5-flash`) is accepted and echoed back as `modelVersion`.

| Method | Endpoint | Purpose |
| --- | --- | --- |
| `POST` | `https://api.directinference.com/di/v1beta/models/{model}:generateContent` | Generate content. |
| `POST` | `https://api.directinference.com/di/v1beta/models/{model}:streamGenerateContent?alt=sse` | Streaming generate content (SSE). |
| `POST` | `https://api.directinference.com/di/v1beta/models/{model}:countTokens` | Count tokens. |
| `GET` | `https://api.directinference.com/di/v1beta/models` | List models. |

Full detail — function calling, streaming, and `countTokens` — is in the [Gemini](https://docs.directinference.com/gemini/) guide.

## Model discovery

`GET /di/v1/models` lists the DI Model three ways: `di-fusion` (the default), plus `di-saver` and `di-max` — the same model with the effort knob pinned low and high, not separate models. Every entry carries `root: "di-fusion"`. Listing requires authentication.

```bash
curl https://api.directinference.com/di/v1/models \
  -H "Authorization: Bearer llm_live_..."
```

```python
from openai import OpenAI

client = OpenAI(
    api_key="llm_live_...",
    base_url="https://api.directinference.com/di/v1",
)

for m in client.models.list().data:
    print(m.id, "->", m.root)   # di-fusion -> di-fusion, di-saver -> di-fusion, ...
```

```typescript
import OpenAI from "openai";

const client = new OpenAI({
  apiKey: "llm_live_...",
  baseURL: "https://api.directinference.com/di/v1",
});

for (const m of (await client.models.list()).data) {
  console.log(m.id, "->", (m as any).root); // di-fusion -> di-fusion, ...
}
```

A successful response (abridged):

```json
{
  "object": "list",
  "data": [
    {
      "id": "di-fusion",
      "object": "model",
      "owned_by": "direct-inference",
      "root": "di-fusion",
      "context_length": 262144,
      "top_provider": { "context_length": 262144, "max_completion_tokens": 32768 },
      "supported_parameters": [
        "max_tokens", "temperature", "top_p", "stop", "stream",
        "response_format", "reasoning_effort", "reasoning", "tools", "tool_choice"
      ]
    },
    { "id": "di-saver", "object": "model", "root": "di-fusion", "...": "same shape" },
    { "id": "di-max",   "object": "model", "root": "di-fusion", "...": "same shape" }
  ]
}
```

:::note[Read the catalog at runtime]
The token-limit fields — `context_length` and `top_provider.max_completion_tokens` — reflect the live model and can change, so read them from this endpoint rather than hardcoding the values shown above. There is nothing else to pin: there is no model to choose, and any other `model` id you send is treated as intent and echoed back unchanged. See [Capabilities](https://docs.directinference.com/capabilities/).
:::

## Account & billing

A small read-only REST API reports balance and usage. It is account-scoped to the calling key and zero-knowledge — costs come back in USD, and no backend model, provider, or upstream price is ever exposed.

| Method | Endpoint | Purpose |
| --- | --- | --- |
| `GET` | `https://api.directinference.com/di/v1/credits` | Prepaid balance and total used. |
| `GET` | `https://api.directinference.com/di/v1/usage` | Aggregate usage; `group_by` of `day`, `request_type`, `application`, or `api_key`, with optional `start_date` / `end_date`. |
| `GET` | `https://api.directinference.com/di/v1/generation?id=<completion-id>` | Cost and token usage for one request, keyed by its response `id`. |

```bash
curl https://api.directinference.com/di/v1/credits \
  -H "Authorization: Bearer llm_live_..."
# {"balance":"9.800000","total_used":"0.200000"}
```

See [Spend & limits](https://docs.directinference.com/spend/) for caps and the balance lifecycle, and [Usage & analytics](https://docs.directinference.com/usage/) for the in-portal breakdown.

## Response feedback

Rate a response your application received, keyed by the `id` on the completion your code already holds — the same `id` accepted by `GET /v1/generation`. It is one REST call, no SDK required.

| Method | Endpoint | Purpose |
| --- | --- | --- |
| `POST` | `https://api.directinference.com/di/v1/feedback` | Record a thumbs `up` / `down` (plus optional comment, labels, and an opaque end-user id) on one response. |

```bash
curl https://api.directinference.com/di/v1/feedback \
  -H "Authorization: Bearer llm_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "id": "chatcmpl-abc123",
    "rating": "up",
    "comment": "resolved the ticket cleanly",
    "labels": {"category": "support", "helpful": true},
    "end_user": "acct_7f3a"
  }'
# {"object":"feedback","id":"chatcmpl-abc123","rating":"up","recorded":true,"end_user":"acct_7f3a"}
```

- `id` (required) is the response id you received; `rating` (required) is `up` or `down`.
- `comment` is free text; `labels` is a flat object of string / number / boolean annotations; `end_user` is any opaque string you use to attribute the rating — DI never learns who your users are.
- Re-submitting for the same `(id, end_user)` updates the existing rating rather than adding a duplicate.
- An unknown or foreign `id` returns `404`; a response older than 30 days returns `409`. The endpoint is zero-knowledge and does not count toward usage.

## Errors

Each surface returns its native error envelope, and authentication, rate-limit, and spend-cap behavior is shared. Status codes (`400`, `401`, `402`, `413`, `429`, `5xx`) and retry guidance are in [Errors & limits](https://docs.directinference.com/errors/); the observability headers every response carries are in [Response headers](https://docs.directinference.com/headers/).

## Dive into a surface

[OpenAI-compatible](https://docs.directinference.com/openai/)
  [Anthropic Messages](https://docs.directinference.com/anthropic/)
  [Gemini](https://docs.directinference.com/gemini/)
  [Quickstart](https://docs.directinference.com/quickstart/)