Search

Search HiAPI models, tools, and resources.

Back to blog
Tutorial

How to Use deepseek-v4.1-flash via the hiapi API: curl, Python, and a Working Request

hiapideepseekapi-guidetutorial

deepseek-v4.1-flash is a fast, low-cost reasoning model available through the hiapi unified API. It's currently labeled Preview on the model page, which means the underlying build can rotate while the public model ID (deepseek-v4.1-flash) stays stable — you don't need to change any code when that happens. This guide shows a request that actually works: correct endpoint, correct fields, correct auth header.

Prerequisites

  • A hiapi API key (sk-...). Grab one from your hiapi dashboard, then export it:
export HIAPI_API_KEY="sk-your-key-here"
  • Any HTTP client works. Examples below use curl and Python's requests, plus a note on using the official OpenAI SDK.

Minimal working example

hiapi exposes two text endpoints. /v1/responses is the canonical, recommended endpoint (OpenAI Responses API shape, semantic SSE events). /v1/chat/completions is the legacy-compatible endpoint (OpenAI Chat Completions shape) — use it only if you're porting an existing Chat Completions integration. This guide uses /v1/responses.

curl

curl https://api.hiapi.ai/v1/responses \
  -H "Authorization: Bearer $HIAPI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "deepseek-v4.1-flash",
    "input": [
      {"role": "user", "content": "Explain what a hash map is in two sentences."}
    ]
  }'

A successful response returns an output array containing the model's reply plus a usage block:

{
  "id": "resp_...",
  "model": "deepseek-v4.1-flash-expires-on-0910",
  "status": "completed",
  "output": [
    {
      "type": "message",
      "role": "assistant",
      "content": [
        {"type": "output_text", "text": "A hash map stores key-value pairs..."}
      ]
    }
  ],
  "usage": {
    "input_tokens": 14,
    "output_tokens": 42,
    "total_tokens": 56,
    "output_tokens_details": {"reasoning_tokens": 0}
  }
}

Notice the model field in the response is tagged deepseek-v4.1-flash-expires-on-0910 — that's the pinned internal build serving this Preview model. This is expected behavior for Preview models on hiapi, not a sign the model is about to disappear; keep requesting the bare deepseek-v4.1-flash ID and hiapi routes you to the current build automatically.

Python

import os
import requests

resp = requests.post(
    "https://api.hiapi.ai/v1/responses",
    headers={
        "Authorization": f"Bearer {os.environ['HIAPI_API_KEY']}",
        "Content-Type": "application/json",
    },
    json={
        "model": "deepseek-v4.1-flash",
        "input": [
            {"role": "user", "content": "Explain what a hash map is in two sentences."}
        ],
    },
    timeout=60,
)
resp.raise_for_status()
data = resp.json()
print(data["output"][0]["content"][0]["text"])
print(data["usage"])

Using the OpenAI SDK instead

hiapi's /v1/responses and /v1/chat/completions are compatible with the official OpenAI SDKs — just point the base URL at hiapi and keep the model ID bare:

from openai import OpenAI

client = OpenAI(
    api_key=os.environ["HIAPI_API_KEY"],
    base_url="https://api.hiapi.ai/v1",
)
resp = client.responses.create(
    model="deepseek-v4.1-flash",
    input=[{"role": "user", "content": "Explain what a hash map is in two sentences."}],
)
print(resp.output[0].content[0].text)

Production patterns

Requests are stateless — replay the full conversation

hiapi does not keep server-side conversation state for this model. Every request must include the full message history in input. Do not send store, previous_response_id, conversation, background, or context_management — these are not supported and will be ignored or rejected. For a multi-turn chat, append each new user/assistant turn to the input array yourself and send the whole array each time.

history = [{"role": "user", "content": "What's a hash map?"}]
# ... call, get a reply, then append it and the next question ...
history.append({"role": "assistant", "content": "<model's previous reply>"})
history.append({"role": "user", "content": "How is that different from a hash set?"})

Reasoning effort

deepseek-v4.1-flash accepts a reasoning object to control how much internal reasoning it does before answering. The effort enum for this model is none | high | max — note this is not the low/medium/high scale used by some other reasoning models on hiapi, so don't assume it carries over.

{
  "model": "deepseek-v4.1-flash",
  "input": [{"role": "user", "content": "Prove that the square root of 2 is irrational."}],
  "reasoning": {"effort": "high"}
}

Reasoning tokens are billed as output tokens and reported separately in usage.output_tokens_details.reasoning_tokens, so a high/max effort request can cost noticeably more than none even for the same visible answer length. Check current per-token rates on the pricing page before setting a default effort level for production traffic.

Streaming

Pass "stream": true to get Server-Sent Events instead of a single JSON blob. /v1/responses streams semantic events, not raw text deltas wrapped in a Chat-Completions-style [DONE] marker. The event sequence for a normal completion is:

response.created
response.in_progress
response.output_item.added
response.content_part.added
response.output_text.delta   (repeated, one per chunk of text)
response.output_text.done
response.content_part.done
response.output_item.done
response.completed

Handle response.completed as your success terminal event. Also handle response.incomplete (e.g. hit a token/length limit) and response.failed (server-side error) as terminal states — don't assume every stream ends in response.completed.

import json
import requests

with requests.post(
    "https://api.hiapi.ai/v1/responses",
    headers={
        "Authorization": f"Bearer {os.environ['HIAPI_API_KEY']}",
        "Content-Type": "application/json",
    },
    json={
        "model": "deepseek-v4.1-flash",
        "input": [{"role": "user", "content": "Count to 5."}],
        "stream": True,
    },
    stream=True,
    timeout=60,
) as r:
    for line in r.iter_lines():
        if not line or not line.startswith(b"data: "):
            continue
        event = json.loads(line[len(b"data: "):])
        if event.get("type") == "response.output_text.delta":
            print(event["delta"], end="", flush=True)
        elif event.get("type") in ("response.completed", "response.incomplete", "response.failed"):
            break

Error handling

An invalid or missing API key returns HTTP 401 with a structured error body:

{"error": {"code": "permission_denied", "message": "..."}}

Check resp.status_code and branch on error.code rather than parsing the message string, since messages can change wording without notice.

FAQ

Is deepseek-v4.1-flash production-ready, or just for testing? It's labeled Preview, which on hiapi means the model is live and fully callable, but the underlying build can rotate on hiapi's schedule. The public model ID doesn't change when that happens — your code keeps working without edits. If you need a non-Preview commitment, check the model list for a non-Preview DeepSeek v4 variant.

Why does the response show a different model name than what I requested? You'll see something like deepseek-v4.1-flash-expires-on-0910 in the model field of the response. That's the specific pinned build currently serving your request under the deepseek-v4.1-flash ID — expected for Preview models, not an error.

Can I use /v1/chat/completions instead of /v1/responses? Yes, hiapi supports both for this model. /v1/chat/completions uses the OpenAI Chat Completions request/response shape (messages array, choices[0].message.content) instead of /v1/responses's input/output shape. Pick whichever matches your existing integration; new integrations should default to /v1/responses.

Does hiapi store my conversation history so I can just send the latest message? No. There's no previous_response_id or server-side conversation state for this model — send the complete message history in input on every request.

What does reasoning.effort: "none" actually skip? It skips the model's internal reasoning pass entirely, answering directly. Use "high" or "max" for tasks that benefit from multi-step reasoning (math, multi-constraint logic); expect higher output-token usage and latency as effort increases.

Do I need a separate API key for streaming vs. non-streaming requests? No — the same Authorization: Bearer sk-... key works for both. Streaming is controlled purely by the "stream": true field in the request body.

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