メインコンテンツまでスキップ

Webhooks リクエスト

Webhook イベントが発生すると、Logto はそれに登録されたすべてのエンドポイントに POST リクエストを送信します。完全なイベントカタログは Webhooks イベント にあります。このページでは、Logto が配信するリクエストの形状を記載しています。

リクエストヘッダー

Keyカスタマイズ可備考
user-agentデフォルトでは Logto (https://logto.io/)
content-typeデフォルトでは application/json
logto-signature-sha-256リクエストボディの署名。Webhooks のセキュリティ確保 を参照してください。

カスタマイズ可能なヘッダーは、セキュア Webhook 設定を通じて上書きできます。

リクエストボディの概要

ボディは JSON オブジェクトです。その正確な形状は、イベントが属するファミリーによって異なります:

ファミリーイベント発生タイミング
ユーザーフローPostRegister, PostSignIn, PostResetPasswordユーザーが Experience API によって処理されるサインアップ、サインイン、またはパスワードリセットフローを完了したとき。
データ変更User.*, Role.*, Scope.*, Organization.*, OrganizationRole.*, OrganizationScope.*基本データモデルが変更されたとき — Management API コールまたは Experience API 上のユーザーフローによって。
例外Identifier.Lockoutセキュリティインシデント — 例えば、連続した認証失敗後にアカウントがロックされた場合。

すべてのファミリーは、共通フィールド の小さなセットを共有しています。各ファミリーはその後、独自のリクエストコンテキストフィールドとイベント固有のペイロードを追加します。

共通フィールド

ファミリーに関係なく、すべての配信に含まれます:

フィールドタイプオプション備考
hookIdstringLogto 内の Webhook 設定識別子。
eventstringこの配信をトリガーしたイベント。
createdAtstringISO 8601 形式のペイロード作成時間。
userAgentstringトリガーリクエストのユーザーエージェント。

各ファミリーには、トリガーリクエストの IP アドレスも含まれています — ユーザーフローイベントでは userIp フィールド、データ変更および例外イベントでは ip フィールドとして。意味は同じですが、後方互換性のために歴史的な名前の違いが保持されています。

ユーザーフローイベントペイロード

イベント: PostRegister, PostSignIn, PostResetPassword.

ユーザーが Experience API によって処理されるサインアップ、サインイン、またはパスワードリセットフローを完了したときに発生します。共通フィールド に加えて、ボディには以下が含まれます:

フィールドタイプオプション備考
interactionEvent'SignIn' | 'Register' | 'ForgotPassword'ユーザーフローイベントタイプ。PostSignIn / PostRegister / PostResetPassword にそれぞれマッピングされます。フィールド名は歴史的な「インタラクション」命名を保持しています。
sessionIdstringこのイベントのセッション ID(インタラクション ID ではありません)、該当する場合。
userIpstringトリガーリクエストの IP アドレス。
userIdstringこのイベントに関連付けられたユーザー ID、該当する場合。
userUserEntityこのイベントに関連付けられたユーザーエンティティ、該当する場合。
applicationIdstringこのイベントに関連付けられたアプリケーション ID、該当する場合。
applicationApplicationEntityこのイベントに関連付けられたアプリケーションエンティティ、該当する場合。

エンティティの形状

type UserEntity = {
id: string;
username?: string;
primaryEmail?: string;
primaryPhone?: string;
name?: string;
avatar?: string;
customData?: object;
identities?: object;
lastSignInAt?: string;
createdAt?: string;
applicationId?: string;
isSuspended?: boolean;
};
enum ApplicationType {
Native = 'Native',
SPA = 'SPA',
Traditional = 'Traditional',
MachineToMachine = 'MachineToMachine',
Protected = 'Protected',
SAML = 'SAML',
}

type ApplicationEntity = {
id: string;
type: ApplicationType;
name: string;
description?: string;
};

完全なフィールドリファレンスについては、ユーザー および アプリケーション を参照してください。

データ変更イベントペイロード

イベント: User.*, Role.*, Scope.*, Organization.*, OrganizationRole.*, OrganizationScope.* — 完全なカタログについては Webhooks イベント → データ変更フックイベント を参照してください。

ボディには常に以下が含まれます:

  • 共通フィールド
  • ip フィールド — トリガーリクエストの IP アドレス(オプション、既知の場合に存在)。
  • 変更がどのようにトリガーされたかを説明する API コンテキスト。コンテキストは、トリガーソースに応じて 2 つのバリアントのいずれかです:
  • イベント固有のペイロードdata 内の影響を受けたエンティティと(いくつかのイベントでは)追加のトップレベルフィールド。詳細は イベント固有のデータペイロード を参照してください。

Experience API コンテキストフィールド

変更が Experience API 上のユーザー向けフローによってトリガーされた場合に存在します — 例えば、サインアップ中の User.Created やプロフィール更新中の User.Data.Updated

フィールドタイプオプション備考
interactionEvent'SignIn' | 'Register' | 'ForgotPassword'変更を引き起こしたユーザーフローイベントタイプ。フィールド名は歴史的な「インタラクション」命名を保持しています。
sessionIdstringこのイベントのセッション ID(インタラクション ID ではありません)、該当する場合。
applicationIdstringアプリケーション ID、該当する場合。
applicationApplicationEntityアプリケーションエンティティ、該当する場合。

Management API コンテキストフィールド

変更が Management API コールによってトリガーされた場合に存在します。

フィールドタイプオプション備考
pathstringこのフックをトリガーした API コールのパス。
methodstringAPI コールの HTTP メソッド。
statusnumberAPI コールのレスポンスステータスコード。
paramsobjectAPI コールの koa パスパラメータ。
matchedRoutestringkoa の一致したルート。Logto はこのフィールドを使用して有効な Webhook イベントフィルターを一致させます。

イベント固有のデータペイロード

すべてのデータ変更イベントには、影響を受けたエンティティを含むトップレベルの data フィールドが含まれています。変更が単一のエンティティとして要約できない場合(削除およびメンバーシップイベント)、null になります。いくつかのイベントには、data 以外のイベント固有のトップレベルフィールドも含まれています — Organization.Membership.Updated がその一例で、以下に記載されています。

ユーザーイベント

イベントフィールドタイプオプション備考
User.CreateddataUserEntity作成されたユーザーエンティティ。
User.Data.UpdateddataUserEntity更新されたユーザーエンティティ。
User.Deleteddatanull/

ロールイベント

type Role = {
id: string;
name: string;
description: string;
type: 'User' | 'MachineToMachine';
isDefault: boolean;
};
type Scope = {
id: string;
name: string;
description: string;
resourceId: string;
createdAt: number;
};
イベントフィールドタイプオプション備考
Role.CreateddataRole作成されたロールエンティティ。
Role.Data.UpdateddataRole更新されたロールエンティティ。
Role.Deleteddatanull/
Role.Scopes.UpdateddataScope[]ロールに割り当てられた更新されたスコープ。
Role.Scopes.UpdatedroleIdstringスコープが割り当てられたロール ID。(事前に割り当てられたスコープを持つロールの作成によってイベントがトリガーされた場合にのみ利用可能。)

権限 (スコープ) イベント

イベントフィールドタイプオプション備考
Scope.CreateddataScope作成されたスコープエンティティ。
Scope.Data.UpdateddataScope更新されたスコープエンティティ。
Scope.Deleteddatanull/

組織イベント

type Organization = {
id: string;
name: string;
description?: string;
customData: object;
createdAt: number;
};
イベントフィールドタイプオプション備考
Organization.CreateddataOrganization作成された組織エンティティ。
Organization.Data.UpdateddataOrganization更新された組織エンティティ。
Organization.Deleteddatanull/
Organization.Membership.Updateddatanull/変更はオプションのトップレベルのデルタ配列によって説明されます。詳細は Organization.Membership.Updated ペイロード を参照してください。
Organization.Membership.Updated ペイロード

共通フィールドと、トリガーソースに応じた API コンテキストフィールド(Management API ルートの場合は Management API コンテキスト、ジャストインタイムプロビジョニングの場合は Experience API コンテキスト)に加えて、Organization.Membership.Updated イベントは organizationId とペイロードのトップレベルにオプションのデルタ配列を持ちます(eventcreatedAt などの隣に。このイベントでは常に null である data 内ではありません)。

フィールドタイプオプション備考
organizationIdstringメンバーシップが変更された組織。
addedUserIdsstring[]このトリガーによって新たに追加されたユーザー ID。ユーザーが追加されなかった場合、またはトリガーがユーザーメンバーシップに影響を与えない場合は省略されます。
removedUserIdsstring[]このトリガーによって削除されたユーザー ID。削除されたユーザーがいない場合は省略されます。
addedApplicationIdsstring[]新たに追加されたアプリケーション ID。アプリケーションが追加されなかった場合、またはトリガーがアプリケーションメンバーシップに影響を与えない場合は省略されます。
removedApplicationIdsstring[]削除されたアプリケーション ID。削除されたアプリケーションがいない場合は省略されます。

4 つのデルタ配列は オプションで追加的 です — それらを期待しない消費者に対して既存のペイロード形状を変更せず、レガシーの data: null フィールドは変更されずに出力されます。

トリガーとそれらが発行する可能性のあるデルタフィールド
トリガー可能なデルタフィールド
POST /organizations/:id/usersaddedUserIds
PUT /organizations/:id/usersaddedUserIds, removedUserIds
DELETE /organizations/:id/users/:userIdremovedUserIds
POST /organizations/:id/applicationsaddedApplicationIds
PUT /organizations/:id/applicationsaddedApplicationIds, removedApplicationIds
DELETE /organizations/:id/applications/:applicationIdremovedApplicationIds
PUT /organization-invitations/:id/status (Accepted)addedUserIds
ユーザーを新しい組織に追加する際のジャストインタイムプロビジョニングaddedUserIds
空のデルタは省略されます — 不在 ≠ 空の変更

空のデルタ配列はペイロードから 完全に省略されます。例えば、既存のセットでメンバーシップセットを置き換える PUT /organizations/:id/users は実際の変更を生じず、ペイロードは organizationId のみを持ち、4 つのデルタフィールドはすべて不在です。同様に、既存メンバーの再追加、すでにメンバーであるユーザーによる招待の再受諾も同様です。

消費者は、欠落しているフィールドを「その側に変更なし」として扱い、「空の変更」として扱わないようにしなければなりません。

配列ごとの上限(静かに切り捨て)

各デルタ配列は 5000 エントリ に制限されています。単一の Management API コールが 1 回の操作で 5000 人以上のユーザー(またはアプリケーション)に影響を与える場合、対応するデルタ配列は最初の 5000 エントリに静かに切り捨てられます — 上限が発動したことを示すペイロード内のマーカーはありません

管理上の一括操作が 1 回のコールで 5000 人以上のメンバーに影響を与える可能性がある場合、5000 エントリちょうどの配列を見たら、Management API を介して権威あるメンバーシップを調整する信号として扱います:

  • GET /organizations/:id/users — 完全なユーザーメンバーシップ。
  • GET /organizations/:id/applications — 完全なアプリケーションメンバーシップ。

これは、GitHub の push イベントと同じパターンに従っており、commits を 20 エントリに制限し、消費者に完全なリストのために比較 API を指示します。

無操作イベントのスキップ

メンバーシップルートに対するすべての PUT は、実際に何かが変更されたかどうかに関係なくイベントを発行します — したがって、監査目的で少なくとも 1 つの Webhook 配信があるようにします。消費者側で無操作の配信をスキップするには、デルタ配列の存在でフィルタリングします:

if (
payload.addedUserIds?.length ||
payload.removedUserIds?.length ||
payload.addedApplicationIds?.length ||
payload.removedApplicationIds?.length
) {
// 実際のメンバーシップ変更 — 処理します
}

?.lengthundefined[] の両方に対して偽であるため、フィールドが不在であるか(将来的に仮に)空の配列として出力されるかに関係なく、この述語は堅牢です。

ペイロードの例

ユーザーを追加する(POST /organizations/:id/users):

{
"event": "Organization.Membership.Updated",
"organizationId": "org_abc",
"addedUserIds": ["u_001"]
}

ユーザーメンバーシップセットを置き換える(PUT /organizations/:id/users):

{
"event": "Organization.Membership.Updated",
"organizationId": "org_abc",
"addedUserIds": ["u_002"],
"removedUserIds": ["u_001"]
}

ユーザーを削除する(DELETE /organizations/:id/users/:userId):

{
"event": "Organization.Membership.Updated",
"organizationId": "org_abc",
"removedUserIds": ["u_001"]
}

アプリケーションを追加する(POST /organizations/:id/applications):

{
"event": "Organization.Membership.Updated",
"organizationId": "org_abc",
"addedApplicationIds": ["app_xyz"]
}

既存メンバーの再追加、無操作の PUT、またはすでにメンバーである招待の再受諾(実際の変更なし):

{
"event": "Organization.Membership.Updated",
"organizationId": "org_abc"
}

5000 の上限に達する一括操作(静かに切り捨て):

{
"event": "Organization.Membership.Updated",
"organizationId": "org_abc",
"removedUserIds": ["u_0001", "u_0002", "/* … exactly 5000 entries total */"]
}

5000 エントリちょうどの配列を見たら、調整するために GET /organizations/:id/users(または /applications)を促します。

組織ロールイベント

type OrganizationRole = {
id: string;
name: string;
description?: string;
};
type OrganizationScope = {
id: string;
name: string;
description?: string;
};
イベントフィールドタイプオプション備考
OrganizationRole.CreateddataOrganizationRole作成された組織ロールエンティティ。
OrganizationRole.Data.UpdateddataOrganizationRole更新された組織ロールエンティティ。
OrganizationRole.Deleteddatanull/
OrganizationRole.Scopes.Updateddatanull/
OrganizationRole.Scopes.UpdatedorganizationRoleIdstringスコープが割り当てられたロール ID。(事前に割り当てられたスコープを持つロールの作成によってイベントがトリガーされた場合にのみ利用可能。)

組織権限 (スコープ) イベント

イベントフィールドタイプオプション備考
OrganizationScope.CreateddataOrganizationScope作成された組織スコープエンティティ。
OrganizationScope.Data.UpdateddataOrganizationScope更新された組織スコープエンティティ。
OrganizationScope.Deleteddatanull/

例外イベントペイロード

イベント: Identifier.Lockout.

セキュリティインシデントで発生します — 例えば、連続した認証失敗後にアカウントがロックされた場合。これらのイベントは常にユーザー向けフローから発生するため、ボディには以下が含まれます:

enum SignInIdentifier {
Email = 'email',
Phone = 'phone',
Username = 'username',
}
フィールドタイプオプション備考
typeSignInIdentifierユーザーの識別子タイプ、例:メール、電話番号、またはユーザー名。
valuestringロックアウトを引き起こしたユーザーの識別子値。