The NeverNo API
OpenAI- and Anthropic-compatible endpoints for private open models, anonymized Claude, GPT, Gemini and Grok, images, voice and embeddings. Change the base URL, keep your code and your coding agent.
Quick start
Create a key
Sign in, open Settings, then the API section, and create a key. It is shown once: copy it somewhere safe. You can hold up to 10 keys and revoke any of them in one click.
Add credits
API usage is paid from its own API balance (1 credit = $0.01), separate from your plan’s credits and from credits bought for the app. Top up from Settings, from $10 to $2,000, with a bonus of 6 to 7% on large top-ups.
Point your client at NeverNo
Set the base URL to
https://neverno.ai/api/v1and pass your key. Any OpenAI-compatible SDK or tool works as is.
Base URL and authentication
Every request goes to the base URL below and carries your key as a bearer token, or in an x-api-key header as the Anthropic SDKs send it. Keys start with nn_live_.
- Base URL
- https://neverno.ai/api/v1
- Header
- Authorization: Bearer nn_live_…
Keep your key on your server: never ship it in a web page or a mobile app. A key that leaks can be revoked from Settings at any time, and only its SHA-256 fingerprint is stored on our side.
Endpoints
The same request and response shapes as OpenAI (and as Anthropic for /messages), and Venice’s names for the image tools.
- GET
/modelsEvery model with its type, capabilities (tools, vision, reasoning, response formats), context length and price in credits. Public, no key needed. - POST
/chat/completionsChat replies, in one piece or streamed, with function calling, JSON output and vision. - POST
/messagesAnthropic’s Messages format, for Claude Code and the Anthropic SDKs: tool use, streaming events. - POST
/messages/count_tokensAn estimate of what a Messages request weighs. Free. - POST
/embeddingsVectors for search and memory, float or base64. - POST
/audio/speechText to speech, MP3 out. - POST
/audio/transcriptionsSpeech to text from an audio file of up to 1 MB. - POST
/images/generationsOne to four images from a prompt, returned as base64. - POST
/images/editsAn image changed by an instruction, in OpenAI’s shape. - POST
/image/upscaleAn image enlarged two or four times; the image itself comes back. - POST
/image/background-removeThe subject cut out on a transparent background. - POST
/image/editThe same edit as `/images/edits`, with the image itself in the response.
curl https://neverno.ai/api/v1/models{ "object": "list", "data": [ { "id": "auto", "object": "model", "owned_by": "neverno", "type": "chat", … }, { "id": "z-image-turbo", "object": "model", "owned_by": "tongyi", "type": "image", "pricing": { "unit": "image", "credits": 0.325 }, … } ]}
Chat completions
Send model and messages (roles system or developer, user, assistant and tool, up to 2,000 messages). Use auto and NeverNo picks the cheapest model able to answer well, or name any chat model from /models. temperature, top_p, stop and seed are passed to the models that take them and left out for the others (their supported_parameters in /models).
Images can be read by the models with the vision trait: pass a content part of type image_url, with a public https address (answering directly, 4 MB at most) or a data:image/png;base64,… URL (up to 20 images, 4.5 MB per request). Each image must be a still PNG, JPEG or WebP, 256 to 4096 pixels a side; it is checked against the hard limits and the account’s content filter before the model sees it (no one who could be a minor), then sent re-encoded without metadata. The checks are billed with the reply, at the same rate. max_tokens (or max_completion_tokens) caps the reply; reasoning_effort turns on reasoning for the models that support it, returned in reasoning_content.
Web search: enable_web_search set to on searches the web (Google results) before every reply, auto only when the question needs fresh facts, off never (the default). enable_web_scraping: true reads the web pages linked in the last message. The model cites the pages as [1], [2]…, numbered like web_search_citations (title, url, snippet), returned in the response and in the first streamed chunk. Both are billed in credits at their real cost × 2.5, with the reply (about 0.25 credit per search). They can also be passed inside venice_parameters.
curl https://neverno.ai/api/v1/chat/completions \ -H "Authorization: Bearer $NEVERNO_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "auto", "messages": [{"role": "user", "content": "Explain how a VPN works in three sentences."}] }'
Streaming
Set stream: true to receive server-sent events in the OpenAI format, chunk by chunk, ending with [DONE]. Add stream_options: { "include_usage": true } to get a last chunk with the usage and no choices.
curl -N https://neverno.ai/api/v1/chat/completions \ -H "Authorization: Bearer $NEVERNO_API_KEY" \ -H "Content-Type: application/json" \ -d '{"model": "deepseek-v4-flash", "stream": true, "messages": [{"role": "user", "content": "Write a haiku about the sea."}]}'
試してみる
お持ちのキーを1つ貼り付け、モデルを選んでメッセージを送信してください。返答は API から届いた順に表示されます。通常の API 呼び出しと同じく、クレジットで課金されます。
Function calling and JSON output
Pass tools (functions with a JSON schema), and optionally tool_choice (auto, none, required or one named function) and parallel_tool_calls. When the model calls a tool, the reply holds tool_calls and finish_reason is tool_calls; run the function, then send the assistant message back with a tool message holding the result (tool_call_id), and the model answers from it. The models whose capabilities.tools is true in /models support it, auto included; any other model answers with a clear 400 tools_not_supported.
response_format: { "type": "json_object" } asks for valid JSON, and json_schema for JSON that follows your schema, on the models listed with response_format and json_schema in their capabilities.
import jsontools = [{ "type": "function", "function": { "name": "get_weather", "description": "Current weather of a city", "parameters": {"type": "object", "properties": {"city": {"type": "string"}}, "required": ["city"]}, },}]messages = [{"role": "user", "content": "What is the weather in Paris?"}]reply = client.chat.completions.create(model="deepseek-v4-flash", messages=messages, tools=tools)call = reply.choices[0].message.tool_calls[0] # finish_reason == "tool_calls"args = json.loads(call.function.arguments) # {"city": "Paris"}messages += [reply.choices[0].message, {"role": "tool", "tool_call_id": call.id, "content": '{"temperature_c": 18}'}]final = client.chat.completions.create(model="deepseek-v4-flash", messages=messages, tools=tools)print(final.choices[0].message.content)
Streamed tool calls
In a stream, each call arrives as OpenAI writes it: a first delta with its index, id, type and function name, then the arguments in pieces under the same index, and a last chunk with finish_reason: "tool_calls".
data: {"choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null}], …}data: {"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"id":"call_8f…","type":"function","function":{"name":"get_weather","arguments":""}}]}, …}]}data: {"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"{\"city\":"}}]}, …}]}data: {"choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"\"Paris\"}"}}]}, …}]}data: {"choices":[{"index":0,"delta":{},"finish_reason":"tool_calls"}], …}data: [DONE]
Anthropic Messages and Claude Code
POST /messages speaks Anthropic’s format: system, text, image, tool_use and tool_result blocks, tools with input_schema, tool_choice, stop_sequences, thinking, and the streaming events (message_start, content_block_start, text_delta, input_json_delta, content_block_stop, message_delta, message_stop, ping). The key goes in x-api-key or Authorization: Bearer; anthropic-version and anthropic-beta are accepted.
Claude model names (claude-sonnet-…, claude-opus-…, claude-haiku-…, with or without a date) are served by the Claude model of that family listed in /models, and any other chat model id of the catalog works too: deepseek-v4-pro or glm-5.2 through the same endpoint cost far less. The model that answered is named in the X-NeverNo-Model header. Anthropic’s own server tools (its web search, its code execution) are left out; your client’s tools work as usual.
import osimport anthropicclient = anthropic.Anthropic(base_url="https://neverno.ai/api", api_key=os.environ["NEVERNO_API_KEY"])message = client.messages.create( model="claude-sonnet-4-5", # served by the Claude Sonnet model in /models max_tokens=1024, messages=[{"role": "user", "content": "Explain how a VPN works in three sentences."}],)print(message.content[0].text)
Claude Code
Point Claude Code at NeverNo with two environment variables, then run claude as usual. It calls https://neverno.ai/api/v1/messages.
export ANTHROPIC_BASE_URL="https://neverno.ai/api"export ANTHROPIC_AUTH_TOKEN="nn_live_…"# optional: the models Claude Code usesexport ANTHROPIC_MODEL="claude-sonnet-4-5"export ANTHROPIC_SMALL_FAST_MODEL="claude-haiku-4-5"claude
ANTHROPIC_MODEL and ANTHROPIC_SMALL_FAST_MODEL choose the models (a Claude name, or any chat model id from /models). Every call is billed in credits like any other API call. Anthropic’s prompt cache goes through: the cache_control breakpoints Claude Code sets (system, tool results, last messages; four at most, ttl 5m or 1h) are passed on to the Claude models, and usage reports cache_creation_input_tokens and cache_read_input_tokens. A cache write is billed 1.25 × the input price (2 × with ttl: "1h"), a cache read 0.025 to 0.1 × depending on the model (/models lists each price): on a long session, each turn costs a fraction of its uncached price. On the OpenAI endpoint, put cache_control on a text part of a system, user or tool message, or at the top level of the request for an automatic breakpoint; prompt_tokens_details then shows cached_tokens and cache_write_tokens.
Coding agents and tools
Any tool that accepts an OpenAI-compatible provider works with the base URL and a key; the models with tools in /models handle agent work.
| Tool | Setting |
|---|---|
| Claude Code | ANTHROPIC_BASE_URL=https://neverno.ai/api and ANTHROPIC_AUTH_TOKEN=nn_live_… (see above). |
| Cline, Roo Code | API provider “OpenAI Compatible”, base URL https://neverno.ai/api/v1, your key, a model id such as deepseek-v4-pro. Or the “Anthropic” provider with the custom base URL https://neverno.ai/api. |
| Cursor | Settings › Models: add the model id, turn on “Override OpenAI Base URL” with https://neverno.ai/api/v1, and paste your key as the OpenAI API key. |
| Aider | OPENAI_API_BASE=https://neverno.ai/api/v1 and OPENAI_API_KEY=nn_live_…, then aider --model openai/deepseek-v4-pro. |
| Continue | In config.yaml: provider: openai, apiBase: https://neverno.ai/api/v1, your apiKey and the model id; qwen3-embedding-0.6b as the embeddings model. |
| OpenCode | A provider using @ai-sdk/openai-compatible with baseURL: https://neverno.ai/api/v1, your key and the model ids you want. |
Coding agents send their whole session again on every turn, so a long session costs more per call. Cheaper models (deepseek-v4-flash, glm-5.2, deepseek-v4-pro) keep it low.
Image generation
Send a prompt and, optionally, a model (default z-image-turbo). Images are returned in b64_json only: they are never stored on our side, so there is no URL to fetch later. Decode the base64 and save the file yourself.
Every image is about one megapixel: the size you ask for is matched to the closest supported aspect (1:1, 4:3, 3:4, 3:2, 2:3, 16:9, 9:16, 21:9), and the size actually produced is returned in the response.
curl https://neverno.ai/api/v1/images/generations \ -H "Authorization: Bearer $NEVERNO_API_KEY" \ -H "Content-Type: application/json" \ -d '{"model": "z-image-turbo", "prompt": "A lighthouse at dawn, 35mm photo", "size": "1024x1024"}' \ | jq -r '.data[0].b64_json' | base64 --decode > lighthouse.webp
Request fields
- prompt
- Required. Up to 1,500 characters.
- model
- An image model id from
/models(typeimage). Defaultz-image-turbo. - n
- Number of images, 1 to 4. Default 1.
- size
1024x1024,832x1216,1792x1024… orauto(square). Ratios up to 3:1.- response_format
b64_jsononly (the default).- output_format
webp(default),pngorjpeg.- negative_prompt
- Optional, up to 500 characters. Used by the models that support it.
- seed
- Optional integer, to reproduce a result.
Response
OpenAI’s shape (created, data[].b64_json), plus the model, the size produced, the output_format and the credits charged.
{ "created": 1793361600, "data": [{ "b64_json": "UklGRk4vAABXRUJQVlA4…", "seed": 81726354 }], "model": "z-image-turbo", "size": "1024x1024", "output_format": "webp", "credits": 0.325}
Embeddings, voice and image tools
/embeddings returns the vectors of the model behind NeverNo’s memory (qwen3-embedding-0.6b, 1,024 values, up to 128 inputs a request); dimensions shortens them and encoding_format: "base64" is understood. OpenAI’s model names are accepted and served by it.
/audio/speech reads up to 4,096 characters in MP3 with the app’s voices: tts-kokoro (default, many languages), tts-xai, tts-qwen3, tts-inworld and tts-minimax; voice is a voice name listed in /models, and OpenAI’s names (tts-1, alloy, nova…) are mapped to Kokoro. /audio/transcriptions takes a multipart file of up to 1 MB (WebM, Ogg, MP4/M4A, MP3, WAV, AAC), billed on its duration, and answers in json, text or verbose_json.
vectors = client.embeddings.create( model="qwen3-embedding-0.6b", input=["NeverNo keeps nothing.", "The sky is blue."], dimensions=512,)print(len(vectors.data[0].embedding)) # 512
Image tools
Send image as base64, a data URL or a public https address (or as a multipart file). The image is checked against the hard limits first, and every edit instruction is reviewed. /image/* returns the image itself (PNG by default, output_format to change it), /images/edits returns b64_json.
Prices in credits
| Model or tool | Unit | Credits |
|---|---|---|
qwen3-embedding-0.6b | 1M tokens | 1.5 |
tts-kokoro | 1,000 characters | 0.15 |
tts-xai | 1,000 characters | 2.25 |
tts-qwen3 | 1,000 characters | 3 |
tts-inworld | 1,000 characters | 7.5 |
tts-minimax | 1,000 characters | 15 |
whisper-large-v3-turbo | minute of audio | 0.03 |
/image/upscale | image | 0.15 |
/image/background-remove | image | 0.15 |
/image/edit | image | 0.325 |
Pricing in credits
1 credit = $0.01. API usage is billed at the real cost of the model you call, times 1.5 for open and closed models (Claude, GPT, Gemini, Grok) alike and times 2.5 for images, with no subscription required. It is paid from a separate API balance: a plan’s included credits and credits bought for the app are never spent by the API, and the API never spends them.
Top-ups of $10, $25, $100, $500 or $2,000 (any amount from $10 to $2,000) carry a volume bonus calculated on the amount paid in one payment: +6% from $100, +7% from $500, usable on open models and images. Taxes are included in the price, charged in your local currency.
Starter credit: the first time you create an API key, your account receives $1 once, usable on open models and images only (a daily budget is shared by all new accounts, so it can run out). The “Dev” subscription, $25 a month, adds $1 of API credit each day, for open models and images only, not carried over to the next day; its request limit is the one of Pro+.
Before a call, the most it can cost is reserved from your balance; once it is done, you pay the real amount and the rest comes back. A call that fails on the provider’s side is refunded.
What a call cost is returned, in credits, in the X-NeverNo-Credits header of the non-streamed answers of /chat/completions and /messages (for example X-NeverNo-Credits: 0.8421, rounded to 4 decimals); a streamed answer sends its headers before the end, so it carries none. When a reply is declined, it may be given back within bounds: the header then reads 0 and nothing is deducted.
Claude models: tokens read from Anthropic’s prompt cache cost 0.025 to 0.1 × the input price depending on the model (0.05 × for Opus and Sonnet) and tokens written to it 1.25 × (2 × for a one-hour cache); /models lists cache_read_credits and cache_write_credits. The reservation assumes the worst case (everything written), the settlement uses what the provider reports.
OpenAI models write the whole prompt to their cache on every call and are billed 1.25 × the input price for it: their input_credits in /models already include it; tokens read back cost cache_read_credits.
Chat models, credits per million tokens
| Model | Privacy | Tools | Input | Output |
|---|---|---|---|---|
NeverNo Uncensoredneverno-uncensored | private | — | 31.65 | 142.425 |
DeepSeek V4 Flashdeepseek-v4-flash | private | ✓ | 14.4008 | 28.8015 |
GLM 5.3 Flashglm-5.3-flash | private | ✓ | 23.7375 | 79.125 |
Qwen 3.5 35Bqwen-3.5-35b | private | ✓ | 22.155 | 158.25 |
Mistral Small 3.2mistral-small-3.2 | private | ✓ | 11.8687 | 31.65 |
GLM 5.2glm-5.2 | private | ✓ | 221.55 | 696.3 |
DeepSeek V4 Prodeepseek-v4-pro | private | ✓ | 205.725 | 411.45 |
Euryale 70Beuryale-70b | private | — | 134.5125 | 134.5125 |
Kimi K3kimi-k3 | private | ✓ | 451.0125 | 2,373.75 |
Claude Fable 5.2claude-fable-5.2 | anonymized | ✓ | 1,266 | 6,330 |
Claude Opus 5.5claude-opus-5.5 | anonymized | ✓ | 633 | 3,165 |
Claude Sonnet 5.5claude-sonnet-5.5 | anonymized | ✓ | 316.5 | 1,582.5 |
Claude Haiku 5.5claude-haiku-5.5 | anonymized | ✓ | 15.825 | 79.125 |
GPT-6 Astragpt-6-astra | anonymized | ✓ | 1,978.125 | 7,912.5 |
GPT-6.1 Solgpt-6.1-sol | anonymized | ✓ | 395.625 | 1,582.5 |
GPT-6.1 Terragpt-6.1-terra | anonymized | ✓ | 197.8125 | 791.25 |
Gemini 4 Argongemini-4-argon | anonymized | ✓ | 316.5 | 1,582.5 |
Grok 4.7grok-4.7 | anonymized | ✓ | 316.5 | 949.5 |
auto is billed at the price of the model it picks for each request. Anonymized models are reached without your identity, but their makers’ own rules still apply.
Image models, credits per image
| Model | Per image |
|---|---|
Z-Image Turboz-image-turbo | 0.325 |
FLUX 3 Kleinflux-3-klein | 0.325 |
NeverNo Uncensoredneverno-uncensored-image | 0.325 |
Z-Imagez-image | 1.6 |
Qwen Image 2.1 Turboqwen-image-2.1-turbo | 3.5 |
Qwen Image 3.0 Proqwen-image-3-pro | 10 |
FLUX 3flux-3 | 12 |
Nano Banana 2.1nano-banana-2.1 | 8.4 |
GPT Image 2.6gpt-image-2.6 | 10.925 |
GPT Image 2.6 Flaregpt-image-2.6-flare | 10.925 |
Muse Imagemuse-image | 2.5 |
Rate limits
Each account has a number of API requests per rolling 24 hours, by plan. Past it, calls get a 429 until the window moves.
| Plan | Requests per 24 h |
|---|---|
| 無料 | 500 |
| Pro | 5,000 |
| Pro+ | 20,000 |
| Max | 50,000 |
Every call counts as one request, whatever the number of tokens or images; `/messages/count_tokens` does not. A short limit per minute also applies (429 with `Retry-After`).
Errors
Errors use OpenAI’s format, so client libraries show the message as is: { "error": { "message", "type", "code" } }.
| Status | Code | Meaning |
|---|---|---|
| 400 | invalid_request | A field is missing or malformed; the message says which. |
| 400 | invalid_size | The image size cannot be read, or its ratio is above 3:1. |
| 400 | unsupported_response_format | Images are returned in b64_json only. |
| 400 | model_no_vision | This chat model does not read images. |
| 400 | tools_not_supported | This chat model does not support function calling: pick one with tools in its capabilities. |
| 400 | response_format_not_supported | This chat model cannot follow the requested response_format. |
| 400 | model_rejected_request | The model refused the request’s options; nothing was charged. |
| 400 | context_length_exceeded | The prompt is longer than the model’s context. |
| 400 | invalid_image | An image could not be read: PNG, JPEG or WebP, 256 to 4096 pixels a side (image_too_small, image_too_large), from a data URL or a public https address. |
| 400 | content_policy_violation | The request breaks the hard limits that apply to everyone. |
| 401 | invalid_api_key | Missing, unknown or revoked key. |
| 402 | insufficient_credits | Not enough credits for this request. |
| 403 | content_filtered | Blocked by the account’s content settings (age confirmation and content filter, in Settings). |
| 404 | model_not_found | Unknown model id: see /models. |
| 413 | too_large | Request body too large. |
| 422 | image_refused | An image breaks the hard limits (no one who could be a minor) or the account’s content filter. |
| 422 | request_refused | The request is outside what NeverNo answers: see the acceptable use policy. |
| 429 | rate_limited | Daily request limit reached. |
| 502 | provider_error | The model provider failed; nothing was charged for what was not delivered. |
| 503 | image_check_unavailable | An image could not be checked; try again in a moment. |
| 503 | safety_check_unavailable | The request could not be checked; try again in a moment. |
{ "error": { "message": "Not enough credits for this request. Buy credits in NeverNo.", "type": "insufficient_quota", "code": "insufficient_credits" }}
Privacy
We do not log or keep your prompts, your messages, the replies or the images. Nothing of a request is used to train a model. Private models run on providers that keep nothing; anonymized models are reached without your identity.
What we do keep is what billing needs: the time of each call, the model and the credits charged, and when each key was last used.
The same hard limits apply to everyone, through the API as in the app: nothing involving minors, nothing about real people without their consent, no real help to seriously harm others.
Build with NeverNo
Create a key in Settings and make your first call in a minute.
Create an API key