DeepSeek V4.1 Flash is now available on Netra

Explore model
Netra Runtime

API REFERENCE

DeepSeek Responses API

Use the Responses API for DeepSeek text, images, streaming, function tools, and structured JSON.

Overview

Netra implements the OpenAI Responses API format for DeepSeek. Use POST https://api.netraruntime.com/v1/responses to generate responses with text, images, function tools, structured JSON, or streaming. The model is the DeepSeek model selected in model; using the OpenAI SDK does not select an OpenAI model or require an OpenAI account.

Authenticate with your Netra API key and configure the OpenAI SDK with https://api.netraruntime.com/v1 as its base URL. Netra implements the stateless creation features described here. OpenAI features such as stored conversations and hosted tools are outside this endpoint's supported scope.

Model IDTextImage input
deepseek/deepseek-v4.1-flashYesYes
deepseek/deepseek-v4-flash-0731YesNo

This endpoint is stateless. Send the conversation history in input on each request. Responses are not stored for later retrieval: omit store or set it to false. Response IDs identify returned objects; they cannot be used with previous_response_id or a retrieve endpoint. Your organization's request-recording setting is separate from this API storage option.

First request

Set NETRA_API_KEY in your environment. For the SDK examples, install openai with pip install openai (Python) or npm install openai (Node.js).

curl https://api.netraruntime.com/v1/responses \
  -H "Authorization: Bearer $NETRA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "deepseek/deepseek-v4.1-flash",
    "instructions": "Answer in one sentence.",
    "input": "What is an API?",
    "max_output_tokens": 256,
    "reasoning": {"effort": "none"},
    "store": false
  }'
import os
from openai import OpenAI

client = OpenAI(
    api_key=os.environ["NETRA_API_KEY"],
    base_url="https://api.netraruntime.com/v1",
)
response = client.responses.create(
    model="deepseek/deepseek-v4.1-flash",
    instructions="Answer in one sentence.",
    input="What is an API?",
    reasoning={"effort": "none"},
    max_output_tokens=256,
    store=False,
)
print(response.output_text)
import OpenAI from "openai";

const client = new OpenAI({
  apiKey: process.env.NETRA_API_KEY,
  baseURL: "https://api.netraruntime.com/v1",
});
const response = await client.responses.create({
  model: "deepseek/deepseek-v4.1-flash",
  instructions: "Answer in one sentence.",
  input: "What is an API?",
  reasoning: { effort: "none" },
  max_output_tokens: 256,
  store: false,
});
console.log(response.output_text);

In raw JSON, read output items with type: "message", then their content parts with type: "output_text". response.output_text is an SDK convenience property. A response can contain function calls instead of answer text.

The examples below reuse client from the SDK setup for their language. Image examples also need the named local image file.

Moving from Chat Completions

Chat CompletionsResponses
client.chat.completions.create(...)client.responses.create(...)
messagesinput; optionally put system instructions in instructions
max_tokensmax_output_tokens
response_formattext.format
tools[].function.name and .parameterstools[].name and .parameters
image_url: {"url": "..."} with type: "image_url"image_url: "..." with type: "input_image"
choices[0].message.contentoutput message content, or SDK output_text
role: "tool", tool_call_idtype: "function_call_output", call_id
Chat delta chunks and [DONE]Named Responses events and a terminal response event

Choose your client's OpenAI Responses interface when it offers separate API formats. Set the Netra base URL and one of the exact model IDs above. A client's DeepSeek Chat Completions adapter is a different interface; changing the URL alone does not convert its request body into Responses format.

Image input with V4.1 Flash

Use input_image with an image_url string. Supply an accessible HTTPS image URL or a Base64 data URL. The image must be part of input, alongside the question.

import base64
from pathlib import Path

encoded = base64.b64encode(Path("photo.png").read_bytes()).decode("ascii")
response = client.responses.create(
    model="deepseek/deepseek-v4.1-flash",
    input=[{
        "role": "user",
        "content": [
            {"type": "input_text", "text": "Describe what is in this image."},
            {"type": "input_image", "image_url": f"data:image/png;base64,{encoded}"},
        ],
    }],
    max_output_tokens=512,
    reasoning={"effort": "none"},
    store=False,
)
print(response.output_text)

Optional image detail values are auto, low, and high. Match the MIME type to the file. File IDs, uploaded files, audio, and video input are not supported. The request body limit is 64 MiB, including encoded images and conversation history. Image tokens count toward input usage.

