Choose a model, enter your prompt, and see the result.
HiAPI Blog
HiAPI
Generate it with HiAPI
deepseek-v4-flash-vision-exp is a reasoning-capable text-and-vision model live on hiapi, reachable through the standard OpenAI-compatible endpoint: POST /v1/chat/completions. It reads images alongside text, supports JSON mode and function/tool calling, and streams — all through the same request shape you'd use for any other hiapi chat model. This guide walks through a working request, the one behavior that trips people up (the model reasons before it answers, and that reasoning eats into your token budget), and the production patterns worth knowing before you ship it.
A script that sends a prompt — optionally with an image — to deepseek-v4-flash-vision-exp and reads back a real answer, not just its internal reasoning trace.
Prerequisite: an hiapi API key. Grab one from the dashboard — every request below needs it in the Authorization header.
curl -s -X POST "https://api.hiapi.ai/v1/chat/completions" \
-H "Authorization: Bearer sk-your-api-key" \
-H "Content-Type: application/json" \
-d '{
"model": "deepseek-v4-flash-vision-exp",
"messages": [
{ "role": "user", "content": "Say OK and nothing else." }
],
"max_tokens": 200
}'
A trimmed response looks like this:
{
"choices": [
{
"finish_reason": "stop",
"message": {
"role": "assistant",
"content": "OK",
"reasoning_content": "We need to respond exactly \"OK\" and nothing else. ..."
}
}
],
"usage": {
"completion_tokens": 37,
"completion_tokens_details": { "reasoning_tokens": 34 },
"prompt_tokens": 89,
"total_tokens": 126
}
}
Two fields matter here: message.content is the actual answer, and message.reasoning_content is the model's internal chain-of-thought before it commits to that answer. usage.completion_tokens_details.reasoning_tokens tells you how much of your max_tokens budget the reasoning pass consumed — in this trivial example, 34 of 37 completion tokens went to reasoning before the model even wrote "OK".
This is the gotcha: set max_tokens too low and the model can burn its entire budget reasoning, leaving content as null with finish_reason: "length". The same request above with max_tokens: 10 returns content: null — the model was still mid-thought when it hit the cap. Give this model room: 150–300 tokens minimum for short answers, more for anything that needs real reasoning depth.
import requests
resp = requests.post(
"https://api.hiapi.ai/v1/chat/completions",
headers={
"Authorization": "Bearer sk-your-api-key",
"Content-Type": "application/json",
},
json={
"model": "deepseek-v4-flash-vision-exp",
"messages": [
{"role": "user", "content": "Say OK and nothing else."},
],
"max_tokens": 200,
},
timeout=60,
)
resp.raise_for_status()
message = resp.json()["choices"][0]["message"]
print(message["content"])
Pass an image alongside text by making content an array of typed parts — image_url accepts any publicly reachable image URL:
curl -s -X POST "https://api.hiapi.ai/v1/chat/completions" \
-H "Authorization: Bearer sk-your-api-key" \
-H "Content-Type: application/json" \
-d '{
"model": "deepseek-v4-flash-vision-exp",
"messages": [
{
"role": "user",
"content": [
{ "type": "text", "text": "What color is the dominant background color of this image? One word." },
{ "type": "image_url", "image_url": { "url": "https://example.com/photo.jpg" } }
]
}
],
"max_tokens": 200
}'
The model returned "Beige" for a real test image, with reasoning_content showing it walking through the visual description before committing to the one-word answer — same reasoning-then-answer pattern as text-only requests, just grounded in the image.
Structured JSON output — add response_format: {"type": "json_object"} and mention JSON in your prompt:
{
"model": "deepseek-v4-flash-vision-exp",
"messages": [
{ "role": "user", "content": "Return a JSON object with keys name and age for a fictional person." }
],
"response_format": { "type": "json_object" },
"max_tokens": 300
}
message.content comes back as a parseable JSON string ({"name": "Alex Doe", "age": 30}), while reasoning_content still carries the model's scratch-work — parse content only, never reasoning_content.
Function/tool calling — pass a standard OpenAI-style tools array:
{
"model": "deepseek-v4-flash-vision-exp",
"messages": [
{ "role": "user", "content": "What is the weather in Tokyo right now? Use the get_weather tool." }
],
"tools": [
{
"type": "function",
"function": {
"name": "get_weather",
"description": "Get current weather for a city",
"parameters": {
"type": "object",
"properties": { "city": { "type": "string" } },
"required": ["city"]
}
}
}
],
"max_tokens": 300
}
The model responds with finish_reason: "tool_calls" and a tool_calls array (function.name, function.arguments as a JSON string, and a call_id you echo back on the follow-up turn) — the standard OpenAI function-calling loop works unmodified.
max_tokens for reasoning, not just the answer. This is a reasoning model — every response includes a reasoning_content pass before the final content, and both draw from the same max_tokens pool. Check usage.completion_tokens_details.reasoning_tokens in early testing to calibrate a safe ceiling for your prompts, and always check finish_reason — "length" with a null content means you got cut off mid-thought, not a real answer.stream: true. Unlike some reasoning models on hiapi that force streaming, this one supports both modes. In streaming mode, reasoning_content and content arrive as separate delta fields on the same chunk stream — buffer them separately if you want to show "thinking" and "answer" as distinct UI states."code": "permission_denied" in the error body, plus a request_id. Branch on the code field rather than matching the message string, and include the request_id if you contact support.reasoning_content to end users as the answer. It's unstructured scratch-work, not a final response — for JSON mode or tool calling in particular, only content (or tool_calls) is meant to be machine-consumed.image_url.url needs to be fetchable by hiapi's servers; host the image yourself or use a URL you already control before sending the request.Does deepseek-v4-flash-vision-exp support vision input?
Yes. Send an array content with a text part and one or more image_url parts, each pointing at a publicly reachable image URL. The model reasons over the image the same way it reasons over text before answering.
Why is message.content null in my response?
Your max_tokens was too low and the model's reasoning pass consumed the entire budget before it could write an answer. Check finish_reason — "length" with content: null means this; raise max_tokens and retry.
Does it support JSON mode?
Yes, via response_format: {"type": "json_object"}. The JSON lands in message.content as a string you parse yourself; reasoning_content is not part of the structured output and should be ignored for this purpose.
Does it support function/tool calling?
Yes, using the standard OpenAI tools array format. A tool-triggering response comes back with finish_reason: "tool_calls" and a tool_calls array containing the function name and arguments.
Can I stream responses?
Yes — set "stream": true and consume chat.completion.chunk events. Both content and reasoning_content stream as separate delta fields within the same chunks.
What does an authentication error look like?
HTTP 401 with a JSON body containing "type": "hiapi_error", "code": "permission_denied", a human-readable message, and a request_id you can hand to support if the issue persists.