PopNowAPI ドキュメント
連携
本文

Vercel AI SDK プロバイダー

Vercel AI SDK 7 から PopNow のモデルを使います。generateImage で画像生成と画像編集、generateSpeech・transcribe・チャットモデルも使えます。API キー 1 つで、米ドルの API 残高から課金されます。

@popnow/ai-sdk-provider は、PopNow のモデルを Vercel AI SDK から使えるようにします。API キー 1 つで、画像生成と画像編集のモデルは generateImage、テキスト読み上げは generateSpeech、音声の文字起こしは transcribe、チャットモデルは generateText と streamText から呼び出せます。料金はすべて、別に用意された API 残高から米ドルで課金されます。

このパッケージは MIT ライセンスのオープンソースです(GitHub)。AI SDK 7(ai@^7)と Node.js 22 以降が必要です。

概要

AI SDK の関数PopNow のモデルファクトリ
generateImageテキストからの画像生成と画像編集: Nano Banana、GPT Image、Seedream、FLUX、Qwen Image などpopnow.image(id)
generateSpeechテキスト読み上げpopnow.speech(id)
transcribe音声の文字起こしpopnow.transcription(id)
generateText、streamTextOpenAI 互換のエンドポイント経由のチャットモデルpopnow(id)、popnow.chat(id)

セットアップ

パッケージをインストールする

npm install @popnow/ai-sdk-provider ai

API キーを作成する

API コンソールでキーを作成します。キーは sk-popnow- で始まります。API 残高は $0 から始まるので、最初の有料呼び出しの前に API の課金でチャージしてください。

環境変数にキーを設定する

既定の popnow インスタンスは POPNOW_API_KEY を読み取ります。

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

キーはサーバー側に置いてください。キーを読める人は、あなたの API 残高を使えてしまいます。

画像を生成する

TypeScript
import { popnow } from '@popnow/ai-sdk-provider';
import { generateImage } from 'ai';
import fs from 'node:fs';

const { image } = await generateImage({
  model: popnow.image('google/nano-banana-2.1/text-to-image'),
  prompt: 'A cozy reading nook beside a rain-streaked window, warm lamp light',
  aspectRatio: '16:9',
  providerOptions: {
    popnow: { resolution: '2k' },
  },
});

await fs.promises.writeFile('nook.png', image.uint8Array);

プロバイダーの設定

ほかの設定を使う場合は、createPopNow で独自のインスタンスを作成します。

TypeScript
import { createPopNow } from '@popnow/ai-sdk-provider';

const popnow = createPopNow({
  apiKey: process.env.POPNOW_API_KEY, // default: POPNOW_API_KEY
  baseURL: 'https://api.popnow.ai', // default: POPNOW_BASE_URL or https://api.popnow.ai
  headers: { 'X-PopNow-Tags': 'my-app' }, // optional, sent with every request
});

createPopNow は、独自の fetch 関数も受け取れます。

画像を編集する

編集用モデルの ID は /edit で終わります。元画像を渡し、モデルがマスクを必要とする場合は、そのマスクも prompt に含めます。

TypeScript
import { popnow } from '@popnow/ai-sdk-provider';
import { generateImage } from 'ai';

const { image } = await generateImage({
  model: popnow.image('google/nano-banana-2.1/edit'),
  prompt: {
    text: 'Change the jacket to deep forest green; keep the face and background',
    images: ['https://example.com/portrait.jpg'],
  },
});

URL はそのまま渡されます。バイト列や base64 で渡された画像は、JPEG・PNG・WebP・GIF で 1 MiB 以下であればインラインで送られます。それ以外は PopNow にアップロードされます。

設定が PopNow にどう対応するか

PopNow の各モデルは、自身の JSON Schema に照らして input を検証し、未知の項目を拒否します。プロバイダーはモデルの Schema(GET /api/v1/models/{model}、10 分間キャッシュ)を読み、モデルに対応する項目がある場合にのみ設定を送ります。

