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.createto 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):
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:
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)
Install the SDK version pinned by the gateway package:
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);
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. |
Related links¶