Search

Search HiAPI models, tools, and resources.

Back to blog
Tutorial

How to Use the grok-4.6 API: cURL, Python, and a Working Request

Streaming, tool calls, and JSON mode on hiapi's OpenAI-compatible chat completions endpoint

hiapigrokchat-completionstutorial

grok-4.6 is a reasoning-tuned chat model available through the hiapi API. Unlike hiapi's image and video models, it doesn't use the async /v1/tasks pipeline — it's a synchronous, OpenAI-compatible chat completion, so you get a normal HTTP response (or an SSE stream) with no polling required. This recipe covers a minimal working request, then the parts you actually need in production: streaming, tool calls, JSON mode, and error handling.

What you'll need

  • A hiapi API key. Grab one from the dashboard if you don't have one yet — every request below needs it in an Authorization: Bearer sk-... header.
  • Any HTTP client. The examples use curl and Python's requests; the JSON shape is the same regardless of language.
  • No SDK is required. grok-4.6's request/response format follows the OpenAI chat completions convention closely enough that OpenAI-compatible tooling generally works, but hiapi ships its own chat completions endpoint rather than a proprietary one — point your client at https://api.hiapi.ai/v1/chat/completions and use the bare model id grok-4.6.

The minimal request that works

curl https://api.hiapi.ai/v1/chat/completions \
  -H "Authorization: Bearer $HIAPI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "grok-4.6",
    "messages": [
      {"role": "user", "content": "Give me one sentence explaining what a Kalman filter does."}
    ]
  }'

A successful response looks like this:

{
  "id": "b6c018d3-218e-9b06-aa12-5afc02e21b5c",
  "object": "chat.completion",
  "model": "grok-4.6",
  "choices": [
    {
      "index": 0,
      "message": {
        "role": "assistant",
        "content": "A Kalman filter estimates the true state of a system over time by combining noisy measurements with a predictive model, weighting each by its uncertainty."
      },
      "finish_reason": "stop"
    }
  ],
  "usage": {
    "prompt_tokens": 24,
    "completion_tokens": 31,
    "total_tokens": 55
  }
}

The answer text is at choices[0].message.content, same as any OpenAI-style chat API.

Here's the same call in Python with requests:

import os
import requests

resp = requests.post(
    "https://api.hiapi.ai/v1/chat/completions",
    headers={"Authorization": f"Bearer {os.environ['HIAPI_API_KEY']}"},
    json={
        "model": "grok-4.6",
        "messages": [
            {"role": "user", "content": "Give me one sentence explaining what a Kalman filter does."}
        ],
    },
    timeout=60,
)
resp.raise_for_status()
print(resp.json()["choices"][0]["message"]["content"])

grok-4.6's reasoning knob

grok-4.6 is a reasoning model: before it writes the final answer, it can spend extra tokens "thinking," and those reasoning tokens are billed as output tokens (see pricing for current rates). You control how much thinking happens with reasoning_effort, one of low, medium, high, or xhigh (the API defaults to high if you omit it):

curl https://api.hiapi.ai/v1/chat/completions \
  -H "Authorization: Bearer $HIAPI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "grok-4.6",
    "messages": [{"role": "user", "content": "Say hi in five words."}],
    "reasoning_effort": "low"
  }'

Non-streaming responses expose the model's reasoning trace in message.reasoning_content, separate from the final message.content. For short, low-latency tasks, drop to low or medium; for multi-step problems, high or xhigh trades latency and tokens for better answers.

Streaming responses

Set "stream": true and read the response as Server-Sent Events instead of waiting for the full completion:

curl -N https://api.hiapi.ai/v1/chat/completions \
  -H "Authorization: Bearer $HIAPI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "grok-4.6",
    "messages": [{"role": "user", "content": "Count from 1 to 5."}],
    "stream": true
  }'

Each line is a data: {...} chunk. Reasoning tokens stream in choices[0].delta.reasoning_content, then answer tokens stream in choices[0].delta.content, and the stream ends with a literal data: [DONE]:

data: {"id":"...","object":"chat.completion.chunk","choices":[{"index":0,"delta":{"reasoning_content":"Listing"},"finish_reason":null}]}

data: {"id":"...","object":"chat.completion.chunk","choices":[{"index":0,"delta":{"content":"1, 2"},"finish_reason":null}]}

data: {"id":"...","object":"chat.completion.chunk","choices":[{"index":0,"delta":{},"finish_reason":"stop"}]}

data: [DONE]

In Python, requests can iterate the stream line by line:

import json
import requests

with requests.post(
    "https://api.hiapi.ai/v1/chat/completions",
    headers={"Authorization": f"Bearer {os.environ['HIAPI_API_KEY']}"},
    json={
        "model": "grok-4.6",
        "messages": [{"role": "user", "content": "Count from 1 to 5."}],
        "stream": True,
    },
    stream=True,
    timeout=60,
) as resp:
    for line in resp.iter_lines():
        if not line or not line.startswith(b"data: "):
            continue
        payload = line[len(b"data: "):]
        if payload == b"[DONE]":
            break
        chunk = json.loads(payload)
        delta = chunk["choices"][0]["delta"]
        if "content" in delta:
            print(delta["content"], end="", flush=True)