Streaming

Set stream: true. The API returns named Server-Sent Events with an increasing sequence_number.

stream = client.responses.create(
    model="deepseek/deepseek-v4.1-flash",
    input="Explain caching in two sentences.",
    reasoning={"effort": "none"},
    max_output_tokens=256,
    store=False,
    stream=True,
)
terminal = False
for event in stream:
    if event.type == "response.output_text.delta":
        print(event.delta, end="", flush=True)
    elif event.type == "response.refusal.delta":
        print(event.delta, end="", flush=True)
    elif event.type == "response.completed":
        terminal = True
        print("\nUsage:", event.response.usage)
    elif event.type in ("response.failed", "response.incomplete"):
        terminal = True
        print("\nGeneration ended:", event.response.status)
if not terminal:
    raise RuntimeError("Stream disconnected before a terminal response event")

The event sequence starts with response.created and response.in_progress. Output items have response.output_item.added and response.output_item.done events. Message content emits response.content_part.added, response.output_text.delta, response.output_text.done, and response.content_part.done. Tool arguments emit response.function_call_arguments.delta and response.function_call_arguments.done.

A model refusal is returned as a message content part with type: "refusal" and a refusal string. Streaming refusals use response.refusal.delta and response.refusal.done, within the same content-part lifecycle. A refusal can be a completed model response; it is not a transport error. SDK output_text excludes refusal parts, so inspect message content when it is empty.

The terminal event is response.completed, response.incomplete, or response.failed; this protocol does not end with Chat Completions' [DONE] marker. Read usage from the terminal completed or incomplete response. A disconnect without a terminal event is not confirmed success.

SSE comments such as : heartbeat may arrive before the first event or between events. Standard SSE clients and the OpenAI SDK ignore comments. They carry no model output, usage, or sequence number. HTTP 200 and a keepalive do not establish a successful generation: wait for the terminal event. Errors before SSE headers are committed use a non-2xx HTTP response. Once SSE is committed, generation failures use response.failed, including failures before any output item. A broken connection may prevent delivery of that event.

For JavaScript, handle the same terminal states:

const stream = await client.responses.create({
  model: "deepseek/deepseek-v4.1-flash",
  input: "Explain caching in two sentences.",
  reasoning: { effort: "none" },
  max_output_tokens: 256,
  store: false,
  stream: true,
});
let terminal = false;
for await (const event of stream) {
  if (event.type === "response.output_text.delta" || event.type === "response.refusal.delta") {
    process.stdout.write(event.delta);
  } else if (["response.completed", "response.incomplete", "response.failed"].includes(event.type)) {
    terminal = true;
    console.log("\nStatus:", event.response.status, "Usage:", event.response.usage);
  }
}
if (!terminal) throw new Error("Stream disconnected before a terminal response event");

Function tools and continuation

Function definitions have name, description, parameters, and optional strict directly on the tool object. Your application executes the function and returns its result using the matching call_id. Validate generated arguments and authorize any side effects before execution.

import json

model = "deepseek/deepseek-v4.1-flash"
tools = [{
    "type": "function",
    "name": "lookup_stock",
    "description": "Return available units for a product.",
    "parameters": {
        "type": "object",
        "properties": {"product": {"type": "string"}},
        "required": ["product"],
        "additionalProperties": False,
    },
    "strict": True,
}]
history = [{"role": "user", "content": "How many blue mugs are available?"}]
first = client.responses.create(
    model=model, input=history, tools=tools,
    tool_choice={"type": "function", "name": "lookup_stock"},
    reasoning={"effort": "none"}, max_output_tokens=256, store=False,
)
history += [item.model_dump(exclude_none=True) for item in first.output]
for item in first.output:
    if item.type == "function_call":
        arguments = json.loads(item.arguments)
        # Replace this sample result with your application's validated lookup.
        result = {"product": arguments["product"], "available": 12}
        history.append({
            "type": "function_call_output",
            "call_id": item.call_id,
            "output": json.dumps(result),
        })
final = client.responses.create(
    model=model, input=history, tools=tools, tool_choice="none",
    reasoning={"effort": "none"}, max_output_tokens=256, store=False,
)
print(final.output_text)

