Quickstart for OpenRouter NSFW users
Integrate our uncensored LLM API into your existing codebase by updating the base URL and API key. This guide covers the standard OpenAI-compatible endpoints, streaming, and constraint handling for direct developer use.
Base URL and Authentication
Replace your current provider's base URL with https://api.openrouternsfw.com/v1. Authentication uses the standard Authorization: Bearer <key> header. You obtain your key immediately after signing up via Google or email on the Get API key page. No phone number is required, and the key is displayed only once, so copy it before leaving the page.
Our service is an independent API, not a reseller of other vendors' models. The model identifier you send in requests is uncensored, which runs on our own servers. It is tuned to answer without content refusals for lawful adult use, but it is not GPT, Claude, or any other named vendor model.
Ensure your client library is configured to use this new base URL. All requests must include a valid API key in the header. If the key is missing or invalid, the server returns a 401 error. If you have no prepaid credit, you receive a 402 error. These are standard HTTP status codes indicating authentication or payment issues, not server errors.
Chat Completions Endpoint
The core functionality is provided via the POST /v1/chat/completions endpoint. This endpoint accepts a JSON body containing the model name, messages array, and optional parameters. It returns a JSON object with the generated text, token usage statistics, and finish reason. This structure is compatible with the official OpenAI SDKs and most OpenAI-compatible client libraries.
You do not need to write custom HTTP clients if you prefer using an SDK. However, you must update the configuration to point to our base URL. The following example demonstrates a standard completion request using cURL. This request sends a prompt to the uncensored model and expects a text response.
curl https://api.openrouternsfw.com/v1/chat/completions \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "uncensored",
"messages": [{"role": "user", "content": "Write a blunt product review of a cheap VPN."}]
}'Remember that this API serves only text. There are no embeddings, image, audio, or video generation endpoints. If your application requires multimodal inputs or outputs, you will need to handle those separately. Our service focuses exclusively on high-quality text generation with an uncensored model.
Python SDK Integration
Using the Python SDK simplifies the integration process. Initialize the client with the correct base URL and your API key. The library handles the HTTP requests and JSON parsing for you. You can specify the model ID as uncensored to ensure you are using our specific model.
from openai import OpenAI
client = OpenAI(base_url="https://api.openrouternsfw.com/v1", api_key="YOUR_KEY")
resp = client.chat.completions.create(
model="uncensored",
messages=[{"role": "user", "content": "Summarise this thread without softening it."}],
)
print(resp.choices[0].message.content)This code snippet shows how to send a message and retrieve the response. The client automatically handles the connection and error reporting. If the server returns an error, the SDK raises an exception. You should handle these exceptions in your application logic to provide a better user experience.
The Python SDK is just one option. You can use any language that supports HTTP requests. The endpoint structure remains the same regardless of the client you choose. This flexibility allows you to integrate the uncensored model into any existing workflow without significant code changes.
Node SDK Usage
The Node SDK works similarly to the Python version. Configure the client with the base URL and API key, then call the chat completions method. This approach is ideal for server-side applications or backend services that need to generate text asynchronously.
import OpenAI from "openai";
const client = new OpenAI({ baseURL: "https://api.openrouternsfw.com/v1", apiKey: process.env.API_KEY });
const resp = await client.chat.completions.create({
model: "uncensored",
messages: [{ role: "user", content: "Draft a villain monologue for my game." }],
});
console.log(resp.choices[0].message.content);Node.js developers can easily integrate this API into their existing projects. The SDK handles the serialization and deserialization of JSON data. You can also specify additional parameters such as temperature or top_p to control the randomness of the output.
Make sure to handle the asynchronous nature of the requests properly. Use async/await or Promise chains to manage the response data. This ensures that your application remains responsive while waiting for the model to generate the text. The Node SDK is a reliable choice for building scalable text generation services.
Streaming Responses
Enable streaming by setting the stream parameter to true in your request. The server will send a series of Server-Sent Events (SSE) instead of a single JSON response. Each event contains a partial chunk of the generated text.
stream = client.chat.completions.create(
model="uncensored",
messages=[{"role": "user", "content": "Tell the story in second person."}],
stream=True,
)
for chunk in stream:
if chunk.choices and chunk.choices[0].delta.content:
print(chunk.choices[0].delta.content, end="", flush=True)Streaming is useful for real-time applications where you want to display the output as it is generated. The final chunk of the stream contains the total token usage for the request. This allows you to track costs accurately without waiting for the entire response to complete.
Handle the stream events carefully to ensure that the text is assembled correctly. Concatenate the chunks in the order they are received. The server guarantees that the chunks are sent in sequence. If the connection is interrupted, you may need to retry the request. Streaming is a powerful feature that enhances the user experience for text generation tasks.
Rate Limits and Context Window
Each API key is limited to 300 requests per minute and 8 concurrent requests. The request body size is capped at 8 MB. If you exceed these limits, the server returns a 429 status code. This is a standard HTTP status code indicating that you have sent too many requests in a given time window. You should implement exponential backoff in your client to handle these errors gracefully.
The context window supports up to 100,000 tokens for the combined prompt and completion. There is no separate output cap. If you do not specify the max_tokens parameter, the response can run to the end of the window. You can limit the output length by setting max_tokens to a lower value.
Monitor your token usage to manage your prepaid credit effectively. Errors and refusals do not consume tokens, so you are not charged for failed requests. This ensures that you only pay for successful text generation. Keep an eye on your rate limits to avoid interruptions in your service.
Specs at a glance
Everything the endpoint can and cannot do, in one place — check it before you top up.
| Parameter | Details |
|---|---|
| API format | OpenAI Chat Completions schema; official openai SDKs work unchanged |
| Authentication | Bearer token in the Authorization header |
| Endpoints | POST /v1/chat/completions · GET /v1/models |
| Base URL | https://api.openrouternsfw.com/v1 |
| Model | uncensored |
| Structured output | JSON object mode via response_format json_object |
| Max output | up to the rest of the 100,000-token window; max_tokens optional (no separate cap) |
| Context window | 100,000 tokens, input and output combined |
| Other parameters | temperature, top_p, stop, seed and the two penalties are passed through |
| Tools / tool calls | Yes — tools, tool_choice; replies carry tool_calls, also when streaming; send results back as role: tool |
| Streaming | Yes — server-sent events; the last chunk carries token usage |
| Response headers | X-Request-Id, X-Balance-USD, X-RateLimit-Limit-Requests, X-RateLimit-Limit-Concurrency |
| Request size | up to 8 MB per request |
| Concurrency | up to 8 in parallel per key |
| Rate limit | 300 requests per minute per key |
| Payment | crypto: USDT on TRON or USDC on Base, $20–$500, any whole sum |
| Credit expiry | no monthly fee; paid credit does not expire |
| How you pay | prepaid credit, charged by real token usage; errors and refusals are free |
| Trial credit | $0.50 for 7 days, no card · Trial key: 2 parallel requests, 60 req/min; full limits (8 and 300) after first top-up |
| Volume bonus | +5% from $50, +10% from $100, +15% from $200 |
| Price | input $0.15 / 1M tokens, output $0.50 / 1M tokens |
| Content policy | adult content allowed; sexual content involving minors is refused |
| Sign-in | Google or e-mail and password |
| Key management | one active key per account; a new key replaces the old one |
Errors and what to do
Every error is JSON with a type you can switch on. You are never charged for an error.
| Code | Type | Meaning |
|---|---|---|
400 | bad_request | invalid JSON, empty messages, bad parameter, or a prompt longer than the window — fix and resend |
401 | missing_key · invalid_key · key_revoked | no key, wrong key, or a key replaced by a newer one |
402 | no_credit | out of credit; add credit and retry |
403 | content_blocked | sexual content involving minors — refused, not billed |
404 | not_found | unknown endpoint |
413 | request_too_large | request body larger than 8 MB |
429 | rate_limited · concurrency | over 300/min or 8 parallel — back off and retry |
503 | upstream_busy | temporary overload, retry shortly |
Questions and answers
How is the uncensored model different from other vendors?
Our model is an open-weight model run on our own servers, tuned to answer without content refusals for lawful adult use. It is not GPT, Claude, Gemini, Grok, DeepSeek, Qwen, Llama, or any other vendor's model. We do not route between vendors; we serve a single uncensored endpoint.
What happens if I exceed the rate limit?
If you exceed 300 requests per minute or 8 concurrent requests per key, the server returns a 429 status code. This is a standard HTTP status code indicating that you have sent too many requests in a given time window. You should implement backoff logic in your client to handle these errors.
Does the API support function calling and JSON mode?
Yes, the API supports function calling (tools, tool_choice) and JSON mode (response_format json_object). You can also specify parameters like temperature, top_p, stop, seed, presence_penalty, and frequency_penalty to control the output.
Your key is one form away
Create an account, copy the key, change the base URL. That is the whole setup.
Get API key