Schnellstart
Von null zum ersten erzeugten Bild in drei Schritten.
Schritt 1 – Schlüssel anlegen
Öffne „Konto → API-Plattform“ und klicke oben rechts auf „Schlüssel erstellen“. Gib ihm einen Namen, den du später wiedererkennst. Der Schlüssel landet direkt nach dem Anlegen in der Zwischenablage und lässt sich danach jederzeit erneut aus der Liste kopieren.
Schritt 2 – Verfügbare Modelle ansehen
Leg den Schlüssel in eine Umgebungsvariable und liste die Modelle. Die id aus der Antwort ist genau das, was du später als model übergibst.
curl https://open.pikpikgo.com/v1/models \
-H "Authorization: Bearer $PIKPIK_API_KEY"Schritt 3 – Ein Bild erzeugen
curl https://open.pikpikgo.com/v1/images/generations \
-H "Authorization: Bearer $PIKPIK_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"prompt": "eine regennasse Cyberpunk-Straße bei Nacht, Neonspiegelungen",
"size": "16:9",
"quality": "2k",
"n": 1
}'Standardmäßig synchron: Der Aufruf wartet, bis das Bild fertig ist, und data[0].url enthält es bereits – ein Auftragsabruf entfällt. Ein Bild braucht meist über 30 Sekunden, setze das Client-Timeout also auf 300 Sekunden.
{
"created": 1786000246,
"data": [
{ "url": "https://cdn.pikpikgo.com/ai/xxxx.png", "revised_prompt": "eine regennasse Cyberpunk-Straße bei Nacht, Neonspiegelungen" }
],
"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": "eine regennasse Cyberpunk-Straße bei Nacht, Neonspiegelungen" }]
}
]
}Schritt 4 – Lieber nicht warten? Asynchron
Mit async: true kehrt der Aufruf sofort zurück: status ist queued und data noch leer – gerendert wurde bisher nichts. Merke dir tasks[0].id.
curl https://open.pikpikgo.com/v1/images/generations \
-H "Authorization: Bearer $PIKPIK_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"prompt": "eine regennasse Cyberpunk-Straße bei Nacht, Neonspiegelungen",
"size": "16:9",
"quality": "2k",
"n": 1,
"async": true
}'{
"id": "2608101909450810293847",
"object": "image.generation",
"created": 1786000185,
"model": "img-std-1",
"status": "queued",
"n": 1,
"credits": 10,
"tasks": [
{ "id": "2608101909450810293847", "status": "queued", "data": [] }
],
"data": []
}Diese id pollen: Sobald status auf succeeded steht, enthält data[0].url das Bild. Videos funktionieren ausschließlich so.
curl https://open.pikpikgo.com/v1/tasks/2608101909450810293847 \
-H "Authorization: Bearer $PIKPIK_API_KEY"{
"id": "2608101909450810293847",
"object": "image.generation",
"created": 1786000185,
"model": "img-std-1",
"status": "succeeded",
"prompt": "eine regennasse Cyberpunk-Straße bei Nacht, Neonspiegelungen",
"size": "16:9",
"quality": "2k",
"credits": 10,
"error": "",
"data": [
{ "url": "https://cdn.pikpikgo.com/ai/xxxx.png", "revised_prompt": "eine regennasse Cyberpunk-Straße bei Nacht, Neonspiegelungen" }
]
}Vollständige Beispiele
Den synchronen Weg beherrscht das offizielle OpenAI-SDK direkt – nur die baseURL ändert sich:
import OpenAI from 'openai'
const client = new OpenAI({
apiKey: process.env.PIKPIK_API_KEY,
baseURL: 'https://open.pikpikgo.com/v1',
timeout: 300 * 1000,
})
// Synchron: ein Roundtrip liefert die URL, Timeout auf 300 Sekunden angehoben
const res = await client.images.generate({
model: 'img-std-1',
prompt: 'eine regennasse Cyberpunk-Straße bei Nacht, Neonspiegelungen',
size: '1792x1024',
n: 1,
})
console.log(res.data[0].url)Beim asynchronen Weg setzt du Abschicken und Pollen selbst zusammen, in Node.js:
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
}
// Absenden und auf Fertigstellung warten: alle 3 Sekunden pollen, nach 10 Minuten abbrechen
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 || 'Generierung fehlgeschlagen')
await new Promise((r) => setTimeout(r, 3000))
}
throw new Error('Zeitüberschreitung beim Warten')
}
generateImage('eine regennasse Cyberpunk-Straße bei Nacht, Neonspiegelungen').then(console.log)Python (diesmal Video, mit größerem Poll-Intervall):
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})
# Video dauert meist 1-5 Minuten; alle 5 Sekunden zu pollen reicht, engere Schleifen verbrauchen nur Rate-Limit
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 "Generierung fehlgeschlagen")
time.sleep(5)
raise TimeoutError("Zeitüberschreitung beim Warten")
print(generate_video("langsame Kamerafahrt nach vorn, ein Mädchen dreht sich um und lächelt"))
