Lingara Lingara ドキュメント 学習ガイド API ライブラリ アプリ 作成 ウェブ版
言語: 日本語

認証

API バージョン 2026-10-affable-towhee

Lingara API へのすべての呼び出しにはアクセストークンが付きます。サーバーは、OAuth クライアントの ID とシークレットをトークンエンドポイントで交換してアクセストークンを取得します。これは、サーバーが自分自身として動作するための OAuth 2.0 のクライアントクレデンシャルグラントです。クライアントは Lingara ウェブアプリの「連携」ページ(app.getlingara.com/admin)で作成してください。

セッションかクライアントか

Lingara のアプリはセッションでサインインします。セッションはすべてのスコープを持ち、プランの利用枠を消費します。クライアントはそれより範囲が狭く、作成時に許可するスコープを選びます。クライアントが取得する各アクセストークンは、要求したスコープだけを持ちます。

3つの値

クライアント ID は lgr_cid_ で始まり、トークンエンドポイントでクライアントを識別します。シークレットではありません。

クライアントシークレットは lgr_cs_ で始まり、トークンエンドポイントにだけ送ります。表示されるのは作成時の一度だけです。Lingara はそのハッシュしか保存しないため、その場でコピーしてください。

アクセストークンは lgr_at_ で始まり、有効期間は1時間です。/v1/ 配下の呼び出しの Authorization: Bearer ヘッダーに入れ、それ以外の場所には入れません。このヘッダーに入れてよいのはアクセストークンだけです。クライアントシークレットをそこに送ると 401 で拒否されます。

アクセストークンを取得する

grant_type=client_credentials を付けたフォームをトークンエンドポイントに POST します。クライアント ID とシークレットは、HTTP Basic 認証か、client_id と client_secret のフォームフィールドのどちらか一方で送ります。両方は使えません。scope は、クライアントに許可されたスコープをスペース区切りで並べたものです。省略すると、クライアントに許可されたすべてのスコープを取得します。下のコマンドは usage:read だけを要求します。これは後述の GET /v1/usage の例が必要とするスコープです。

curl -X POST "https://api.getlingara.com/oauth/token" \
  -u "$LINGARA_CLIENT_ID:$LINGARA_CLIENT_SECRET" \
  -d "grant_type=client_credentials" \
  --data-urlencode "scope=usage:read"

レスポンスには access_token、token_type(Bearer)、expires_in(3600、秒単位)、そしてトークンが実際に持つスコープである scope が含まれます。交換に失敗すると、/v1/ の {code, error} エンベロープではなく、OAuth のエラー形式 {error, error_description} で応答します。誤ったシークレットや取り消されたシークレット、または削除されたクライアントは 401 と invalid_client で拒否されます。クライアントが要求できないスコープを含めると、交換全体が 400 と invalid_scope で拒否されます。黙って範囲が狭められることはありません。

別の Lingara ユーザーの代わりに動作する

別の Lingara ユーザーの代わりに動作するアプリは、認可コードグラントを使います。ユーザーのブラウザを、response_type=code、client_id、登録済みのものと完全に一致する redirect_uri、scope、state、そして S256 の code_challenge を付けて認可 URL に送ります。ユーザーには Lingara の同意ページが表示され、code、state、iss を付けて redirect_uri に戻ってきます。コードを使う前に、state が送ったものと同じであること、iss が https://api.getlingara.com であることを確認してください。

PKCE は必須

すべてのクライアントが PKCE を使い、方式は S256 のみです。ランダムな code_verifier を作り、その SHA-256 ハッシュを base64url エンコードしたものを code_challenge として code_challenge_method=S256 とともに送り、ベリファイアは交換のために保持してください。方式を指定しないリクエストや plain を指定したリクエストは invalid_request で拒否されます。

コードを交換する

60 秒以内に、クライアントとして認証したうえで、grant_type=authorization_code、code、同じ redirect_uri、code_verifier をトークンエンドポイントに POST します。パブリッククライアントは client_id だけを送ります。レスポンスには lgr_rt_ で始まる refresh_token が加わります。コードは lgr_ac_ で始まり、一度だけ使えます。2 回目の使用は invalid_grant で拒否され、最初の交換で発行されたトークンも無効になります。

リフレッシュする

アクセストークンの期限が切れたら、再びクライアントとして認証したうえで、grant_type=refresh_token と refresh_token をトークンエンドポイントに POST します。リフレッシュのたびに新しいリフレッシュトークンが返されるので、最新のものだけを保持してください。リフレッシュは同時に行わず、順番に実行してください。置き換えられてから 60 秒を過ぎて使われた古いリフレッシュトークンは盗まれたものとみなされ、そのインストールのトークンが invalid_grant で無効になります。30 日間使われなかったリフレッシュトークンは期限切れになります。トークンエンドポイントはアドレスごとにリクエスト数を制限しているため、リフレッシュはトークンが切れたときだけ行ってください。

ネイティブアプリはパブリッククライアント

デスクトップ、モバイル、コマンドラインのアプリはシークレットを秘密に保てないため、パブリッククライアントになります。シークレットを持たず、トークンエンドポイントには client_id だけを送り、http://127.0.0.1/callback(ポートは任意)のようなループバックのリダイレクトか、com.example.app:/callback のようなプライベート用途のスキームを登録します。ユーザーには毎回同意ページが表示されます。ウェブページはクライアントになれません。トークンエンドポイントも /v1/ もクロスオリジンのプリフライトに応答しないためです。

ユーザーがアプリを削除したとき

