PopNowAPI ドキュメント
はじめに
本文

クイックスタート

API キーを作成し、最初のリクエストを送り、結果をダウンロードするまで。所要時間は約 5 分です。

このページでは、キー 1 つとリクエスト 1 回で最初の画像を生成するところまでを案内します。動画、音声、Webhook、ファイルのアップロードも、あとは model と input を変えるだけで同じリクエストです。

始める前に

  • PopNow のアカウント。 popnow.ai で登録してください。登録時にもらえる無料クレジットは API でも使えます。足りなくなったらクレジットパックを購入します。API 専用のプランはありません。
  • curl が使えるターミナル。 例は bash で書いています。Windows では WSL か Git Bash を使ってください。

1. API キーを作成する

API コンソールを開き、Create key を選びます。キーはすぐにコピーしてください。全体が表示されるのはこの一度だけです。コードに書き込まないよう、環境変数に入れておきます。

export POPNOW_API_KEY="sk-popnow-..."

キーはすべて sk-popnow- で始まり、アカウントのクレジットを消費します。キーはサーバー側だけに置いてください。制限の付け方、ローテーション、漏れたときの対処は認証にまとめています。

2. タスクを送る

同じターミナルにこれを貼り付けます。高速な画像モデルに 1 枚生成させるリクエストで、費用は 1〜2 クレジットです。

POST /api/v1/jobs/createTask?wait=60
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"
  }
}'

それぞれの意味:

  • model はモデル ID です。どのモデルが何をするかを決めます。全モデルの ID はモデルにあります。
  • input はそのモデル固有の入力スキーマで検証されます。未知のフィールドは拒否されるので、綴りの間違いは黙って無視されずにすぐエラーになります。
  • Idempotency-Key を付けると再送が安全になります。タイムアウト後に同じキーで送り直すと、二重課金ではなく元のタスクが返ります。冪等性を参照してください。
  • ?wait=60 は接続を最大 60 秒保ちます。すぐ終わる画像なら、この同じレスポンスで結果が返ってきます。

3. 結果を読む

完了したタスクはこうなります。

200 · recordInfo / createTask?wait=60
{
  "code": 200,
  "msg": "success",
  "data": {
    "taskId": "job_01JH8Z4Q5W2N7R3K9M6P1C0VXD",
    "model": "alibaba/z-image-turbo/text-to-image",
    "state": "succeeded",
    "output": {
      "assets": [
        {
          "url": "https://…signed-link…",
          "expiresAt": "2026-10-16T09:20:00Z",
          "mime": "image/png",
          "width": 1024,
          "height": 1024
        }
      ]
    },
    "credits": 2,
    "cost": "0.02",
    "settled": true
  },
  "request_id": "req_…"
}
  • state は succeeded です。完了できなかったタスクは failed になり、errorCode が付きます。エラーを参照してください。
  • output.assets[0].url はファイルへの署名付きリンクです。有効なのは約 20 分で、ダウンロードに API キーは不要です。期限が切れたらタスクを読み直せば新しいリンクがもらえます。
  • credits はこのタスクで実際に消費した整数のクレジット(1 クレジット = $0.01)、cost は同じ金額を米ドルの文字列で表したものです。

モデルが 60 秒以上かかる場合(動画モデルはすべてそうです)、レスポンスは 202 で、state: "queued" と taskId が返ります。終わるまでタスクを確認します。

curl "https://api.popnow.ai/api/v1/jobs/recordInfo?taskId=job_..." \
  -H "Authorization: Bearer $POPNOW_API_KEY"

state が succeeded、failed、expired のいずれかになるまで、数秒おきに確認してください。本番では callBackUrl を渡し、Webhook で通知を受け取るのがおすすめです。

同じリクエストをコードで

JavaScript (Node.js 18+)
const API = 'https://api.popnow.ai/api/v1';
const headers = {
  Authorization: `Bearer ${process.env.POPNOW_API_KEY}`,
  'Content-Type': 'application/json',
};

const created = await fetch(`${API}/jobs/createTask`, {
  method: 'POST',
  headers: { ...headers, 'Idempotency-Key': crypto.randomUUID() },
  body: JSON.stringify({
    model: 'alibaba/z-image-turbo/text-to-image',
    input: { prompt: 'A small red fox curled up in a teacup, soft morning light' },
  }),
}).then((r) => r.json());
if (created.code !== 200) throw new Error(`${created.code} ${created.msg}`);

// Poll until the task reaches a final state.
let task;
do {
  await new Promise((r) => setTimeout(r, 3000));
  const res = await fetch(`${API}/jobs/recordInfo?taskId=${created.data.taskId}`, { headers });
  task = (await res.json()).data;
} while (task.state === 'queued' || task.state === 'running');

console.log(task.state, task.output?.assets?.[0]?.url);
Python (requests)
import os, time, uuid, requests

API = "https://api.popnow.ai/api/v1"
headers = {"Authorization": f"Bearer {os.environ['POPNOW_API_KEY']}"}

created = requests.post(
    f"{API}/jobs/createTask",
    headers={**headers, "Idempotency-Key": str(uuid.uuid4())},
    json={
        "model": "alibaba/z-image-turbo/text-to-image",
        "input": {"prompt": "A small red fox curled up in a teacup, soft morning light"},
    },
    timeout=30,
).json()
if created["code"] != 200:
    raise RuntimeError(f'{created["code"]} {created["msg"]}')

# Poll until the task reaches a final state.
while True:
    time.sleep(3)
    task = requests.get(
        f"{API}/jobs/recordInfo",
        headers=headers,
        params={"taskId": created["data"]["taskId"]},
        timeout=30,
    ).json()["data"]
    if task["state"] not in ("queued", "running"):
        break

print(task["state"], task.get("output", {}).get("assets", [{}])[0].get("url"))

レスポンスの外枠

JSON レスポンスはすべて同じ 4 つのフィールドを持ちます。

{ "code": 200, "msg": "success", "data": { }, "request_id": "req_…" }

code は HTTP ステータスではなく業務コードです。200 が成功で、それ以外はエラーに一覧があります。分岐は code で行い、msg の文言には頼らないでください。サポートに問い合わせるときは request_id を添えてください。

次のステップ

このページの内容