diff --git a/_snippets/snippet-example.mdx b/_snippets/snippet-example.mdx
deleted file mode 100644
index 089334c..0000000
--- a/_snippets/snippet-example.mdx
+++ /dev/null
@@ -1,3 +0,0 @@
-## My Snippet
-
-This is an example of a reusable snippet
diff --git a/guides/custom-emails/email-delivery.mdx b/guides/custom-emails/email-delivery.mdx
index c8b87da..6d4252e 100644
--- a/guides/custom-emails/email-delivery.mdx
+++ b/guides/custom-emails/email-delivery.mdx
@@ -4,6 +4,8 @@ title: Send Custom Emails
description: Send emails with your own text and style.
---
+import ProFeatureNote from '/snippets/pro-feature-note.mdx'
+
This guide will walk you through the process of sending your own emails instead of relying on Hanko's default email delivery.
## Create a Webhook
@@ -17,63 +19,39 @@ Create a webhook with the event `email.send`. This webhook will be triggered whe
## Disable Email delivery by Hanko
-1. Log in to the [Hanko Cloud Console](https://cloud.hanko.io) and select your project.
-2. Navigate to `Settings > Email`.
-3. Disable the Email delivery by Hanko.
+
+
+
+
+ Log in to Hanko Cloud, select your organization and project and navigate to `Settings > Email delivery`.
+
+
+ Find the `Email delivery by Hanko` setting and click the toggle to disable it.
+
+
Once disabled, Hanko will no longer send any emails on your behalf.
## Send your own emails
-When an email needs to be sent, the `email.send` webhook event will be triggered, providing you with all the necessary data to send your own email. The webhook payload will include the following information:
-
-```json
-{
- "subject": "",
- "body_plain": "",
- "body": "",
- "to_email_address": "",
- "delivered_by_hanko": true,
- "accept_language": "",
- "type": "passcode",
- "data": {
- "service_name": "",
- "otp_code": "",
- "ttl": 1000,
- "valid_until": 1000
- }
-}
-```
-
-* `subject`: The subject line of the email.
-* `body_plain`: The plain text version of the email body.
-* `body`: The HTML version of the email body. (`nullable`)
-* `to_email_address`: The recipient's email address.
-* `delivered_by_hanko`: Indicates whether the email was delivered by Hanko (true) or not (false).
-* `accept_language`: The preferred language for the email content.
-* `type`: The type of the email being sent (e.g., "passcode").
-* `data`: Additional data specific to the email type.
-
-The `data` property in the webhook payload provides type-specific data that can be used to personalize the email further. The structure of the `data` property varies depending on the `type` of the email being sent.
+When an email needs to be sent, the `email.send` webhook event will be triggered, providing you with all the necessary
+data to send your own email. The webhook token payload will include the following information:
-For example, if the email type is "passcode", the `data` property will include the following fields:
+import WebhookEmailSendExample from '/snippets/webhooks/email-send-example.mdx';
+import WebhookEmailSendProperties from '/snippets/webhooks/email-send-properties.mdx';
-
-
- ```json
- "service_name": "",
- "otp_code": "",
- "ttl": 1000,
- "valid_until": 1000
- ```
+
+
+
+
+
+
+
+
- |property|description|
- |----|----|
- |`service_name`|The name of the service set in the console as project name|
- |`otp_code`|The passcode the user can use to log in|
- |`ttl`|The validity duration of the passcode in seconds|
- |`valid_until`|The Unix timestamp indicating when the passcode expires|
-
-
+The `data` property in the token payload provides type-specific data that can be used to personalize
+the email further. The structure of the `data` property varies depending on the `type`
+of the email being sent.
-Using the provided webhook data, you can compose and send the email to the user using your preferred email service provider or custom email infra.
+Using the provided webhook data, you can compose and send the email to the user using your preferred email service
+provider or custom email infrastructure.
diff --git a/guides/webhooks/introduction.mdx b/guides/webhooks/introduction.mdx
index a66a277..03471cc 100644
--- a/guides/webhooks/introduction.mdx
+++ b/guides/webhooks/introduction.mdx
@@ -1,68 +1,389 @@
---
sidebarTitle: "Webhooks"
-title: Learn more about Webhooks
-description: Webhooks allow you to get notified on changes
+title: Webhooks
+description: Learn more about Webhooks
---
-Webhooks are an easy way to get informed about changes in your Hanko instance (e.g. user or email updates).
-To use webhooks you have to provide an endpoint on your application which can process the events. Please be aware that your
-endpoint need to respond with an HTTP status code 200. Else-wise the delivery of the event will not be counted as successful.
+import WebhookUserPayloadExample from '/snippets/webhooks/user-payload-example.mdx';
+import WebhookUserPayloadProperties from '/snippets/webhooks/user-payload-properties.mdx';
+import WebhookEmailSendExample from '/snippets/webhooks/email-send-example.mdx';
+import WebhookEmailSendProperties from '/snippets/webhooks/email-send-properties.mdx';
+import ProFeatureNote from '/snippets/pro-feature-note.mdx'
+
+
+
+## About webhooks
+
+Webhooks allow you to subscribe to events within a Hanko project and automatically receive data deliveries to your
+server/application whenever those events take place. This allows you to, for example, synchronize user data between your
+application(s) and Hanko.
+
+To create a webhook you specify a callback URL and subscribe to events that occur in your Hanko project. Once an
+event that your webhook is subscribed to occurs, Hanko will send an HTTP POST request with data about the event to the
+URL that you specified. If your application provides a publicly available HTTP endpoint listening for webhook deliveries
+at the configured callback URL, it can react and process webhook data.
+
+
+ ```mermaid
+ sequenceDiagram
+ participant A as Relying Party
+ participant B as Hanko
+
+ A->>B: Create webhook
+ B->>B: Event occurs
+ B->>A: HTTP POST to callback URL
+ A->>A: Parse webhook payload
+ A->>A: Validate event data
+ A->>A: Process event data
+ A-->>B: Acknowledge delivery
+ ```
+
+
+
+## Creating webhooks
+
+To create a webhook:
+
+
+
+ Log in to the [Hanko Cloud Console](https://cloud.hanko.io), select your organization and project and navigate to
+ `Settings > Webhooks`.
+
+
+ Click `Create webhook`. Enter a callback URL and select the events that you want to subscribe to.
+ See [Events](#events) for more information on the events you can subscribe to.
+
+
+
+You are free to choose whether you create a single webhook with one HTTP endpoint processing multiple events or
+multiple webhooks with more than one HTTP endpoint handling specific events or event groups.
+
+## Handling webhook deliveries
+
+To handle webhook deliveries:
+
+
+
+ In order to handle webhook deliveries, your application must provide a publicly available HTTP POST endpoint
+ listening for webhook deliveries at the configured callback URL.
+
+
+ Once you have an endpoint set up you need to extract the webhook [event payload](#event-payload). It
+ contains information about which event occurred and the actual event data encoded in a JSON Web Token (JWT).
+
+
+ To ensure that your application only processes webhook deliveries that were sent by Hanko and to ensure that
+ the delivery has not been tampered with, you should validate the JWT's signature before processing the delivery
+ further. You can use the JSON Web Key Set available through your tenant's
+ [.well-known](/api-reference/public/well-known/get-json-web-key-set) endpoint to do so.
+
+
+ The JWT contained in the webhook payload must be parsed to obtain the event
+ data from the token payload. The structure of the event data may differ from event type to event type.
+ For more information, see [Event types and token payloads](#event-types-and-token-payloads).
+
+
+ Once you have extracted the event data from the token you can process it according to your application's needs.
+
+
+
+
+This example uses [express](https://www.npmjs.com/package/express) and the [jose](https://www.npmjs.com/package/jose)
+package to parse and verify JWTs.
+
+```shell
+npm install express jose
+```
+
+The example assumes usage of a single HTTP endpoint for all event types but you could just as well configure
+multiple webhooks and use multiple HTTP endpoints.
+
+```javascript
+// These are the dependencies you should have installed for
+// this example.
+const express = require('express');
+const { createRemoteJWKSet, jwtVerify } = require('jose');
+
+const app = express();
+
+// Middleware for parsing requests with a JSON payload.
+app.use(express.json());
+
+// Step 1: This defines a POST endpoint at the `/webhook` path.
+// This path should match the path portion of the URL that you
+// specified for the callback URL when you created the webhook.
+// Once you edit a webhook by updating the callback URL of your
+// webhook, you should change this to match the path portion of
+// the updated URL for your webhook.
+app.post('/webhook', async (req, res) => {
+ // Step 2: Extract the event and token from the request body.
+ // You could use the event type to branch and apply
+ // logic/code for specific event types.
+ // This example assumes one endpoint for all event types so
+ // extracting the `event` property may lead to an unused
+ // variable.
+ const { event, token } = req.body;
+
+ try {
+ // This would likely come from your environment/config.
+ // You can always find your tenant ID on the dashboard
+ // for your project in the Hanko Cloud Console.
+ const tenantId = 'your-tenant-id';
+
+ // See also the API reference:
+ // http://docs.hanko.io/api-reference/public/well-known/get-json-web-key-set
+ const jwksUrl = `https://${tenantId}.hanko.io/.well-known/jwks.json`;
+
+ // Step 3 + 4: Fetch the JWKS of your Hanko tenant, verify
+ // the token signature using the JWKS and extract the
+ // payload.
+ const jwks = createRemoteJWKSet(new URL(jwksUrl));
+ const { payload } = await jwtVerify(token, jwks);
+
+ console.log('Decoded token payload:', payload);
+
+ // Step 6: Do further processing according to your
+ // application's needs.
+
+ } catch (error) {
+ console.error('Error processing the token:', error.message);
+ }
+
+ // Your endpoint should respond with a 2XX response within 30 seconds
+ // of receiving a webhook delivery to indicate that the delivery was
+ // successfully received. If your server takes longer than that to
+ // respond, then Hanko terminates the connection and considers the
+ // delivery a failure.
+ res.sendStatus(202);
+});
+
+// Start the Express server
+const PORT = 3000;
+app.listen(PORT, () => {
+ console.log(`Server is running on http://localhost:${PORT}`);
+});
+
+```
+
Your server **must** return the complete certificate chain otherwise the request will fail.
+## Editing/removing webhooks
+
+You can edit or remove configured webhooks. To do so:
+
+
+
+ Log in to [Hanko Cloud](https://cloud.hanko.io), select your organization and project and navigate to
+ `Settings > Webhooks`.
+
+
+ Locate the desired webhook and click on the three dots (`...`). Select `Edit` to change either the callback URL
+ of the webhook or the events to subscribe to. Select `Delete` to remove the webhook entirely.
+
+
+
## Events
-When a webhook is triggered it will send you a **JSON** body which contains the event and a jwt.
-The JWT contains 2 custom claims:
-* **data**: contains the whole object for which the change was made. (e.g.: the whole user object when an email or user is changed/created/deleted)
-* **evt**: the event for which the webhook was triggered
+There are different types of events you can subscribe to. The event type determines the contents of the event payload
+(i.e. the body content of the request to your callback URL in response to an event occurrence).
-A typical webhook event looks like:
+### Event payload
+
+The structure of the event payload is the same across all event types. It contains the event type and the event data in the form of a JSON Web
+Token (JWT).
+
+
+
+ ```json user.create
+ {
+ "token": "eyJhbGciOiJSUzI1NiIsImtpZCI6...",
+ "event": "user.create"
+ }
+ ```
+
+
+
+ The JWT that contains the actual webhook event data. It is a JSON Web Signature (JWS). Webhook recipients
+ should verify the signature to ensure that the webhook deliveries were sent by Hanko and have not been
+ tampered with.
+
+
+
+ The event that triggered this webhook
+
+
+
+
+### Event types and token payloads
+
+Events are structured hierarchically with some events subsuming the occurrence of multiple ("sub")-events. These
+types of events do not actually appear as the value for the `event` property in the webhook event payload. Subscribing
+to these types of events when creating a webhook is a convenient way to group certain event types and allows you to
+structure your callback endpoints around these groups.
+
+A webhook's event data is encoded as a JWT in the webhook's callback request body. You need to parse the token
+to access the token's payload which contains the actual event data (see
+[Handling webhook deliveries](#handling-webhook-deliveries) for an example).
+
+#### user
+
+Subscribing to this event implies subscription to the following events:
+[`user.create`](#user-create),
+[`user.delete`](#user-delete),
+[`user.udpate.email.create`](#user-update-email-create),
+[`user.update.email.delete`](#user-update-email-delete),
+[`user.update.email.primary`](#user-update-email-primary),
+[`user.update.username.create`](#user-update-username-create),
+[`user.update.username.delete`](#user-update-username-delete),
+[`user.update.username.update`](#user-update-username-update)
+
+#### user.create
+
+This event is triggered when a new user is created.
+
+
+
+
+
+
+
+
+
+
+#### user.delete
+
+This event is triggered when a user is deleted.
+
+
+
+
+
+
+
+
+
+
+#### user.update
+
+Subscribing to this event implies subscription to the following events:
+[`user.udpate.email.create`](#user-update-email-create),
+[`user.update.email.delete`](#user-update-email-delete),
+[`user.update.email.primary`](#user-update-email-primary),
+[`user.update.username.create`](#user-update-username-create),
+[`user.update.username.delete`](#user-update-username-delete),
+[`user.update.username.update`](#user-update-username-update)
+
+
+#### user.update.email
+
+Subscribing to this event implies subscription to the following events:
+[`user.udpate.email.create`](#user-update-email-create),
+[`user.update.email.delete`](#user-update-email-delete),
+[`user.update.email.primary`](#user-update-email-primary)
+
+#### user.update.email.create
+
+This event is triggered when an email is created for a user.
+
+
+
+
+
+
+
+
+
+
+#### user.update.email.delete
+
+This event is triggered when a user's email is deleted.
+
+
+
+
+
+
+
+
+
+
+
+#### user.update.email.primary
+
+This event is triggered when a user's email is set as the primary email.
+
+
+
+
+
+
+
+
+
+
+#### user.update.username
+
+Subscribing to this event implies subscription to the following events:
+[`user.update.username.create`](#user-update-username-create),
+[`user.update.username.delete`](#user-update-username-delete),
+[`user.update.username.update`](#user-update-username-update)
+
+#### user.update.username.create
+
+This event is triggered when a username is created for a user.
+
+
+
+
+
+
+
+
+
-```json
-{
- "token": "the-jwt-token-which-contains-the-data",
- "event": "name of the event"
-}
-```
-## Event Types
+#### user.update.username.delete
-Hanko sends webhooks for the following event types:
+This event is triggered when a user's username is deleted.
-| Event | Triggers on |
-|---------------------------|----------------------------------------------------------------------------------------------------|
-| user | user creation, user deletion, user update, email creation, email deletion, change of primary email |
-| user.create | user creation |
-| user.delete | user deletion |
-| user.update | user update, email creation, email deletion, change of primary email |
-| user.update.email | email creation, email deletion, change of primary email |
-| user.update.email.create | email creation |
-| user.update.email.delete | email deletion |
-| user.update.email.primary | change of primary email |
-| email.send | an email was send |
+
+
+
+
+
+
+
+
-As you can see, events can have subevents. You are able to filter which events you want to receive by either selecting
-a parent event when you want to receive all subevents or selecting specific subevents.
+#### user.update.username.update
-## Restrictions
+This event is triggered when a user's username is updated.
-Due to security concerns there are some usage restrictions for webhooks in place:
+
+
+
+
+
+
+
+
-* A webhook will be disabled after 30 days without usage. In this scenario usage describes the successful triggering of events
-This mechanism can be disabled by setting `webhooks.allow_time_expiration` to `false`
+#### email.send
-* A webhook will also be disabled when our trigger mechanism is not successful. The mechanism will try 5 attempts of sending events before disabling a webhook. A trigger is unsuccessful when:
- * your callback URL is not reachable due to network errors or a wrong url
- * your webhook endpoint returns HTTP Status codes >= 400
+This event is triggered when an email is sent. Subscribe to this event if you want
+to send customized emails instead of emails based on built-in templates.
+See [Custom Emails](/guides/custom-emails/email-delivery) for more information.
-The restrictions are not available for webhooks defined in the config file.
+
+
+
+
+
+
+
+
-## Data
-When a webhook is triggered it will send you a **JSON** body which contains the event and a jwt.
-The JWT contains 2 custom claims:
-* **data**: contains the whole object for which the change was made. (e.g.: the whole user object when an email or user is changed/created/deleted)
-* **evt**: the event for which the webhook was triggered
diff --git a/openapi-admin.yaml b/openapi-admin.yaml
index e8f99c3..c3d8ac1 100644
--- a/openapi-admin.yaml
+++ b/openapi-admin.yaml
@@ -1145,6 +1145,11 @@ components:
- user.update.email.create
- user.update.email.delete
- user.update.email.primary
+ - user.update.username
+ - user.update.username.create
+ - user.update.username.delete
+ - user.update.username.update
+ - email.send
DatabaseWebhook:
type: object
title: DatabaseWebhook
@@ -1196,6 +1201,11 @@ components:
- user.update.email.create
- user.update.email.delete
- user.update.email.primary
+ - user.update.username
+ - user.update.username.create
+ - user.update.username.delete
+ - user.update.username.update
+ - email.send
required:
- callback
- events
diff --git a/snippets/pro-feature-note.mdx b/snippets/pro-feature-note.mdx
new file mode 100644
index 0000000..282f570
--- /dev/null
+++ b/snippets/pro-feature-note.mdx
@@ -0,0 +1,3 @@
+
+ This feature is only available in the Pro or Enterprise [plan](https://www.hanko.io/pricing).
+
\ No newline at end of file
diff --git a/snippets/webhooks/email-send-example.mdx b/snippets/webhooks/email-send-example.mdx
new file mode 100644
index 0000000..2dbd33d
--- /dev/null
+++ b/snippets/webhooks/email-send-example.mdx
@@ -0,0 +1,25 @@
+```json
+{
+ "aud": [
+ "Test Service ABC"
+ ],
+ "data": {
+ "subject": "Use passcode 325139 to verify your email address",
+ "body_plain": "Enter the following passcode to verify your email address:\n\n325139\n\nThe passcode is valid for 5 minutes.",
+ "to_email_address": "test@example.com",
+ "delivered_by_hanko": false,
+ "language": "en",
+ "type": "passcode",
+ "data": {
+ "service_name": "Test Service ABC",
+ "otp_code": "325139",
+ "ttl": 300,
+ "valid_until": 1737128997
+ }
+ },
+ "evt": "email.send",
+ "exp": 1737128997,
+ "iat": 1737128697,
+ "sub": "hanko webhooks"
+}
+```
\ No newline at end of file
diff --git a/snippets/webhooks/email-send-properties.mdx b/snippets/webhooks/email-send-properties.mdx
new file mode 100644
index 0000000..ccf37fd
--- /dev/null
+++ b/snippets/webhooks/email-send-properties.mdx
@@ -0,0 +1,64 @@
+
+ The recipients the token is intended for
+
+
+
+
+ The subject line of the email
+
+
+ The plain text version of the email body
+
+
+ The HTML version of the email body (nullable)
+
+
+ The recipient’s email address
+
+
+ Indicates whether the email was delivered by Hanko (`true`) or not (`false`).
+
+
+ Deprecated, rely on `language` instead.
+
+ The preferred language for the email content.
+
+
+ The preferred language for the email content.
+
+
+ The type of the email being sent.
+
+ Available options: `login`, `email_login_attempted`, `email_registration_attempted`, `email_verification`,
+ `recovery`
+
+
+ Additional data.
+
+
+ The name of the service set in the console as the project name
+
+
+ The passcode the user can use to log in
+
+
+ The validity duration of the passcode in seconds
+
+
+ The Unix timestamp indicating when the passcode expires
+
+
+
+
+
+
+ The event that triggered the webhook containing this data
+
+
+ The expiration date of the token
+
+
+ The time at which the token was issued
+
+
+
\ No newline at end of file
diff --git a/snippets/webhooks/user-payload-example.mdx b/snippets/webhooks/user-payload-example.mdx
new file mode 100644
index 0000000..830823f
--- /dev/null
+++ b/snippets/webhooks/user-payload-example.mdx
@@ -0,0 +1,81 @@
+```json
+{
+ "aud": [
+ "Test Service ABC"
+ ],
+ "data": {
+ "created_at": "2025-01-15T12:57:56.724052Z",
+ "emails": [
+ {
+ "id": "d31be36d-08d7-409f-8437-1920628e6e51",
+ "address": "test@example.com",
+ "is_verified": true,
+ "is_primary": true,
+ "created_at": "2025-01-15T13:57:56.72784Z",
+ "updated_at": "2025-01-15T13:57:56.72801Z"
+ }
+ ],
+ "id": "42fbd0dc-28fb-4144-892c-c2c4a0f8f5d8",
+ "identities": [
+ {
+ "id": "b3af92c5-414c-4c6b-a3ea-82ee263badef",
+ "provider_id": "123456abcd",
+ "provider_name": "testprovider",
+ "email_id": "d31be36d-08d7-409f-8437-1920628e6e51",
+ "created_at": "2025-01-17T13:40:11Z",
+ "updated_at": "2025-01-17T13:40:13Z"
+ }
+ ],
+ "otp": {
+ "id": "a7efd1ee-d7b2-440e-9284-625e06931745",
+ "created_at": "2025-01-17T13:39:29.081428Z"
+ },
+ "password": {
+ "id": "6ec87b0c-67db-42ef-9adb-d106734bde02",
+ "created_at": "2025-01-15T13:57:56.735651Z",
+ "updated_at": "2025-01-15T13:57:56.735651Z"
+ },
+ "updated_at": "2025-01-15T13:57:56.724255Z",
+ "username": {
+ "id": "61580d7d-0c11-4c25-bfca-ace21a14cc01",
+ "username": "testmakker",
+ "created_at": "2025-01-15T14:45:00.293001Z",
+ "updated_at": "2025-01-17T13:46:41.700373Z"
+ },
+ "webauthn_credentials": [
+ {
+ "id": "eaYxbrFQJjl5dW5SAr0KznEmHwAen8HUAiaKN9ijsDY",
+ "public_key": "pQECAyYgASFYIMq-SVnCDGIJjK2TAJyEQyXNtOw7x_MuEVUQuW80-AOcIlggyEcR_v5C8PuhrThwgx2urmRqviIb7dyXmGr3oyWk2rU",
+ "attestation_type": "packed",
+ "aaguid": "70a4ab68-d027-451a-9c86-3b8fd8414f68",
+ "last_used_at": "2025-01-17T12:38:28.698563Z",
+ "created_at": "2025-01-17T12:38:28.698563Z",
+ "transports": [
+ "usb"
+ ],
+ "backup_eligible": false,
+ "backup_state": false,
+ "mfa_only": true
+ },
+ {
+ "id": "BPtYkS1prrGu1owU3StJwWM5uYtVoD1-h4N_rPHrB84",
+ "public_key": "pQECAyYgASFYILo4i3yC0V2kciBHL96EOx08h32CXXIFnuUmggHOhkGvIlggQFIp4CeJhzGpCiTNuQQoyiKV7oMLYxM549ctLJXJkZ0",
+ "attestation_type": "packed",
+ "aaguid": "649b9062-5892-4223-832b-921c5bce5827",
+ "last_used_at": "2025-01-17T12:39:06.718171Z",
+ "created_at": "2025-01-17T12:39:06.718171Z",
+ "transports": [
+ "usb"
+ ],
+ "backup_eligible": false,
+ "backup_state": false,
+ "mfa_only": false
+ }
+ ]
+ },
+ "evt": "", // the corresponding event type
+ "exp": 1737118303,
+ "iat": 1737118003,
+ "sub": "hanko webhooks"
+}
+```
\ No newline at end of file
diff --git a/snippets/webhooks/user-payload-properties.mdx b/snippets/webhooks/user-payload-properties.mdx
new file mode 100644
index 0000000..2b8febb
--- /dev/null
+++ b/snippets/webhooks/user-payload-properties.mdx
@@ -0,0 +1,115 @@
+
+ The recipients the token is intended for
+
+
+
+
+ The ID of the user
+
+
+ Registered WebAuthn credentials (passkeys and security keys) of the user
+
+
+ The ID authenticator that created the credential
+
+
+ Format in which the signature is represented and the various contextual
+ bindings are incorporated into the attestation statement by the authenticator
+
+
+ Indicates whether the credential may be backed up in some fashion such that they may become present
+ on an authenticator other than their generating authenticator
+
+
+ Indicates whether this credential is backed up or not
+
+
+ The time of creation of the credential
+
+
+ The ID of the credential
+
+
+ Indicates when the credential was lst used
+
+
+ The public key of the credential (Base64URL string)
+
+
+ Communication methods/protocols used to create the credential
+
+
+ Indicates whether this is an MFA credential (security key) or a first factor credential
+ (passkey)
+
+
+
+
+ The username of the user
+
+
+ Time of creation of the user
+
+
+ Time of last update of the user
+
+
+ Representation of the password credential of the user
+
+
+ The ID of the password credential
+
+
+ Time of creation of the password credential
+
+
+ Time of last update of the password credential
+
+
+
+
+
+
+ The ID of the identity
+
+
+ The ID of the user at the third party provider
+
+
+ The name of the third party provider
+
+
+ The ID of the email the identity is related to
+
+
+ Time of creation of the identity
+
+
+ Time of last update of the identity
+
+
+
+
+ MFA OTP credential of the user
+
+
+ ID of the OTP credential
+
+
+ Time of creation of the OTP credential
+
+
+
+
+
+
+ The event that triggered the webhook containing this data
+
+
+ The expiration date of the token
+
+
+ The time at which the token was issued
+
+
+
\ No newline at end of file