Tutorial
How to Call gpt-5.6-terra@azure via the HiAPI API: curl and Python Guide
Build a working request, add streaming and tool calls, and handle errors without guesswork
On this page
What gpt-5.6-terra@azure Means in a HiAPI Request
In a HiAPI request, gpt-5.6-terra@azure is a model identifier — a string you place in the model field of a chat request body. That is the whole contract from your side. You do not construct a provider-specific URL, you do not swap SDKs, and you do not change the shape of your payload.
The @azure suffix is routing metadata. It tells HiAPI which backend should serve the request for this model variant. Everything else in the body — messages, temperature, max_tokens, stream, tools — keeps the standard chat-completions shape you already know. This matters practically: if you have a working request for another model on HiAPI, moving to gpt-5.6-terra@azure is usually a one-line edit.
{
"model": "gpt-5.6-terra@azure",
"messages": [
{ "role": "user", "content": "Hello" }
]
}
Two habits keep model-id bugs rare:
- Treat the id as an opaque string. Copy it exactly, including the
@and lowercase suffix. No spaces, no capitalization changes. - Keep it in configuration, not scattered through code. A constant or environment variable makes A/B testing between model ids a config change rather than a refactor.
Because the suffix handles routing, you should not assume anything about the underlying serving stack from the id alone. Latency, limits, and supported parameters are properties of the model as HiAPI exposes it, so verify behavior empirically with a small request before building assumptions into your app.
Prerequisites and Getting Your Key Ready
Before your first call, confirm three things:
- A HiAPI account. You need to be signed in to create credentials and to view the current model and pricing information in your dashboard.
- An API key. Generate one from the dashboard and store it somewhere safe — treat it like a password. This guide does not assume a particular key format; whatever string the dashboard gives you is what goes in the
Authorizationheader. - An HTTP client.
curlfor smoke tests, and Python 3 with eitherrequestsor the OpenAI-compatible SDK for application code.
Keep the key out of your source files
Use environment variables. The pattern is the same on every platform:
export HIAPI_API_KEY="your-key-here"
Then reference it at runtime. In shell: "$HIAPI_API_KEY". In Python: os.environ["HIAPI_API_KEY"]. In CI, use your provider's secret store rather than committing a .env file.
If you ever paste a key into a terminal for debugging, remember it may persist in shell history — rotate it afterwards if it was a real credential. For local development, a throwaway key scoped to testing is easier to reason about than reusing production credentials.
Confirm your base URL and endpoint
HiAPI exposes an OpenAI-compatible chat completions endpoint. Take the base URL and path from your dashboard documentation and use them consistently across curl and Python — most "it works in curl but not in Python" reports come down to a trailing slash or a missing path segment.
A Working Request with curl
Here is the smallest correct call. Replace the base URL with the one shown in your dashboard, and make sure HIAPI_API_KEY is exported.
curl -sS https://api.hiapi.ai/v1/chat/completions \
-H "Authorization: Bearer $HIAPI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-5.6-terra@azure",
"messages": [
{"role": "system", "content": "You are a concise assistant."},
{"role": "user", "content": "Explain what an API gateway does in two sentences."}
],
"max_tokens": 200
}'
Field by field:
-sSsilences the progress meter but still shows errors. Add-iif you want response headers alongside the body.Authorization: Bearer $HIAPI_API_KEYauthenticates the request. TheBearerprefix and the space are required.Content-Type: application/json— omit this and many servers will reject the body before parsing it.model— the exact idgpt-5.6-terra@azure.messages— an ordered array.systemsets behavior;usercarries the prompt. Multi-turn conversations appendassistantanduserturns in order.max_tokens— an upper bound on the response length. Keep it small for smoke tests so failures are cheap and fast.
A successful response is JSON with a choices array; the text you want is at choices[0].message.content. Pipe the output through a JSON formatter the first few times so you can see the structure rather than squinting at one long line.
Once this works, save it as a shell script with the key read from the environment. That gives you a repeatable health check you can run whenever you change model ids or parameters.
The Same Request in Python
The payload is identical — only the transport changes. Using requests:
import os
import requests
api_key = os.environ["HIAPI_API_KEY"]
payload = {
"model": "gpt-5.6-terra@azure",
"messages": [
{"role": "system", "content": "You are a concise assistant."},
{"role": "user", "content": "Explain what an API gateway does in two sentences."},
],
"max_tokens": 200,
}
response = requests.post(
"https://api.hiapi.ai/v1/chat/completions",
headers={
"Authorization": f"Bearer {api_key}",
"Content-Type": "application/json",
},
json=payload,
timeout=60,
)
response.raise_for_status()
print(response.json()["choices"][0]["message"]["content"])
Three details worth keeping: pass json=payload rather than hand-serializing (it sets the header and encoding for you), always set a timeout, and call raise_for_status() so a 4xx or 5xx surfaces as an exception instead of an IndexError when you index into an error body.
Provider-SDK style
Because the endpoint is OpenAI-compatible, an SDK configured with a custom base URL produces the same request:
import os
from openai import OpenAI
client = OpenAI(
api_key=os.environ["HIAPI_API_KEY"],
base_url="https://api.hiapi.ai/v1",
)
completion = client.chat.completions.create(
model="gpt-5.6-terra@azure",
messages=[{"role": "user", "content": "Say hello in one word."}],
max_tokens=50,
)
print(completion.choices[0].message.content)
The point of showing both: the model id is the only variable that identifies which model serves you. Everything else is ordinary chat-completions plumbing, so you can switch between raw HTTP and an SDK without rewriting logic.
Adding Streaming and Tool Calling
Both features are additive. You are not rewriting the base request — you are adding fields and changing how you consume the response.
Streaming
Set "stream": true in the body:
stream = client.chat.completions.create(
model="gpt-5.6-terra@azure",
messages=[{"role": "user", "content": "Count from 1 to 10."}],
stream=True,
)
for chunk in stream:
delta = chunk.choices[0].delta.content
if delta:
print(delta, end="", flush=True)
The response becomes a sequence of server-sent events instead of one JSON object. Each chunk carries a delta with a fragment of content; delta.content can be None on the first and last chunks, so guard before concatenating. With raw HTTP the same applies — read the body line by line, strip the data: prefix, skip [DONE], and parse each JSON line.
Tool calling
Describe tools in the request and let the model decide when to call them:
payload = {
"model": "gpt-5.6-terra@azure",
"messages": [{"role": "user", "content": "What's the weather in Berlin?"}],
"tools": [{
"type": "function",
"function": {
"name": "get_weather",
"description": "Get current weather for a city",
"parameters": {
"type": "object",
"properties": {"city": {"type": "string"}},
"required": ["city"],
},
},
}],
"tool_choice": "auto",
}
When the model wants a tool, choices[0].message contains a tool_calls array instead of plain text. Each entry has an id and a function with name and arguments (a JSON string you must parse). Execute your function, then send the result back as a message with role: "tool", the matching tool_call_id, and the serialized output — then make another request to get the final answer.
tool_choice accepts "auto" (model decides), "none" (prose only), or a specific function. Streaming and tools can be combined, but tool-call arguments then arrive as fragments across chunks that you must accumulate before parsing — start by getting non-streamed tool calls working first.
Troubleshooting Common Request Errors
Debug in this order; each step isolates one layer so you do not chase two problems at once.
1. Authentication (401 / 403)
Most likely causes: the key is missing, the Bearer prefix was dropped, or an environment variable expanded to an empty string. Echo the header construction without printing the full key, and confirm the variable is set in the same shell or process that runs the request.
2. Endpoint and path (404)
A 404 usually means the path is wrong — a typo, a missing /v1, or a trailing slash where none belongs. Copy the exact URL from your dashboard rather than retyping it.
3. Model id (400 with a model-related message)
The id must match exactly: gpt-5.6-terra@azure. Common slips are capitalization changes, a missing @azure, or a stray space from a copy-paste. If the message says the model is unknown, compare your configured string character by character against the dashboard listing before assuming an outage.
4. Malformed body (400 / 422)
If the error mentions the payload, check JSON validity first — a trailing comma or unescaped quote is the usual culprit. Then verify field names (messages, not message) and roles (system, user, assistant, tool). max_tokens must be a number, and tools must be an array of properly shaped objects.
5. Streaming handled as plain JSON
If output is empty, garbled, or raises a parse error, you likely requested stream: true but parsed the response as a single JSON document. Read it as an event stream, skip [DONE], and guard against None deltas.
6. Client-side timeouts
Long generations can exceed a default HTTP timeout. Raise it explicitly in your client, or switch to streaming so bytes start arriving immediately.
A fast reproduction checklist
- Run the minimal
curlcall. If it succeeds, the problem is in your code. - If it fails, retry with your key and model id in a single fresh shell.
- Log the HTTP status and the response body together — error bodies carry the diagnostic detail.
- Only after these pass should you suspect a service-side issue worth escalating.
With a working request, a streaming loop, and this checklist in place, gpt-5.6-terra@azure behaves like any other chat model in your stack — and switching models becomes a one-line change in configuration.
Related articles
View all articles →-
Tutorial
gemini-omni-1.2-flash in practice: 3 video generation business scenarios and a go-live checklist
Three application scenarios: text-based creative, first-frame animation, and reference-image-constrained visuals
-
Tutorial
How to Call gpt-image-2.5-sunburst/text-to-image via the HiAPI API: curl and Python
An integration walkthrough with a working request, reference-image handling, and retry patterns
9 min read -
Tutorial
How to Use flux-1.1-pro via the HiAPI API: curl, Python, and Working Requests
A hands-on integration guide: requests that actually run, async handling, and prompt recipes with real outputs
13 min read