Skip to content

Make Your First Model Request

Make one model request with a personal key and keep its Trace ID. This tutorial uses Chat Completions; the Model gateway is the authoritative compatibility contract.

Prerequisites

  • Access to an existing Mission Control inference origin and active Team membership.
  • keys.user.create to create your own virtual key, or an administrator-provisioned ordinary service key. Human roles alone do not permit inference.
  • A generation model allowed by catalog, Team allowance and key policy with model.generate. An administrator should configure pricing for finite spending caps.

1. Get a personal key

Open Access → Virtual keys → Create key, choose your Team and For me, review the generation operation/model and optional cap, then save the one-time secret. Use a service-account key for backend ownership independent of a person. No Builder Agent is needed. See virtual keys.

In a new scratch application directory, set the inference origin and real secret in your local environment. These examples use fictional values:

export MISSION_CONTROL_URL=https://gateway.example.test
export MISSION_CONTROL_API_KEY=mck_example_not_a_real_key

Keep this directory/environment for the SDK examples. The URL is an origin without /v1; scripts append the path. A fictional key safely returns 401 until replaced.

2. List the models you may use

curl --fail-with-body \
  --header "Authorization: Bearer $MISSION_CONTROL_API_KEY" \
  "$MISSION_CONTROL_URL/v1/models"

The response is an OpenAI-style object with a data array. Each entry has a virtual model id and capabilities; select one supporting chat.completions and text input. Discovery consumes no request limit. An illustrative entry is:

{"id":"support","object":"model","owned_by":"mission-control","capabilities":{"protocols":["chat.completions","responses"],"input_modalities":["text"],"streaming":true}}

Set the exact ID you discovered (the name support is an example, not a bundled model):

export MISSION_CONTROL_MODEL=support

3. Send a request

Choose one recipe. The SDK scripts also confirm the model is visible before making the request. Each sends one non-streaming completion and prints its returned Trace ID. Omit traceparent for this first call so the gateway generates a fresh Trace; see Tracing to continue an existing one.

Generate JSON safely from the selected model and send it. Headers are printed before the body.

python3 - <<'PYCODE' > request.json
import json, os
print(json.dumps({
    "model": os.environ["MISSION_CONTROL_MODEL"],
    "messages": [{"role": "user", "content": "Say hello in one sentence."}], "max_completion_tokens": 128,
}))
PYCODE
curl --fail-with-body --include \
  --header "Authorization: Bearer $MISSION_CONTROL_API_KEY" \
  --header "Content-Type: application/json" \
  --data-binary @request.json \
  "$MISSION_CONTROL_URL/v1/chat/completions"

Install the version range used by the repository's Python integration:

python3 -m venv .venv
. .venv/bin/activate
python -m pip install 'openai>=2.45,<3'

Save as first_model.py:

import os
from openai import OpenAI

client = OpenAI(
    base_url=f"{os.environ['MISSION_CONTROL_URL'].rstrip('/')}/v1",
    api_key=os.environ["MISSION_CONTROL_API_KEY"],
    max_retries=0,
)
model = os.environ["MISSION_CONTROL_MODEL"]
visible = [entry.id for entry in client.models.list()]
print("Visible models:", visible)
if model not in visible:
    raise SystemExit("Selected model is not visible; check Team/key access.")
raw = client.chat.completions.with_raw_response.create(
    model=model,
    messages=[{"role": "user", "content": "Say hello in one sentence."}],
    max_completion_tokens=128,
)
print("Trace ID:", raw.headers.get("x-mission-control-trace-id"))
print("Correlation ID:", raw.headers.get("x-mission-control-correlation-id"))
print(raw.parse().choices[0].message.content)
python first_model.py

Install the SDK version pinned by the gateway package:

npm init -y
npm install openai@7.10.0

Save as first-model.mts. Node.js 24 runs this TypeScript directly:

import OpenAI from "openai";

const origin = process.env.MISSION_CONTROL_URL;
const key = process.env.MISSION_CONTROL_API_KEY;
const model = process.env.MISSION_CONTROL_MODEL;
if (!origin || !key || !model) throw new Error("Set all three MISSION_CONTROL variables.");
const client = new OpenAI({
  baseURL: `${origin.replace(/\/$/, "")}/v1`, apiKey: key, maxRetries: 0,
});
const visible: string[] = [];
for await (const entry of client.models.list()) visible.push(entry.id);
console.log("Visible models:", visible);
if (!visible.includes(model)) throw new Error("Selected model is not visible; check Team/key access.");
const { data, response } = await client.chat.completions.create({
  model,
  messages: [{ role: "user", content: "Say hello in one sentence." }],
  max_completion_tokens: 128,
}).withResponse();
console.log("Trace ID:", response.headers.get("x-mission-control-trace-id"));
console.log("Correlation ID:", response.headers.get("x-mission-control-correlation-id"));
console.log(data.choices[0].message.content);
node first-model.mts

Expected result

HTTP 200, a completion in choices[0].message.content, and X-Mission-Control-Trace-Id and X-Mission-Control-Correlation-Id headers. Generated text and usage vary with the selected model. A gateway-generated Trace ID is 32 hexadecimal characters; keep it for verification.

Verification

Open Observe → Requests and locate the canonical request using its safe correlation/Trace ID. An exact own-key read does not authorize the whole shared Trace. Team observability.read opens metadata; captured content and export use separate permissions. Canonical decision evidence exists even if the Collector is unavailable. Each physical attempt records usage independently; model discovery is not an inference call.

Failure recovery

Symptom Recovery
401 / authentication_failed Check the inference URL and key; issue a replacement for a revoked or expired key under Access → Virtual keys. Suspension or deactivation revokes a person's keys: after an administrator reactivates you, issue a new key.
Empty discovery or 403 / operation_denied Ask a Team administrator to review your Team membership, the Team allowance and the key's operation/resource policy; share the safe correlation ID, never the key. See Get the access you need.
400 / unsupported_feature Remove unsupported fields using the Model gateway contract.
400 / capability_unavailable Select a model whose eligible deployment supports the requested fields.
429 Honor Retry-After; ask an administrator about the spend, request, token or concurrency limit.
Trace or decision not visible Confirm the selected Team and the distinct own-key/Team metadata and separate content permissions.