Skip to main content
業務自動化更新

ドキュメントに載っていないAPIの仕様は、どう調べるのか

外部サービスと連携するとき、必要な情報が公開ドキュメントに載っていないことがあります。応答コードとトークンの中身から、接続先・認可の範囲・指定方法を絞り込む手順を説明します。

モニタに表示されたプログラムのコード
Photo: Al Nahian / Pexels

以下は2026年8月時点で確認した挙動です。

外部サービスのAPIに繋ごうとして、接続先のURLもリクエストの形も公開情報から分からないことがあります。マネーフォワード クラウド会計のAPIで仕訳の登録を自動化した作業がこれでした。技術サポートの窓口は士業事務所向けに限られ、問い合わせ先もありません。

行き詰まりの本体は、情報が無いことではありません。当てずっぽうで叩くと、動かない原因がURLの誤りなのか、認証が通っていないのか、権限が足りないのか、パラメータが違うのかを切り分けられません。どれも「エラーが返る」としか見えないので、直す場所が決まらないまま時間が溶けます。推測のまま設計を書き切れば、実物と食い違ったときに丸ごと書き直しになります。

切り分けの道具は、API自身が返します(応答の形や挙動はサービスごとに異なります)。

  • 応答コードは確定診断ではなく、候補間の応答差から仮説を立てる手がかりになります。404 は無いことの証明になりません
  • 認可が成功しても、要求した権限が付いたとは限りません。エラー文よりトークンの中身が速いです
  • 検証で弾かれる 400 応答から、リクエスト本文の形を読み取れることがあります(更新系では安全条件の確認が先です)

応答コードの違いが、そこに何があるかを教えます

応答コードの意味はRFC 9110が定めています[1]。ただし仕様は「どの処理段階まで届いたか」を保証しません。下の表の右列は、同じ条件で候補を比べたときの差から立てる、このAPIでの読み方(仮説)です。

コード 仕様上の意味[1] このAPIでの読み方(観測に基づく仮説)
404 対象が見つからない 不在の証明にならない
401 有効な認証情報を欠く 認証処理まで届いた可能性
403 理解したうえで実行を拒否 認証は通り、権限で止まった可能性
400 クライアント側の誤り 本文の形まで検証された可能性

第一段で効くのは 401 です。認証の判定が返るのは、リクエストが認証の層まで届いたからです。ただし、認証を入口で一律に処理する構成では、存在しないパスにも 401 が返ります。

404 だけは逆に読めません。RFC 9110は、在る資源を隠すために 404 を返してよいと定めています[1]。

接続先は、返るコードを見比べて絞り込めます

候補のどれが正しいかを教える情報源はありません。認証のチュートリアルに載っていたのは別サービスのホスト名だけでした。そこで、ありそうなホスト名を並べ、同じ経路に同じリクエストを投げました。どの経路でも 404 を返す側と 401 を返す側に割れました。違いはハイフンの有無だけでした。

トークンをデコードするほうが、エラー文を読むより速いです

APIキーをトークンに交換する処理は成功しました。ところが目的のAPIは 401 を返し、トークンが有効でないという文面が返ります。この文面では、期限切れ・形式の誤り・権限不足を区別できません。

決め手はペイロードのデコードでした。使われていたのはJWTで、権限や発行者などの情報をJSONで書き、URLで運べる形に符号化したトークンです[2]。JWTには暗号化された形式もありますが、このトークンは暗号化されていない署名つきの形式(JWS)だったため、ペイロードは鍵がなくても読めます。読めることと信頼できることは別で、判断に使うときは発行者・署名・期限の検証を別に行います。デコードすると、トークンが有効なサービスを列挙したクレームに、目的のサービスが入っていません。

認可の成功は、要求が通ったことを意味しません

認可画面を通りトークンも手元にあるなら、権限は付いていると考えるのが自然です。この前提が崩れます。権限の委譲はOAuth 2.0で行い、範囲はスコープと呼ぶ空白区切りの文字列です。RFC 6749の §3.3 は、認可サーバが要求されたスコープを全部または一部無視してよいと定めています[3]。付与した範囲が要求と異なる場合は scope パラメータで伝えなければならない、とも定めています。

検証では、スコープ名を複数形で綴り間違えたまま要求しました。認可は成功しました。付与された一覧から、その名前だけが消えていました。このサービスでは、存在しない権限名は誤りとして返らず、単に無視されました。

対策は、トークン取得の直後に差分を取ることです。

requested = set(scopes.split())
dropped = sorted(requested - set(granted.split()))

dropped が空でなければ警告を出して止めます。この検査がなければ、綴り間違いは後の権限エラーになります。

エラーメッセージの主語を疑います

権限が足りないというエラーは、どの主体の話なのかを書いているとは限りません。返ってきた本文は、アクセスされている事業者に十分な権限がない、と読めるものでした。この主語に従えば、疑う先は契約や事業者の設定です。実際の原因はトークンのスコープ不足でした。

RFC 6750 は、トークンの権限が足りない場合のエラーを insufficient_scope と定め、403 を推奨しています[5]。ただし 403 は権限以外の理由でも返り、どの主体の権限が足りないかも区別しません。権限の主体はトークン・利用者・事業者に分かれます。3つを別々に確かめます。

送るべき形は、失敗する 400 が教えてくれます

送るキーの名前が分からなければ、総当たりすら組めません。候補を順に投げ、最初に受理されたもので止められます。ただし、400 が返ることは副作用がないことの保証ではありません。この探索を使ってよいのは、検証用の環境や帳簿で試せる、実行後に状態を確認できる、といった安全条件を確保できる場合に限ります。今回は、400 で拒否されたリクエストが何も作成していないことを、一覧の再取得で確かめながら進めました。

1回目の応答が道標になります。

400 missing_required_request_body_key: Target: account_id
  • 不足しているキーの名前が返ります。account_id を加えて再送し、別の不足キーが返れば同じ手順を繰り返します
  • ネストした構造は拒否され、受理されたのはフラットな本文でした

この手順は、成功すると取り消せない操作には使えません。その場合の設計は 取り消せない操作を含む処理は、どう自動化するのか に記載しています。

なお、応答コードを先に見る習慣は、探索が終わったあとの実装でも効きます。一覧取得で 429(リクエスト過多[4])が返ったとき、本文の配列が空だからと正常終了させると、取りこぼしが「全部取れた」に化けます。非200は必ず例外にし、終端の判定を中身に任せないことです。

調べる順序は、接続先、認証と認可、リクエスト本文の3段階です。どの段階でも、確定診断をくれる応答はありません。同じ条件で比べた応答の差から仮説を立て、安全に試せる方法で確かめて、実測になった事実だけを設計に書く。それが、ドキュメントのないAPIとの付き合い方でした。

参考文献

  1. RFC 9110 — HTTP Semantics, Status Codes
  2. RFC 7519 — JSON Web Token (JWT)
  3. RFC 6749 — The OAuth 2.0 Authorization Framework, Section 3.3 Access Token Scope
  4. RFC 6585 — Additional HTTP Status Codes
  5. RFC 6750 — The OAuth 2.0 Authorization Framework: Bearer Token Usage
LET'S START TOGETHER

Ready to
Design Your Voice?

法人向け受託開発から、コンシューマーアプリの導入相談まで。まずはお気軽にお問い合わせください。