Search

Search HiAPI models, tools, and resources.

Back to blog
Tutorial

How to Use gpt-6.1-terra via the hiapi API: curl, Python, and a Working Request

hiapigpt-6.1-terratutorialtext-generation

What you'll build

A working call to gpt-6.1-terra on hiapi: one curl request, then the same call in Python with streaming and error handling. You need a hiapi API key from your dashboard; the quickstart covers key setup.

Everything below was run against the live endpoint on 2026-10-28.

Confirm the model id

curl -s https://api.hiapi.ai/v1/models -H "Authorization: Bearer $HIAPI_API_KEY" \
  | python3 -c "import sys,json; print([m['id'] for m in json.load(sys.stdin)['data'] if 'gpt-6' in m['id']])"

Output: ['gpt-6-astra', 'gpt-6.1-sol', 'gpt-6.1-terra']. The id is gpt-6.1-terra (dot, not dash). The dash form gpt-6-1-terra is only the URL slug of the model page. In /v1/models the entry reports supported_endpoint_types: ["openai-response", "openai"], so both /v1/responses and /v1/chat/completions are exposed.

Minimal request (curl, Responses API)

curl -N https://api.hiapi.ai/v1/responses \
  -H "Authorization: Bearer $HIAPI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gpt-6.1-terra",
    "stream": true,
    "input": [{"role": "user", "content": "Reply with exactly: pong"}]
  }'

/v1/responses is the default route for Terra and it only streams. The reply is a server-sent-event stream. These are the events I received, in order:

response.created
response.in_progress
response.output_item.added
response.content_part.added
response.output_text.delta      -> "delta":"pong"
response.metadata
response.output_text.done
response.content_part.done
response.output_item.done
response.completed              -> status "completed", usage{...}

Token counts arrive only in the final response.completed event (usage_delivery: terminal_event in the pricing contract). For the 11-token prompt above, usage was input_tokens: 11, output_tokens: 5, total_tokens: 16.

Python: streaming with error handling

import json, os, requests

URL = "https://api.hiapi.ai/v1/responses"
HEADERS = {"Authorization": f"Bearer {os.environ['HIAPI_API_KEY']}", "Content-Type": "application/json"}

def ask(prompt: str, effort: str = "medium") -> str:
    body = {
        "model": "gpt-6.1-terra",
        "stream": True,  # required on /v1/responses
        "reasoning": {"effort": effort},
        "instructions": "Answer concisely.",
        "input": [{"role": "user", "content": prompt}],
    }
    text = []
    with requests.post(URL, headers=HEADERS, json=body, stream=True, timeout=120) as r:
        if r.status_code != 200:
            raise RuntimeError(f"{r.status_code}: {r.text[:300]}")
        for line in r.iter_lines(decode_unicode=True):
            if not line or not line.startswith("data: "):
                continue
            ev = json.loads(line[6:])
            if ev["type"] == "response.output_text.delta":
                text.append(ev["delta"])
            elif ev["type"] == "response.completed":
                print("usage:", ev["response"]["usage"])
    return "".join(text)

if __name__ == "__main__":
    print(ask("Name the capital of France in one word.", effort="low"))

Running it printed usage: {'input_tokens': 24, ..., 'output_tokens': 5, ..., 'total_tokens': 29} and Paris. Two details:

  • instructions is the system prompt on this route; put it there instead of a system message in input.
  • reasoning.effort was echoed back as {'effort': 'low', ...} in the completed response. The contract lists six values: none, low, medium, high, xhigh, max, and medium is the default.

Chat Completions also works (non-streaming)

Unlike a Responses-only route, Terra answered a plain buffered /v1/chat/completions call:

curl https://api.hiapi.ai/v1/chat/completions \
  -H "Authorization: Bearer $HIAPI_API_KEY" -H "Content-Type: application/json" \
  -d '{"model":"gpt-6.1-terra","messages":[{"role":"user","content":"Reply with exactly: pong"}]}'

Response: HTTP 200, choices[0].message.content = "pong", finish_reason: "stop", usage.total_tokens = 16. "stream": true on this route returned normal chat.completion.chunk SSE frames.

Function calling worked on this route. With one get_weather tool and the prompt "Weather in Paris?", the model returned finish_reason: "tool_calls" and arguments: {"city":"Paris"}.

Observed behavior and errors

RequestResult
/v1/responses without stream: trueHTTP 400, invalid_parameter, "stream: must be true"
reasoning_effort: "ultra" on chatHTTP 400, invalid_parameter, "reasoning_effort: is outside allowed values"
Invalid API keyHTTP 401, permission_denied, includes a request_id for support
temperature: 0.2 or max_tokens: 20 on chatHTTP 200, no error

On the last row: the pricing contract marks temperature and max_tokens as enabled: false. The request still succeeded, but I did not test whether the value changes the output, so don't assume it is applied. If you need to cap length, test it against your own prompts first.

Timing: in one Responses run, created_at and completed_at were 13 seconds apart for a one-word answer. That is a single sample, but set client timeouts well above a few seconds.

What the contract says about limits

From the live pricing feed for gpt-6.1-terra: 1,050,000-token context window, 128,000 max output tokens, image input, strict JSON-schema output, function calling, and a tiered rate where requests above 272,000 input tokens bill at a higher tier. I did not test image input or the long-context tier. Current rates are on the pricing page and are not copied here, so they cannot go stale.

Terra vs Sol vs Astra

Same ids appear in the same /v1/models list, so switching is a one-string change. The existing gpt-6.1-sol guide covers the Responses route in depth, and the gpt-6-astra guide covers Astra. For Terra specifically, the verified points are above. In my probe on 2026-10-28, gpt-6.1-sol also returned HTTP 200 on /v1/chat/completions, so don't rely on older "Responses-only" notes without re-testing. I did not measure quality differences between the three, so this guide makes no claim about which is smarter. Check the model catalog for the current lineup and prices.

FAQ

Which endpoint should I use? Use /v1/responses if you want the default route and are fine with streaming. Use /v1/chat/completions if you have existing OpenAI-style code or need a buffered response; both worked in testing.

Why "stream: must be true"? You called /v1/responses without streaming. Set "stream": true and read the SSE events.

Where do I find token usage when streaming? In the final response.completed event, under response.usage.

Which reasoning levels exist? none, low, medium, high, xhigh, max; other values return HTTP 400.

Generate it with HiAPI

Choose a model, enter your prompt, and see the result.

HiAPI Blog

Related articles

HiAPI

Generate it with HiAPI

Start generating