# The NSFW alternative to the OpenAI API — same shape, no wall

> Your OpenAI integration works until the content does't pass the filter. eroq keeps the request shape and swaps the policy: uncensored roleplay, images and voice for adult products, ported in three strings.

Published 2026-08-28 · eroq.ai — canonical: https://eroq.ai/blog/openai-api-nsfw-alternative


Every adult product hits the same commit eventually: the OpenAI integration works beautifully, the product grows, and then the refusals start — mid-scene, unpredictably, on exactly the content your users signed up for. The filter isn't a bug; it's OpenAI's policy working as intended. It's just not *your* policy.

The fix doesn't require a rewrite. It requires an API that kept the shape and changed the rules.

## Three strings

eroq follows the OpenAI request convention on every surface that has one — `chat/completions`, `images/generations`, `audio/speech`. Migrating an existing integration is, almost always, literally this:

```diff
- baseURL: "https://api.openai.com/v1"
+ baseURL: "https://eroq.ai/v1"
- apiKey: process.env.OPENAI_API_KEY
+ apiKey: process.env.EROQ_API_KEY
- model: "gpt-4o-mini"
+ model: "eroq-rp-mini"
```

Messages array, streaming SSE chunks, `usage` block, error envelope — the shapes your code already handles. The [docs](/docs) even serve every page as raw markdown for your copilot, and the [quickstart](/docs/quickstart) is genuinely five minutes.

## What actually changes

**The policy becomes yours to rely on.** Adult and NSFW fiction between adult characters renders in character — the boundary is a [four-paragraph written policy](/legal/aup) (no minors, no real people, nothing illegal), enforced deterministically: out-of-policy requests return `content_blocked`, uncharged. You can quote our policy inside your own terms; try quoting a filter's mood.

**The pricing becomes flat.** OpenAI bills tokens; adult products have the industry's heaviest chatters. On eroq a completion is [1 or 3 credits](/pricing) regardless of length, images are 10, and failed generations refund themselves. Your scariest power user becomes a multiplication, not a variance.

**The models are specialists.** RP+ and RP mini aren't general assistants with the guardrails off — they're [roleplay-tuned](/blog/why-roleplay-needs-its-own-tuning): persona hold at depth, repetition damping at hot temperatures, a `context` field for character sheets, a texting mode for DM products.

**The stack goes past chat.** NSFW-capable [image generation](/docs/images), [async video](/docs/video), [voice both ways](/docs/speech) — and the [eroq Store](/storage), CDN hosting that won't terminate your account over the media your product exists to make.

## What honestly doesn't change

General-purpose intelligence isn't the trade: keep OpenAI (or any mainstream API) for your summaries, embeddings and tool-calling — many customers run both, routed by task. eroq takes the seat where the filter was the problem, not every seat.

## The migration checklist

1. [Key in hand](/signup) — 50 free credits, no card.
2. Swap the three strings behind a feature flag; run your worst-refused prompts first — that's the test that matters.
3. Wire [402 handling](/docs/errors) to your top-up flow (flat prepaid credits, so "out of budget" is a product event, not an invoice surprise).
4. Move persona/system blocks into the [`context` field](/docs/chat) when you're ready — cleaner transcripts, same behavior.

The whole point is that step 2 takes an afternoon, and the refusal alerts in your error tracker go quiet the same day.
