Open account

Unfiltered Chatbot API: First Request in Five Minutes

An unfiltered chatbot API takes five minutes to try if you already have Python. You need a key, two changed settings in the OpenAI SDK and one request. After that, a system prompt and streaming turn it into a chatbot.

Last updated

Glass paper plane carrying a chat bubble from a key-shaped launch pad toward a lighthouse

Key takeaways

Minute 1 to 2: get a key

Go to the API key page and sign up with Google, or with email and password. After sign-up the key page shows a button to claim trial credit: $0.50, one per person, valid for 7 days, no card needed.

Copy the key and put it in an environment variable. A key in a file you commit by mistake is the most common way to lose credit.

# model ID for later requests: uncensored
export UF_API_KEY="paste-your-key-here"
pip install openai

A trial key allows 2 concurrent requests and 60 requests per minute. Those limits are plenty for this tutorial.

Minute 3: the first request

The service is OpenAI-compatible, so the official SDK works as soon as you change base_url and the key. The model ID is uncensored.

import os
from openai import OpenAI

client = OpenAI(
    base_url="https://api.chatbotunfiltered.com/v1",
    api_key=os.environ["UF_API_KEY"],
)

resp = client.chat.completions.create(
    model="uncensored",
    messages=[{"role": "user", "content": "Give me three names for a cyberpunk bar."}],
)

print(resp.choices[0].message.content)
print("tokens in/out:", resp.usage.prompt_tokens, resp.usage.completion_tokens)

Run it with python first.py. A list of names and a token count means everything works. If you see an authentication error, check the variable. If the connection fails, check that the base URL ends in /v1.

The response follows the OpenAI chat format: a choices list with the message, a usage block with token counts and, in that format, a finish reason telling you why generation stopped. A cut-off answer usually means a low max_tokens. As for cost, a request with 500 input tokens and 300 output tokens costs $0.000075 + $0.00015 = $0.000225. The five requests in this tutorial cost about a tenth of a cent in all, so the trial credit is barely touched.

Minute 4: add a system prompt and settings

A bare request gives you a default assistant voice. For a chatbot, add a system message that defines a character, and pass sampling settings that suit it.

import os
from openai import OpenAI

client = OpenAI(
    base_url="https://api.chatbotunfiltered.com/v1",
    api_key=os.environ["UF_API_KEY"],
)

raw = client.chat.completions.with_raw_response.create(
    model="uncensored",
    messages=[
        {"role": "system", "content": "You are Rook, a smuggler with a dry sense of humor. Stay in character. Keep replies under 80 words."},
        {"role": "user", "content": "Can you get me across the border tonight?"},
    ],
    temperature=0.9,
    top_p=0.95,
    max_tokens=200,
    seed=7,
)

resp = raw.parse()
print(resp.choices[0].message.content)
print("balance:", raw.headers.get("x-balance-usd"))
print("request id:", raw.headers.get("x-request-id"))
  • temperature and top_p control variety. Higher values give livelier, less predictable text.
  • seed makes tests easier to repeat. It is passed through, so use it to compare prompt edits.
  • max_tokens is optional. Without it, the completion can use the rest of the 100,000-token window.
  • The balance header tells you your remaining credit after each call.

The prompt is the product here. Keep it short and specific. Say who the character is, how they talk, what the story is and what the length should be. All of that goes into the system message once, and you send it again with every request, since the API remembers nothing between calls.

Minute 5: streaming

Streaming prints text as it is generated. It is a one-word change in the request, plus a loop to read chunks.

import os
from openai import OpenAI

client = OpenAI(
    base_url="https://api.chatbotunfiltered.com/v1",
    api_key=os.environ["UF_API_KEY"],
)

stream = client.chat.completions.create(
    model="uncensored",
    stream=True,
    messages=[
        {"role": "system", "content": "You are Rook, a smuggler with a dry sense of humor."},
        {"role": "user", "content": "Tell me about the worst job you ever took."},
    ],
)

for chunk in stream:
    if chunk.choices and chunk.choices[0].delta.content:
        print(chunk.choices[0].delta.content, end="", flush=True)
print()

A streamed request holds one of your concurrency slots until the stream ends. With a trial key, two open streams already use all of them, and a third request returns HTTP 429 with code concurrency. Wait and try again.

If you want to confirm usage after a stream, the final chunk includes a usage block.

Pick sampling values with a plan

