Skip to main content

APIの概要

Log Query API は、アカウント内で実行されたすべての API 呼び出しの詳細記録を返します。 これには、使用されたモデル、実際に請求された金額、レイテンシ、呼び出しがストリーミングだったかどうか、 および呼び出しが失敗したときのエラーコードが含まれます。 これは 残高照会 API を補完するものです。残高照会では残っているクレジット量がわかり、 ログ照会ではそれがどこに使われたかがわかります。 代表的なユースケースは3つあります:

自動照合

期間ごと、またはモデルごとに実際の支出を集計し、自社の課金と照合する

セルフサービスのトラブルシューティング

失敗したリクエストのエラーコードを確認し、パラメータの問題か上流側の問題かを見分ける

サポートチケット

正確な呼び出しを特定できるよう、request_id をサポートに提供する
ログはコンソールの Logs ページでも確認できます。この API は同じデータへのプログラム用エントリーポイントであり、自動照合、定期エクスポート、または独自の監視への取り込みを目的としています。手動で確認する場合はコンソールを使用してください — 呼び出し記録の確認方法をご覧ください。
推奨される使い方: 1日1回同期し、ログを自分のデータベースに保存してください。この API は、リアルタイムで繰り返し照会する用途ではなく、定期的な増分エクスポート向けに設計されています:
  • 1日1回実行し、前回の同期以降に作成されたレコードだけを自分の データベースまたは CSV ファイルに取り込んでください
  • 1回のリクエストでより多く取得してください: pageSize は 5000 まで対応しています — デフォルトの 10 のままにしないでください。 この落とし穴については下のパラメータ注記を参照してください
  • 一括バックフィルには使わないでください(3か月分を一度に取得するなど)。また、 UI でのライブページネーションにも使わないでください
  • 同時に呼び出さないでください — ページは逐次的に、ページ間隔をおおむね1秒空けて取得してください
  • 各期間は1日以内に抑え、高ボリュームのアカウントでは時間単位で分割してください
その理由は下記の Performance Notes セクションをご覧ください。期間が古いほど、ページネーションが深いほど、 各リクエストのコストは高くなります。サーバー側の制限を超えるとエラーが返り、 同じパラメータで再試行しても速くはなりません。このページの Python の例はすでに このパターンに従っており、そのまま日次の cron ジョブに組み込めます。

System Token の取得方法

Log Query API は System Token で認証します。これは API キーとは同じものではありません(このページ末尾の重要な注意事項を参照してください)。
1

コンソールにアクセス

api.apiyi.com/account/profile にアクセスしてプロフィールページを開きます
2

System Token を確認

ページ下部の「アカウントオプション - System Token」セクションを見つけてください
3

AccessToken を生成

アカウントのパスワードを入力すると、その後の API クエリに使用できる AccessToken を受け取れます
System Token を取得

API情報

リクエストの詳細

リクエストヘッダー

Query Parameters

Treat the time window as required.The endpoint does not actually enforce these two parameters — a call without them succeeds. But omitting them tells the server to search your account’s entire history backwards from the newest record, and accounts with a large call history will hit the server-side limit and get an error rather than a slow response.This is the easiest mistake to make on this page and the one with the most direct consequences. We mark it Required not because the server rejects the call, but because the failure mode is hard to recognize: it does not report a missing parameter, it reports a timeout.
pageSize is the only camelCase parameter on this endpoint. Spelling it page_size is silently ignored.Every other parameter (model_name, token_name, start_timestamp, request_id, …) uses snake_case — this one does not. Getting it wrong does not raise an error: the server treats the parameter as absent and falls back to the default of 10 records per page, which is easy to misread as “the cap is 10” or “I only made 10 calls in this period.”
Going above 5000 does raise a clear error rather than truncating silently.
Raising pageSize is the single most effective optimization for this endpoint. At 10 records per page, an account making 500,000 calls a day needs 50,000 requests; at 5000 per page it needs 100. Two orders of magnitude fewer requests, and the pagination offset drops with it — see Performance Notes below.A 5000-record page measures roughly 700 KB gzipped and takes about 2.5 seconds. If bandwidth or memory is tight, 1000 is a comfortable middle ground.

パフォーマンスに関する注意

