EN ▾

chatbotnsfw.comUncensored LLM API for developers

NSFW Chatbot API for Developers: How to Build One

An NSFW chatbot API for developers is an ordinary chat endpoint backed by a model that does not refuse lawful adult content. The endpoint is the easy part. The persona, memory, age gate and moderation around it are yours to build.

Last updated

Isometric stage with glowing chat bubbles passing through a gate above a server rack

Summary

  1. The API replaces a refusing model with one that answers adult fiction; everything product-side stays with you.
  2. Keep the key on your server, store history yourself and resend a trimmed window each turn.
  3. Gate access to adults before any chat call and keep a hard block on content involving minors.
  4. Streaming, retries on 429 and a per-user cap keep a small bot stable on 8 concurrent requests.

What the API gives you and what you still own

The service is a hosted, OpenAI-compatible text API. You point an OpenAI SDK at https://api.chatbotnsfw.com/v1, use the model ID uncensored and send normal chat messages. The model is an open-weight model tuned to answer without content refusals for lawful adult use. It is text only: no images, audio or video.

That is the whole contract. The API does not know who your user is, how old they are, or what your platform allows. It also does not remember anything between calls. Every request must carry the full conversation you want the model to see.

ConcernWho handles it
Generating replies without content refusalsThe API
Persona, tone and story rulesYou, in the system prompt
Conversation memoryYou, in your database
Age verification and consentYou
Blocking content involving minorsYou, and the API has the same hard limit
Reporting, bans, terms of useYou

If you have not built against a chat API before, the API documentation covers the request format. The existing NSFW LLM integration guide goes through the integration side in more detail; this article is about the product around it.

Architecture: keep the key on the server

Your frontend should never hold the API key. Put a small backend between the browser or app and the API. The backend authenticates your user, checks the age gate, loads their history, calls the API and stores the reply.

  1. Browser sends the user's message to your backend with their session.
  2. Backend checks the user is verified as an adult and under their rate cap.
  3. Backend builds the message list: system prompt, memory, recent turns, new message.
  4. Backend calls POST /v1/chat/completions and streams tokens back.
  5. Backend saves the new turn after the stream finishes.

A full key allows 8 concurrent requests and 300 requests per minute. That is plenty for a hobby bot and a fair start for a small product, as long as your backend does not let one user open many streams at once. A streamed request holds its concurrency slot until the stream ends, so a user who walks away from an open stream still costs you a slot.

Write the persona as a contract

The system prompt does most of the product work. A good one reads like a short contract with the model, not a paragraph of adjectives. Cover four things: who the character is, how it speaks, what the story is, and what is out of bounds.

import os
from openai import OpenAI

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

PERSONA = """You play Mara, a 34-year-old ship's navigator in a slow-burn
space romance. All characters are adults.
Voice: dry, warm, short paragraphs, first person.
Story rules: keep continuity with the notes below; never speak for the user;
stay in character unless the user writes OOC: in brackets.
Hard limits: no sexual content involving anyone under 18, ever. If the user
steers there, refuse in character and change the scene."""

def reply(history, user_text):
    messages = [{"role": "system", "content": PERSONA}]
    messages += history[-24:]
    messages.append({"role": "user", "content": user_text})
    r = client.chat.completions.create(
        model="uncensored",
        messages=messages,
        temperature=0.9,
        top_p=0.95,
    )
    return r.choices[0].message.content

Two details matter more than they look. State that all characters are adults, in plain words, in the prompt. And tell the model what to do at the edge, for example to change the scene, so the story keeps moving instead of ending in an error message. Raise temperature for livelier prose and lower it if the character drifts.

Test the persona before you ship it

Run the same twenty user messages through the prompt after every edit, including awkward ones: a user who asks the bot to drop character, one who changes the setting mid-scene, one who pushes toward the minors rule. Save the outputs and read them. Prompt edits that fix one case often break another.

Memory that fits inside the window

The context window is 100,000 tokens, prompt plus completion, so there is room for a long story. Longer is not always better. You pay for every input token on every turn, and a model with a huge history can lose early details anyway.

A practical layout has three layers. The system prompt holds the persona. A short notes block holds facts that must survive: names, relationship state, promises made in the story. The last 20 to 30 turns go in verbatim. Older turns are summarized into the notes block by a cheap call every 20 turns or so.

The code above already slices history[-24:], which keeps the last 24 messages. Add the notes block as a second system message when you have one. Costs stay low this way: a typical turn sends a few thousand input tokens, which at $0.15 per 1M input tokens is a fraction of a cent. The pricing page has the numbers, and the article on integration shows request shapes.

