Summary
- Base URL is https://api.modelsunlocked.com/v1 and the model id is uncensored.
- Official OpenAI SDKs in Python and Node work unchanged apart from base URL and key.
- Unlocked means fewer refusals, not no rules: sexual content involving minors is never allowed.
- Store the key in an environment variable and call the API from your server.
What you need before you start
- An account. Sign up with Google, or with email and password.
- An API key from the API key page. New users can claim $0.50 of trial credit there with one click; it is valid for 7 days and needs no card.
- A recent Python 3 or Node.js, or just curl.
Keep the key out of your source code. Put it in an environment variable such as API_KEY, and never ship it inside a browser page or a mobile app. If it leaks, regenerate it on the key page. The old key stops working at once, and you do not have to contact support.
Python setup
Install the official package, then point it at the new base URL.
pip install openai
export API_KEY="paste-your-key-here"
import os
from openai import OpenAI
client = OpenAI(
base_url="https://api.modelsunlocked.com/v1",
api_key=os.environ["API_KEY"],
)
resp = client.chat.completions.create(
model="uncensored",
messages=[
{"role": "system", "content": "You are a helpful, frank assistant."},
{"role": "user", "content": "In two sentences, what is a token in an LLM?"},
],
)
print(resp.choices[0].message.content)
print(resp.usage)
The reply sits in choices[0].message.content. The usage block gives prompt and completion token counts, which is what billing uses.
Node and curl setup
The Node SDK takes the same two settings.
npm install openai
import OpenAI from "openai";
const client = new OpenAI({
baseURL: "https://api.modelsunlocked.com/v1",
apiKey: process.env.API_KEY,
});
const resp = await client.chat.completions.create({
model: "uncensored",
messages: [{ role: "user", content: "Name three uses for a binary tree." }],
});
console.log(resp.choices[0].message.content);
And the raw HTTP version, useful for testing from a shell or debugging a proxy:
curl https://api.modelsunlocked.com/v1/chat/completions \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{"model":"uncensored","messages":[{"role":"user","content":"Hello"}]}'
Besides POST /v1/chat/completions, the service also exposes POST /v1/responses and GET /v1/models. The docs show the request fields for each.
Streaming and options
Add stream=True to get the reply token by token over server-sent events. Usage numbers arrive at the end of the stream.
stream = client.chat.completions.create(
model="uncensored",
messages=[{"role": "user", "content": "Write a limerick about compilers."}],
stream=True,
temperature=0.8,
max_tokens=120,
)
for chunk in stream:
if chunk.choices and chunk.choices[0].delta.content:
print(chunk.choices[0].delta.content, end="", flush=True)
print()
Sampling settings (temperature, top_p, stop, seed and the frequency and presence penalties) are passed through to the model. max_tokens is optional; when it is absent the completion can use whatever remains of the 100,000-token window. JSON mode (response_format set to {"type": "json_object"}) and tool calling with tools and tool_choice also work, including streamed tool_calls.
Streamed requests hold a concurrency slot until they finish, so read each stream to the end.
Check the connection with a models call
Before you write any application code, confirm that the key and base URL work by listing the models. The call produces no text, so it is the cheapest possible test.
for m in client.models.list():
print(m.id)
You should see uncensored, and nothing else. If the call raises an authentication error, the key is wrong or was regenerated. If it cannot connect, look for a typo in the base URL. Many chat front ends run this same call when you press a connect button, which is why it is worth getting right first.
What unlocked means in practice
The word is marketing shorthand, so here is the working definition. The model behind this API is one open-weight model run by an independent provider. It is tuned so that it does not decline or water down requests that are lawful for adults, such as dark fiction, blunt advice, mature roleplay or edgy humour. It is not the official API of any model vendor and it does not route between vendors.
Unlocked does not mean unlimited in every direction. Three things stay the same:
- Sexual content involving minors is a hard limit and is never allowed.
- The model can still be wrong. Fewer refusals do not make facts more accurate, so check anything important.
- You remain responsible for your application, its users and the laws that apply to you.
Practically, this means your system prompt does more of the work. Say who the audience is, what tone you want and what is out of bounds for your product. The model follows those instructions rather than a built-in policy of its own. Our production checklist for uncensored LLM APIs turns that into a list you can work through before launch.
Configure by environment variables
Both official SDKs read standard environment variables, which lets you point existing code at this service without editing it. Set the base URL and key in your shell or your deployment settings:
export OPENAI_BASE_URL="https://api.modelsunlocked.com/v1"
export OPENAI_API_KEY="paste-your-key-here"
Then create the client with no arguments, OpenAI(), and set the model to uncensored. This is handy for frameworks and scripts that build the client for you. Many tools that accept an OpenAI-compatible endpoint offer the same two settings in their configuration screens. If a tool refuses to start without a key from its default provider, use the same value there; the key is just a Bearer token.
Keep separate keys for development and production when you can. Accounts that have topped up can hold up to 5 keys, label them and revoke any one without touching the others.
Limits, errors and cost
A full key allows 8 concurrent requests and 300 requests per minute. The trial key allows 2 and 60. Requests can be up to 8 MB. If you exceed a limit, you get HTTP 429 with the error code rate_limited (too many per minute) or concurrency (too many at once). A 429 with Retry-After: 5 means temporary overload; wait and retry.
import time
from openai import RateLimitError
def call(messages, tries=4):
for n in range(tries):
try:
return client.chat.completions.create(model="uncensored", messages=messages)
except RateLimitError as exc:
wait = exc.response.headers.get("Retry-After")
time.sleep(float(wait) if wait else 2 ** n)
raise RuntimeError("Rate limited too long")
Pricing is $0.15 per 1M input tokens and $0.50 per 1M output tokens, billed from prepaid credit. As an example, a call with 2,000 input tokens and 500 output tokens costs 2,000 x $0.15 / 1M + 500 x $0.50 / 1M = $0.0003 + $0.00025 = $0.00055. Failed or refused requests are not charged. Top-ups run from $20 to $500 in crypto, with bonuses of 5% from $50, 10% from $100 and 15% from $200; the pricing page has the details.
Troubleshooting
401 error. The key is wrong, has a stray space, or was regenerated. Copy it again from the key page.
404 error. Check that the base URL ends in /v1 and that you did not add the path twice.
Model not found. Use uncensored. Names from other vendors do not exist here.
Empty or cut-off replies. A low max_tokens ends the answer early. Raise it, or remove it.
Balance surprises. Read the X-Balance-USD response header after each call, or request GET /v1/balance. Log X-Request-Id with any error so a support request can point to the exact call. Prompts are not used for training.