単一リクエストのコストは固定ではありません。それは 3 つの要素に依存します。これらのルールに従えば API は高速ですが、無視するとサーバー側の 60 秒クエリ制限に達し、エラーが返ります。 実践的なルールは 4 つあります。
  1. start_timestampend_timestamp を必ず渡してください。 ウィンドウを省略するのは、この API を呼び出すうえで最も高くつく方法です。
  2. pageSize を引き上げてください。 これは簡単です。1ページあたり 10 件から 1000〜5000 件にすると、リクエスト数を 2 桁減らせて、オフセットもそれに伴って小さくなります。
  3. オフセットを深くするのではなく、ウィンドウを狭めてください。 コストがかかるのは「どのページか」ではなく、「そこにたどり着くまでに何件スキップしたか」であり、それは超線形に増えます。1つの大きなウィンドウを最後までページングするのではなく、24 個の 1 時間ウィンドウに分割し、各ウィンドウを offset 0 から再開するようにしてください。
  4. 履歴は一度だけバックフィルして保存し、その後は増分だけを同期してください。 古いデータは最新データよりクエリコストがはるかに高いため、同じ履歴を何度も読み直すのは完全な無駄です。
pageSize=1000 でもウィンドウが数十ページかかるなら、その期間の呼び出し量は多いということです — ウィンドウを半分に分け、それぞれを別々に取得してください。これは、さらに深くページングするよりずっと速いです。下の Python 例にある MAX_PAGES 定数は、まさにこれを行っています。

60 秒は厳格な上限で、それを超えるとエラーが返ります

サーバーは単一クエリを 60 秒 に制限しています。それを過ぎると遅い応答が返るのではなく、 エラーが返り、そこまでに費やした時間ではデータは一切得られません。 次の 3 つのパターンは、これを引き起こしやすいです。再試行して期待するのではなく、最初から避けてください。 同じパラメータで再試行しても速くはなりません。単にさらに 60 秒かかるだけです。 正しい対応は、時間ウィンドウを狭めるか、pageSize を引き上げてページングを減らすことです — どちらにしても、1 回の呼び出しでサーバーが処理するデータ量を減らしてください。

ログタイプ

支出額を計算する際は、必ず type=2 を渡してください。 これを指定しない場合、チャージおよびシステム付与の記録も 返されます。これらの quota は0ですが、model_nametoken_name も空であるため、単純に 合計したりモデルごとにグループ化したりすると、誤った結果になります。アカウントで非同期動画モデル(Seedance など)を使用している場合は、type=11 も取得してください。タスクが失敗すると、その事前課金分が負の返金エントリとして戻されるため、type=2 だけを合計すると、その事前課金分が支出としてカウントされます。

レスポンス詳細

成功レスポンスの例

主要レスポンスフィールド

otherフィールドにはネストされたオブジェクトではなくJSON文字列が格納されるため、2回目のパースが必要です (Pythonではjson.loads()、JavaScriptではJSON.parse())。これにはbilling_typerequest_path(実際に呼び出されたエンドポイント)、group_ratiomodel_ratio、およびusageが含まれます。非同期動画タスクの精算エントリには、final_quota(タスクの最終合計)、original_quota (送信時に行われた事前課金)、adjustment_quota(このエントリの差額)およびactual_tokensも含まれます。詳細は以下のFAQを参照してください。

クォータ換算

換算ルール

500,000クォータ = $1.00 USD
計算式: USD金額 = quota ÷ 500,000 例:
  • quota: 7500 → $0.015 USD
  • quota: 22500 → $0.045 USD
  • quota: 18 → $0.000036 USD
これは残高照会APIで使用される換算と同じです。 そのため、両者は直接対応します。

エラー応答

HTTP 401 - 認証に失敗しました

理由: システム token が無効または期限切れであるか、あるいは sk- で始まる API キーが 誤ってシステム token として使用されています。 解決策: コンソールでシステム token を再生成し、Authorization には Bearer プレフィックスなし の生の値を指定してください。

コード例

cURL の例(1ページ、簡易確認)

--compressed オプションは必須です, API が gzip 圧縮されたコンテンツを返すためです。 これがないと文字化けした出力になります。
これを使って token が動作することを確認してください。実際の照合には、下の毎日同期スクリプトを使用してください。

Python の例: 日次の増分同期(cron ジョブとしてすぐ使えます)

これは 推奨される標準的な使い方 です。1日1回実行し、前回の同期以降に新しくなったものだけを取得して、 ローカルの SQLite データベースに書き込みます。再実行しても安全です(レコードは request_id で重複排除されます)。また、途中で中断された実行は停止したところから再開されます。
サンプル出力:
データがローカルにあれば、モデル別、日別、token 別など、必要なあらゆる集計はすべて ご自身のデータベースに対して実行されるため、そのために再び API に問い合わせる必要はありません。これははるかに高速で、 すでに保持期間を過ぎて消えたデータが欲しくなる問題も回避できます。