AI SDK の設定PopNow の入力項目
promptprompt
aspectRatioaspect_ratio
sizewidth と height。対応していない場合は aspect_ratio に変換され、compatibility の警告が出ます
seedseed
nnum_outputs または num_images。どちらもないモデルでは、画像ごとに個別のタスクになり、AI SDK が複数回呼び出します
prompt の imagesimage_urls。単一画像のモデルでは image_url
prompt の maskmask_url

モデルにない設定は省かれ、warnings に unsupported として報告されます。それ以外のモデル項目は providerOptions.popnow に指定します。綴りはモデルの Schema どおり(snake_case)にしてください。たとえば resolution、output_format、quality などです。これらの値は、対応づけで得られた値より優先されます。

テキスト読み上げ

TypeScript
import { popnow } from '@popnow/ai-sdk-provider';
import { generateSpeech } from 'ai';
import fs from 'node:fs';

const { audio } = await generateSpeech({
  model: popnow.speech('openai/tts-1/text-to-speech'),
  text: 'Hello from PopNow.',
  voice: 'nova',
  speed: 1.1,
});

await fs.promises.writeFile('hello.mp3', audio.uint8Array);

voice は voice_id に、outputFormat は output_format に対応します。instructions、speed、language は、モデルが持っている場合に同名の項目に対応します。各モデルの Schema には、そのモデルが受け付ける声が一覧で載っています。

文字起こし

TypeScript
import { popnow } from '@popnow/ai-sdk-provider';
import { transcribe } from 'ai';
import fs from 'node:fs';

const result = await transcribe({
  model: popnow.transcription('openai/whisper-1/speech-to-text'),
  audio: await fs.promises.readFile('meeting.mp3'),
  providerOptions: { popnow: { language: 'en' } },
});

console.log(result.text, result.words);

音声データは、まず PopNow にアップロードされます(MP3 と WAV に対応し、最大 90 MiB)。公開されている https:// の URL(audio: new URL('https://...'))は、ダウンロードせずにそのまま PopNow に渡されます。

チャットモデル

PopNow は、OpenAI 互換の API でチャットモデルを提供しています。API のアドレスは https://api.popnow.ai/v1 です。プロバイダーは、これらのモデルに @ai-sdk/openai-compatible を使います。同じ API キーと同じ残高で動作します。

TypeScript
import { popnow } from '@popnow/ai-sdk-provider';
import { generateText } from 'ai';

const { text } = await generateText({
  model: popnow('anthropic/claude-haiku-5.5/chat'),
  prompt: 'Suggest three names for a kite shop by the sea.',
});

streamText も同じモデルで使えます。

TypeScript
import { popnow } from '@popnow/ai-sdk-provider';
import { streamText } from 'ai';

const result = streamText({
  model: popnow('anthropic/claude-haiku-5.5/chat'),
  prompt: 'Write a short welcome message for a kite shop.',
});

for await (const delta of result.textStream) process.stdout.write(delta);

チャットモデルはトークン単位で料金が決まり、リクエストごとの最低料金はありません。チャットモデルのページに、すべてのモデルと対応するパラメータが載っています。

モデル ID

モデル ID は <maker>/<model>/<task> の形式です。たとえば google/nano-banana-2.1/text-to-image、openai/tts-1/text-to-speech、openai/whisper-1/speech-to-text などがあります。TypeScript の型には代表的なものがいくつか候補として出ますが、キーで呼び出せる ID であれば、どれでも使えます。モデルのページには、すべてのモデルのパラメータと価格があります。入力 Schema を含めてコードから一覧を取得するには、次のようにします。

curl "https://api.popnow.ai/api/v1/models?modality=image&includeSchema=1" \
  -H "Authorization: Bearer $POPNOW_API_KEY"

modality には image、video、audio を指定します。チャットモデルは GET https://api.popnow.ai/v1/models で一覧を取得できます。

料金

料金は米ドルで、モデルによって、画像 1 枚ごと、秒ごと、または 1,000 文字ごとに決まります。モデルと各モデルのページに掲載されています。AI 価格指数にも一覧があります。各タスクは受け付けられた時点で、API 残高から最大料金を保留し、完了すると実際の料金で精算されます。失敗したタスクや期限切れのタスクは課金されません。詳しくは課金と見積もりを参照してください。