Sampling settings change the feel of the bot more than most people expect. Start with the values below and move one at a time.

GoalSettingWhy
Lively storytellingtemperature 0.9 to 1.0, top_p 0.95More variety between runs
Consistent charactertemperature 0.6 to 0.7Fewer surprises
Repeatable testsseed fixed, temperature 0Same prompt gives the same kind of answer
Less repetitionFrequency or presence penalty around 0.3Discourages loops
Cut a reply at a markerstop with a stringEnds output when it appears

The temperature and top_p controls shift variety, and the penalties are passed through to the model. Change one value, run the same prompt five times, and read the five answers before changing the next.

Turn it into a conversation

The API does not keep history. To make Rook remember, keep a list and append both sides after every turn.

import os
from openai import OpenAI

client = OpenAI(
    base_url="https://api.chatbotunfiltered.com/v1",
    api_key=os.environ["UF_API_KEY"],
)

messages = [{"role": "system", "content": "You are Rook, a smuggler with a dry sense of humor."}]

def talk(text):
    messages.append({"role": "user", "content": text})
    r = client.chat.completions.create(model="uncensored", messages=messages)
    answer = r.choices[0].message.content
    messages.append({"role": "assistant", "content": answer})
    return answer

print(talk("Where are we headed?"))
print(talk("And what did I just ask you?"))

The second question works only because the first exchange is in the list. This is also why chat cost grows with length: each turn resends everything. The cost and trade-off analysis goes through that effect in depth, and the pricing page shows the rates of $0.15 and $0.50 per 1M tokens.

Two cautions as the list grows. The first is cost, since long histories raise the price of every turn. The second is the window: 100,000 tokens for prompt plus reply is generous, but a roleplay that runs for weeks will hit it. Drop the oldest turns, keeping the system message, once the list is long, or replace them with a short summary.

Common problems and next steps

ProblemLikely causeFix
Authentication errorWrong or empty keyPrint the variable length, remove spaces
Not foundBase URL missing /v1Use the exact base URL from this page
429 rate_limitedOver 60 requests per minute (trial)Slow down or use a full key (300 per minute)
429 with Retry-After: 5Temporary overloadWait 5 seconds and retry
Odd or flat repliesWeak system promptAdd voice, setting, length limit

Failed or refused requests are not charged. For next steps, read the API docs for tools and JSON mode. The model is text only, so there are no images, audio or embeddings. Top-ups are from $20 to $500 in crypto (USDT on TRC20 or USDC on Base), and credit never expires. You are responsible for adult-only access and moderation in anything you build on top of it.

If a problem is not in the table, reduce the request to the smallest working case: one user message, no system prompt, no extra parameters. Then add pieces back until it breaks. Nearly every issue in a first integration comes from a typo in the URL, a key copied with a trailing space or a messages list in the wrong shape.

Handle errors in code

A script that works once is not a bot. Add a retry for the cases where the API tells you to wait.

import os, time
from openai import OpenAI, RateLimitError

client = OpenAI(
    base_url="https://api.chatbotunfiltered.com/v1",
    api_key=os.environ["UF_API_KEY"],
    max_retries=0,
)

def ask(messages, tries=4):
    for i in range(tries):
        try:
            r = client.chat.completions.create(model="uncensored", messages=messages)
            return r.choices[0].message.content
        except RateLimitError:
            time.sleep(5 * (i + 1))
    raise RuntimeError("still rate limited after retries")

The SDK raises RateLimitError on HTTP 429. For temporary overload the API sends Retry-After: 5, so waiting five seconds is the right first step. For repeated concurrency errors, queue requests on your side instead of retrying faster.

Frequently asked questions

Is an unfiltered chatbot API the same as the OpenAI API?

The protocol is the same, so the OpenAI SDK works. The model is different: an open-weight model from an independent provider, tuned to answer without content refusals for lawful adult use.

What base URL and model should I use?

Base URL https://api.chatbotunfiltered.com/v1 and the model ID uncensored.

Do I need to pay to try it?

No. The $0.50 trial credit needs no payment details. Paid top-ups are by crypto only.

Can I stream responses?

Yes. Set stream to true. A streamed request occupies a concurrency slot until the stream ends.

How do I see my balance?

Read the X-Balance-USD header on any response, or call GET /v1/balance.

Get your API key instantly

Register, copy your key, update your base URL. Setup is complete.