Moving from the PirateDiffusion API to Not Safu API
Not Safu API is the adult-branded HTTPS front door for the same PirateDiffusion API you already call. In most integrations you change only the host to api.notsafu.com and keep /api/v3/… paths, headers and your existing key.
URL map
| Piece | PirateDiffusion API (old) | Not Safu API (new) |
|---|---|---|
| Base | https://OLD_HOST/api/v3Replace OLD_HOST with the API host from your onboarding email or SDK default. | https://api.notsafu.com/api/v3Drop-in alias: https://api.notsafu.com/v1 |
| Auth | Authorization: Bearer YOUR_KEY | Same header, same key |
| Content-Type / Accept | application/vnd.api+json | Same |
| WebSocket | wss://OLD_HOST/render-events/{hash}?token=YOUR_KEY | wss://api.notsafu.com/v1/render-events/{hash} (Bearer preferred; ?token= still works). Bare /render-events/{hash} is also accepted. |
| Method | Old path | New path | Purpose |
|---|---|---|---|
POST | https://OLD_HOST/api/v3/render | https://api.notsafu.com/api/v3/renderor https://api.notsafu.com/v1/render | Create a render |
GET | https://OLD_HOST/api/v3/render/{hash} | https://api.notsafu.com/api/v3/render/{hash}or https://api.notsafu.com/v1/render/{hash} | Get a render |
GET | https://OLD_HOST/api/v3/render/from-url/{url} | https://api.notsafu.com/api/v3/render/from-url/{url}or https://api.notsafu.com/v1/render/from-url/{url} | Look up a render from an image URL |
POST | https://OLD_HOST/api/v3/chat | https://api.notsafu.com/api/v3/chator https://api.notsafu.com/v1/chat | Chat |
GET | https://OLD_HOST/api/v3/bot/{slug} | https://api.notsafu.com/api/v3/bot/{slug}or https://api.notsafu.com/v1/bot/{slug} | Get a persona |
GET | https://OLD_HOST/api/v3/concepts | https://api.notsafu.com/api/v3/conceptsor https://api.notsafu.com/v1/concepts | List concepts |
GET | https://OLD_HOST/api/v3/workflows | https://api.notsafu.com/api/v3/workflowsor https://api.notsafu.com/v1/workflows | List workflows |
POST | https://OLD_HOST/api/v3/knowledge | https://api.notsafu.com/api/v3/knowledgeor https://api.notsafu.com/v1/knowledge | Create a knowledge base |
POST | https://OLD_HOST/api/v3/knowledge/{domain}/search | https://api.notsafu.com/api/v3/knowledge/{domain}/searchor https://api.notsafu.com/v1/knowledge/{domain}/search | Search a knowledge base |
POST | https://OLD_HOST/api/v3/knowledge/{domain}/chat | https://api.notsafu.com/api/v3/knowledge/{domain}/chator https://api.notsafu.com/v1/knowledge/{domain}/chat | Chat with a knowledge base |
POST | https://OLD_HOST/api/v3/knowledge/{domain}/crawl | https://api.notsafu.com/api/v3/knowledge/{domain}/crawlor https://api.notsafu.com/v1/knowledge/{domain}/crawl | Crawl into a knowledge base |
POST | https://OLD_HOST/api/v3/knowledge/{domain}/fact | https://api.notsafu.com/api/v3/knowledge/{domain}/factor https://api.notsafu.com/v1/knowledge/{domain}/fact | Add a fact |
GET/POST/PATCH/DELETE | https://OLD_HOST/api/v3/skills | https://api.notsafu.com/api/v3/skillsor https://api.notsafu.com/v1/skills | Skills list/get/create/update/delete/select/invoke/auto |
POST/GET | https://OLD_HOST/api/v3/virtualuser/ | https://api.notsafu.com/api/v3/virtualuser/or https://api.notsafu.com/v1/virtualuser/ | Virtual users (login/otp stay blocked) |
Your API key stays the same
Not Safu is a relay: it forwards your Authorization header unchanged to the rendering backend. The key you already use for the PirateDiffusion API keeps working. There is no re-issue step on this site. If a key is compromised, reply to your access email right away.
Before / after
Only the host changes in these samples. Keep the same env var name you already use, or rename it to NOTSAFU_API_KEY for clarity.
curl — before
curl -sS -X POST "https://OLD_HOST/api/v3/render" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/vnd.api+json" \
-H "Accept: application/vnd.api+json" \
-d '{"prompt":"/images:1 lingerie editorial, soft window light","callback_url":"https://your-app.example/webhooks/render"}'
curl — after
curl -sS -X POST "https://api.notsafu.com/api/v3/render" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/vnd.api+json" \
-H "Accept: application/vnd.api+json" \
-d '{"prompt":"/images:1 lingerie editorial, soft window light","callback_url":"https://your-app.example/webhooks/render"}'
Python — before
import os, requests
BASE = "https://OLD_HOST/api/v3"
r = requests.post(
f"{BASE}/render",
headers={
"Authorization": f"Bearer {os.environ['API_KEY']}",
"Content-Type": "application/vnd.api+json",
"Accept": "application/vnd.api+json",
},
json={"prompt": "/images:1 lingerie editorial, soft window light",
"callback_url": "https://your-app.example/webhooks/render"},
timeout=120,
)
print(r.json())
Python — after
import os, requests
BASE = "https://api.notsafu.com/api/v3" # or "https://api.notsafu.com/v1"
r = requests.post(
f"{BASE}/render",
headers={
"Authorization": f"Bearer {os.environ['API_KEY']}",
"Content-Type": "application/vnd.api+json",
"Accept": "application/vnd.api+json",
},
json={"prompt": "/images:1 lingerie editorial, soft window light",
"callback_url": "https://your-app.example/webhooks/render"},
timeout=120,
)
print(r.json())
JavaScript — before
const res = await fetch("https://OLD_HOST/api/v3/render", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.API_KEY}`,
"Content-Type": "application/vnd.api+json",
Accept: "application/vnd.api+json",
},
body: JSON.stringify({
prompt: "/images:1 lingerie editorial, soft window light",
callback_url: "https://your-app.example/webhooks/render",
}),
});
console.log(await res.json());
JavaScript — after
const res = await fetch("https://api.notsafu.com/api/v3/render", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.API_KEY}`,
"Content-Type": "application/vnd.api+json",
Accept: "application/vnd.api+json",
},
body: JSON.stringify({
prompt: "/images:1 lingerie editorial, soft window light",
callback_url: "https://your-app.example/webhooks/render",
}),
});
console.log(await res.json());
What is different
- Host only for REST.
/api/v3/…paths, JSON:API envelopes, and Bearer auth match the PirateDiffusion API./v1/…is an identical shorter alias. - Media URLs. Image/video/audio links in responses are rewritten to
https://api.notsafu.com/v1/assets/…. Download and store your own copy; you can pass those URLs back as inputs. - Webhooks. Your
callback_url/error_urlstill receive POSTs from the rendering backend when a job finishes. Payload shape is unchanged; media links inside webhooks may still use backend storage hosts until the optional scrubbing relay is enabled. - WebSocket. Prefer
Authorization: Beareron the handshake.?token=remains for compatibility. Events are the same JSON shapes. - Blocked paths.
/virtualuser/loginand/virtualuser/otpstay refused (they return auto-login links for the web app, not for API customers). - No CORS. Call from your server only.
Checklist
- Point the base URL at
https://api.notsafu.com/api/v3(orhttps://api.notsafu.com/v1). - Keep
Authorization: Bearerand your existing key. - Keep
Content-Type/Accept: application/vnd.api+json. - Update any hardcoded media host allowlists to accept
https://api.notsafu.com/v1/assets/. - Update WebSocket clients to
wss://api.notsafu.com/v1/render-events/…. - Smoke-test:
GET https://api.notsafu.com/api/v3/conceptswith your key; start one render with a webhook you control. - Read the acceptable use policy (18+, legal and consensual, no real or realistic-looking minors).
Support and abuse
Product / access questions: reply to the email that issued your key.
Abuse reports and takedown requests: legal@notsafu.com. See Abuse and takedown.
Full endpoint reference: Developer guide.