オープン API
キャラクターを呼び出せる、OpenAI 互換のエンドポイント。
Reverie は OpenAI 互換の Chat Completions エンドポイントを公開しています。どの OpenAI クライアントでもそこへ向け、Reverie の API キーを渡し、model フィールドには LLM ではなくキャラクターかシナリオを指定します。会話も記憶も要約も Reverie 側が持っているので、リクエストごとに必要なのは新しいメッセージだけです。
サインインしていれば誰でも使えます。サブスクリプションの区分も順番待ちもありません——必要なのは API キーだけです。作成する →
ベース URL と認証
https://www.reverie.im/api/device/v1
Authorization: Bearer rk_...設定 → その他 → APIキーの API Endpoint カードに正確なベース URL が表示され、コピーボタンも付いています。
これはサーバー側の API です。 クロスオリジンのブラウザリクエストは遮断されるので、自分のウェブページからの fetch はキーが正しくても失敗します。バックエンドから呼び出し、キーはクライアントのコードに置かないでください。
クイックスタート
curl --no-buffer https://www.reverie.im/api/device/v1/chat/completions \
-H "Authorization: Bearer $REVERIE_API_KEY" \
-H "Content-Type: application/json" \
--data-binary '{
"model": "Luna [abc12345]",
"messages": [
{
"role": "user",
"content": "Hi"
}
],
"stream": true,
"temperature": 0.8
}'設定 → その他 → APIキーには、あなたの実際のキーと実在のキャラクターを使って上の 3 つのコードを生成するリクエストビルダーもあります。
model フィールドはキャラクターを指す
キャラクター名だけでは動きません。 model: "Luna" は Luna という名前のキャラクターを探してはくれません。どれにも一致せず、キーの既定キャラクターか直近のチャットに流れ、エラーも出ないまま別のキャラクターから返事が来ます。必ず GET /models が返す 名前 [短いID] の形を使ってください。
model の値 | 答えるもの |
|---|---|
Luna [abc12345] | ID がその 8 文字で終わるキャラクターまたはシナリオ |
| 完全なキャラクター ID またはシナリオ ID | そのキャラクターまたはシナリオ |
Reverie のモデル ID(例:deepseek-v4-flash) | LLM を選びます。キャラクターはキーか直近のチャットから決まります |
| 省略 | キーに固定されたキャラクター、なければ直近のチャット |
短い ID が解決できるかどうかを決める細かい点:
[...]は文字列の末尾になければなりません。- 8 文字以下の接尾辞は、すでにチャットのあるキャラクター(ウェブでも API でも)だけを対象に照合されます。一度も開いたことのないキャラクターの短い ID は、黙って外れます。
- シナリオの検索は、キーがキャラクターに固定されているときだけ走ります。グローバルなキーでは、短いシナリオ ID は決して解決しません。
- 8 文字を超えると、完全な ID として扱われます。
話せる相手を一覧する
curl https://www.reverie.im/api/device/v1/models \
-H "Authorization: Bearer $REVERIE_API_KEY"グローバルなキーは直近のキャラクターを返します。キャラクターに固定されたキーは、そのキャラクターのシナリオを返し、ひとつもなければキャラクター自身を返します。各項目はこんな形です:
{
"id": "Luna [abc12345]",
"object": "model",
"created": 1759200000,
"owned_by": "character",
"permission": [],
"root": "<full character id>",
"parent": null
}id をそのまま model にコピーしてください。このエンドポイントのエラーは OpenAI の外枠ではなく、素朴なエラー形式を使います。
リクエストボディのどこが読まれるか
読まれるのは 4 つのフィールドだけです。それ以外は受け付けられたうえで黙って捨てられます。
| フィールド | 型 | 既定値 | 備考 |
|---|---|---|---|
messages | 配列 | 必須 | 下記参照——使われるのは一部だけです |
model | 文字列 | 任意 | 上記のとおり、キャラクター・シナリオ・LLM |
stream | 真偽値 | true | OpenAI API と違い、既定でストリーミングです |
temperature | 0〜2 の数値 | キャラクターの設定、なければ 0.8 | 範囲外の値は拒否されます |
警告なしに無視されるもの: max_tokens, top_p, n, stop, presence_penalty, frequency_penalty, logit_bias, seed, user, response_format, tools, tool_choice, logprobs, stream_options.
messages の扱い:
systemメッセージは捨てられます。 人格や振る舞いはリクエストではなく、キャラクター自身のフィールドから来ます。プロンプトのフィールド →- 画像の理解には対応していません。 内容は文字列でもパーツの配列でもかまいませんが、読まれるのは
textパーツだけで、画像パーツは無視されます。 - 会話に加えられるのは最後の
userメッセージだけです。それより前のユーザーメッセージは無視されます。 - アシスタントメッセージは履歴の同期(下記)にだけ使われます。
- 最後のユーザーメッセージが空、または空白だけの場合は
missing_user_messageが返ります。
レスポンス
非ストリーミングのレスポンスは通常の chat.completion オブジェクトです。finish_reason は常に stop で——内部のツール呼び出しが表に出ることはありません——usage のカウンターはすべてゼロなので、トークン数はレスポンスではなく API キーのページの使用統計で測ってください。
ストリーミングのレスポンスは text/event-stream です。
- コンテンツのチャンク:
delta.contentを持つchat.completion.chunkオブジェクト。冒頭のdelta: {"role": "assistant"}チャンクは送られません。 - 終了チャンク。
finish_reasonはstop、length、content_filterのいずれか。ツール呼び出しによる終了はstopとして報告されます。 choicesが空配列の使用量チャンク。data: [DONE].
途中で生成に失敗した場合、ストリームは data: {"error": {...}} を出してから [DONE] を送ります。
会話の状態
会話は Reverie が保存します。チャットはキーとキャラクターの組ごとに 1 つ存在し、ウェブアプリでもほかのチャットと並んで表示されます。各ターンは、キャラクターのシステムプロンプトとシナリオ、ワールドブックの設定、長期記憶、随時更新される要約、キャラクターの語り口・応答の長さ・NSFW 設定、アカウントのロケールによる言語の固定、そしてモデルのコンテキストウィンドウに収まるだけの直近の履歴から組み立てられます。モデルがツールに対応していれば、記憶のツールも動きます。
履歴はサーバーが持っているので、あなたが送り直す必要はありません。
アシスタントメッセージを送ると履歴が消えることがあります。 messages 配列にアシスタントメッセージが含まれていると、Reverie はその最後のものを取り、保存済みの直近 20 件の中から探します。見つかった場合、それ以降に作られたメッセージと、その時点より後に作られた記憶をすべて完全に削除します。見つからなければ何も削除されません。配列の長さは関係ありません。これを完全に避けるには、新しいユーザーメッセージだけを送ってください。
どの LLM が答えるか
決めるのはキャラクターであってリクエストではありません——LLM を名指しした場合を除きます。優先順位は低いほうから、既定のチャットモデル、キャラクター自身のモデル設定、model として渡された Reverie のモデル ID、そして最後にウェブアプリでそのチャットに設定したモデルの指定で、これがすべてに勝ちます。モデル →
エラー
/chat/completions のエラーは OpenAI の外枠を使います: {"error": {"message", "type", "param": null, "code"}}.
| HTTP | code | type | 原因 |
|---|---|---|---|
| 401 | invalid_api_key | invalid_request_error | Authorization がない・形式が違う、キーが不明、またはキーが無効 |
| 401 | api_key_expired | invalid_request_error | キーの有効期限が切れている |
| 404 | scenario_not_found | invalid_request_error | シナリオ ID は解決したが、そのシナリオが存在しない |
| 404 | character_not_found | invalid_request_error | キャラクターが存在しないか削除済み |
| 404 | no_chat_history | invalid_request_error | model もなく、固定キャラクターもなく、戻れる過去のチャットもない |
| 400 | missing_user_message | invalid_request_error | 空でない user メッセージがない |
| 429 | rate_limit_exceeded | rate_limit_exceeded | 無料モデルの枠を使い切った。Retry-After に待つ秒数が入ります |
| 429 | insufficient_quota | insufficient_quota | このリクエストに足りるクレジットがない |
| 502 | MODEL_EMPTY_RESPONSE | server_error | モデルは正常に終わったが、テキストが出なかった |
| 場合による | プロバイダーのコード | server_error | 上流で生成に失敗 |
この外枠に入らないものが 2 つあります:GET /models のエラーと、検証で弾かれたリクエストボディ(たとえば範囲外の temperature)——どちらも素朴なエラー形式を返します。
レート制限とクォータ
この API にはキー単位のレート制限も、同時実行の上限も、リクエストのクォータもありません。使用量を縛るのは次の 2 つだけです。
| 制約 | 値 |
|---|---|
| クレジット残高 | リクエストのたびに確認され、足りなければ insufficient_quota が返ります |
| 無料モデルの枠 | アカウントごとに 3 時間で 15 通——Pro ×3(45)、Premium ×4(60)、Ultimate ×5(75) |
無料モデルの枠は、ウェブのチャット、ストーリー、小説、ボットと共通です——入口ごとではなく、アカウントごとに 1 つの持ち分です。無料モデル →
Reverie は外向きの webhook を送りません。生成完了を受け取るために購読するものはありません。
キャラクターの取り込み
もう 1 つのエンドポイント POST /api/v1/characters/import は、キャラクターカードからキャラクターを作ります。取り込み用の権限を持つキーが必要で、これは設定ページが作るキーとは別種です。APIキー → と キャラクターの取り込み →