PopNowAPI 문서
API로 만들기
본문

작업

작업을 만들고 상태를 따라가며 결과를 읽는 방법, 그리고 wait, 작업 목록, 재시도, 삭제 사용법.

모든 생성은 하나의 작업입니다. 호출 한 번으로 만들면 알아서 진행되고, 결과가 준비되면 조회하거나, 첫 요청에서 기다리거나, 웹훅으로 받으면 됩니다.

  1. POST /jobs/createTasktaskId
  2. GET /jobs/recordInfostate
  3. GET output.assets[].url
호출은 이 순서로 세 번입니다. 종료 상태가 될 때까지 recordInfo를 확인하고, 링크가 만료되기 전에 파일을 내려받습니다.

작업 만들기

curl -X POST "https://api.popnow.ai/api/v1/jobs/createTask" \
  -H "Authorization: Bearer $POPNOW_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
    "model": "alibaba/wan-3.0/image-to-video",
    "input": {
      "image_url": "https://media.popnow.ai/movie/lighthouse.webp",
      "prompt": "Waves roll in slowly, the camera drifts toward the lighthouse",
      "resolution": "480p",
      "duration_seconds": 5
    },
    "callBackUrl": "https://your-app.example.com/hooks/popnow"
  }'

본문

필드필수의미
model예모델의 모델 ID
input예해당 모델의 필드. 입력 스키마로 검증됩니다
callBackUrl아니요완료된 작업을 받을 공개 HTTPS URL. 웹훅 참고
quoteId, expectedCredits아니요jobs/quote로 확인한 가격을 고정

헤더

헤더의미
Authorization: Bearer sk-popnow-…API 키
Idempotency-Key꼭 보내는 것을 권장합니다. 같은 키로 재시도하면 원래 작업이 돌아옵니다. 멱등성 참고
X-PopNow-Retention선택. 이 작업의 결과물과 프롬프트를 보관할 초 단위 시간. 보관 기간을 줄일 수만 있고 늘릴 수는 없습니다
Accept-Language선택. 오류 메시지 언어. 오류 참고

응답

새 작업은 HTTP 202로 돌아옵니다.

{
  "code": 200,
  "msg": "success",
  "data": {
    "taskId": "job_01JH8Z4Q5W2N7R3K9M6P1C0VXD",
    "state": "queued",
    "estimatedCredits": 34,
    "estimatedCost": "0.34",
    "deadlineAt": "2026-10-16T09:40:00Z"
  },
  "request_id": "req_…"
}

202는 접수됐다는 뜻이지 끝났다는 뜻이 아닙니다. estimatedCredits는 잔액에서 잡아 둔 크레딧, 즉 이 작업이 쓸 수 있는 최대 금액입니다(estimatedCost는 같은 금액을 달러로 표시). 생성에 실패하면 아무것도 만들어지지 않고 잡아 두지도 않으며, 이유는 code로 알 수 있습니다(오류).

상태

queued
running
succeededfailedexpired
작업은 언제나 하나의 상태에만 머뭅니다. 크레딧이 차감되는 것은 succeeded뿐이고, 나머지 종료 상태에서는 잡아 둔 크레딧이 전액 돌아옵니다.
상태종료?의미
queued아니요접수됨, 시작 대기 중
running아니요생성 중
succeeded예완료. 파일은 output.assets에 있습니다
failed예끝내지 못함. errorCode와 errorMessage를 보세요. 잡아 둔 크레딧은 돌아옵니다
expired예마감 시간까지 끝나지 않음. 잡아 둔 크레딧은 돌아옵니다
canceled예예전 기록에만 나타납니다. 지금은 접수된 작업을 취소할 수 없습니다

모르는 상태가 오면 "아직 안 끝났다"고 보고 계속 조회하세요.

wait로 폴링 건너뛰기

createTask에 ?wait=<초>(최대 60)를 붙이면, 작업이 끝나거나 시간이 다 될 때까지 연결을 유지합니다.

  • 시간 안에 끝남 → HTTP 200과 함께 recordInfo와 같은 형태의 전체 작업 기록이 옵니다. data.state를 확인하세요. 종료가 항상 성공은 아닙니다.
  • 끝나지 않음 → 평소처럼 202가 오고, 폴링을 이어 가거나 웹훅을 기다리면 됩니다.

이미지와 짧은 오디오에 알맞고, 영상은 거의 항상 60초를 넘깁니다. 일찍 연결을 끊어도 작업은 멈추거나 취소되지 않습니다.

작업 읽기