ユーザーは「接続済みアプリ」からいつでもアプリを削除できます。アプリをインストールした場合はアンインストールでも削除でき、その後のアプリの呼び出しは 401 で失敗します。ユーザーがアプリからサインアウトしたときは、取り消しエンドポイントでそのリフレッシュトークンを取り消してください。これにより、そのインストールのトークンが無効になります。

トークンの有効期限が切れたとき

1時間が過ぎると、/v1/ は 401 とコード unauthorized、invalid_token で始まるエラーで応答します。呼び出しが 401 を受け取ったとき、または expires_in が尽きる少し前に再度交換し、呼び出しを一度だけ再試行してください。交換自体が invalid_client または invalid_scope で失敗した場合は、クライアントまたはそのシークレットが削除されたか、取り消されたか、範囲を狭められています。再試行しても成功しないため、中止して「連携」ページで修正してください。トークンは呼び出しの間で保持してください。トークンエンドポイントはクライアントごと、アドレスごとに交換回数を制限しており、呼び出しのたびに交換するプログラムは1時間以内に 429 と rate_limited で拒否されます(Retry-After まで待ってください)。このグラントにはリフレッシュトークンがなく、シークレットを再度交換します。

アクセストークンが使えるのは API ルートだけ

アクセストークンは /v1/ 配下のルートでのみ機能します。Lingara のそれ以外のルートに送ると 401 で拒否され、本文はプレーンテキストまたは error フィールド内で api_token_not_accepted から始まります。/v1/ のルートが使う {code, error} エンベロープで返ることはありません。アクセストークンは以下のように Authorization ヘッダーで送ってください。

curl "https://api.getlingara.com/v1/usage" \
  -H "Authorization: Bearer $LINGARA_TOKEN"

スコープ

各操作にはちょうど1つのスコープが必要で、その操作のページに記載されています。そのスコープを持たないアクセストークンは 403 とコード insufficient_scope で拒否されます。その操作を呼び出すには、クライアントに許可されていれば、交換時にそのスコープを要求してください。下の表に、各スコープとそれが許可する操作を示します。

スコープ
vocab:generate 単語リストを生成します。 単語リストを生成
lesson_plans:read 自分のレッスンプランを読み取り、その進捗に再接続します。 レッスンプランを取得レッスンプランに再接続
lesson_plans:write レッスンプランを作成します。 レッスンプランを作成
tutor:converse チューターと会話します。有料プランが必要です。 チューターに1ターン送信
usage:read 残りの利用枠、または `metered` クライアントの今月の利用量を確認します。 残りの利用枠を取得
events:read 自分のアカウントに関するイベントを読み取り、それを受け取るエンドポイントを登録します。 イベントを一覧表示イベントをストリーム配信
events:write ゲームや連携から Lingara にイベントを送信します。 イベントを送信

呼び出しの費用は誰が負担するか

クライアントの課金方法は 2 種類あり、作成時に選びます。allowance クライアントは所有者の利用枠を消費します。これはアプリと同じ利用枠で、クライアントのアクセストークンも同じく消費します。残りは GET /v1/usage で確認できます。metered クライアントは利用枠を消費せず、「連携」ページで設定する従量課金サブスクリプションを通じてクレジット単位で課金されます。クライアントまたはアカウントが月間の支出上限に達すると、その呼び出しは 402 と spend_cap_reached で拒否され、従量課金が有効でない間は 402 と metered_billing_inactive で拒否されます。レッスンプランは 10 クレジット、チューターとの 1 ターンは 1 クレジット、単語リストの生成は 3 クレジットです。GET /v1/usage が報告する units は、この重みでクレジットに換算できます。アプリが認可コードから得たトークンで別のユーザーの代わりに行う呼び出しは、クライアントのモードにかかわらず、常にそのユーザーの利用枠を消費します。

シークレットとトークンはサーバー上に置く

クライアントシークレットは、自分が管理するサーバーに置くものです。誰でも読み取れるウェブページ、ブラウザ拡張機能、アプリバンドルには決して含めないでください。ネイティブアプリはパブリッククライアントであり、シークレットを持ちません。/v1/ もトークンエンドポイントもクロスオリジンのプリフライトに応答しないため、いずれにしても他のサイト上のブラウザからは呼び出せません。

クライアントの管理

「連携」ページ(app.getlingara.com/admin)では、クライアントの作成、名前の変更、削除、各クライアントにできることや固定するバージョンの変更、シークレットの作成と取り消しを行えます。クライアントを削除すると、そのクライアントが持つすべてのアクセストークンが直ちに使えなくなり、すべてのユーザーがそのクライアントに与えた許可も終了します。シークレットを取り消すと、そのシークレットと交換されたすべてのアクセストークンが直ちに使えなくなります。クライアントのスコープを狭める変更も直ちに適用されます。スコープを広げる変更やバージョンの変更は、次の交換から適用されます。

シークレットをローテーションする

1つのクライアントは同時に2つのシークレットを持てます。ローテーションするには、新しいシークレットを作成してデプロイし、「連携」ページで古いシークレットの「最終使用」の日付が変わらなくなったら、古いシークレットを取り消します。新しいシークレットをすでに持っていても、古いシークレットのトークンをまだ保持しているプロセスは、401 を一度受け取って再度交換します。クライアントの唯一のシークレットは取り消せません。先に代わりのシークレットを作成するか、クライアントを削除してください。

翻訳と英語版リファレンスの内容が異なる場合は、英語版リファレンスが正しいものとします。