PopNowAPI 문서
연동
본문

Vercel AI SDK 제공자

Vercel AI SDK 7에서 PopNow 모델 사용. 이미지 생성과 편집, 음성 합성, 음성 인식, 채팅 모델을 USD로 결제합니다.

@popnow/ai-sdk-provider는 PopNow 모델을 Vercel AI SDK에 연결합니다. API 키 하나로 이미지 생성과 편집 모델은 generateImage로, 텍스트 음성 변환은 generateSpeech로, 음성 텍스트 변환은 transcribe로, 채팅 모델은 generateText와 streamText로 호출합니다. 모든 요금은 별도의 API 잔액에서 USD로 결제됩니다.

이 패키지는 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로 끝납니다. 원본 이미지를 프롬프트에 넘기고, 모델이 마스크를 받는 경우 마스크도 함께 넘기세요:

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을 검증하고, 알 수 없는 필드는 거부합니다. 제공자는 모델의 스키마(GET /api/v1/models/{model}, 10분 캐시)를 읽고, 모델에 맞는 필드가 있을 때만 설정을 보냅니다:

AI SDK 설정PopNow 입력 필드
promptprompt
aspectRatioaspect_ratio
sizewidth와 height; 없으면 aspect_ratio로 줄이고 compatibility 경고
seedseed
nnum_outputs 또는 num_images; 둘 다 없는 모델은 이미지마다 별도 작업이 되고 AI SDK가 여러 번 실행
프롬프트의 imagesimage_urls, 단일 이미지 모델은 image_url
프롬프트의 maskmask_url

모델에 없는 설정은 빼고 warnings에 unsupported로 보고합니다. 그 밖의 모델 필드는 모델 스키마와 똑같이(snake_case로) providerOptions.popnow에 넣으세요. 예: 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는 모델이 같은 이름의 필드를 가진 경우 그대로 전달됩니다. 각 모델의 스키마에 사용 가능한 음성이 나열되어 있습니다.

음성 인식

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는 채팅 모델을 https://api.popnow.ai/v1의 OpenAI 호환 API로 제공합니다. 제공자는 이 모델에 @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가 동작합니다. 모델에서 모든 모델의 파라미터와 가격을 볼 수 있습니다. 코드에서 입력 스키마와 함께 목록을 가져오려면:

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,000자당 USD로 표시되며, 모델과 각 모델 페이지에 나와 있습니다. AI 가격 지수에서도 볼 수 있습니다. 각 작업은 접수될 때 최대 가격을 API 잔액에서 홀드하고, 완료되면 실제 금액을 정산합니다. 실패하거나 만료된 작업은 청구되지 않습니다. 자세한 내용은 결제와 견적을 참고하세요.

providerMetadata.popnow.images의 각 이미지 항목에는 taskId, costUsd(USD 소수 문자열), 청구가 settled인지 여부가 들어 있습니다. 음성과 인식 결과도 providerMetadata.popnow에 같은 필드를 담습니다.

작업, 폴링, 재시도

PopNow 생성은 비동기입니다. 각 호출은 작업을 만들고, 생성 요청에서 최대 60초 기다린 뒤, 작업이 최종 상태가 될 때까지 폴링합니다(처음에는 2초 간격, 점차 15초까지 늘어남). 그리고 서명된 링크에서 출력 파일을 내려받습니다. API 키는 이 링크에 절대 전송되지 않습니다.

다음 옵션은 providerOptions.popnow에 넣으며, 모델로는 전송되지 않습니다:

옵션기본값의미
pollIntervalMs2000첫 폴링까지의 대기 시간
pollTimeoutMs작업 기한 + 2분이 시간이 지나면 대기를 멈춤; 작업은 계속 실행됨
waitSeconds60생성 요청을 열어 두는 시간(0~60)
idempotencyKey호출마다 생성하나의 논리적 생성을 위한 고정 키
metadata없음작업과 함께 저장되는 사용자 라벨

모든 생성 요청에는 Idempotency-Key가 붙습니다. 연결 오류, 429, 재시도 가능한 5xx 응답은 같은 키로 두 번 재시도되므로 재시도가 작업을 두 번 만들지 않습니다. 직접 idempotencyKey를 넘기면 AI SDK 자체 재시도(maxRetries)도 그 키를 씁니다. 멱등성을 참고하세요.

abortSignal은 즉시 대기를 멈춥니다. 이미 접수된 작업은 PopNow에서 계속 실행됩니다.

오류

  • API 오류는 @ai-sdk/provider의 APICallError로 전달됩니다. 메시지에는 40201(API 잔액 부족), 40301(키로 이 모델을 호출할 수 없음) 같은 PopNow 비즈니스 코드가 들어 있습니다. 오류를 참고하세요.
  • 작업이 failed 또는 expired로 끝나면 PopNowTaskError가 발생합니다. taskId, state, errorCode(예: content_rejected), errorMessage, costUsd를 가집니다. 이런 작업은 청구되지 않습니다.
  • pollTimeoutMs가 지나면 PopNowTaskTimeoutError가 발생합니다. 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 호환 엔드포인트로 사용할 수 있습니다.
  • 임베딩. embeddingModel은 NoSuchModelError를 던집니다.

어떤 AI SDK 버전이 필요한가요?

AI SDK 7(ai@^7)과 Node.js 22 이상이 필요합니다. npm install @popnow/ai-sdk-provider ai로 둘을 함께 설치하세요.

브라우저에서 호출할 수 있나요?

페이지에 API 키를 넣으면 안 됩니다. 키를 읽을 수 있는 사람은 누구든 API 잔액을 쓸 수 있습니다. Next.js 라우트 핸들러나 서버 액션처럼 서버 라우트에서 AI SDK를 호출하고, 결과만 브라우저로 보내세요.

영상 모델을 지원하나요?

아직 지원하지 않습니다. AI SDK의 영상 인터페이스가 실험 단계이기 때문입니다. 영상은 작업 API나 JavaScript SDK를 사용하세요.

호출 비용은 어떻게 확인하나요?

providerMetadata.popnow를 읽으세요. 각 작업은 taskId, costUsd, 청구가 settled인지 여부를 알려 줍니다. API 콘솔에서는 키별 사용량을 볼 수 있습니다.

이 페이지에서