API 문서

빠른 시작

키 발급부터 첫 이미지까지 세 단계.

1단계: 키 만들기

「내 계정 → API 플랫폼」에서 오른쪽 위 「키 만들기」를 누르고, 용도를 알아볼 수 있는 이름을 지어 주세요. 만들자마자 키가 클립보드에 복사되며, 이후에도 목록의 복사 버튼으로 언제든 다시 가져올 수 있습니다.

키는 곧 계정이며 크레딧을 직접 소비합니다. 목록에서 언제든 다시 복사할 수 있으니 사본을 여기저기 남길 필요가 없습니다. 사본이 많아질수록 유출 면이 넓어집니다.

2단계: 사용 가능한 모델 확인

키를 환경 변수에 넣고 모델 목록을 한 번 조회합니다. 응답의 id가 이후 model 파라미터에 넣을 값입니다.

bash
curl https://open.pikpikgo.com/v1/models \
  -H "Authorization: Bearer $PIKPIK_API_KEY"

3단계: 이미지 한 장 만들기

bash
curl https://open.pikpikgo.com/v1/images/generations \
  -H "Authorization: Bearer $PIKPIK_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "prompt": "비 내리는 사이버펑크 야간 거리, 네온 반사",
    "size": "16:9",
    "quality": "2k",
    "n": 1
  }'

기본은 동기입니다. 이미지가 나올 때까지 기다렸다가 응답하고, data[0].url 이 곧 이미지 주소라 작업을 따로 조회할 필요가 없습니다. 한 장에 보통 30초 이상 걸리므로 클라이언트 타임아웃을 300초까지 늘려 주세요.

json
{
  "created": 1786000246,
  "data": [
    { "url": "https://cdn.pikpikgo.com/ai/xxxx.png", "revised_prompt": "비 내리는 사이버펑크 야간 거리, 네온 반사" }
  ],
  "id": "2608101909450810293847",
  "object": "image.generation",
  "model": "img-std-1",
  "status": "succeeded",
  "n": 1,
  "credits": 10,
  "tasks": [
    {
      "id": "2608101909450810293847",
      "status": "succeeded",
      "data": [{ "url": "https://cdn.pikpikgo.com/ai/xxxx.png", "revised_prompt": "비 내리는 사이버펑크 야간 거리, 네온 반사" }]
    }
  ]
}

4단계: 기다리기 싫다면 비동기로

async: true 를 추가하면 즉시 응답이 오고 status는 queued, data는 아직 비어 있습니다. 아직 아무것도 그려지지 않았습니다. tasks[0].id를 기록해 두세요.

bash
curl https://open.pikpikgo.com/v1/images/generations \
  -H "Authorization: Bearer $PIKPIK_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "prompt": "비 내리는 사이버펑크 야간 거리, 네온 반사",
    "size": "16:9",
    "quality": "2k",
    "n": 1,
    "async": true
  }'
json
{
  "id": "2608101909450810293847",
  "object": "image.generation",
  "created": 1786000185,
  "model": "img-std-1",
  "status": "queued",
  "n": 1,
  "credits": 10,
  "tasks": [
    { "id": "2608101909450810293847", "status": "queued", "data": [] }
  ],
  "data": []
}

그 id로 폴링해 status가 succeeded가 되면 data[0].url이 이미지 주소입니다. 영상 생성은 이 방식뿐입니다.

bash
curl https://open.pikpikgo.com/v1/tasks/2608101909450810293847 \
  -H "Authorization: Bearer $PIKPIK_API_KEY"
json
{
  "id": "2608101909450810293847",
  "object": "image.generation",
  "created": 1786000185,
  "model": "img-std-1",
  "status": "succeeded",
  "prompt": "비 내리는 사이버펑크 야간 거리, 네온 반사",
  "size": "16:9",
  "quality": "2k",
  "credits": 10,
  "error": "",
  "data": [
    { "url": "https://cdn.pikpikgo.com/ai/xxxx.png", "revised_prompt": "비 내리는 사이버펑크 야간 거리, 네온 반사" }
  ]
}

전체 예제

동기 방식은 OpenAI 공식 SDK로 바로 쓸 수 있고, baseURL만 바꾸면 됩니다:

javascript
import OpenAI from 'openai'

const client = new OpenAI({
  apiKey: process.env.PIKPIK_API_KEY,
  baseURL: 'https://open.pikpikgo.com/v1',
  timeout: 300 * 1000,
})

// 동기 생성: 한 번의 왕복으로 주소를 받고, 타임아웃은 300초로 늘림
const res = await client.images.generate({
  model: 'img-std-1',
  prompt: '비 내리는 사이버펑크 야간 거리, 네온 반사',
  size: '1792x1024',
  n: 1,
})

console.log(res.data[0].url)

비동기 방식은 요청과 폴링을 직접 이어 붙입니다. Node.js 예제:

javascript
const BASE = 'https://open.pikpikgo.com/v1'
const KEY = process.env.PIKPIK_API_KEY

async function call(path, body) {
  const res = await fetch(BASE + path, {
    method: body ? 'POST' : 'GET',
    headers: {
      Authorization: `Bearer ${KEY}`,
      'Content-Type': 'application/json',
    },
    body: body ? JSON.stringify(body) : undefined,
  })
  const json = await res.json()
  if (json.error) throw new Error(json.error.message)
  return json
}

// 제출 후 완료까지 대기: 3초 간격으로 폴링하고 10분이면 중단
async function generateImage(prompt) {
  const job = await call('/images/generations', { prompt, size: '16:9', async: true })
  const id = job.tasks[0].id

  for (let i = 0; i < 200; i++) {
    const task = await call(`/tasks/${id}`)
    if (task.status === 'succeeded') return task.data[0].url
    if (task.status === 'failed') throw new Error(task.error || '생성 실패')
    await new Promise((r) => setTimeout(r, 3000))
  }
  throw new Error('대기 시간 초과')
}

generateImage('비 내리는 사이버펑크 야간 거리, 네온 반사').then(console.log)

Python 예제 (이쪽은 영상 생성이며 폴링 간격은 5초):

python
import os, time, requests

BASE = "https://open.pikpikgo.com/v1"
KEY = os.environ["PIKPIK_API_KEY"]
HEAD = {"Authorization": f"Bearer {KEY}", "Content-Type": "application/json"}


def call(path, body=None):
    if body is None:
        r = requests.get(BASE + path, headers=HEAD, timeout=30)
    else:
        r = requests.post(BASE + path, headers=HEAD, json=body, timeout=60)
    data = r.json()
    if "error" in data:
        raise RuntimeError(data["error"]["message"])
    return data


def generate_video(prompt, seconds=5):
    job = call("/video/generations", {"prompt": prompt, "duration": seconds})

    # 영상은 보통 1~5분. 폴링은 5초 간격이면 충분하며, 더 촘촘히 해도 호출 제한만 소모된다
    for _ in range(200):
        task = call(f"/video/generations/{job['task_id']}")
        if task["status"] == "succeeded":
            return task["url"]
        if task["status"] == "failed":
            raise RuntimeError(task["error"] or "생성 실패")
        time.sleep(5)
    raise TimeoutError("대기 시간 초과")


print(generate_video("카메라가 천천히 다가가고, 소녀가 돌아보며 미소 짓는다"))