Dev.to AI 🤖 Ai 👁 0 📖 8 min read

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:

What you need

  1. A popnow.ai account.
  2. An API key from the API console. Keys start with sk-popnow- and are shown in full only once.
  3. 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

  1. When createTask accepts 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.
  2. When the task finishes:
    • succeeded: you pay the actual amount, capped at the hold. The unused part of the hold returns to your balance.
    • failed or expired: the whole hold is released. You pay nothing.
  3. 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-java on 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_rejected at no cost. Prompts and input images are also checked before a task is accepted; a declined submission returns 400 with 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/quote and 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.

📰 Read the original article on Dev.to AI

Originally published by Dev.to AI. Aggregated on AIWithGhost for educational purposes — full credit and traffic to the original publisher.