Chat-Completions
POST /v1/chat/completions
Ruft ein Textmodell auf. Anders als Bild und Video ist dieser Endpunkt synchron: ein Hin und Zurück, kein Pollen. Anfrage und Antwort folgen OpenAI chat/completions, Streaming inklusive — jedes OpenAI-SDK funktioniert, sobald du die Basis-URL tauschst.
Parameter
| Parameter | Typ | Beschreibung |
|---|---|---|
| model | string | Pflicht. Modell-id aus /v1/models mit type text |
| messages | object[] | Pflicht. Je Eintrag {role, content}; role ist system, user oder assistant. Höchstens 64 pro Anfrage |
| stream | boolean | Optional. true schaltet auf SSE-Deltas um, Standard false liefert die Antwort in einem Stück |
| temperature | number | Optional. Wird durchgereicht |
| top_p | number | Optional. Wird durchgereicht |
| max_tokens | integer | Optional. Wird durchgereicht |
| stop | string|string[] | Optional. Wird durchgereicht |
| presence_penalty / frequency_penalty | number | Optional. Wird durchgereicht |
model ist Pflicht und hat keinen Standard: Textmodelle unterscheiden sich stark in Ton, Länge und Preis — still eines auszuwählen hieße, eine Entscheidung für dich zu treffen, die du nie gesehen hast.
Anfrage
bash
curl https://open.pikpikgo.com/v1/chat/completions \
-H "Authorization: Bearer $PIKPIK_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "text-fast-1",
"messages": [
{ "role": "system", "content": "Du bist Drehbuchautor und auf Kurzdramen spezialisiert." },
{ "role": "user", "content": "Schreib mir den Auftakt eines urbanen Mystery-Kurzfilms, höchstens drei Sätze." }
]
}'Antwort
json
{
"id": "chatcmpl-2608102214300000123456",
"object": "chat.completion",
"created": 1786372470,
"model": "text-fast-1",
"choices": [
{
"index": 0,
"message": { "role": "assistant", "content": "Um Mitternacht hält der Aufzug im 13. Stock. Das Haus hat nur zwölf." },
"finish_reason": "stop"
}
],
"usage": { "prompt_tokens": 38, "completion_tokens": 126, "total_tokens": 164 },
"credits": 4
}| Feld | Beschreibung |
|---|---|
| choices[0].message.content | Der Antworttext |
| choices[0].finish_reason | stop bei normalem Ende, length wenn max_tokens erreicht wurde |
| usage | Token-Zahlen. Text wird pro Token abgerechnet, das hier ist die Grundlage |
| credits | Tatsächlich abgezogene Credits (kein OpenAI-Feld) |
Text wird pro Token abgerechnet, nicht pro Aufruf: Credits = Eingabe-Token × Eingabepreis + Ausgabe-Token × Ausgabepreis, aufgerundet, mindestens 1 pro Aufruf. Die Preise stehen pro Million Token auf der Preisseite.
Streaming
Mit stream: true wird die Antwort text/event-stream und kommt als chat.completion.chunk-Frames: der erste nennt die role, der Inhalt folgt Delta für Delta, dann ein Frame mit finish_reason, dann ein letzter Frame mit leerem choices-Array plus usage und credits, abgeschlossen von data: [DONE].
bash
curl -N https://open.pikpikgo.com/v1/chat/completions \
-H "Authorization: Bearer $PIKPIK_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "text-fast-1",
"messages": [
{ "role": "user", "content": "Schreib mir den Auftakt eines urbanen Mystery-Kurzfilms, höchstens drei Sätze." }
],
"stream": true
}'text
data: {"id":"chatcmpl-2608102214300000123456","object":"chat.completion.chunk","created":1786372470,"model":"text-fast-1","choices":[{"index":0,"delta":{"role":"assistant"},"finish_reason":null}]}
data: {"id":"chatcmpl-2608102214300000123456","object":"chat.completion.chunk","created":1786372470,"model":"text-fast-1","choices":[{"index":0,"delta":{"content":"Um Mit"},"finish_reason":null}]}
data: {"id":"chatcmpl-2608102214300000123456","object":"chat.completion.chunk","created":1786372470,"model":"text-fast-1","choices":[{"index":0,"delta":{},"finish_reason":"stop"}]}
data: {"id":"chatcmpl-2608102214300000123456","object":"chat.completion.chunk","created":1786372470,"model":"text-fast-1","choices":[],"usage":{"prompt_tokens":38,"completion_tokens":126,"total_tokens":164},"credits":4}
data: [DONE]Mit dem offiziellen OpenAI-SDK musst du SSE nicht selbst parsen:
javascript
import OpenAI from 'openai'
const client = new OpenAI({
apiKey: process.env.PIKPIK_API_KEY,
baseURL: 'https://open.pikpikgo.com/v1',
})
// Streaming: Deltas Frame für Frame, im letzten Frame stehen usage und Credits
const stream = await client.chat.completions.create({
model: 'text-fast-1',
messages: [{ role: 'user', content: 'Schreib mir den Auftakt eines urbanen Mystery-Kurzfilms, höchstens drei Sätze.' }],
stream: true,
})
for await (const chunk of stream) {
process.stdout.write(chunk.choices[0]?.delta?.content || '')
}Grundlage der Abrechnung ist beim Streaming das usage im letzten Frame; liefert der Upstream keins, wird der Mindestbetrag von 1 Credit berechnet. Außerdem steht der HTTP-Status schon auf 200, sobald Frames fließen – ein Fehler mitten im Stream kann kein 4xx/5xx mehr werden. Er kommt als Frame {"error": {...}} im Stream, gefolgt vom üblichen [DONE]; behandle diesen Frame beim Lesen mit.