providerMetadata.popnow.images の各画像のエントリには、taskId、costUsd(米ドルの十進数の文字列)、そして料金が settled(精算済み)かどうかが入ります。音声の読み上げと文字起こしの結果も、同じ項目を providerMetadata.popnow に持ちます。

タスク、ポーリング、再試行

PopNow の生成は非同期です。呼び出しごとにタスクが作成され、作成リクエストは最大 60 秒待ちます。その後、タスクが最終状態になるまでポーリングします。ポーリングの間隔は最初は 2 秒で、最終的には 15 秒まで延びます。出力ファイルは署名付きリンクからダウンロードします。API キーがこれらのリンクに送られることはありません。

次のオプションは providerOptions.popnow に指定します。モデルには送られません。

オプション既定値意味
pollIntervalMs2000最初のポーリングまでの待ち時間
pollTimeoutMsタスクの期限に 2 分を足した時間この時間を過ぎたら待機をやめます。タスク自体は実行を続けます
waitSeconds60作成リクエストを開いたままにする時間(0〜60)
idempotencyKey呼び出しごとに生成1 回の論理的な生成に対応する固定のキー
metadataなし任意のラベル。タスクと一緒に保存されます

作成リクエストには、すべて Idempotency-Key が付きます。接続エラー、429、再試行可能な 5xx の応答は、同じキーで 2 回まで再試行されます。そのため、再試行で 2 つ目のタスクが作られることはありません。独自の idempotencyKey を渡した場合は、AI SDK 自身の再試行(maxRetries)でもそれが再利用されます。冪等性を参照してください。

abortSignal を使うと、すぐに待機をやめられます。すでに受け付けられたタスクは、PopNow 上で実行され続けます。

エラー

  • APICallError(@ai-sdk/provider 由来)は API のエラーです。エラーメッセージには PopNow の業務コードが含まれます。たとえば 40201(API 残高が不足)や 40301(そのキーではこのモデルを呼び出せない)などです。エラーを参照してください。
  • PopNowTaskError は、タスクが failed または expired で終わったときに発生します。taskId、state、errorCode(たとえば content_rejected)、errorMessage、costUsd を持ちます。これらのタスクは課金されません。
  • PopNowTaskTimeoutError は、pollTimeoutMs を使い切ったときに発生します。taskId を持ちます。タスクは実行を続けます。
TypeScript
import { popnow, PopNowTaskError } from '@popnow/ai-sdk-provider';
import { generateImage } from 'ai';

try {
  await generateImage({
    model: popnow.image('google/nano-banana-2.1/text-to-image'),
    prompt: 'A lighthouse at dawn, watercolor',
  });
} catch (error) {
  if (PopNowTaskError.isInstance(error)) console.log(error.taskId, error.errorCode);
}

含まれないもの

  • 動画。 AI SDK の動画モデルのインターフェースは、まだ実験的段階です(experimental_generateVideo)。そのため、このパッケージではまだ実装していません。PopNow の動画モデルは、タスク API、公式 SDK、OpenAI Videos 互換のエンドポイントから使えます。
  • Embeddings。 embeddingModel は NoSuchModelError を投げます。

必要な AI SDK のバージョンは?

AI SDK 7(ai@^7)と、Node.js 22 以降です。npm install @popnow/ai-sdk-provider ai で両方を一度にインストールできます。

ブラウザから呼び出せますか?

API キーをページに置いたままでは使えません。キーを読める人は、あなたの API 残高を使えてしまいます。Next.js の route handler や server action のようなサーバー側のルートから AI SDK を呼び出し、結果をブラウザに送ってください。

動画モデルに対応していますか?

まだ対応していません。AI SDK の動画インターフェースが実験的段階にあるためです。動画は タスク API か JavaScript SDK を使ってください。

呼び出しにいくらかかったか、どう確認しますか?

providerMetadata.popnow を読んでください。各タスクには taskId、costUsd、そして料金が精算済みかどうかが報告されます。API コンソールでは、キーごとの利用状況を確認できます。

このページの内容