API REFERENCE
Anthropic Messages API
Use Anthropic SDKs with Netra models for text, tools, thinking, streaming and images.
Overview
Use the Anthropic Messages API with the official Anthropic SDKs to generate responses from Netra’s DeepSeek models. It supports text, streaming, tool calling, thinking and V4.1 image input as described below. Your requests use Netra models and your Netra account.
Connect an SDK
Use the API origin as ANTHROPIC_BASE_URL because these clients append /v1/messages. Keep real model IDs. V4 Flash 0731 is text-only; V4.1 Flash supports the image input described below. Existing organization credits, prices and limits apply.
export ANTHROPIC_BASE_URL=https://api.netraruntime.com
export ANTHROPIC_API_KEY="$NETRA_API_KEY"
curl "$ANTHROPIC_BASE_URL/v1/messages" \
-H "x-api-key: $ANTHROPIC_API_KEY" \
-H "anthropic-version: 2023-06-01" \
-H "content-type: application/json" \
-d '{"model":"deepseek/deepseek-v4.1-flash","max_tokens":1024,"messages":[{"role":"user","content":"Hello"}]}'Bearer authorization works too. Conflicting keys are rejected. request-id and X-Request-Id match; the returned message ID is separate. Omitted version selects the implemented 2023-06-01 contract; other versions are rejected. The only supported query parameter is beta=true. Accepted anthropic-beta tokens are claude-code-20250219, interleaved-thinking-2025-05-14, fine-grained-tool-streaming-2025-05-14, context-management-2025-06-27, prompt-caching-scope-2026-01-05 and effort-2025-11-24. They negotiate only the supported fields below; they do not enable cache controls or context clearing.
Python (pip install anthropic):
import os
from anthropic import Anthropic
client = Anthropic(base_url="https://api.netraruntime.com",
api_key=os.environ["NETRA_API_KEY"])
model = "deepseek/deepseek-v4.1-flash"
messages = [{"role": "user", "content": "Hello"}]
reply = client.messages.create(model=model, max_tokens=1024, messages=messages)
print(reply.content)
with client.messages.stream(model=model, max_tokens=1024, messages=messages) as stream:
for text in stream.text_stream:
print(text, end="", flush=True)
final_message = stream.get_final_message()TypeScript (npm install @anthropic-ai/sdk):
import Anthropic from '@anthropic-ai/sdk';
const client = new Anthropic({
baseURL: 'https://api.netraruntime.com',
apiKey: process.env.NETRA_API_KEY,
});
const request = {
model: 'deepseek/deepseek-v4.1-flash', max_tokens: 1024,
messages: [{role: 'user' as const, content: 'Hello'}],
};
const reply = await client.messages.create(request);
const stream = client.messages.stream(request);
stream.on('text', text => process.stdout.write(text));
const finalMessage = await stream.finalMessage();For bearer authentication use Anthropic(api_key=None, auth_token=os.environ["NETRA_API_KEY"], base_url=...) in Python or {apiKey:null, authToken:process.env.NETRA_API_KEY, baseURL:...} in TypeScript.
The Python examples below reuse client and model from the connection example.
Tools and continuation
Custom schemas are preserved. Supported tool_choice types are auto, any, tool with a declared name, and none. The client executes tools. Ordinary answer text is never converted into tool calls. Return every outstanding tool result before new user text; results can be strings or text blocks. Set is_error when execution fails.
This example uses a local sample lookup. Replace its implementation with your application's authorized lookup and return a string or supported text blocks.
import json
def run_your_validated_tool(name, arguments):
if name != "lookup" or not isinstance(arguments.get("city"), str):
raise ValueError("Invalid lookup call")
cities = {"jakarta": {"city": "Jakarta", "country": "Indonesia"}}
return json.dumps(cities.get(arguments["city"].casefold(), {"error": "City not found"}))
tools = [{"name": "lookup", "description": "Look up a city",
"input_schema": {"type": "object", "properties": {
"city": {"type": "string"}}, "required": ["city"]}}]
history = [{"role": "user", "content": "Look up Jakarta"}]
reply = client.messages.create(model=model, max_tokens=4096,
messages=history, tools=tools,
tool_choice={"type": "tool", "name": "lookup"},
thinking={"type": "enabled", "budget_tokens": 1024})
history.append({"role": "assistant", "content": reply.content})
results = []
for block in reply.content:
if block.type == "tool_use":
result = run_your_validated_tool(block.name, block.input)
results.append({"type": "tool_result", "tool_use_id": block.id,
"content": result})
if results:
history.append({"role": "user", "content": results})
continuation = client.messages.create(model=model, max_tokens=4096,
messages=history, tools=tools, tool_choice={"type": "none"},
thinking={"type": "enabled", "budget_tokens": 1024})Each continuation is a separate billed generation. Strict schemas and disabling parallel tool calls are unsupported. Tool-result images and arbitrary result objects are unsupported; send supported text blocks rather than serializing an arbitrary prompt.
Thinking
thinking:{type:"disabled"} disables reasoning. Enabled thinking requires budget_tokens at least 1024 and below max_tokens. The reasoning budget is approximate rather than a guaranteed hard limit. thinking:{type:"adaptive"} with output_config:{effort:"high"} selects Netra's supported reasoning policy; actual reasoning behaviour depends on the selected Netra model. Medium may map to high. An explicit effort without a thinking object enables reasoning; explicit disabled thinking conflicts with effort. Do not combine a budget and effort.
Returned thinking is unsigned Netra reasoning with an empty signature. Preserve it with the assistant content during a tool loop. Claude signatures and opaque encrypted provider history cannot be replayed; such unsupported metadata produces an explicit error. Reasoning stays separate from answer text and is already included in output_tokens.
V4.1 image input
import base64
with open("example.png", "rb") as f:
data = base64.b64encode(f.read()).decode("ascii")
reply = client.messages.create(model="deepseek/deepseek-v4.1-flash",
max_tokens=1024, messages=[{"role": "user", "content": [
{"type": "text", "text": "Describe this image"},
{"type": "image", "source": {"type": "base64",
"media_type": "image/png", "data": data}}
]}])PNG, JPEG, GIF and WebP are accepted up to 5 MiB per image, within the overall request limit. MIME/encoding are validated. Text-only models reject images. URL images, PDFs, audio, files, transformations and server tools are unsupported.
Token counting
count = client.messages.count_tokens(model=model, system="Be brief",
messages=[{"role": "user", "content": "Hello"}], tools=tools)
print(count.input_tokens)Token counting estimates input usage for the selected model, including system instructions, history, tools and supported images. Counting does not generate a response or incur inference charges. The X-Netra-Token-Count-Mode: model-template-estimate header identifies an estimate; final generation usage can differ and determines billing. Use the same messages, tools and thinking settings when comparing requests. For enabled thinking, the eventual output limit can also affect reasoning settings. Count requests accept at most 16 MiB JSON and static inline images up to 5 MiB and 40 million pixels each. Animated images are unsupported for counting. Rate or capacity limits return 429 with Retry-After; temporary unavailability returns 503 and timeouts return 504.
Usage, privacy and limits
Input usage is partitioned: input_tokens + cache_read_input_tokens + cache_creation_input_tokens equals total prompt usage. Cache creation is reported as zero, with no separate cache-write charge. Output includes reasoning once. Final streaming usage replaces earlier cumulative totals. Usage may be estimated when exact counts are unavailable; use your recorded usage to reconcile charges.
Anthropic cache_control, breakpoint and TTL controls are unsupported. API request recording is off by default. If you choose to enable recording, request and response captures are scheduled for deletion after 30 days. Turning recording off does not immediately delete existing captures. Trace export requires recording to be enabled. See Observe for recording controls and data handling for related guidance.
Assistant prefill, mid-conversation system messages, structured output_config.format, context clearing/compaction, unknown betas and unsupported meaningful fields return errors. The single context-management preservation setting edits:[{type:"clear_thinking_20251015",keep:"all"}] is accepted. Recognized beta headers do not enable other unsupported operations. SSE failures emit error events without message_stop; do not treat a partial answer as success. SDK retries can create further generations.
Claude Code setup
Configure Claude Code with the API origin and a Netra model for each model role. The configuration below uses V4.1 Flash for the main model and V4 Flash 0731 for smaller tasks. Tool execution happens in your client. Features that require unsupported API operations, including conversation compaction, are unavailable; check the supported fields above when configuring your workflow.
export ANTHROPIC_BASE_URL=https://api.netraruntime.com
export ANTHROPIC_API_KEY="$NETRA_API_KEY"
export ANTHROPIC_MODEL=deepseek/deepseek-v4.1-flash
export ANTHROPIC_DEFAULT_OPUS_MODEL=deepseek/deepseek-v4.1-flash
export ANTHROPIC_DEFAULT_SONNET_MODEL=deepseek/deepseek-v4.1-flash
export ANTHROPIC_DEFAULT_HAIKU_MODEL=deepseek/deepseek-v4-flash-0731
export ANTHROPIC_SMALL_FAST_MODEL=deepseek/deepseek-v4-flash-0731
export DISABLE_PROMPT_CACHING=1
export CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1
export MAX_THINKING_TOKENS=1024
export CLAUDE_CODE_MAX_OUTPUT_TOKENS=4096
claude --bare --model "$ANTHROPIC_MODEL"For bearer mode, unset ANTHROPIC_API_KEY and set ANTHROPIC_AUTH_TOKEN="$NETRA_API_KEY". Keep the explicit Netra model-role settings above. MAX_THINKING_TOKENS=0 alone may not disable reasoning if the client also sends an effort setting. Use the Messages API’s explicit thinking: {"type":"disabled"} when your application requires reasoning to be disabled.