tool_choice accepts auto, none, required, or a named function object. parallel_tool_calls controls whether the model may request multiple functions. Return one result for every call. For ordinary multi-turn text conversations, append response.output and the next user message to the prior input in the same way. Resend instructions and tools on each request where they are needed.

Set strict explicitly when you need schema-constrained function arguments. Netra does not automatically rewrite omitted strict settings or schemas. Schema enforcement depends on the selected model's capabilities; validate arguments in your application before executing a function.

Structured JSON output

Use text.format, rather than Chat Completions' response_format field:

import json

response = client.responses.create(
    model="deepseek/deepseek-v4.1-flash",
    input="Return the city and country for Jakarta as JSON.",
    text={"format": {
        "type": "json_schema",
        "name": "location",
        "strict": True,
        "schema": {
            "type": "object",
            "properties": {"city": {"type": "string"}, "country": {"type": "string"}},
            "required": ["city", "country"],
            "additionalProperties": False,
        },
    }},
    reasoning={"effort": "none"}, max_output_tokens=256, store=False,
)
location = json.loads(response.output_text)

text.format.type also accepts text and json_object. For json_object, explicitly request JSON in your prompt. Always check the response status before parsing output; a token limit can leave JSON unfinished.

Parameters and boundaries

ParameterBehaviour
modelOne of the two DeepSeek IDs listed above.
inputA string or nonempty array of messages, function calls, and function results. Message roles: user, assistant, system, developer.
instructionsOptional system instructions for this request.
max_output_tokensPositive integer. Includes reasoning tokens when the model uses them. Omission preserves the model's normal generation policy.
reasoning.effortnone, minimal, low, medium, high, or max, subject to the model's supported settings. Reasoning text, summaries, and encrypted reasoning items are not returned.
temperature, top_pNumbers in the ranges 0–2 and 0–1 respectively, subject to model support.
tools, tool_choice, parallel_tool_callsFunction tools only, as shown above.
text.formatText, JSON object, or JSON schema output.
streamDefaults to false; use true for Responses SSE events.
store, backgroundOmit or set to false.
metadataUp to 16 string entries, with keys up to 64 characters and values up to 512 characters; echoed in the response.
truncationOmit or use disabled; history is not automatically truncated.
service_tierOmit, auto, or default. No alternative priority tier is offered by this endpoint.
userOptional application end-user identifier; avoid personal data.

Stored conversations, previous_response_id, item references, response retrieval/deletion/cancellation, background jobs, hosted tools, nonempty include, and other undocumented generation options are not supported. Unsupported request fields return HTTP 400. This is a supported subset of the Responses protocol, so check an agent's feature requirements before connecting it.

Status, usage, and request IDs

status: "completed" means generation finished. status: "incomplete" includes incomplete_details.reason, such as max_output_tokens or content_filter. A streaming generation failure produces response.failed with an error; retain any partial output separately from a successful answer.

A failed generation can still incur charges for tokens processed or generated before the failure, including reasoning and tool arguments. Keepalive comments are not billable tokens. A failed response may have usage: null; check your settled usage record for the charge.

Usage fields are input_tokens, output_tokens, and total_tokens. Completed and incomplete responses also include input_tokens_details and output_tokens_details. cached_tokens and reasoning_tokens are subsets of input and output tokens respectively; do not add them again. These detail counts use zero when a breakdown is unavailable; use the total counts to reconcile usage. input_tokens_details.cache_write_tokens is zero: there is no separate cache-write charge. Normal model pricing, credit checks, API-key limits, and request recording settings apply. Each generation is metered once; a tool-result continuation is a new billable generation.

For example, this usage object represents 20 input tokens and 5 output tokens in total:

{
  "input_tokens": 20,
  "input_tokens_details": {"cached_tokens": 0, "cache_write_tokens": 0},
  "output_tokens": 5,
  "output_tokens_details": {"reasoning_tokens": 0},
  "total_tokens": 25
}

Use the HTTP X-Request-Id for support and request correlation. It is distinct from the resp_... response object ID. See errors, limits, and retries before retrying an interrupted generation.

Compatibility reference

The protocol reference is OpenAI's Responses API and streaming event reference. Netra's supported request schema is published at OpenAPI. The feature boundaries on this page take precedence over examples for OpenAI-hosted models: Netra does not implement every OpenAI endpoint or tool.

Search documentation

Search across all documentation.

Up and down arrows to navigate

Enter to open

esc to close