Tool calls

grok-4.6 supports OpenAI-style function calling: pass a tools array and let the model decide when to invoke one via tool_choice: "auto".

curl https://api.hiapi.ai/v1/chat/completions \
  -H "Authorization: Bearer $HIAPI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "grok-4.6",
    "messages": [{"role": "user", "content": "What is the weather in Tokyo?"}],
    "tools": [
      {
        "type": "function",
        "function": {
          "name": "get_weather",
          "description": "Get the current weather for a city",
          "parameters": {
            "type": "object",
            "properties": {"city": {"type": "string"}},
            "required": ["city"]
          }
        }
      }
    ],
    "tool_choice": "auto"
  }'

When the model decides to call the tool, finish_reason comes back as "tool_calls" and the arguments arrive as a JSON string you parse yourself:

{
  "choices": [
    {
      "message": {
        "role": "assistant",
        "tool_calls": [
          {
            "id": "call_...",
            "type": "function",
            "function": {"name": "get_weather", "arguments": "{\"city\":\"Tokyo\"}"}
          }
        ]
      },
      "finish_reason": "tool_calls"
    }
  ]
}

Run your function, then append a role: "tool" message with the result (and the matching tool_call_id) to messages and send the conversation back for a final natural-language answer.

JSON mode

For a response you can parse without a tool call round-trip, set response_format:

curl https://api.hiapi.ai/v1/chat/completions \
  -H "Authorization: Bearer $HIAPI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "grok-4.6",
    "messages": [
      {"role": "system", "content": "Respond with a JSON object with keys \"city\" and \"country\"."},
      {"role": "user", "content": "Where is the Eiffel Tower?"}
    ],
    "response_format": {"type": "json_object"}
  }'

message.content comes back as a JSON string (still inside the normal chat completion envelope), which you parse with json.loads(...) on your end. Always instruct the model in your prompt to actually produce JSON — response_format constrains the output format but doesn't invent the schema for you.

Production patterns

  • Handle the documented error codes. A bad or missing key returns HTTP 401 with {"error":{"code":"permission_denied","message":"...","request_id":"...","type":"hiapi_error"}}. Insufficient balance returns 402; an invalid model id or malformed parameter returns 400. Check the status code first, and log request_id from the error body — it's what you'll want on hand if you ever need to report an issue.
  • Retry 429 and 503 with backoff. hiapi enforces per-account rate limits; a 429 means you're over the limit, and a 503 means the model is temporarily unavailable. Both are safe to retry with capped exponential backoff (for example 1s, 2s, 4s, giving up after a handful of attempts) rather than looping tightly.
  • Set a request timeout. Reasoning at high or xhigh effort takes noticeably longer than low; size your client timeout to the effort level you're using rather than a single global constant.
  • Prefer streaming for anything user-facing. Non-streaming calls block until the full response (including all reasoning tokens) is ready; streaming gets the first tokens to your UI immediately and lets you show a "thinking" state while reasoning_content deltas arrive ahead of the final answer.
  • Don't hardcode the key. Load it from an environment variable or secret manager, never from source control — the examples above read it from $HIAPI_API_KEY / os.environ["HIAPI_API_KEY"] for exactly that reason.

For the full parameter reference, including every field grok-4.6 accepts, see the model page and the grok-4.6 docs.

FAQ

Is grok-4.6 on hiapi OpenAI SDK-compatible? The request and response shapes follow the OpenAI chat completions convention (messages, choices[0].message.content, streaming deltas, tool calls), so most OpenAI-compatible tooling that lets you override the base URL and model id should work. Point the base URL at https://api.hiapi.ai/v1 and use grok-4.6 as the model id.

Why is my response slower than other models? grok-4.6 spends tokens on an internal reasoning pass before answering, and those tokens are billed as output tokens. Lower reasoning_effort to low or medium for latency-sensitive calls, or switch to streaming so you're not waiting for the whole response at once.

What does reasoning_content mean and can I hide it from users? It's the model's intermediate reasoning trace, returned separately from content (or as delta.reasoning_content while streaming). You can simply not render it in your UI — only content is the final answer.

I got a 401 with permission_denied — what's wrong? Your Authorization header is missing, malformed, or the key is invalid or revoked. Re-check that you're sending Authorization: Bearer sk-... with a live key from your dashboard.

Can I use grok-4.6 for function calling and JSON mode in the same request? tools/tool_choice and response_format are independent parameters and can both be set, but if the model decides to call a tool, finish_reason will be "tool_calls" and message.content may be empty on that turn — handle the tool call first, then request the final JSON-formatted answer on the follow-up turn.

How do I control cost? Reasoning tokens count as output tokens, so cost scales with reasoning_effort and response length. Check current per-token rates on the pricing page before running high-volume workloads.

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