Node.js の例(単一の時間枠)

考え方は同じです。1時間ごとに分割し、順番にページングし、ページネーションが深くなりすぎたら時間枠を縮小します。
Python の requests ライブラリと Node.js の fetch API はどちらも gzip を自動的に展開するため、 その場合は追加の設定は不要です。明示的な --compressed フラグが必要なのは curl のみです。

Common Scenarios

日次照合(推奨される方法)

上の Python スクリプトを 1 日に 1 回実行するようにスケジュールし、ログをローカルデータベースに保存します。必要な内訳——総支出、モデル別、token別——はすべて、自分のデータベースに対する SQL クエリで取得できます。 これが適切な形である理由は 3 つあります。ローカルのクエリは高速であること、ログの保持期間の影響を受けないこと、そして古い履歴を繰り返し読み直すことで API の速度を落とさずに済むことです。 1 つの model のレコードだけを同期するには、リクエストに model_name パラメータを追加します。

失敗した呼び出しの見つけ方

データがローカルにあれば、自分のテーブルを直接クエリします:
ゲートウェイによって拒否されたリクエスト(無効なパラメータなど)は、quota が 0 であり、 課金されません。ログ内の error_code を使うと、「呼び出しが失敗した」のか 「呼び出しは成功したが、結果が気に入らなかった」のかを分けられます。

サポートに渡すリクエスト ID の指定

ログ内で問題のある呼び出しを見つけ、サポートに request_id を伝えてください。これにより、 エンドツーエンドで正確なリクエストを特定できるため、「ある model への呼び出しが ある時刻の前後で失敗した」と説明するより、はるかに効率的です。

よくある質問

まず次の3点を確認してください。遅いクエリのほとんどは、これらのいずれかが原因です。
  1. start_timestampend_timestamp を渡していますか? 時間範囲を省略することは、この API を呼び出すうえで 最もコストの高い方法です。サーバーが履歴全体を検索します。
  2. 範囲が古すぎる、または広すぎませんか? 1か月前のデータをクエリするコストは、 昨日のデータをクエリするよりはるかに高くなります。範囲は1日未満に保ち、大量の場合は時間単位で分割してください。
  3. p が数千に達していませんか? ページネーションのコストは超線形に増加します。対処方法は、 各時間範囲が数十ページだけで済むよう時間範囲を縮小することであり、1つの大きな範囲内で さらに深くページングすることではありません。
