Skip to Content
デベロッパーガイドREST API 統合ガイド

REST API 統合ガイド

Qwen Code を HTTP 経由で自社プロダクトに組み込むチーム向け: qwen serve をバックエンドとして実行し、独自のフロントエンドから制御します。

このページがエントリーポイントです。完全なルート��ファレンスは qwen-serve-protocol.md、内部構造は デーモン詳細、実行可能な TypeScript のウォークスルーは examples/daemon-client-quickstart.md です。

利用可能なパス

デーモン上に構築する方法は 6 通りあり、フロントエンドのどこまでを自社で所有するか という 1 つの質問で分かれます。

パス所有範囲ステータス
デーモン + 同梱 Web Shellなし — 出荷時のまま使用現在出荷中 (ユーザーガイド)
デーモン --no-web + 独自の UIフロントエンド全体現在出荷中 — このページ
デーモン + ブランド付き Web Shellブランディング、コードは含まず未実装 (#11357 )
デーモン + 自己ホスト Web Shell ビルドフロントエンドビル未実装 (#11358 )
SDK DaemonClient 経由のデーモンクライアントコード、生 HTTP は使用しない現在出荷中 (TSJava) — Python SDK はプロセストランスポートのみでデーモンクライアントを持たないため、Python 統合はパス 2 を生 HTTP で駆動します
MCP ブリッジ経由のデーモンなし — 別のエージェントが駆動@qwen-code/sdkqwen-serve-mcp として出荷 — ブリッジ READMEを参照。QWEN_BRIDGE_ALLOW_GLOBAL_SCOPE でグローバルスコープの書き込み変更を任意に許可可能

ヘッドレス qwen -p とエディタ向け stdio 経由の ACP は別の統合 パスです。チャネルと拡張機能もデーモン経由で実行できます。 チャネルガイド拡張機能リファレンスを参照してください。

設計前に知っておくべき 2 つのこと

デーモンはプロセス内で推論を実行しません。 qwen --acp 子 プロセスを生成し、それらと HTTP の間で仲介を行います。CLI エントリースクリプトを 同じ Node バイナリで実行し、QWEN_CLI_ENTRY または process.argv[1] を使用します。 Node バックエンドに埋め込む場合は、QWEN_CLI_ENTRY をインストール済みの Qwen CLI エントリースクリプトに向ける必要があります。PATH 上の qwen 検索は行いません。エントリポイントが見つからない場合は MissingCliEntryError として表面化します。

定常状態では、アクティブなワークスペースランタイムごとに 1 つの子プロセスがあり、セッションごとではありません。ワークスペース内の全セッションがその子プロセスに多重化され、 プロセス、OAuth 状態、ファイルキャッシュ、階層メモリ解析を共有します。したがって障害ドメインは ワークスペースです。子プロセスが終了すると、それに多重化されている全セッションが同時に 破棄されます。コンテナのサイジングは、デーモン + 登録済みワークスペースごとに 1 つの子プロセスに加え、チャネルスワップ時のランタイムごとに 1 つの追加子プロセス分の余裕を持たせてください。 セッションを独立して失敗させる必要がある場合は、個別のデーモンを実行してください — --max-sessions は同時実行数を制限するものであり、影響範囲を制限するものではありません。

認証は単一オペレーターです。 ランタイムベアラートークンは ベアラートークンで保護された API 全体に権限を付与し、信頼されたループバック呼び出し元は デーモンユーザーとしてのコード実行を含む完全な権限を持ちます。エンドユーザーごとのプリンシパル モデルは存在しません。これを マルチユーザープロダクトの背後に配置する場合、バックエンドがユーザー ID を所有し、デーモントークンをブラウザに 渡してはなりません。コンテナ化およびマルチテナントデプロイメントは 明示的に延期されています — ユーザーガイドの「v0.16-alpha の既知の制限」を 参照してください。

設定済みのチャネル Webhook インゲスト (POST /channels/:channelName/webhooks/:source) はベアラ認証の前に独自の x-qwen-webhook-secret 認証を 使用します。チャネル Webhook ソースが設定されるまでは機能しません。

デーモンの起動

export QWEN_SERVER_TOKEN="$(openssl rand -hex 32)" qwen serve --no-web --require-auth \ --hostname 0.0.0.0 --port 4170 \ --workspace /srv/project

--no-web は以下にリストされたルートを保持しますが、Web Shell アセットと 依存するサーフェスを無効にします。macOS では /live/* ルートと /live/host ソケット、および 全プラットフォームで GET /mcp-app-sandbox です。トークンは --token ではなく環境変数で 渡してください。--token/proc/<pid>/cmdline を通じてローカルユーザーから読み取り可能です。

以下の Bash 例では、シェルの printf ビルトインを使用してファイルディスクリプタ経由で Authorization ヘッダーを渡し、トークンを curl の引数から除外しています。

統合で実際に使用するルート

デーモンが登録するものの大部分は Web Shell の駆動用です — git 操作、拡張機能のインストール、ワークスペースの信頼、音声、スケジュールタスク — そして その UI と共に変更されます。以下のサブセットは 1 桁小さい規模です。

これらが REST 統合に必要なルートです。残りは内部用として扱ってください。

ディスカバリー

ルート目的
GET /healthLiveness プローブ
GET /capabilitiesプリフライト — 他の何よりも先に workspaceCwdpolicy.permission を読み取ります

セッションライフサイクル

ルート目的
POST /session作成。独立した会話には sessionScope: "thread" を送信します
DELETE /session/:id閉じる。永続化されたセッションは保持され、再読み込み可能です
POST /session/:id/load · /resume永続化されたセッションを復元
POST /session/:id/heartbeatアイドルリーパーを延期
PATCH /session/:id/metadataセッションメタデータ
POST /session/:id/modelバインドされたサービス内でモデルを切り替え
GET /session/:id/statusランタイムステータス — 専用リファレンスセクションはまだありません

プロンプトとストリーミング

ルート目的
POST /session/:id/prompt送信。完了ではなく受け入れ時に 202 を返します
POST /session/:id/cancelアクティブなプロンプトのみをキャンセル
GET /session/:id/eventsSSE ストリーム。プロンプト送信にサブスクライブ
GET /session/:id/transcript会話履歴
GET /session/:id/contextコンテキストウィンドウの使用状況
GET /session/:id/export · GET /session/:id/pending-prompts専用リファレンスセクションはまだありません

権限

ルート目的
POST /session/:id/permission/:requestIdpermission_request に応答します。セッションを所有するランタイムにルーティングされるため、どのワークスペース状態でも正しく動作します — 専用セクションはまだありません
POST /permission/:requestIdプロセスグローバル形式。プライマリワークスペースのブリッジにのみ接続されるため、別の登録済みランタイムが所有するセッションでは 404 を返し、デフォルトの first-responder-wins ポリシーによる投票喪失と同じボディを返します — ここでの 404 はリクエストがすでに応答済みであったことを必ずしも意味しません

読み取り専用ワークスペースコンテキスト

ルート目的
GET /file · /file/bytesファイルまたはバイト範囲を読み取り
GET /stat · GET /list · GET /globパスメタデータ、ディレクトリリスト、グロブ — 専用セクションはまだありません
GET /workspace/toolsライブ ACP 子プロセスが報告するツール。子プロセスがない場合、レスポンスは acpChannelLive: falsetools: []not_started エラーを含みます — 専用セクションはまだありません

リファレンスカバレッジ。 上記 25 ルートのうち 17 に専用セクションがあります。 それ以外とマークされた 8 ルートのうち、一部は言及のみで、3 つは 完全に欠落しています: GET /session/:id/pending-promptsPOST /session/:id/permission/:requestIdGET /workspace/tools。 このギャップの解消は #11359  で追跡されています。

最小フロー

1. プリフライト。 workspaceCwd(作成時に cwd を省略できるように)と policy.permission(権限リクエストに誰が応答できるかを確認するために)を読み取ります。

curl -sH @<(printf 'Authorization: Bearer %s\n' "$QWEN_SERVER_TOKEN") http://daemon:4170/capabilities

2. セッションを作成。 呼び出し元が 1 つの会話を共有する意図でない限り、sessionScope: "thread" を使用します — デフォルトの "single" は同じワークスペースでの 2 回目の作成で既存のセッションを再利用し、無関係な呼び出し元を 1 つのキューで直列化します。

curl -sX POST http://daemon:4170/session \ -H @<(printf 'Authorization: Bearer %s\n' "$QWEN_SERVER_TOKEN") -H 'Content-Type: application/json' \ -d '{"sessionScope":"thread"}' # → {"sessionId":"…","workspaceCwd":"/srv/project","attached":false}

3. プロンプト前にサブスクライブ。 Last-Event-ID: 0 は最古の 保持イベントからリプレイし、作成とサブスクライブの間に発生したイベントをキャッチする方法です — 特に model_switch_failedアタッチ(デフォルトの sessionScope: "single" で既存セッションを再利用)の場合、このイベントが悪意のある modelServiceId が拒否された唯一のシグナルです。なぜなら、障害は意図的に HTTP エラーとして伝播されないからです。新規作成modelServiceId を含む場合(ステップ 2 のボディには含まない)は、200 のボディにも modelApplied が含まれ、スイッチが拒否された場合は false になります。これが有界リング上のイベントよりも優先して対応すべき決定的なシグナルです。modelServiceId なしでの作成には modelApplied キー自体が存在しません。

curl -N http://daemon:4170/session/$SID/events \ -H @<(printf 'Authorization: Bearer %s\n' "$QWEN_SERVER_TOKEN") \ -H 'Accept: text/event-stream' -H 'Last-Event-ID: 0'

data: 行は 1 行の完全なエンベロープです。エンベロープの typeevent: 行と一致します。

リプレイは --event-ring-size とサブスクリプションごとの固定 8 MiB バイト 予算によって制限されます。ストリームが state_resync_requiredreason: "replay_budget_exceeded" で発行した場合、リプレイが完了したものとして扱うのではなく、POST /session/:id/load を介して回復してください。

4. プロンプト。 202 は受け入れを意味し、完了ではありません。ストリーム上の turn_complete / turn_errorpromptId で相関付けます。turn_completestopReason を読み取ります。 turn_error では message と任意の code / errorKind を読み取ります — POST /session/:id/prompt を参照。

curl -sX POST http://daemon:4170/session/$SID/prompt \ -H @<(printf 'Authorization: Bearer %s\n' "$QWEN_SERVER_TOKEN") -H 'Content-Type: application/json' \ -d '{"prompt":[{"type":"text","text":"What does src/main.ts do?"}]}' # → 202 {"promptId":"…","lastEventId":42}

5. 権限リクエストに応答。 エージェントがツールを実行したいかつ承認モードが確認を要求する場合permission_request を発行し、誰かが応答するかキャンセルするまでターンがブロックされます — デフォルトではタイムアウトはありません--permission-response-timeout-ms のデフォルトは 0 = 無期限に待機)、そのため 応答されないリクエストはセッションのプロンプトキューのスロットを保持し続けます。キャンセルまたはセッションを閉じるまでです。フローに期限が必要な場合は独自に設定してください。

モードは子プロセス自体の Qwen 設定 tools.approvalMode であり、 デーモンホストと --workspace ディレクトリの設定から解決されます。デーモンは 生成時に何もピン留めしません。デフォルトは auto で、特定のクラスのツール呼び出しを 確認なしに承認します — これらは permission_request を全く発行しません — が、 それ以外については引き続き確認を求めます。信頼されていないワークスペースフォルダは default(確認)に強制ダウングレードされます。これが、あるデプロイメントではこれらのイベントが表示され、別のデプロイメントでは表示されない理由です。また、GET /capabilities は承認モードではなく投票仲介ポリシーを報告するため、プリフライトでは現在の体制を把握できません。統合が承認ゲーティングに依存する場合は、tools.approvalMode を明示的にピン留めし、どのように応答するかを事前に決定してください。自動承認は誰も選択していなくてもすでに有効になっている可能性があります。

セッションスコープのルートで応答してください。セッションを所有するランタイムにルーティングされるため、ワークスペースの設定に関係なく機能します。

curl -sX POST http://daemon:4170/session/$SID/permission/$REQUEST_ID \ -H @<(printf 'Authorization: Bearer %s\n' "$QWEN_SERVER_TOKEN") -H 'Content-Type: application/json' \ -d '{"outcome":{"outcome":"selected","optionId":"proceed_once"}}'

6. 閉じる。 DELETE /session/$SID204。ディスク上のセッションは保持されます。

運用

項目参照先
同時実行数上限--max-sessions--max-total-sessions。上限超過の作成は Retry-After 付きの 503 を返します
レート制限--rate-limit とクラスごとの --rate-limit-* フラグ
アイドルクリーンアップ--session-idle-timeout-msPOST /session/:id/heartbeat で alive を保持
メモリ--child-heap-mode は監視のみ。--memory-budget-mbPOST /session/:id/load のアダプティブライブジャーナル成長プールを制御します。SSE リプレイ用ではありません。--max-journal-bytes または --max-journal-events のいずれかをピン留めすると成長が無効になります。どちらのフラグも子プロセスのサイジングや生成拒否、実際のヒープ上限(--max-old-space-size、ホストメモリから派生)を制御しません。予算計算については設定を参照。SSE リプレイは --event-ring-size とサブスクリプションごとの固定 8 MiB 予算で別途制限されます。末尾が欠落すると state_resync_requiredreason: "replay_budget_exceeded" で発行されます
プロンプトデッドライン--prompt-deadline-ms。期限超過時に turn_error を発行
エラーエラー分類
可観測性可観測性
全フラグリスト設定
Last updated on