curl "https://api.popnow.ai/api/v1/jobs/recordInfo?taskId=job_01JH8Z4Q5W2N7R3K9M6P1C0VXD" \
  -H "Authorization: Bearer $POPNOW_API_KEY"
필드의미
taskId, model, state어떤 작업, 어떤 모델, 어디까지 왔는지
input실제로 실행된 입력. seed를 생략했다면 선택된 값도 포함
output.assets[]결과 파일. 각각 url, expiresAt, mime과, 해당되면 width, height, durationSeconds, bytes, role이 있습니다
errorCode, errorMessage작업이 실패한 이유. 분기는 errorCode, 표시는 errorMessage
credits, cost, settledsettled가 false인 동안 credits는 잡아 둔 금액이고, true가 되면 최종 청구액입니다. cost는 같은 금액의 달러 표시
createdAt, completedAt, deadlineAt타임스탬프. deadlineAt은 끝나지 않은 작업이 만료되는 시각
retention.outputsExpireAt이 작업의 파일이 삭제되는 시각
contentStatepresent. 내용이 지워지면 expired 또는 purged

서로 다른 세 가지 만료 시각

  • deadlineAt: 작업이 실행될 수 있는 시간. 지나면 expired가 되고 잡아 둔 크레딧이 돌아옵니다.
  • output.assets[].expiresAt: 그 서명 링크 하나가 유효한 시간으로, 약 20분입니다. 작업을 다시 읽으면 새 링크가 나오고 파일 자체는 그대로 있습니다.
  • retention.outputsExpireAt: 저장된 파일이 삭제되는 시각. 남기고 싶은 파일은 그 전에 내려받거나 에셋 라이브러리에 저장하세요.

output에 담기는 것

대부분의 작업은 파일 하나를 돌려줍니다. 여러 개를 돌려주는 경우도 있습니다. 변형을 여러 장 만드는 모델은 이미지 여러 장을, 영상 이어 만들기는 이어 붙인 전체 영상(role: "video")과 새로 만든 부분(role: "segment")을, 레이어 분리는 바탕 이미지와 투명 레이어(각각 layer 객체 포함)를 돌려줍니다. 음성-텍스트 변환 결과는 output.text에 있습니다.

결과 링크는 가진 사람이면 누구나 쓸 수 있는 링크입니다. 만료되기 전까지는 URL만 있으면 내려받을 수 있으니, 받을 때 API 키는 보내지 마세요.

웹훅을 기본으로, 폴링은 보조로

폴링도 되지만 웹훅이 양쪽 모두에게 더 싸게 먹힙니다. 결과가 나오는 즉시 알 수 있고 그사이 요청을 낭비하지 않습니다. 탄탄한 연동은 둘 다 씁니다. 평소에는 웹훅으로 받고, 가끔 recordInfo로 웹훅을 못 받은 작업을 훑어 줍니다.

폴링할 때는 간격을 두세요. 이미지는 23초, 영상은 1015초마다 확인하고 deadlineAt이 되면 멈춥니다.

작업 목록

GET /api/v1/jobs는 이 키로 만든 작업을 최신순으로 돌려주며, 입력과 결과는 담지 않습니다.

curl "https://api.popnow.ai/api/v1/jobs?state=failed&from=2026-10-01&limit=50" \
  -H "Authorization: Bearer $POPNOW_API_KEY"

필터: from과 to(UTC 날짜, 최대 92일 간격, 기본은 최근 7일), state, model, limit(최대 100). hasMore가 true이면 같은 필터로 nextCursor를 cursor에 넘기세요.

실패한 작업 재시도

POST /api/v1/jobs/retry에 { "taskId": "…" }를 보내면, failed 또는 expired 작업의 원래 입력으로 오늘 가격에 맞춰 새 작업을 만듭니다. 원래 작업은 바뀌지 않습니다. 원래 작업이 아직 끝나지 않았으면 409가 오고, 성공한 작업은 재시도할 수 없으니 새로 만드세요.

작업 내용 삭제

POST /api/v1/jobs/purge에 { "taskId": "…" }를 보내면 작업의 파일, 결과, 저장된 프롬프트를 지웁니다. 결제 기록은 남습니다. 청구액, 모델, 상태, 타임스탬프는 그대로이며 응답의 billingRetained: true가 이를 알려 줍니다. 종료된 작업만 지울 수 있고, 여러 번 호출해도 안전합니다.

다음 단계

  • 웹훅: 폴링 대신 결과를 받기.
  • 미디어: 참조 파일 업로드하기.
  • 오류: 모든 코드와 재시도 여부.

이 페이지에서