API ドキュメント

エージェントから Litlas のライブラリを整理する

アカウント専用 API で、ボードの作成・削除、ボード内の論文管理、論文メモの取得・更新ができます。

クイックスタート

すべてのエンドポイントは JSON を使い、次のベースパス以下にあります。

API ベースパス/api/v1/agent

対話型の Bash では、一度だけ表示されたキーを非 export の変数へ画面表示なしで読み、非公開の設定用ファイルディスクリプタだけを通して curl へ渡します。キーをシェル履歴、子プロセスの環境変数、curl の引数へ残しません。

unset LITLAS_API_KEY
builtin printf 'Litlas API key: ' >&2
IFS= read -r -s LITLAS_API_KEY
builtin printf '\n' >&2
litlas_curl() {
  if [[ ! ${LITLAS_API_KEY-} =~ ^litlas_sk_[A-Za-z0-9_-]{43}$ ]]; then
    builtin printf 'Invalid Litlas API key.\n' >&2
    return 64
  fi
  command curl --config <(
    builtin printf 'header = "Authorization: Bearer %s"\n' "$LITLAS_API_KEY"
  ) "$@"
}

認証と API キー

すべてのリクエストで Litlas API キーを Authorization ヘッダーに指定します。

Authorization: Bearer <YOUR_LITLAS_API_KEY>

設定を開いて API キーを発行・ローテートする

完全なキーを表示するのは、発行またはローテートの直後に一度だけです。Litlas はキーの検証に必要な情報だけを保存するため、あとから完全な値を再表示できません。

ローテートすると以前のキーは即時に失効します。次のリクエストより前にエージェントやシークレットストアを更新してください。古いキーを使ったリクエストは 401 になります。

キーはパスワードと同様に扱ってください。URL、ソースコード、チャット記録、ログ、シェル履歴、リポジトリには記載しないでください。完全な値をシェルコマンドへ直接入力しないでください。意図したシークレットストアへ貼り付けたあとは、クリップボードを上書きし、設定画面でキーを隠してください。

使い終わったら、現在のシェルからキーと補助関数を消去します。

unset LITLAS_API_KEY
unset -f litlas_curl

識別子とメモの扱い

board_id

ボード一覧・作成 API が返す不透明なボード識別子です。ボード名から推測せず、返された値をそのまま使います。

item_count

ボードに紐づく有効なアイテムの総数で、論文とドキュメントの両方を含みます。ボード内論文 API は論文だけを返すため、その papers.length とは一致しないことがあります。

paper_id

論文とともに返される Litlas の不透明な論文識別子です。解釈したり、タイトル、DOI、ボード内の位置から導出したりせず、返された値を正確にコピーします。API は前後の空白だけを除去し、内部の文字はすべて保持します。連続する空白は別の値として扱われ、paper_id には / ? # % も含まれることがあります。

パス内の paper_id を URL エンコードする

識別子全体を一つのパスセグメントとしてエンコードします。スラッシュで分割したり、URL 全体をエンコードしたりしないでください。

const paperId = 'SOURCE/ID';
encodeURIComponent(paperId); // 'SOURCE%2FID'

メモは論文に属します

論文メモはアカウント内で一つであり、すべてのボードで共通です。どのボードから更新しても同じメモが全体で変わります。論文をボードから外しても、そのメモは削除されません。GET と PATCH は、その論文がアカウントのライブラリに有効な保存アイテムとして存在する場合だけ使えます。存在しない場合は 404 を返します。

入力上限

  • ボード名: 1〜120 文字で、空白を正規化する前の文字数で判定します。そのうえで前後の空白を除去し、連続する空白をまとめます。同じアカウント内の大文字・小文字だけが異なる同名ボードは 400 で拒否します。
  • paper_id: 前後の空白を除去したあと 1〜120 文字です。内部の空白はまとめずそのまま保持します。不透明な識別子のため、大文字・小文字の変換やその他の正規化を行わないでください。
  • note: 最大 2000 文字です。空文字列を送るとメモを消去します。
  • expected_updated_at: 1〜64 文字で、空白だけの値は使えません。
  • JSON リクエスト本文の未知フィールドは 422 で拒否します。

ほかのエージェントの編集を上書きせずにメモを更新する

expected_updated_at は必須です。すべてのメモ編集で楽観的排他制御を使います。

  1. GET でメモを取得し、返された updated_at を保持します。
  2. 編集した note と、その値を変更せず入れた expected_updated_at を PATCH で送ります。
  3. 409 note_conflict のときは上書きや自動マージをしません。競合レスポンスの current_note と current_updated_at を読み、明示的に調整してから新しい PATCH を送ります。
{
  "detail": {
    "code": "note_conflict",
    "paper_id": "P43NTWMNFA70",
    "current_note": "The note saved by another client.",
    "current_updated_at": "2026-09-03T12:34:00Z"
  }
}

