negbeta inference

API docs

An OpenAI-compatible chat completions API for open-weight models. If your code already talks to the OpenAI API, change the base URL, the key and the model id.

https://inference.negbeta.com/v1Base URL
qwen/qwen3.8-27bModel id
262,144 tokensContext (prompt plus output)
65,536 tokensMaximum output

Quickstart

curl https://inference.negbeta.com/v1/chat/completions \
  -H "Authorization: Bearer $NEGBETA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "qwen/qwen3.8-27b",
    "messages": [{"role": "user", "content": "Write a haiku about tokens."}]
  }'

With the OpenAI Python SDK:

from openai import OpenAI

client = OpenAI(base_url="https://inference.negbeta.com/v1", api_key=NEGBETA_API_KEY)
resp = client.chat.completions.create(
    model="qwen/qwen3.8-27b",
    messages=[{"role": "user", "content": "Write a haiku about tokens."}],
)
print(resp.choices[0].message.content)

Authentication

Send your API key as a bearer token on every request: Authorization: Bearer sk-negbeta-.... Each platform or customer gets its own key, which we can revoke or rotate on request. To get a key, email info@negbeta.com. A missing or wrong key gets 401 with code invalid_api_key.

Keep keys server-side. Never put them in browser code or a public repository.

Models

Model idDetails
qwen/qwen3.8-27b Qwen3.8 27B (Qwen/Qwen3.8-27B, Apache-2.0), NVFP4 weights. Text and image input, text output. Context 262,144 tokens, output up to 65,536 tokens.
deepseek/deepseek-v4.1-flash-1017 DeepSeek V4.1 Flash 1017 (deepseek-ai/DeepSeek-V4.1-Flash-1017), FP8. Text and image input, text output. Context 1,048,576 tokens, output up to 393,216 tokens.

Model ids are exact and case-sensitive. If your platform needs its own name for a model, we can add it for your key on request. The response's model field repeats the id you sent. A missing model gets 400 (missing_required_parameter); any other id gets 404 (model_not_found). More models are coming; we give at least 14 days' notice before a model is retired, with its replacement.

Chat completions

POST /v1/chat/completions, with OpenAI's request and response shapes. This is the only inference endpoint: there is no Anthropic Messages API, no Responses API and no embeddings endpoint.

Messages

  • Roles: system, user, assistant and tool.
  • System messages only at the start. A system message after a user, assistant or tool message gets 400 with the message System message must be at the beginning. Put all system instructions first.
  • Images: image_url content parts, as an https URL or a base64 data URI (PNG, JPEG or WebP, at most 20 MB each), up to 16 images per request. No audio, video or files.
  • Request bodies up to 64 MB.

Parameters

ParameterValues
max_tokens, max_completion_tokens1 to 65,536. Prompt plus output must fit in 262,144 tokens.
temperature0 to 2
top_p0 to 1
top_k, min_pAccepted (top_k -1 means off)
presence_penalty, frequency_penalty-2 to 2
repetition_penalty0 to 2
stopString or array of strings
logprobs, top_logprobsBoolean; 0 to 20
n1 only
seedAccepted, but output is not guaranteed to be reproducible
tools, tool_choice, parallel_tool_calls, response_formatSee Tools and structured output
reasoning, reasoning_effortSee Reasoning

Out-of-range values get 400 with param naming the field. Responses include usage with prompt_tokens, completion_tokens, total_tokens and prompt_tokens_details.cached_tokens.

Long requests: if a non-streamed request is still running after 15 seconds, the 200 headers are sent early and a newline follows every 15 seconds until the JSON body (leading whitespace is valid JSON, and OpenAI SDKs read it normally). If such a request then fails, the error object comes in the body with status 200. Use streaming for long generations. If the client disconnects, generation stops.

Streaming

Set "stream": true to receive server-sent events (text/event-stream) in OpenAI's chunk format. Every stream ends with a usage chunk (empty choices, full usage), whether or not you set stream_options.include_usage; a stream that completes then sends data: [DONE].

data: {"id":"...","object":"chat.completion.chunk","model":"qwen/qwen3.8-27b","choices":[{"index":0,"delta":{"content":"OK."},"finish_reason":null}]}

data: {"id":"...","object":"chat.completion.chunk","model":"qwen/qwen3.8-27b","choices":[],"usage":{"prompt_tokens":15,"completion_tokens":3,"total_tokens":18,"prompt_tokens_details":{"cached_tokens":0}}}

