How to generate images, video and audio with the PopNow API
The PopNow API is a single REST interface for image, video and audio generation, plus optional chat models. You send a task, wait or get a webhook, and receive a signed download link. This guide follows the official docs
The PopNow API is a single REST interface for image, video and audio generation, plus optional chat models. You send a task, wait or get a webhook, and receive a signed download link. This guide follows the official docs as they stood on 14 November 2026. If a setting, price or limit matters for production, confirm it on the live pages — model catalogs and rates change.
Disclosure: I work on PopNow. The steps and limits below come from official docs, not from an anonymous review.
Official starting points:
- Docs home: popnow.ai/docs
- Quickstart: popnow.ai/docs/quickstart
- API reference: popnow.ai/docs/api-reference
- OpenAPI 3.1 contract: popnow.ai/docs/openapi.yaml
- Changelog (UTC dates): popnow.ai/docs/changelog
What you need
- A popnow.ai account.
- An API key from the API console. Keys start with
sk-popnow-and are shown in full only once. - Funds on your PopNow balance. A new account starts at $0. Add funds under API billing in the console.
There is no separate API plan or subscription. As of 13 November 2026, API-key calls, the developer MCP, the API Playground, the website, the PopNow app, and PopNow in ChatGPT or Claude spend one account balance. The API and console show it in USD; the website shows the same balance in credits, where 1 credit = $0.001.
Keep the key on a server or in a secret store (POPNOW_API_KEY). Official docs are explicit: do not put a key in a browser, a mobile app, or any code that runs on someone else's device. Anyone who can read it can spend the balance. Official SDKs include a server-side proxy (@popnow/proxy) if a client app needs to trigger generation.
Your website login does not authenticate API requests. Keys in the URL query string are not accepted. Native /api/v1 routes only read the Authorization header. OpenAI-compatible routes under /v1 also accept x-api-key.
The request shape
Base URL for the native API:
https://api.popnow.ai/api/v1
Chat and OpenAI-compatible routes use https://api.popnow.ai/v1 (and Gemini uses /v1beta).
Every native response uses this envelope:
{ "code": 200, "msg": "success", "data": { }, "request_id": "req_…" }
code: 200 means success. Branch on code, not on the wording of msg. Log request_id (also returned as X-Request-Id) so you can quote it to support. Never send the API key to support.
Amounts such as costUsd, estimatedCostUsd, maxChargeUsd, availableUsd and heldUsd are USD decimal strings with up to nine decimal places. Keep every digit; do not round them through binary floating point.
Your first image
This is the official quickstart pattern: create a task and wait up to 60 seconds for the result.
export POPNOW_API_KEY="sk-popnow-..." # your key from the API console
curl -X POST "https://api.popnow.ai/api/v1/jobs/createTask?wait=60" \
-H "Authorization: Bearer $POPNOW_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{
"model": "alibaba/z-image-turbo/text-to-image",
"input": {
"prompt": "A small red fox curled up in a teacup, soft morning light, studio photo"
}
}'
On success, data.output.assets[0].url is a signed link to the file. Longer jobs such as video often return a taskId before the file is ready. Read it later with GET /jobs/recordInfo?taskId=..., or register a webhook.
Model IDs follow publisher/model/operation, for example google/nano-banana-2.1/text-to-image. List every callable model, with prices and optional input schemas, from:
GET https://api.popnow.ai/api/v1/models
GET https://api.popnow.ai/api/v1/models/{model}
Add ?includeSchema=1 on the list endpoint when you want input schemas. The models index and each model page document parameters and USD prices.
Quote first, then confirm
POST /jobs/quote takes the same body you would send to createTask and returns a price without creating a task or holding funds. Quotes expire after five minutes.
To lock the price you showed a user, submit the same request with quoteId and expectedCostUsd set to quote.maxChargeUsd before expiresAt. If the price changed or the quote expired, createTask returns 40901 and holds nothing. Quote again and show the new amount.
maxChargeUsd is the most that will be held. expectedChargeUsd is the expected cost; the two can differ when the final charge depends on the output, such as a clip's real length. A succeeded task is charged what it actually used, never more than the hold.
How a task is charged
- When
createTaskaccepts a task, the highest price it can reach is held from your balance (estimatedCostUsd). Held funds cannot be spent twice, but they are not charged yet. - When the task finishes:
-
succeeded: you pay the actual amount, capped at the hold. The unused part of the hold returns to your balance. -
failedorexpired: the whole hold is released. You pay nothing.
-
- Rejected requests (
400,402,403,429, and similar) do not create a task or a hold.
If your connection drops after you send createTask, the outcome is unknown until you check. Resend with the same Idempotency-Key. Write idempotency keys are remembered for 24 hours, so a retry does not start a second paid task.
You cannot cancel a task once it has been accepted. It runs to a final state. If it fails or expires, the hold is released.
There is no sandbox or test mode. Official guidance is to use the cheapest models and lowest settings while you build, and to try models in the Playground on their API pages first. Playground runs are also paid from the same balance.
Polling and webhooks
For images, the docs suggest a few seconds between polls; for video, 10–15 seconds. Prefer webhooks when you run many jobs.
There are two webhook styles, both documented at popnow.ai/docs/webhooks:
| Kind | How you set it up | What it covers |
|---|---|---|
| Task callback |
callBackUrl on each createTask
|
That one task |
| Account endpoint | Once, in the API console | Every matching task on the account |
Acknowledge with any 2xx within 15 seconds. Failed deliveries are retried seven more times over about nine hours (10s, 30s, 2min, 10min, 30min, 2h, 6h). The same task can arrive more than once, so make the handler idempotent (for example, unique on request_id). Webhooks only fire on a final state (succeeded, failed, expired). queued and running are never delivered. Deliveries themselves are free.
What to do with the file
Signed download links last about 20 minutes. Refresh them by reading the task again, or request a fresh link with POST /common/download-url. Copy anything you want to keep to your own storage or to the asset library. Each task record includes retention.outputsExpireAt. You can shorten retention on a request with the X-PopNow-Retention header (seconds), or delete a finished task's content with POST /jobs/purge.
Tasks belong to the key that created them. Querying a task created with another key on your account returns 404. Tasks started on the website are not accessible through API keys; use the API console for an account-wide view.
Rate limits and key caps
Default REST limits, from Rate limits:
- Writes (
createTask,retry, uploads, …): 1,000 per 10 seconds per account - Reads (
recordInfo, models, jobs, quote, …): 1,000 per 10 seconds per account - Upload tickets: 1,000 per 10 seconds, on top of writes
- Usage report: 30 per minute
- Asset library: 60 reads and 30 saves per minute, plus a daily limit on new assets
- Any request before the key is checked: 6,000 per minute per network
- Request body: 2 MiB of JSON
These numbers are defaults and can change. Trust the X-RateLimit-Limit, X-RateLimit-Remaining and Retry-After headers rather than hard-coding the table. Limits count per account, not per key — creating more keys does not raise them. A request over the limit is rejected immediately, not queued, and costs nothing.
Each key can also have a model allow-list, an IP allow-list, and daily, monthly and lifetime USD spend caps (dailySpendCap, monthlySpendCap, totalSpendCap). Daily caps reset at 00:00 UTC; monthly caps on the 1st of the month at 00:00 UTC. A request that would exceed a cap returns 40202 and holds nothing. Keys have no caps unless you add them. You can also set a monthly USD budget for the API balance in API billing (alert only, or block new requests with HTTP 402 / budget_exceeded).
Official SDKs and nearby APIs
Official packages are MIT-licensed under github.com/popnow-ai:
- Python:
pip install popnow - JavaScript/TypeScript:
npm install popnow - CLI:
npm install -g @popnow/cli - Go:
go get github.com/popnow-ai/popnow-go - PHP:
composer require popnow/popnow - Java:
ai.popnow:popnow-javaon Maven Central
The same docs also cover LangChain (pip install -U langchain-popnow), a Vercel AI SDK 7 provider (@popnow/ai-sdk-provider), a ComfyUI node pack, a Blender add-on, and an n8n community node for self-hosted n8n (n8n-nodes-popnow). That n8n node is not a verified node yet, so n8n Cloud cannot install it; the HTTP Request workflow works there.
The API also exposes:
- Chat models (Claude, Gemini, DeepSeek, GLM, Grok, Kimi and others) through OpenAI, Anthropic or Gemini protocols, priced per token in USD — see Chat models
- OpenAI Videos-compatible routes under
/v1/videos— see OpenAI Videos - Saved recipes, canvas workflows and agent skills — see Saved recipes
If you want an agent to call models from Claude Code, Cursor or Codex, use the developer MCP at https://api.popnow.ai/api/v1/mcp with an API key, not the OAuth connector URL. That setup is a separate article.
Limits worth reading before you ship
- Failed and expired tasks are not charged. That is also part of the API SLA: a quote is a price cap, and a model family below 95% success (at least 50 finished tasks in a full UTC hour) pays 10% of that hour's spend on it back to qualifying accounts, automatically, with stated caps and conditions.
- PopNow does not use your prompts, uploads or results to train AI models, per the official FAQ and Privacy Policy.
- Content rules in the Terms of Service apply to the API. A request a model declines fails as
content_rejectedat no cost. Prompts and input images are also checked before a task is accepted; a declined submission returns400with a reason and holds nothing. - Official starting prices on the website (one image, one 5-second video, or one song at the lowest setting) are listed on Pricing. The exact charge for a given request is whatever
jobs/quoteand the create button return for those settings. - Volume pricing is not a published self-serve rate. The API pricing page explains how to inquire about volume pricing for specific models and expected usage.
For a production pass, use the official production checklist. If something fails, include the request_id or task ID, the time in UTC, and the code — and never the key — when you write to support.
Originally published by Dev.to AI. Aggregated on AIWithGhost for educational purposes — full credit and traffic to the original publisher.