同じパラメータで再試行しても速くなりません。 タイムアウトした場合は、同一のリクエストを繰り返すのではなく、 上記のようにパラメータを調整してください。単純な再試行では、再び待つだけです。
10回中9回は、パラメータが snake_case の page_size として記述されています。正しいスペルは camelCase の pageSize です。これはこの エンドポイントで唯一の camelCase パラメータです。ほかのすべて(model_nametoken_namestart_timestamp、…)は snake_case であるため、間違えやすくなっています。エラーは発生せず、サーバーはこの パラメータが存在しないものとして扱い、1ページあたり10レコードにフォールバックします。
最大値は5000で、これを超えると明確なエラーが返されます。大量の場合でも、レスポンスが空の配列を返すまで ページネーション(p=0p=1、…)を行う必要があります。上記の Python と Node.js の例では、すでにこの処理がカプセル化されています。
はい。request_id を渡すと、そのレコードのみが返されます。
特定の1件の呼び出しを調査する場合、これは時間範囲を取得して 自分でフィルタリングするよりはるかに高速です。
いいえ。一部のフィールドにはプラットフォーム内部の情報が格納されており、通常の アカウントの観点では空またはゼロになります。これは想定どおりであり、照合やトラブルシューティングに必要な フィールドには影響しません。quotamodel_nameerror_code、および request_id はすべて完全に設定されています。
API はグループの識別子を返しますが、コンソールにはグループのラベルが表示されます。 これらは異なる場合があります。たとえば、API は default を返しますが、コンソールには Default と表示されます。完全なマッピングは、公開エンドポイント https://api.apiyi.com/api/pricingusable_group フィールドから取得できます。このフィールドは識別子をラベルにマッピングします。レポートを コンソールと一致させたい場合は、このマッピングを自身で適用してください。
quota を使用してください。これは呼び出しに対して実際に差し引かれた金額であり、 照合に適した唯一のフィールドです。画像生成や動画生成などの呼び出しごとに価格設定されるモデルでは、 レスポンス内の token 数が価格設定に関与しないプレースホルダー値である場合があります。 これらのモデルは、other.billing_typeby_count を報告します。
直近30日間のみクエリ可能であることを前提に、同期ロジックを設計してください。実際にはクエリ可能な範囲は通常もっと長いですが、保持については一切保証しません。 これはログクリーンアップポリシーに応じて変更され、その変更は個別に告知されません。30日間を 計画上の下限として扱えば、そのポリシーが変わっても照合処理は壊れません。また、範囲が古いほどクエリのコストは高くなります。データがまだ存在していても、 取得にははるかに時間がかかります。したがって、適切なパターンは1日に1回、自身のデータベースへ同期することであり、履歴分析は ローカルで実行してください。長期間保持する必要があるものは、自身でアーカイブしてください。この API から後で取得できることに依存しないでください。
理由: API は gzip 圧縮されたコンテンツ(Content-Encoding: gzip)を返しますが、curl が それを展開していません。解決策: --compressed フラグを追加してください。
Python の requests ライブラリと Node.js の fetch API は自動的に展開します。
非同期動画タスク(Seedance など)は「送信時に事前チャージし、完了時に差額を精算する」方式で課金されるため、 1本の動画につき2件のエントリが残ります。事前チャージ(completion_tokens が0で、request_id が存在)と精算 (completion_tokens が実際の使用量、request_id は空quota は差額のみ)です。 どちらのエントリにも task_id は含まれないため、この API ではエントリをタスクに対応付けられません。動画の実際のコストを取得するには、task_id でタスク API をクエリしてください。その quota は2件のエントリの合計です。
そのページングパラメータは snake_case の page_size であり、p は1から始まる点に注意してください。これはこの API と逆です。 失敗したタスクでも quota には事前チャージが表示されますが、実際のコストは0です(ログには負の type=11 の返金エントリが含まれます)。 詳しい手順:task_id で Seedance 動画の実際のコストを検索する方法
いいえ。ログクエリのエンドポイントはクォータを消費しません。

重要な注意事項

システム token は APIキー ではなく、両者は互換ではありません
  • APIキー (starting with sk-) は /v1/* 推論エンドポイント用です。これを /api/log/self に対して使用すると、401 が返ります。
  • システム token (プレフィックスのない単純な文字列) は /api/* 管理エンドポイント用です。 これを /v1/chat/completions に対して使用すると、無効な token エラーが返ります。
システム token のスコープはアカウント全体に及ぶため、アカウントのパスワードと同じように扱ってください: コードではなくシークレットマネージャーに保管し、リポジトリにコミットせず、定期的にローテーションしてください。
ログレスポンスには、あなた自身の APIキーが平文で含まれています各ログレコードには、その呼び出しを行った token に関する情報が含まれます。生のログレスポンスを公開の場に貼り付けたり、スクリーンショットを共有したり、第三者に渡したりしないでください — エクスポートする前に機密フィールドを削除してください。特に、この平文には sk- プレフィックスが付かないため、一般的なシークレットスキャナーでは検出できない場合があります。自動チェックで見つけてもらえると期待しないでください。
推奨される呼び出しパターン
  • 1日に1回同期する — それ以上頻繁に行う必要はありません。各実行では新しいものだけを取得します
  • pageSize を 1000〜5000 にする — デフォルトの 10 ではありません。これは他の項目を合わせたものより重要です
  • 直列で呼び出す。ページ間はおおむね1秒空け、同時実行しないでください
  • クライアント側のタイムアウトを 60 秒に設定してください(サーバー側のクエリ制限も 60 秒です)
  • 各時間窓は 1 日以下にしてください。大量利用アカウントでは 1 時間単位に分割してください
  • タイムアウトした場合は、再試行する前に時間窓を狭めてください — 同じ内容を再試行しても速くはなりません
これらは厳格なクォータではありません。単に、自分のデータを最速で取り出す方法です。このパターンに従えば、一般的なアカウントでは 1 日分のログを1分未満で同期でき、1日に何十万回もの呼び出しを行う大規模なアカウントでも、必要なリクエストは約100件で済みます。
このエンドポイントに将来レート制限を導入する権利を留保します。現時点ではレート制限はありませんが、スケジュールジョブを「無制限」を前提に設計しないでください。上記のパターン、つまり1日1回、直列で、大きな pageSize を守れば、将来レート制限が導入されても影響はありません。

関連ドキュメント