| --- |
| title: HTTP API リファレンス |
| --- |
| |
| # HTTP API リファレンス |
|
|
| Koharu は次のローカル HTTP API を公開しています。 |
|
|
| ```text |
| http://127.0.0.1:<PORT>/api/v1 |
| ``` |
|
|
| これはデスクトップ UI と headless Web UI が使っているのと同じ API です。 |
|
|
| ## ランタイムモデル |
|
|
| 現在の実装で重要な挙動は次の通りです。 |
|
|
| - API は GUI または headless ランタイムと同じプロセスで提供される |
| - サーバーは既定で `127.0.0.1` にバインドされる。別ホストに公開したい場合は `--host` を使う |
| - API と MCP サーバーは同じ読み込み済みプロジェクト、モデル、パイプライン状態を共有する |
| - `--port` を指定しない場合、Koharu はランダムなローカルポートを選ぶ |
| - `/api/v1/downloads`、`/api/v1/operations`、`/api/v1/events` を除く全エンドポイントは、アプリのブートストラップが完了するまで `503 Service Unavailable` を返す |
|
|
| ## リソースモデル |
|
|
| API はプロジェクト中心です。一度に開けるプロジェクトは 1 つで、次のものを含みます。 |
|
|
| - `PageId` でインデックスされた `Pages` のリスト |
| - `NodeId` で参照されるページごとの `Nodes` (画像レイヤー、マスク、テキストブロック) |
| - 画像のバイト列を Blake3 ハッシュで保存する content-addressed な `Blob` ストア |
| - それらから組み立てられる `Scene` スナップショット (`epoch` カウンタで進む) |
| - undo/redo 可能な `Op` 変更の履歴 |
|
|
| すべてのシーン変更は履歴レイヤー (`POST /history/apply`) を経由するため、シーン、自動保存、イベント購読者は常に同期されます。 |
|
|
| ## よく使うレスポンス型 |
|
|
| 頻出するレスポンス型には次があります。 |
|
|
| - `MetaInfo` — アプリバージョンと ML デバイスラベル |
| - `EngineCatalog` — パイプライン段階ごとにインストール可能な engine id |
| - `ProjectSummary` — id、name、path、ページ数、最終オープン日時 |
| - `SceneSnapshot` — `{ epoch, scene }` |
| - `LlmState` — 現在の LLM 読み込み状態 (status、target、error) |
| - `LlmCatalog` — ローカルおよびプロバイダのモデルを family ごとにまとめたもの |
| - `JobSummary` — `{ id, kind, status, error }` |
| - `DownloadProgress` — パッケージ id、バイト数、ステータス |
|
|
| ## エンドポイント |
|
|
| ### Meta |
|
|
| | Method | Path | 目的 | |
| | ------ | ----------- | ---------------------------------------------------- | |
| | `GET` | `/meta` | アプリバージョンと有効な ML バックエンドを取得する | |
| | `GET` | `/engines` | 段階ごとに登録済みのパイプライン engine を一覧する | |
|
|
| ### フォント |
|
|
| | Method | Path | 目的 | |
| | ------ | ------------------------------------- | ------------------------------------------------------------- | |
| | `GET` | `/fonts` | レンダリング用に system + Google Fonts を統合したカタログ | |
| | `GET` | `/google-fonts` | Google Fonts カタログを単体で取得する | |
| | `POST` | `/google-fonts/{family}/fetch` | Google Fonts の family を 1 つダウンロードしてキャッシュする | |
| | `GET` | `/google-fonts/{family}/{file}` | キャッシュ済みの TTF/WOFF ファイルを返す | |
|
|
| ### Projects |
|
|
| すべてのプロジェクトは管理対象の `{data.path}/projects/` 配下に置かれ、クライアントがファイルシステムパスを渡すことはありません。 |
|
|
| | Method | Path | 目的 | |
| | -------- | --------------------------------- | ----------------------------------------------------------------- | |
| | `GET` | `/projects` | 管理されているプロジェクトを一覧する | |
| | `POST` | `/projects` | 新しいプロジェクトを作成する (body `{ name }`) | |
| | `POST` | `/projects/import` | `.khr` アーカイブを新しいディレクトリへ展開して開く | |
| | `PUT` | `/projects/current` | `id` で管理対象プロジェクトを開く | |
| | `DELETE` | `/projects/current` | 現在のセッションを閉じる | |
| | `POST` | `/projects/current/export` | 現在のプロジェクトを書き出す。バイナリを返す | |
|
|
| `POST /projects/current/export` は `{ format, pages? }` を受け付け、`format` は `khr`、`psd`、`rendered`、`inpainted` のいずれかです。複数ファイルを生成する形式の場合、レスポンスは `application/zip` になります。 |
|
|
| ### Pages |
|
|
| | Method | Path | 目的 | |
| | ------ | --------------------------------------- | --------------------------------------------------------------- | |
| | `POST` | `/pages` | アップロードされた N 枚の画像からページを作る (multipart) | |
| | `POST` | `/pages/from-paths` | 絶対パスで取り込む Tauri 専用の高速パス | |
| | `POST` | `/pages/{id}/image-layers` | アップロード画像から Custom 画像ノードを追加する | |
| | `PUT` | `/pages/{id}/masks/{role}` | 生 PNG バイト列からマスクノードを upsert する | |
| | `GET` | `/pages/{id}/thumbnail` | ページサムネイルを取得する (WebP としてキャッシュ) | |
|
|
| `role` は `segment` または `brushInpaint` です。`POST /pages` は任意の `replace=true` フィールドを受け付け、取り込みはファイル名を natural order で整列して行われます。 |
|
|
| ### Scene と blob |
|
|
| | Method | Path | 目的 | |
| | ------ | ------------------- | ---------------------------------------------------------------------- | |
| | `GET` | `/scene.json` | Web/UI クライアント用のフルシーンスナップショット | |
| | `GET` | `/scene.bin` | Tauri クライアント用に postcard エンコードされた `Snapshot { epoch, scene }` | |
| | `GET` | `/blobs/{hash}` | Blake3 ハッシュで指定した blob の生バイト | |
|
|
| `/scene.bin` は現在の epoch をレスポンスヘッダ `x-koharu-epoch` に含めて返します。 |
|
|
| ### History (mutations) |
|
|
| シーンの変更はすべてここを通します。各レスポンスは `{ epoch }` を返します。 |
|
|
| | Method | Path | 目的 | |
| | ------ | ------------------- | ------------------------------------------------- | |
| | `POST` | `/history/apply` | `Op` を適用する (`Op::Batch` を含む) | |
| | `POST` | `/history/undo` | 最後に適用された op を取り消す | |
| | `POST` | `/history/redo` | 最後に取り消された op を再適用する | |
|
|
| `Op` はノードの追加/削除/更新、ページの追加/削除、batch などのシーン遷移を表す discriminated union です。body は JSON タグ付きの variant を渡します。 |
|
|
| ### Pipelines |
|
|
| | Method | Path | 目的 | |
| | ------ | ------------- | ------------------------------------------------- | |
| | `POST` | `/pipelines` | パイプライン実行を operation として開始する | |
|
|
| body のフィールド: |
|
|
| - `steps` — 順に実行する engine id (レジストリで検証される) |
| - `pages` — 任意の `PageId` 部分集合。省略するとプロジェクト全体が対象 |
| - `region` — inpainter 用の任意のバウンディングボックス (repair-brush フロー) |
| - `targetLanguage`、`systemPrompt`、`defaultFont` — この実行のみの任意上書き |
|
|
| レスポンスは `operationId` を返します。進捗と完了は `/events` から `JobStarted`、`JobProgress`、`JobWarning`、`JobFinished` として届きます。 |
|
|
| ### Operations |
|
|
| `/operations` は実行中および直近完了したジョブ (パイプラインとダウンロード) を統一的に扱うレジストリです。 |
|
|
| | Method | Path | 目的 | |
| | -------- | --------------------- | ------------------------------------------------------------------- | |
| | `GET` | `/operations` | 実行中または直近の operation 一覧スナップショット | |
| | `DELETE` | `/operations/{id}` | パイプライン実行をキャンセル。ダウンロードは best-effort で除去 | |
|
|
| ### Downloads |
|
|
| | Method | Path | 目的 | |
| | ------ | ------------------- | ------------------------------------------------- | |
| | `GET` | `/downloads` | 実行中または直近のダウンロードのスナップショット | |
| | `POST` | `/downloads` | モデルパッケージのダウンロードを開始する (`{ modelId }`) | |
|
|
| `modelId` は `declare_hf_model_package!` で宣言されたパッケージ id (例: `"model:comic-text-detector:yolo-v5"`) です。レスポンスはパッケージ id を再利用した `{ operationId }` を返します。 |
|
|
| ### LLM 制御 |
|
|
| ロード済みモデルは `/llm/current` に対するシングルトンリソースとして扱われます。 |
|
|
| | Method | Path | 目的 | |
| | -------- | ---------------- | ---------------------------------------------------------- | |
| | `GET` | `/llm/current` | 現在の状態 (status、target、error) | |
| | `PUT` | `/llm/current` | 指定 target をロードする (local または provider) | |
| | `DELETE` | `/llm/current` | モデルをアンロード/解放する | |
| | `GET` | `/llm/catalog` | ローカルおよびプロバイダのモデルを一覧する | |
|
|
| `PUT /llm/current` は `LlmLoadRequest` を受け付けます。 |
|
|
| - provider target — `{ kind: "provider", providerId, modelId }` |
| - local target — `{ kind: "local", modelId }` |
| - 任意 `options { temperature, maxTokens, customSystemPrompt }` |
|
|
| `PUT /llm/current` はロードタスクをキューに入れた時点で `204` を返します。実際のロード完了状態は `/events` の `LlmLoaded` で通知されます。 |
|
|
| ### Config |
|
|
| | Method | Path | 目的 | |
| | -------- | --------------------------------------- | ---------------------------------------------------------- | |
| | `GET` | `/config` | 現在の `AppConfig` を取得する | |
| | `PATCH` | `/config` | `ConfigPatch` を適用する。永続化と broadcast を行う | |
| | `PUT` | `/config/providers/{id}/secret` | プロバイダの API キーを保存 (上書き) する | |
| | `DELETE` | `/config/providers/{id}/secret` | プロバイダに保存された API キーを削除する | |
|
|
| `AppConfig` はトップレベルに `data`、`http`、`pipeline`、`providers` を持ちます。 |
|
|
| - `data.path` — ランタイム、モデルキャッシュ、プロジェクトに使うローカルデータディレクトリ |
| - `http { connectTimeout, readTimeout, maxRetries }` — ダウンロードと provider リクエストで共有される HTTP クライアント |
| - `pipeline { detector, fontDetector, segmenter, bubbleSegmenter, ocr, translator, inpainter, renderer }` — 各段階で選ばれた engine id |
| - `providers[] { id, baseUrl?, apiKey? }` — 保存された API キーは生値ではなく、マスク済みプレースホルダ `"[REDACTED]"` で往復する |
|
|
| 組み込みの provider id: |
|
|
| - `openai` |
| - `gemini` |
| - `claude` |
| - `deepseek` |
| - `deepl` |
| - `google-translate` |
| - `caiyun` |
| - `openai-compatible` |
|
|
| API キーはプラットフォームの credential store に保存され、`config.toml` には書き出されません。`apiKey: ""` を PATCH すると保存済みキーが削除され、`"[REDACTED]"` を PATCH するとそのまま維持されます。`/config/providers/{id}/secret` は、PATCH を介さずに 1 プロバイダのシークレットを明示的に管理するための専用ルートです。 |
|
|
| ## Events stream |
|
|
| Koharu は次の URL で Server-Sent Events を公開しています。 |
|
|
| ```text |
| GET /events |
| ``` |
|
|
| 挙動: |
|
|
| - 新規接続 (`Last-Event-ID` ヘッダなし) では、最初に現在のジョブとダウンロードのレジストリを含む `Snapshot` イベントを送る |
| - 再接続時は `seq > Last-Event-ID` のバッファ済みイベントを順に再送する。要求された id が ring からスクロールアウトしている場合はサーバーが再度 `Snapshot` を送る |
| - 各ライブイベントは SSE の `id:` フィールドに `seq` を付けて発行される |
| - 15 秒ごとに keep-alive を送信する |
|
|
| 現在のイベント variant: |
|
|
| - `Snapshot` — 新規接続および遅延回復クライアント用の完全な状態シード |
| - `JobStarted`、`JobProgress`、`JobWarning`、`JobFinished` — パイプライン job のライフサイクル |
| - `DownloadProgress` — パッケージダウンロード進捗 |
| - `ConfigChanged` — `PATCH /config` または secret ルートで config が更新された |
| - `LlmLoaded`、`LlmUnloaded` — LLM ライフサイクル遷移 |
| - `SceneAdvanced` — シーン変更により epoch が進んだときに発行される |
|
|
| ## 典型的なワークフロー |
|
|
| 新規プロジェクト 1 件分の通常の API 呼び出し順は次の通りです。 |
|
|
| 1. `POST /projects` — プロジェクトを作成する |
| 2. `POST /pages` (または Tauri からは `/pages/from-paths`) — 画像を取り込む |
| 3. `PUT /llm/current` — 翻訳用モデルをロードする (local または provider) |
| 4. `POST /pipelines` — `detect → ocr → translate → inpaint → render` を開始する |
| 5. `JobFinished` まで `GET /events` を tail する |
| 6. `format = "rendered"` または `"psd"` を指定して `POST /projects/current/export` |
|
|
| より細かく制御したい場合は、フルパイプラインを実行する代わりに、明示的な `Op` ペイロードで `POST /history/apply` を呼びます。 |
|
|
| HTTP エンドポイントを順に叩く代わりに、エージェント向けのアクセスが欲しい場合は [MCP ツールリファレンス](mcp-tools.md) を参照してください。 |
|
|