Compatible AIArticles
Open AI Compatible Uncensored API: What Works
An OpenAI-compatible API accepts the same requests as OpenAI's SDKs, so you change a base URL and a key instead of rewriting code. Here is exactly which parts carry over and which do not.
Last updated
Summary
- Change the base URL and key, set the model to uncensored, and existing OpenAI SDK code runs.
- Chat completions, responses, models, streaming, tool calling and JSON mode are supported.
- Embeddings, images, audio and fine-tuning are not offered; it is a text API.
- Limits are 8 concurrent requests and 300 per minute on a full key.

What compatible means in practice
An open ai compatible uncensored api is a hosted service that speaks the OpenAI wire format but runs a different model: one open-weight model tuned to answer without content refusals for lawful adult use. Compatible describes the request and response shapes, not the company behind the model. This service is not OpenAI's API, and it is not a router that forwards to other vendors.
In practice that means three things stay the same in your code: the URL paths (/v1/chat/completions and friends), the JSON fields you send, and the auth header (Authorization: Bearer <key>). Three things change: the base URL, the key, and the model ID, which is always uncensored.
If you already use an OpenAI SDK, you are most of the way there. The rest of this page covers the details that decide whether a migration takes five minutes or an afternoon.
What is supported and what is not
| Feature | Status | Notes |
|---|---|---|
| POST /v1/chat/completions | Supported | The main endpoint; messages, sampling parameters, stop sequences |
| POST /v1/responses | Supported | For clients that use the newer Responses format |
| GET /v1/models | Supported | Returns the model list; the ID to use is uncensored |
| Streaming (SSE) | Supported | stream: true, usage reported at the end |
| Tool calling | Supported | tools, tool_choice, streamed tool_calls, results as role: "tool" |
| JSON mode | Supported | response_format: {"type":"json_object"} |
| Embeddings | Not offered | Use a separate embedding service |
| Image, audio, video generation | Not offered | Text in, text out only |
| Fine-tuning | Not offered | One hosted model, no custom weights |
Sampling fields such as temperature, top_p, stop, seed and the frequency and presence penalties are passed through to the model. The context window is 100,000 tokens, prompt and completion together, and max_tokens is optional.
The one hard rule on content is that nothing sexual involving minors is allowed. Everything else about the model's behaviour is described on the documentation page.
Swap the base URL in existing code
Most SDKs read the base URL and key either from constructor arguments or from environment variables. The cleanest migration touches only configuration.
Python
from openai import OpenAI
client = OpenAI(
base_url="https://api.compatibleaiopen.com/v1",
api_key="YOUR_KEY",
)
resp = client.chat.completions.create(
model="uncensored",
messages=[{"role": "user", "content": "Write a two-line villain monologue."}],
)
print(resp.choices[0].message.content)Node.js
import OpenAI from "openai";
const client = new OpenAI({
baseURL: "https://api.compatibleaiopen.com/v1",
apiKey: process.env.UNCENSORED_KEY,
});
const resp = await client.chat.completions.create({
model: "uncensored",
messages: [{ role: "user", content: "Write a two-line villain monologue." }],
});
console.log(resp.choices[0].message.content);curl
curl https://api.compatibleaiopen.com/v1/chat/completions \
-H "Authorization: Bearer $UNCENSORED_KEY" \
-H "Content-Type: application/json" \
-d '{"model":"uncensored","messages":[{"role":"user","content":"Say hello."}]}'Many OpenAI clients also honour OPENAI_BASE_URL and OPENAI_API_KEY. If your tool does, you can point it at this service without editing a line of code. You can get a key on the API key page.
Where migrations usually break
- Hard-coded model names. Code that sends a vendor model name will not find it here. Replace it with
uncensored, and make the model name a config value so you never edit it again. - Embeddings in the same client. A RAG pipeline often calls the embeddings endpoint through the same SDK object. That call has no equivalent here, so give embeddings their own client with their own base URL.
- Vendor-specific extras. Features that exist only on one vendor's platform, such as hosted file search or built-in web browsing tools, are not part of this API. Tool calling works with functions you define and run yourself.
- Context assumptions. The window is 100,000 tokens in total. If your code budgets against a different number, change it, or long prompts will be trimmed too early or too late.
- Concurrency. A full key allows 8 requests at once and 300 per minute. A batch job that fires 50 parallel calls will see HTTP 429 until you add a limiter.
The last point is the most common one. A 429 with code rate_limited means too many requests per minute, and concurrency means too many at once. On temporary overload you also get a 429 with a Retry-After: 5 header. Honour that header and retry.
Tool calling and JSON mode carry over too
Two features decide whether an agent or a data pipeline can move over, and both use the standard OpenAI fields. For tools, you pass a tools array of function definitions and optionally tool_choice. When the model wants a function run, the reply contains tool_calls; you run the function yourself and send the result back as a message with role: "tool". Streamed responses deliver tool_calls in pieces, the same way OpenAI's stream does.
tools = [{
"type": "function",
"function": {
"name": "get_weather",
"description": "Current weather for a city",
"parameters": {
"type": "object",
"properties": {"city": {"type": "string"}},
"required": ["city"],
},
},
}]
resp = client.chat.completions.create(
model="uncensored",
messages=[{"role": "user", "content": "Weather in Oslo?"}],
tools=tools,
)
print(resp.choices[0].message.tool_calls)For structured output, set response_format={"type": "json_object"} and say in the prompt that you want JSON. Validate the result anyway. JSON mode asks for valid JSON, but your own schema checks still belong in your code.
Choose /v1/chat/completions if your code already uses it, which is the case for most tools. Use /v1/responses only when your client is built around that format. You do not need both.
A five-minute compatibility test
Before you move production traffic, run a short script that exercises the features your app actually uses. If a feature is missing, you find out now.
- List models with
GET /v1/modelsand confirmuncensoredis present. - Send a plain chat request and check that
choices[0].message.contentis filled. - Repeat it with
stream: trueand confirm chunks arrive and a final usage block closes the stream. - If you use tools, send one request with a single function and check that the reply contains
tool_calls. - If you parse JSON, send a request with
response_formatset tojson_objectand run it through your parser 20 times.
Every response carries an X-Request-Id header, plus X-Balance-USD with your remaining credit. Log both. When something looks wrong, the request ID is what you give to support.
Cost and next steps
Pricing is $0.15 per 1M input tokens and $0.50 per 1M output tokens, from prepaid credit. There is no subscription, failed or refused requests are not charged, and credit does not expire. A request with 2,000 input tokens and 500 output tokens costs $0.00055. Details and the top-up bonuses are on the pricing page.
New accounts can claim $0.50 of trial credit with one click on the key page, valid for 7 days, no card needed. That is enough for several hundred small test calls. If you are comparing this with routing services, the open router alternative integration guide covers that angle.
More guides
Common questions
Do I need a special SDK?
No. The official OpenAI SDKs for Python and Node work once you set the base URL and key. Any other client that lets you set a custom endpoint also works.
Is this the official API of the model's original developer?
No. It is a hosted service running one open-weight model from an independent provider. It is not the official API of OpenAI, Meta, Mistral or any other vendor.
Can I use it for embeddings or images?
No. It is text only: chat completions, responses and the models list. Use a separate service for embeddings and image generation.
What does uncensored mean here?
The model is tuned to answer without content refusals for lawful adult use. Content involving minors in a sexual context is never allowed.