エンドポイント

JSON 本文があるコマンドは、表示した例を引数ではなく標準入力から curl へ渡します。実際の本文に機密情報が含まれる場合は、対話シェルのコマンドや履歴内の例を実値へ置き換えず、エージェントからログへ出さずに標準入力へ生成してください。

GET/api/v1/agent/boards

ボード一覧を取得

API キーのアカウントが所有するボードを返します。item_count の計算前に、所有者の古い所属ミラーを検証します。検証に論文カタログが必要で利用不能な場合はリクエスト全体を 502 paper_metadata_unavailable、保存済み ID が曖昧な場合は 409 library_identity_ambiguous にします。一部だけのボード一覧や不正確な可能性がある件数は返しません。

litlas_curl --fail-with-body --silent --show-error \
  --request GET \
  'https://litlas.ai/api/v1/agent/boards'
成功レスポンス (HTTP 200)
{
  "boards": [
    {
      "board_id": "board_01JABCDEF",
      "name": "Reading list",
      "item_count": 0,
      "created_at": "2026-09-03T12:30:00Z",
      "updated_at": "2026-09-03T12:30:00Z"
    }
  ]
}
再試行と冪等性

安全に再実行できます。上記の所属自己修復を行うことがあります。502 では論文カタログの復旧後だけ再試行します。論文 ID に関する 409 では、推測せず下記の retryable 契約に従ってください。

POST/api/v1/agent/boards

ボードを作成

アカウントにボードを作成し、board 内に作成結果を返します。

JSON リクエスト本文
{
  "name": "Reading list"
}
litlas_curl --fail-with-body --silent --show-error \
  --request POST \
  --header 'Content-Type: application/json' \
  --data-binary @- \
  'https://litlas.ai/api/v1/agent/boards' <<'JSON'
{"name":"Reading list"}
JSON
成功レスポンス (HTTP 201)
{
  "board": {
    "board_id": "board_01JABCDEF",
    "name": "Reading list",
    "item_count": 0,
    "created_at": "2026-09-03T12:30:00Z",
    "updated_at": "2026-09-03T12:30:00Z"
  }
}
再試行と冪等性

冪等ではありません。同じ名前を再送すると、重複を作らず 400 を返します。結果が不明なときは、再試行を決める前にボード一覧を取得してください。

DELETE/api/v1/agent/boards/{board_id}

ボードを削除

指定したボードを削除し、論文とドキュメントのボードへの紐付けを外します。保存論文とそのメモはアカウントのライブラリに残り、紐付いていたドキュメント本体も残ります。

litlas_curl --fail-with-body --silent --show-error \
  --request DELETE \
  'https://litlas.ai/api/v1/agent/boards/board_01JABCDEF'
成功レスポンス (HTTP 200)
{
  "board_id": "board_01JABCDEF",
  "deleted": true
}
再試行と冪等性

削除成功後に同じリクエストを繰り返すと 404 になります。結果が不明なときは、再試行前にボード一覧を取得してください。

GET/api/v1/agent/boards/{board_id}/papers

ボード内の論文一覧を取得

指定したボードに現在入っている論文を返します。応答前に、所有者の古い所属ミラーを検証します。検証に必要な論文カタログが利用不能な場合はリクエスト全体を 502 paper_metadata_unavailable、保存済み ID が曖昧な場合は 409 library_identity_ambiguous にします。返却対象論文のメタデータを解決できない場合も 502 になります。未検証の所属や、メタデータを解決できた論文だけを入れた 200 応答は返しません。

litlas_curl --fail-with-body --silent --show-error \
  --request GET \
  'https://litlas.ai/api/v1/agent/boards/board_01JABCDEF/papers'
成功レスポンス (HTTP 200)
{
  "board_id": "board_01JABCDEF",
  "papers": [
    {
      "paper_id": "P43NTWMNFA70",
      "title": "Example paper title",
      "authors": [
        "Ada Lovelace",
        "Alan Turing"
      ],
      "year": 2026
    }
  ]
}
再試行と冪等性

安全に再実行できます。上記の所属自己修復を行うことがあります。502 では論文カタログの復旧後だけ再試行します。論文 ID に関する 409 では、推測せず下記の retryable 契約に従ってください。

POST/api/v1/agent/boards/{board_id}/papers

ボードへ論文を追加

paper_id で指定した論文をボードへ追加します。その論文が有効な保存論文としてまだ存在しない場合は、同時にアカウントのライブラリへ保存します。正常なカタログ照会でメタデータが見つからず、そのアカウント所有のスナップショットからも解決できない場合に限り 404、論文カタログへ到達できない、または応答を検証できず、かつ所有スナップショットからも解決できない場合は detail.code が paper_metadata_unavailable の 502 を返します。

