トークンが取得できない(認証エラー)

トラブル トークン 認証 OAuth

トークンエンドポイント POST https://receiptroller.io/api/v1/auth/token が 400 または 401 を返し、アクセストークンが取得・更新できないときの切り分け方をまとめます。返ってきた error と error_description を下の表と照らし合わせてください。認可URLの段階でエラーになる場合は、後半の表をご覧ください。

トークンエンドポイントのエラー

HTTP / error error_description 原因と対処
400 invalid_requestなし、code is required、refresh_token is required本文を JSON として読み取れない、または必須の値がありません。Content-Type と本文の形式を確認してください。
400 unsupported_grant_typeなしgrant_type が空か、authorization_code / refresh_token 以外です。client_credentials は使えません。
401 invalid_clientclient authentication failedクライアントIDが存在しない(アプリが削除された場合を含む)、またはクライアントシークレットが違います。シークレットを再生成した後は新しい値を使ってください。
401 invalid_grantauthorization code is invalid, expired, or already used認可コードの10分が過ぎた、すでに交換済み、または値が違います。認可からやり直してください。
401 invalid_grantredirect_uri does not match the authorization request交換時の redirect_uri が、認可リクエストで送った値と違います。
401 invalid_grantauthorization code was issued to a different client別のアプリのクライアントIDで交換しようとしています。開発用と本番用のアプリを取り違えていないか確認してください。
401 invalid_grantpublic clients require PKCE; the code was issued without a code_challenge公開クライアントが code_challenge なしで認可しました。PKCE を付けて認可し直してください。
401 invalid_grantcode_verifier is required / PKCE verification failedcode_verifier がない、または code_challenge と合いません。S256 では SHA-256 を Base64URL(+→-、/→_、末尾の = なし)にします。
401 invalid_grantthe business account's plan does not include the developer API; it needs Starter or above連携先のビジネスアカウントのプランがスタータープラン未満です。認可コードは使用済みにならないので、10分以内にプランを変更すれば同じコードで交換できます。
401 invalid_grantrefresh token is invalid, expired, or revokedリフレッシュトークンが30日を過ぎた、すでに更新に使った、または取り消されました。最後に受け取ったリフレッシュトークンを使い、だめなら再認可してください。
401 invalid_grantrefresh token was issued to a different client別のアプリのリフレッシュトークンです。

invalid_grant も 400 ではなく 401 で返ります。ステータスコードだけで判断せず、error を見てください。

認可URLの段階で止まる場合

/oauth/authorize で次のエラーが出た場合は、リダイレクトされずにブラウザへ 400 の JSON が表示されます。

error 対処
invalid_redirect_uriアプリにリダイレクトURIを登録し、redirect_uri を完全に一致させます(リダイレクトURLの設定)。
invalid_clientclient_id を確認します。アプリが無効になっている場合も返ります。
unsupported_response_typeresponse_type=code を指定します。
invalid_scopescope を指定し、user.* とそれ以外のスコープを1回の要求に混ぜないでください。
invalid_requestcode_challenge_method は S256(推奨)か plain を、大文字・小文字もこのとおりに指定します。
app_not_approveduser.* を使うにはアプリの審査承認が必要です(User系スコープの審査申請)。
no_organizationログインしているユーザーがオーナーであるビジネスアカウントがありません。オーナーのアカウントで認可してください。

コールバックに error=access_denied が付いて戻った場合は、ユーザーが拒否したか、すべてのスコープのチェックを外しました(error_description=no_scopes_approved)。

切り分けチェックリスト

  • クライアントID・シークレットを、開発用と本番用のアプリで取り違えていないか
  • シークレットを最近再生成していないか
  • 認可コードを10分以内に、1回だけ交換しているか
  • redirect_uri が認可リクエストと同じ値か(URL エンコードした後の値ではなく、元の文字列が同じか)
  • client_id と client_secret を本文に入れているか(Authorization ヘッダーの Basic 認証は読み取りません)
  • パラメーターをクエリ文字列ではなく本文に入れているか
  • 公開クライアントの場合、code_challenge を付けて認可し、code_verifier を送っているか
  • リフレッシュの場合、最後に受け取ったリフレッシュトークンを使っているか

本文の形式

本文は application/x-www-form-urlencoded(キーは snake_case)を推奨します。JSON も受け付け、キーは grant_type のような snake_case、grantType のような camelCase のどちらでも読み取ります。JSON として壊れている本文は 400 invalid_request になります。

関連ガイド

公開日: 2026-04-27 更新日: 2026-10-26