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

# Calling a model deployment

> OpenAI-compatible inference against a promoted deployment revision.

```bash theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
curl https://starforge.your-company.com/inference/dep-7c1e/v1/chat/completions \
  -H "Authorization: Bearer $DEPLOYMENT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "default",
    "messages": [{"role": "user", "content": "Summarise this contract clause."}]
  }'
```

The path is stable, the body is whatever the serving engine accepts, and the response is whatever it
returns. StarForge authenticates the call, routes it to the deployment's currently promoted
revision, and records it — it does not reshape the payload.

## Base URL

```text theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
https://<your deployment domain>/inference/{deployment_id}/v1
```

Point any OpenAI-compatible client at that, and it works unchanged:

<CodeGroup>
  ```python Python theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
  from openai import OpenAI

  client = OpenAI(
      base_url="https://starforge.your-company.com/inference/dep-7c1e/v1",
      api_key=os.environ["DEPLOYMENT_TOKEN"],
  )

  response = client.chat.completions.create(
      model="default",
      messages=[{"role": "user", "content": "Summarise this contract clause."}],
  )
  ```

  ```typescript TypeScript theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
  import OpenAI from "openai";

  const client = new OpenAI({
    baseURL: "https://starforge.your-company.com/inference/dep-7c1e/v1",
    apiKey: process.env.DEPLOYMENT_TOKEN,
  });

  const response = await client.chat.completions.create({
    model: "default",
    messages: [{ role: "user", content: "Summarise this contract clause." }],
  });
  ```

  ```bash curl theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
  curl https://starforge.your-company.com/inference/dep-7c1e/v1/models \
    -H "Authorization: Bearer $DEPLOYMENT_TOKEN"
  ```
</CodeGroup>

Everything under `/v1` is proxied through: `chat/completions`, `completions`, `embeddings`,
`models`, and anything else the [serving engine](/en/guides/playground) exposes. Streaming works.

## Authentication

Only a **deployment token** opens this path. Not your login token, not an ingest token.

```bash theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
export DEPLOYMENT_TOKEN=sfd_...
```

| Property   | Behaviour                                                                      |
| ---------- | ------------------------------------------------------------------------------ |
| Scope      | One deployment. A token for `dep-7c1e` is rejected by `dep-9a44`               |
| Expiry     | None. It works until somebody revokes it                                       |
| Identity   | The token, not a person. It keeps working after its creator leaves the company |
| Revocation | Immediate, from the console's deployment page                                  |

Create and revoke tokens on the deployment's page in the console. Each token is identified
separately in the traffic record, so you can tell one caller's usage from another's inside a single
deployment.

<Warning>
  A deployment token is a bearer credential with no expiry. Put it in a secret store, not in a
  repository, and issue one per calling service so you can revoke one without breaking the others.
</Warning>

## Which model answers

The `model` field in the body is passed to the serving engine. Use `default` unless the engine was
configured to serve several names.

What actually answers is the deployment's **promoted revision** — the one snapshot of model source
and serving configuration that is currently live. Promoting a new revision changes what this URL
returns without the URL changing. Rolling back does the same in reverse. Callers are not affected
and do not need to know.

## Errors

| Code  | Meaning                                                           |
| ----- | ----------------------------------------------------------------- |
| `401` | Missing, malformed, or revoked deployment token                   |
| `404` | No such deployment                                                |
| `503` | The deployment is suspended, or has no ready revision to route to |

Anything else comes from the serving engine and carries its wording.

## Confirm it worked

```bash theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
curl -s https://starforge.your-company.com/inference/dep-7c1e/v1/models \
  -H "Authorization: Bearer $DEPLOYMENT_TOKEN" | jq
```

A model list means the token is good and a revision is serving. From there, the console's deployment
page shows request volume, latency, and — if [Reflow](/en/guides/reflow) is enabled — the buffer
filling with traffic you can mine into the next version's training data.

## Playground sessions are not this

A Playground session is a short-lived vLLM instance for a human to chat with, started from a run's
artifacts and expiring on its own. It has no stable address and no deployment token. If you are
wiring an application to a model, you want a deployment; if you are deciding whether a checkpoint is
any good, you want the Playground.