JSON リクエスト本文
{
  "paper_id": "P43NTWMNFA70"
}
litlas_curl --fail-with-body --silent --show-error \
  --request POST \
  --header 'Content-Type: application/json' \
  --data-binary @- \
  'https://litlas.ai/api/v1/agent/boards/board_01JABCDEF/papers' <<'JSON'
{"paper_id":"P43NTWMNFA70"}
JSON
成功レスポンス (HTTP 200)
{
  "board_id": "board_01JABCDEF",
  "paper_id": "P43NTWMNFA70",
  "added": true
}
再試行と冪等性

同じボードと論文に対して冪等です。繰り返した場合も成功し、added が false になります。paper_metadata_unavailable の場合は、先に対象ボードの論文一覧を GET してください。その読取が成功し、論文が無いことを確認できた場合だけ追加を最大 1 回再試行し、読取失敗または不存在を確認できない場合は中止してエラーを表面化させます。論文 ID に関する 409 では、下記の retryable 契約に従ってください。

DELETE/api/v1/agent/boards/{board_id}/papers/{paper_id}

ボードから論文を削除

このボードへの所属だけを削除します。アカウントのライブラリにある既存の保存論文と、アカウント共通のメモは削除しません。指定された paper_id がこのボードの所属と正確に一致する場合、または保存論文と正確に一致し、かつそのボードにほかの論文が 1 件も無い場合は、論文カタログを使いません。保存論文と一致するだけでは足りません。それ以外では先に論文カタログで識別子を解決し、論文カタログへ到達できない、または応答を検証できず、かつそのアカウント所有のスナップショットからも解決できない場合は、所属を変更する前に detail.code が paper_metadata_unavailable の 502 を返します。正常なカタログ照会でメタデータが見つからない場合や、識別子に対応する所属がこのボードに無い場合はエラーではなく、removed が false の成功になります。

litlas_curl --fail-with-body --silent --show-error \
  --request DELETE \
  'https://litlas.ai/api/v1/agent/boards/board_01JABCDEF/papers/P43NTWMNFA70'
成功レスポンス (HTTP 200)
{
  "board_id": "board_01JABCDEF",
  "paper_id": "P43NTWMNFA70",
  "removed": true
}
再試行と冪等性

同じボードと論文に対して冪等です。所属がすでに無ければ removed は false になります。paper_metadata_unavailable の場合は無制限に再試行せず、まず対象ボードの論文一覧を GET します。その読取が成功し、同じ不透明な paper_id が正確に含まれる場合だけ、同じ DELETE を最大 1 回再試行します。読取失敗、正確な ID の不在、再試行の失敗のいずれかでは、別名を推測せずに中止し、エラーを表面化させます。論文 ID に関する 409 では、下記の retryable 契約に従ってください。

GET/api/v1/agent/papers/{paper_id}/note

論文メモを取得

アカウント共通メモと、PATCH に必要な updated_at を返します。ローカルの論文 ID と正確に一致する場合、カタログ照会は不要です。保存論文を別名の可能性から特定する必要がある場合、カタログ利用不能なら 502 paper_metadata_unavailable、保存済み ID が曖昧なら 409 library_identity_ambiguous を返し、一部だけの 200 応答にはしません。不在または無効と確認できた場合は 404 を返します。

litlas_curl --fail-with-body --silent --show-error \
  --request GET \
  'https://litlas.ai/api/v1/agent/papers/P43NTWMNFA70/note'
成功レスポンス (HTTP 200)
{
  "paper_id": "P43NTWMNFA70",
  "note": "Initial note.",
  "updated_at": "2026-09-03T12:31:00Z"
}
再試行と冪等性

読み取り専用です。502 では論文カタログの復旧後だけ再試行します。論文 ID に関する 409 では、推測せず下記の retryable 契約に従ってください。

PATCH/api/v1/agent/papers/{paper_id}/note

論文メモを更新

expected_updated_at が現在値と一致する場合に限り、アカウント共通メモを置き換えます。ローカルの論文 ID と正確に一致する場合、カタログ照会は不要です。保存論文を別名の可能性から特定する必要がある場合、カタログ利用不能なら 502 paper_metadata_unavailable、保存済み ID が曖昧なら 409 library_identity_ambiguous を返し、メモは変更しません。不在または無効と確認できた場合は 404 を返します。

JSON リクエスト本文
{
  "note": "Key finding and follow-up questions.",
  "expected_updated_at": "2026-09-03T12:31:00Z"
}
litlas_curl --fail-with-body --silent --show-error \
  --request PATCH \
  --header 'Content-Type: application/json' \
  --data-binary @- \
  'https://litlas.ai/api/v1/agent/papers/P43NTWMNFA70/note' <<'JSON'
{"note":"Key finding and follow-up questions.","expected_updated_at":"2026-09-03T12:31:00Z"}
JSON
成功レスポンス (HTTP 200)
{
  "paper_id": "P43NTWMNFA70",
  "note": "Key finding and follow-up questions.",
  "updated_at": "2026-09-03T12:35:00Z"
}
再試行と冪等性

