Video is where content filters bite hardest. The mainstream video APIs that exist will reject adult prompts outright, and the open-weight video models are heavy to host yourself. A NSFW AI video generation API closes that gap: you send a prompt (or a still image) and get a finished clip back, with no moderation in the way.
This is a developer’s guide to doing exactly that with Api18.dev — the two video modalities, the parameters that matter, sync vs async, and what it costs.
Two ways to make video#
- Text-to-video — describe the scene in a prompt and the model generates a clip. Best when you have no source frame. See the text-to-video guide.
- Image-to-video — supply a public image URL plus a motion prompt and the model animates it. Best for consistency with an existing character or frame. See image-to-video for adult use cases.
Parameters that matter#
- resolution — typically
720por1080p; affects price per second. - aspect_ratio — e.g.
16:9,9:16for vertical. - duration — clip length in seconds; total cost scales with it.
- seed — fix it for reproducible output; omit for random.
Each model documents its exact options on its page in the model reference. Don’t invent parameters — only the ones listed for a model are accepted.
The easy path: one synchronous call#
The simplest integration is POST /v1/generate?wait=true. It routes by the model field, waits for the job, and returns the finished result with the video at data[0].url. No polling loop to write.
curl -X POST "https://api18.dev/v1/generate?wait=true" \
-H "Authorization: Bearer $API18_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "<video-model-id>",
"prompt": "your prompt here",
"resolution": "720p",
"aspect_ratio": "16:9",
"duration": 5
}'
# → returns the finished job; the video URL is at .data[0].urlThe async path: poll for very long jobs#
For long renders you can omit ?wait=true and poll GET /v1/jobs/{id} until status is completed or failed.
let job = await fetch("https://api18.dev/v1/generate", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.API18_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({ model: "<model-id>", prompt: "..." }),
}).then((r) => r.json());
while (job.status !== "completed" && job.status !== "failed") {
await new Promise((r) => setTimeout(r, 3000));
job = await fetch("https://api18.dev/v1/jobs/" + job.id, {
headers: { Authorization: `Bearer ${process.env.API18_KEY}` },
}).then((r) => r.json());
}
if (job.status === "failed") throw new Error(job.error ?? "generation failed");
console.log(job.data.map((d) => d.url));retention_days on the job). Download and store anything you need to keep.What it costs#
Video is billed per second of output in USD, with rates that vary by resolution and model, multiplied by duration. There is no subscription and failed jobs are refunded automatically. Fund your balance with USDT on Solana or Tron — details in Pay-per-call with crypto.
Getting started
- Create an account and grab a key in the dashboard.
- Try models for free with your $10 welcome credit in the playground.
- Top up paid balance in USDT, then call the API from your server.