API ドキュメント

テキスト対話

POST /v1/chat/completions

テキストモデルを呼び出します。画像・動画と違い、このエンドポイントは同期です。一往復で結果が返り、ポーリングは不要です。リクエストとレスポンスはストリーミングを含めて OpenAI の chat/completions に合わせてあるため、OpenAI SDK はベース URL を差し替えるだけで動きます。

パラメータ

パラメータ説明
modelstring必須。/v1/models の type=text の id
messagesobject[]必須。各項目は {role, content}。role は system / user / assistant。1 回につき最大 64 件
streamboolean任意。true で SSE の逐次差分に切り替わる。既定 false は一括で返す
temperaturenumber任意。そのまま上流へ渡す
top_pnumber任意。そのまま渡す
max_tokensinteger任意。そのまま渡す
stopstring|string[]任意。そのまま渡す
presence_penalty / frequency_penaltynumber任意。そのまま渡す
model は必須で既定値はありません。テキストモデルは語調も長さも価格も大きく異なり、黙って選ぶことはあなたの知らない決定を代わりに下すことになるからです。

リクエスト例

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": "あなたはショートドラマを得意とする脚本家です。" },
      { "role": "user", "content": "都市ミステリー短編の冒頭を、三文以内で書いてください。" }
    ]
  }'

レスポンス例

json
{
  "id": "chatcmpl-2608102214300000123456",
  "object": "chat.completion",
  "created": 1786372470,
  "model": "text-fast-1",
  "choices": [
    {
      "index": 0,
      "message": { "role": "assistant", "content": "深夜、エレベーターは13階で止まった。この建物は12階までしかないのに。" },
      "finish_reason": "stop"
    }
  ],
  "usage": { "prompt_tokens": 38, "completion_tokens": 126, "total_tokens": 164 },
  "credits": 4
}
項目説明
choices[0].message.content返答の本文
choices[0].finish_reasonstop=正常終了 / length=max_tokens に到達
usageトークン数。テキストはトークン課金なので、これが課金の根拠になる
credits実際に差し引かれたクレジット(OpenAI 標準の項目ではない)
テキストは回数ではなくトークンで課金します。クレジット = 入力トークン × 入力単価 + 出力トークン × 出力単価で、切り上げ・1 回あたり最低 1 ポイントです。単価は 100 万トークンあたりで、料金ページに掲載しています。

ストリーミング

stream: true を渡すとレスポンスは text/event-stream になり、chat.completion.chunk が順に流れます。最初のフレームは role のみ、本文は 1 フレームずつ、続いて finish_reason のフレーム、最後に choices が空配列で usage と credits を持つフレームが来て、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": "都市ミステリー短編の冒頭を、三文以内で書いてください。" }
    ],
    "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":"深夜、エレベ"},"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]

OpenAI 公式 SDK を使えば SSE を自分で解析する必要はありません:

javascript
import OpenAI from 'openai'

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

// ストリーミング:差分をフレームごとに受け取り、最終フレームに usage と課金クレジットが入る
const stream = await client.chat.completions.create({
  model: 'text-fast-1',
  messages: [{ role: 'user', content: '都市ミステリー短編の冒頭を、三文以内で書いてください。' }],
  stream: true,
})

for await (const chunk of stream) {
  process.stdout.write(chunk.choices[0]?.delta?.content || '')
}
ストリーミングの課金根拠は最終フレームの usage です。上流が返さない場合は最低 1 ポイントで課金します。また、フレームが流れ始めた時点で HTTP は既に 200 なので、途中の失敗は 4xx/5xx になりません。ストリーム内の {"error": {...}} フレームとして届き、その後は通常どおり [DONE] で終わるため、読み取り側でこのフレームも判定してください。