そのまま再試行しないでください。502 では論文カタログの復旧後だけ再試行します。ほかの更新後に同じバージョンを使うと 409 になります。先に GET し直して明示的に調整します。論文 ID に関する 409 では下記の retryable 契約に従ってください。

エラー

2xx 応答だけが成功です。エラー本文を成功結果として扱わないでください。

ステータス意味
400リクエストの形式が不正、または操作を適用できません。
401Bearer キーが無い、無効、またはローテートで失効しています。
403キーは有効ですが、このアカウントにはその操作が許可されていません。
404このアカウントの範囲に、指定したボードまたは論文がありません。
409リソースの状態とリクエストが競合しています。古いメモ、無料プランの容量超過、ライブラリ内の論文 ID の並行変更、安全に解決できない保存済み ID を含みます。
422パス引数または JSON フィールドがドキュメントの形式に合いません。
502必要な論文メタデータまたはカタログ検証を利用できませんでした。detail.code は paper_metadata_unavailable、detail.paper_id は対象論文を示します。ボード一覧は一部だけの一覧や不正確な可能性がある件数を返さず、ボード内論文一覧は未検証の所属やメタデータの部分結果を 200 で返しません。論文追加は成功を報告せず、論文削除とメモ PATCH はこの応答より前に要求された変更を適用しません。
500 / その他の 5xxLitlas がリクエストを完了できませんでした。結果は未確定です。書き込みを再試行する前に応答を確認してください。

エラーレスポンスの形式

すべてのエラーは最上位に detail フィールドを持ちます。エラーに応じて、detail は文字列、機械判定できるオブジェクト、または標準のバリデーション配列になります。最初に HTTP ステータスで分岐し、detail がオブジェクトの場合は detail.code でも分岐してください。すべての非 2xx 応答が同じ detail 形式だと仮定しないでください。

文字列 detail の例

{
  "detail": "Board not found"
}

無料プランの容量超過(409)

{
  "detail": {
    "code": "free_capacity_exceeded",
    "kind": "items",
    "limit": 100,
    "used": 100
  }
}

ライブラリ内の論文 ID が変化(409)

{
  "detail": {
    "code": "library_identity_changed",
    "message": "The library changed concurrently. Retry the request.",
    "retryable": true
  }
}

保存済み論文 ID を一意に解決できない(409)

{
  "detail": {
    "code": "library_identity_ambiguous",
    "message": "Stored library identities cannot be resolved unambiguously. No changes were applied.",
    "retryable": false
  }
}

古いメモによる競合(409)

{
  "detail": {
    "code": "note_conflict",
    "paper_id": "P43NTWMNFA70",
    "current_note": "The note saved by another client.",
    "current_updated_at": "2026-09-03T12:34:00Z"
  }
}

論文メタデータ・カタログ利用不能(502)

{
  "detail": {
    "code": "paper_metadata_unavailable",
    "paper_id": "P43NTWMNFA70"
  }
}

論文 ID の競合を安全に再試行する

保存済み論文 ID を解決するリクエストでは、論文 ID が並行して変わった場合や、保存済み ID を安全に解決できない場合に次の 409 を返すことがあります。retryable を明示的な指示として扱ってください。

  • library_identity_changed かつ retryable: true: Litlas が現在の論文 ID を解決し直せるよう、同じリクエストを最初からやり直します。再試行は最大 1 回とし、繰り返す場合は中止してエラーを表面化させます。
  • library_identity_ambiguous かつ retryable: false: 使用する保存済み ID を推測せず、保存データを変更せず、自動で再試行しません。変更の成功は確定していないため中止し、エラーを表面化させます。アカウント所有者または Litlas サポートに保存済み ID の競合修復を依頼し、明示的に解消されたと確認できたあとだけ、やり直します。
  • その他の 409 には個別の回復手順があります。note_conflict は明示的に内容を調整し、free_capacity_exceeded は同じ内容のまま再試行しません。

例では curl --fail-with-body を使います。HTTP エラー時に終了コードを非ゼロにしつつ、調査用の応答本文を残せます。

リクエスト規約

  • JSON 本文があるリクエストでは Content-Type: application/json を送信します。
  • プログラムでパスへ識別子を埋め込む場合は、必ず URL エンコードします。
  • エラーを含むすべての Agent API 応答には Cache-Control: private, no-store と Pragma: no-cache が付きます。中継キャッシュへアカウントデータを保存しないでください。
  • タイムアウトした書き込みの成否を推測しないでください。再試行を決める前に対象リソースを読み直します。
API ドキュメント | Litlas