An adult-content product needs an age gate before the first chat call, not after. The API does not verify age. That duty sits with you, and the right method depends on where you operate and where your users live.

  • A checkbox that says I am over 18 is a notice, not verification. Some jurisdictions require more.
  • Store the result server-side against the account and check it on every chat request, not only at sign-up.
  • Make the adult-only nature clear on the landing page and in the terms, before sign-up.
  • Keep fictional characters adult in every persona, in the prompt and in the card shown to users.

Ask a lawyer who knows your market what the minimum is. This article cannot tell you, and the API provider cannot decide it for you.

Moderation duties that stay with you

An uncensored model changes what the model refuses. It does not change what you are responsible for. Plan these from day one:

  • Hard block on minors. Sexual content involving minors is banned outright. Add your own input check for obvious attempts and end the session when it triggers.
  • Reporting. Give users a way to flag a conversation, and decide what you do with a report.
  • Account actions. Be able to suspend a user quickly.
  • Data. Decide how long you keep transcripts and say so in your privacy page. The API provider does not use prompts for training, but your own database is your responsibility.
  • Scope. Keep the product to lawful adult use and fiction. State it in your terms.

Failed or refused requests are not charged, which means a request blocked by your own check costs nothing either, because it never reaches the API.

Per-user caps and cost control

An open chat box with no limits is an invitation for one user to drain your credit. Put a daily token cap on every account and check it before the API call. The response tells you what each turn used, so the cap costs one counter.

import os
from openai import OpenAI

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

DAILY_CAP = 400_000   # tokens per user per day
used_today = {}       # user_id -> tokens, keep this in your database

def guarded_reply(user_id, messages):
    if used_today.get(user_id, 0) >= DAILY_CAP:
        return "You have reached today's limit. Come back tomorrow."
    r = client.chat.completions.create(model="uncensored", messages=messages)
    used = r.usage.prompt_tokens + r.usage.completion_tokens
    used_today[user_id] = used_today.get(user_id, 0) + used
    return r.choices[0].message.content

A cap of 400,000 tokens is a number to tune, not a recommendation. With a 6,000-token prompt per turn it allows roughly 65 turns a day. Work out what a user is worth to you, price the cap against it, and look at the X-Balance-USD header in your own monitoring so a bug does not burn through credit overnight.

Keep a separate, small credit balance for staging. Test traffic and real traffic should never share a key, because a test loop that retries on every error can spend more in an hour than a week of real users.

Streaming and handling 429

Chat feels slow without streaming. Set stream: true and forward chunks to the browser. Streaming also ends with a usage block, which you can log for cost tracking.

Over a limit the API answers HTTP 429. The error code is rate_limited for requests per minute and concurrency for too many requests at once. Temporary overload also returns 429 with Retry-After: 5. Honor that header.

import os, time
from openai import OpenAI, RateLimitError

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

def stream_reply(messages):
    for attempt in range(4):
        try:
            stream = client.chat.completions.create(
                model="uncensored",
                messages=messages,
                stream=True,
            )
            for chunk in stream:
                if chunk.choices and chunk.choices[0].delta.content:
                    yield chunk.choices[0].delta.content
            return
        except RateLimitError:
            time.sleep(5)
    yield "The service is busy. Please try again in a moment."

Add a per-user lock so one account holds one stream at a time. Then 8 concurrent requests supports roughly 8 simultaneous chatting users, and a queue absorbs the rest.

To start, get an API key. New users can claim $0.50 of trial credit with one click on the key page. The trial key is limited to 2 concurrent requests and 60 requests per minute, which is enough to test the flow.

Frequently asked questions

Is there an official NSFW chatbot API from the big AI vendors?

This service is not the official API of any model vendor. It runs one open-weight model, run by an independent provider and tuned to answer without content refusals for lawful adult use.

Does the API verify my users are adults?

No. Age verification, consent and your terms of use are your job as the developer. The API does enforce a hard limit against sexual content involving minors.

Can it generate images for my chatbot?

No. It is text only. There is no image, audio or video generation, no embeddings and no fine-tuning.

How do I keep a character consistent over a long chat?

Keep a persona in the system prompt, a short notes block with key facts, and the last 20 to 30 turns verbatim. Summarize older turns into the notes.

How do I pay?

Top up from $20 to $500 with crypto only (USDT on TRC20 or USDC on Base). Credit never expires and there is no subscription.

Get your API key now

Sign up, grab your key, and update your base URL. That’s it.