data: [DONE]
  • When nothing has been sent for 15 seconds (for example while a long prompt is processed), the stream carries an SSE comment line : keep-alive. SSE clients ignore it.
  • An error before the first token comes back as a normal HTTP error status. An error after the stream has started arrives as one event data: {"error": {...}} (same shape as below), preceded by a usage chunk for the tokens already generated; then the stream ends.

Tools and structured output

  • Tools: tools (function tools), tool_choice (auto, none, required or a named function) and parallel_tool_calls. Tool calls come back in message.tool_calls (streamed as indexed delta.tool_calls) with finish_reason: "tool_calls". Send results back as role: "tool" messages with the matching tool_call_id. Tool-call arguments are generated under a grammar from your JSON schema, so they parse as valid JSON.
  • Structured output: response_format {"type": "json_object"} or {"type": "json_schema", "json_schema": {"name": ..., "schema": {...}}}. Output is constrained to the schema. A schema that cannot be compiled gets 400.

Reasoning

Both models think before they answer, by default (DeepSeek V4.1 Flash 1017 at effort high). The reasoning text is returned separately from the answer, in message.reasoning_content (streamed as delta.reasoning_content); message.content holds only the answer. usage.reasoning_tokens counts the reasoning tokens, which are included in completion_tokens.

  • reasoning_effort: none (no thinking), minimal, low, medium, high, xhigh or max.
  • Or OpenRouter's form: "reasoning": {"effort": "low"}, or "reasoning": {"enabled": false} to turn thinking off.

Reasoning tokens count against max_tokens. A small max_tokens with thinking on can end with finish_reason: "length" before any answer; turn thinking off for short, simple replies.

Prompt caching

Automatic for every request: nothing to opt into and no cache-write charge. When a request starts with the same tokens as a recent one (for example the same system prompt, tools and conversation so far), that prefix is not processed again. Cached tokens are reported in usage.prompt_tokens_details.cached_tokens and billed at the cached-input price. There is no fixed lifetime: the least recently used prefixes are evicted first. Keep the stable parts of your prompt at the start and unchanged between requests to get the most hits.

The cache holds the model's internal state for recent prefixes, in memory on the serving machine only. It is not a store of prompts, is never written to logs, and is cleared on restart.

Errors

Errors use OpenAI's shape, and every response, successful or not, carries an X-Request-Id header. Quote it when you contact us.

{"error": {"message": "The model `gpt-4o` does not exist or you do not have access to it.",
           "type": "invalid_request_error", "param": null, "code": "model_not_found"}}
Statustype / codeMeaning and what to do
400invalid_request_error; context_length_exceeded, missing_required_parameter or nullThe request is invalid: a parameter out of range, a system message after the start, a malformed image, prompt plus max_tokens over the model's context. Fix the request; do not retry it unchanged.
401authentication_error / invalid_api_keyMissing or wrong API key.
404invalid_request_error / model_not_found; not_found_errorUnknown model id, or an unknown URL.
405, 413invalid_request_errorWrong HTTP method; body over 64 MB.
429, or 503 for platforms that ask for itrate_limit_exceeded, or the platform's agreed overload typeCapacity is full right now. Retry after the number of seconds in Retry-After.
429insufficient_quotaThe key's usage budget is used up (test keys). No Retry-After: retrying does not help; contact us.
500, 503server_errorA server-side error, or the service is briefly unavailable. Retry with backoff (honour Retry-After when present).
504timeoutThe request timed out before any output. Retry.

Rate limits and retries

We do not queue requests. When the capacity for your traffic is full, the request is refused at once with 429 (rate_limit_exceeded), or 503 for platforms that ask for it, with a Retry-After header in seconds, usually a few seconds. Wait that long and retry; add jitter if you retry many requests at once. Nothing was generated or billed for a refused request.

Limits depend on the capacity agreed for your key, not on a fixed public number of requests per minute. We add GPUs as traffic grows: if you see sustained 429s, or expect a large increase, email us and we will add capacity.

Data handling

  • Zero data retention. Prompts, images and outputs exist only in server memory while the request runs. They are never written to disk or logs, never reviewed by people and never used for training, by us or anyone else.
  • Prompt cache: model-internal state of recent prefixes, in memory on the serving machine only, evicted as new requests arrive and cleared on restart (see Prompt caching).
  • What we keep: operational metadata without content (request id, timings, token counts, sampling settings, counts of messages, tools and images, sanitised error messages, a hashed key) for 180 days; client IP address and user agent for 30 days.
  • Where: we serve from EU and US capacity. Each key is served only from the region agreed for it, so EU-only keys stay in the EU. We can add capacity in other regions on request.

Details: data policy, privacy policy and terms of service.

Contact