openapi: 3.0.0
servers:
  - url: https://YOUR_DOMAIN
    description: Server URL
tags:
  - name: Authentication
    description: |
      Most endpoints in the Identity API require an access token.

      > **Note**: Please, refer to our [Authentication flows](https://developer.reachfive.com/docs/flows.html) to make sure you implement the most secure flow for your requirements.

      # Security Schemes

      <SecurityDefinitions>
  - name: Login/Signup
  - name: SSO
  - name: User Profile
  - name: Phone number
  - name: Email
  - name: MFA
    x-displayName: "Multi-factor Authentication"
    description: |
      Multi-factor Authentication (MFA) requires users to provide two or more verification factors to get access to a resource such as an application, online account, or when making a payment.
      It is an important component of a strong customer identity and access management policy particularly when payments are involved.

      > **The Step Up Flow**
      > - [startPhoneNumberRegistration](#operation/startPhoneNumberRegistration)
      > - [verifyPhoneNumberRegistration](#operation/verifyPhoneNumberRegistration)

      **OR**

      > - [startEmailRegistration](#operation/startEmailRegistration)
      > - [verifyEmailRegistration](#operation/verifyEmailRegistration)

      **THEN**

      > - [listCredentials](#operation/listCredentials) -- ensures MFA credentials are present on a user profile
      > - [stepup](#operation/stepup)
      > - [startPasswordlessFlow MFA](#operation/startPasswordlessFlow)
      > - [verifyPasswordlessPost MFA](#operation/verifyPasswordlessPost)
  - name: Password
  - name: Passwordless
  - name: FIDO
  - name: Events
  - name: Grants
    x-displayName: "Grants"
    description: |
      View and manage authorizations to third-party sites.

      **Note**: Users must be connected with a first-party access token. Otherwise, see the [Management API](https://developer.reachfive.com/api/management.html#tag/Grants).
  - name: AuthDescription
    x-displayName: "Overview"
    description: |-
      Most endpoints in the Identity API require an access token.

      > **Note**: Please, refer to our [Authentication flows](https://developer.reachfive.com/docs/flows.html) to make sure you implement the most secure flow for your requirements.
x-tagGroups:
  - name: Authentication
    tags:
      - AuthDescription
      - OAuth
      - Login/Signup
      - Passwordless
      - FIDO2
      - MFA
  - name: User management
    tags:
      - Email
      - Grants
      - Password
      - Phone number
      - User Profile
  - name: Miscellaneous
    tags:
      - Events
info:
  description: |
    # Introduction
    Welcome to the documentation reference for the ReachFive REST Identity API!

    This API is documented in **OpenAPI standard**, and rendered using [ReDoc](https://github.com/Redocly/redoc).

    If something is missing, incorrect, or unclear, reach us at <documentation@reach5.co>.


    # Environment
    Endpoints are available at `https://{YOUR_DOMAIN}{ENDPOINT}`.

    Find how to obtain your ReachFive domain [here](https://developer.reachfive.com/docs/console.html#access-your-reachfive-console).

    # First and third-party clients

    Except if you want to implement OpenID as a Service (OaaS), **always** use first-party clients.

    In the context of OaaS, third-party clients are used to make calls to:

    - [/oauth/authorize](#operation/authorizeUser)
    - [/oauth/token](#operation/retrieveAccessToken)

    They **cannot** be used with other endpoints.

    If you to call any other endpoint with a third-party client, you will get this error:

    ```
    {
      "error_id": "9z8h7JmIHU",
      "error_description": "Not a first party identity client",
      "error_message_key": "error.client.notFirstParty",
      "error": "unauthorized_client",
      "error_user_msg": "Not a first party identity client"
    }
    ```

    # Errors

    The API uses standard HTTP status codes to indicate the success or failure of the API call.

    |Code   |Notes                                                                                           |
    |-------|------------------------------------------------------------------------------------------------|
    |`2xx`  | Success codes; indicates the request worked as expected.                                  |
    |`4xx`  | Error codes; indicates a client (user) error and more information is provided. See the example below.       |
    |`5xx`  | Server error codes; indicates an error with one of ReachFive's servers.                        |

    The error body is JSON and contains the following fields:

    ```
    {
        "error_id": "2hNBbvYecw",
        "error_description": "Invalid email or password",
        "error_message_key": "error.invalidEmailOrPassword",
        "error": "invalid_grant",
        "error_user_msg": "Invalid email or password"
    }
    ```

    - `error_id` is the auto-generated ID of the error.
    - `error_description` is the default error description.
    - `error_message_key` is the unique key that can be used to bind specific behaviors on other services. This also acts as the `i18n` translation key.
    - `error` is the error type. See the Error Types table below for more details.
    - `error_user_msg` is a user-friendly error message that should be used in the UI. This can be overriden in certain configurations.

    |Error Type|
    |----------|
    |`server_error`|
    |`invalid_request`|
    |`invalid_state`|
    |`invalid_grant`|
    |`invalid_scope`|
    |`insufficient_scope`|
    |`access_denied`|
    |`origin_not_allowed`|
    |`ip_address_not_allowed`|
    |`missing_config`|
    |`invalid_config`|
    |`resource_not_found`|
    |`temporarily_unavailable`|
    |`unsupported_grant_type`|
    |`unsupported_algorithm`|
    |`invalid_client`|
    |`unauthorized_client`|
    |`login_required`|
    |`email_already_exists`|
    |`external_id_already_exists`|
    |`phone_number_already_exists`|
    |`lite_profile_invalid_identifiers`|
    |`lite_profile_missing_profile`|
    |`password_too_weak`|
    |`rate_limit_reached`|
    |`webhook_host_unreachable`|
    |`webhook_invalid_response`|

    **Tip**: For more information, see the individual endpoints.

    # User locale

      For any endpoint in this specification that generates an email or SMS, you can pass the `Custom-Locale` attribute as a header parameter.

      ```sh
      Custom-Locale: fr-FR
      ```

    # User language

      For any endpoint in this specification that pass the `email` field in the request payload:

      - If you are using the ReachFive SDK, the user `lang` attribute is taken from the browser language.
      - If you are calling ReachFive API endpoints **directly**, the `lang` attribute is taken from the information sent in the [Accept-Language header](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept-Language).

    # Security Schemes
    <SecurityDefinitions />
  version: "latest"
  title: ReachFive Identity API
  termsOfService: https://www.reachfive.com/terms-policies
  contact:
    name: Email
    email: documentation@reach5.co
    # url: http://www.reachfive.com/contact
  x-logo:
    url: _images/identity-api.png
    altText: OpenAPI Specification
  license:
    name: Apache 2.0
    url: http://www.apache.org/licenses/LICENSE-2.0.html
# externalDocs:
#   description: Find out how to create Github repo for your OpenAPI spec.
#   url: https://github.com/Rebilly/generator-openapi-repo

# list of Identity Endpoints: https://app.asana.com/0/1142049698926411/1145782625194938 (as of 2.20)

paths:
  /oauth/token:
    # Get access token (auth code): https://developers.reachfive.com/api/identity-rest/#authorization-code
    # Refresh access token: https://developers.reachfive.com/api/identity-rest/#refresh-token
    post:
      summary: Retrieve an access token (authorization code flow)
      tags:
        - OAuth
      description: |
        Retrieve an access token (authorization code flow)

        **Session cookies**:
        If enabled for a First-party Identity client in the ReachFive console, it's possible to retrieve the SSO session cookie as part of the response.

        **Tip**: For more information, see [ReachFive Clients](https://developer.reachfive.com/docs/clients.html).

        **User account protection**:
        If a user reaches the configured login attempt threshold, they are locked out for the time you have configured in the ReachFive console.

        **Tip**: For more information see [Account lockout: failed login attempts](https://developer.reachfive.com/docs/user-account-lockout.html) on the main docs section.
      operationId: retrieveAccessToken
      parameters:
        - $ref: "#/components/parameters/session_cookie"
      requestBody:
        description: ""
        required: true
        content:
          application/json:
            schema:
              oneOf:
                - $ref: "#/components/schemas/retrieveAccessToken"
                - $ref: "#/components/schemas/retrieveAccessTokenWithRefresh"
      responses:
        "200":
          description: A response containing the access token.
          content:
            application/json:
              schema:
                type: object
                properties:
                  access_token:
                    description: The access token. Gains access to resource.
                    type: string
                    example: tb37Sz...h3eh6q
                  id_token:
                    description: The ID token. Contains identity information.
                    type: string
                    example: eEoQAi...yJ04ae
                  refresh_token:
                    description: |
                      The refresh token. Long-lived token that obtains renewed access token(s).

                      > **Note**:
                      >
                      > This is only possible when the `offline_access` scope is requested.
                    type: string
                    example: djnxBN...eXbEbL
                  token_type:
                    description: Specifies the type of token.
                    type: string
                    example: Bearer
                  expires_in:
                    description: Specifies the expiry time in seconds.
                    type: integer
                    example: 86400
                  provider_name:
                    description: The name of the provider. This is only received if the `require_provider_token` boolean is set to `true` in the request payload.
                    type: string
                    example: "kakaotalk"
                  provider_access_token:
                    description: The access token for the specific provider. This is only received if the `require_provider_token` boolean is set to `true` in the request payload.
                    type: string
                    example: "djnxBN...eXbEbL"
        "400":
          description: Bad request
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorFields"
              examples:
                Unsupported grant type:
                  value:
                    error_id: LVigUvj6S8
                    error_description: Unsupported grant type
                    error: unsupported_grant_type
                Invalid grant:
                  summary: Invalid redirect uri
                  value:
                    error_id: b07jNBlUdp
                    error_description: Invalid redirect uri
                    error: invalid_grant
        "401":
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorFields"
              examples:
                error:
                  summary: Unauthorized
                  value:
                    error_id: b07jNBlUdp
                    error_description: Authorization code invalid or expired
                    error: invalid_grant
      x-codeSamples:
        - lang: "cURL"
          source: |
            curl --request POST \
              --url https://YOUR_DOMAIN/oauth/token \
              --header 'Content-Type: application/json' \
              --data '{
                  "grant_type": "authorization_code",
                  "client_id": "slNIt...yKzQM",
                  "client_secret": "dYEa3...3z2m2",
                  "code": "XpcgV...5sSY5",
                  "redirect_uri": "https://example.com/callback"
            }'
        # - lang: 'HTTP'
        #   source: |
        #     POST /oauth/token HTTP/1.1
        #     Host: https://YOUR_DOMAIN
        #     Content-Type: application/json
        # - lang: 'JavaScript'
        #   source: |
        #     var request = require("request");

        #     var options = { method: 'POST',
        #       url: 'https://YOUR_DOMAIN/oauth/token',
        #       headers: { 'content-type': 'application/x-www-form-urlencoded' },
        #       form:
        #       { grant_type: 'authorization_code',
        #         client_id: 'YOUR_CLIENT_ID',
        #         client_secret: 'YOUR_CLIENT_SECRET',
        #         code: 'AUTHORIZATION_CODE',
        #         redirect_uri: 'https://YOUR_APP/callback' }
        #       };

        #     request(options, function (error, response, body) {
        #       if (error) throw new Error(error);

        #       console.log(body);
        #     });
  /oauth/revoke:
    post:
      summary: Revoke a token
      tags:
        - OAuth
      description: |
        Use this endpoint to invalidate (revoke) a refresh or access token.

        - **refresh_token**: When a refresh token is revoked, all the tokens associated with the user and `client_id` are revoked.
        - **access_token**: When an access token is revoked, only the tokens associated with the same specific grant are revoked.
      operationId: revokeToken
      requestBody:
        description: ""
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                client_id:
                  description: Your client ID.
                  type: string
                  example: slNIt...yKzQM
                client_secret:
                  description: Your client Secret. Required if your Client's authorization method is POST.
                  type: string
                  example: dYEa3...3z2m2
                token:
                  description: |
                    The Token to revoke.

                    > **Note**: This can be either an `access_token` or a `refresh_token`.
                  type: string
                  example: XpcgV...5sSY5
                token_type_hint:
                  description: |
                    An optional string where you can hint at what type of token to differentiate between access and refresh.

                    > **Note**: The only meaningful values are `access_token` and `refresh_token`.
                  type: string
                  example: access_token
              required:
                - client_id
                - client_secret
                - token
      responses:
        "204":
          description: No Content.
      x-codeSamples:
        - lang: "cURL"
          source: |
            curl --request POST \
              --url https://DOMAIN/oauth/revoke \
              --header 'Content-Type: application/json' \
              --data '{
                  "client_id": "slNIt...yKzQM",
                  "client_secret": "dYEa3...3z2m2",
                  "token": "XpcgV...5sSY5"
            }'
        # - lang: 'HTTP'
        #   source: |
        #     POST /oauth/revoke HTTP/1.1
        #     Host: https://YOUR_DOMAIN
        #     Content-Type: application/json
        # - lang: 'JavaScript'
        #   source: |
        #     var request = require("request");

        #     var options = { method: 'POST',
        #       url: 'https://YOUR_DOMAIN/oauth/revoke',
        #       headers: { 'content-type': 'application/x-www-form-urlencoded' },
        #       form:
        #       { client_id: 'YOUR_CLIENT_ID',
        #         client_secret: 'YOUR_CLIENT_SECRET',
        #         refresh_token: 'REFRESH_TOKEN_TO_REVOKE' }
        #       };

        #     request(options, function (error, response, body) {
        #       if (error) throw new Error(error);

        #       console.log(body);
        #     });
  /oauth/authorize:
    # https://docs.google.com/document/d/1VKs12nRa7Edxv0BYAdqTi3WgId4ccNhYaoaB0UggNxg/edit#
    get:
      summary: Authorize a user
      tags:
        - OAuth
      description: |
        This endpoint supports different authorization flows:

        1. Redeeming a one-time use authentication token (`tkn`) following an authentication flow (e.g., password auth, Webauthn).
        2. Starting a Social Login authentication flow.
        3. Linking a social account to an existing authenticated profile.
        4. Starting an [OaaS flow](https://developer.reachfive.com/docs/oaas.html).
        5. Session refresh (silent authentication).
           - Orchestrated 1st-party Identity clients.
              - If `prompt=login`, the user is forced to reauthenticate and is redirected to the defined Login URL regardless of their current authentication status.
              - If `prompt=none`, the flow becomes a silent authentication, the user is redirected to the defined Login URL (if unauthenticated) and to the defined redirect URI
              if successfully and currently authenticated. The same occurs if `prompt` is not passed as a query parameter.
           - Non-orchestrated 1st-party Identity clients.
              - Session refreshes for non-orchestrated clients are **always** silent.
              - If a user is not already logged in, they are redirected to the defined redirect URI and forced to login.
              > Example for `response_type=code`:
              >
              > `{{redirect_uri}}?error=login_required` (as a query parameter)
              > 
              > Example for `response_type=token` or `response_type=id_token`:
              >
              > `{{redirect_uri}}#error=login_required` (as a fragment)

        **Tip:** The cURL examples in the *Request samples* panel correspond to the numbers here.
      operationId: authorizeUser
      parameters:
        - $ref: "#/components/parameters/session_cookie"
        - $ref: "#/components/parameters/client_id_auth"
        - $ref: "#/components/parameters/scope"
        - $ref: "#/components/parameters/response_type"
        - $ref: "#/components/parameters/redirect_uri"
        - $ref: "#/components/parameters/code_challenge"
        - $ref: "#/components/parameters/code_challenge_method"
        - $ref: "#/components/parameters/max_age"
        - $ref: "#/components/parameters/provider"
        - $ref: "#/components/parameters/access_token_auth"
        - $ref: "#/components/parameters/origin"
        - $ref: "#/components/parameters/tkn"
        - $ref: "#/components/parameters/prompt"
      responses:
        "303":
          description: "Redirects to the URL specified as redirect_uri"
        "400":
          description: "Required parameters are missing"
      x-code-samples:
        - lang: "cURL 1"
          source: |
            # Exchanging a mandatory token (`tkn`) to be authorized.
            curl --request GET \
              --url https://YOUR_DOMAIN/oauth/authorize?\
                client_id=sg48C...9j1H& \
                scope=openid%20email%20phone%20profile& \
                response_type=code& \
                redirect_uri=https://example.com/redirect& \
                tkn=ol38F...ej3l& \
                code_challenge=lhoa2Ow...oeK1t8U& \
                code_challenge_method=S256& \
                origin=ORIGIN& \
                max_age=500& \
                prompt=login \
              --header 'Content-Type: application/json' \
              --header 'Authorization: Bearer eyJ0eX...ll4Q2NT'
        - lang: "cURL 2"
          source: |
            # Starting a Social Login authentication flow.
            curl --request GET \
              --url https://YOUR_DOMAIN/oauth/authorize?\
                client_id=sg48C...9j1H& \
                scope=openid%20email%20phone%20profile& \
                response_type=code& \
                redirect_uri=https://example.com/redirect& \
                provider=PROVIDER_NAME& \
                origin=ORIGIN& \
                max_age=500& \
                prompt=login \
              --header 'Content-Type: application/json' \
              --header 'Authorization: Bearer eyJ0eX...ll4Q2NT'
        - lang: "cURL 3"
          source: |
            # Linking a social account to an existing authenticated profile.
            curl --request GET \
              --url https://YOUR_DOMAIN/oauth/authorize?\
                client_id=sg48C...9j1H& \
                scope=openid%20email%20phone%20profile& \
                response_type=code& \
                redirect_uri=https://example.com/redirect& \
                provider=PROVIDER_NAME& \
                access_token=k3hUd...MN42& \
                origin=ORIGIN& \
                max_age=500& \
                prompt=login \
              --header 'Content-Type: application/json' \
              --header 'Authorization: Bearer eyJ0eX...ll4Q2NT'
        - lang: "cURL 4"
          source: |
            # Starting an OaaS flow.
            curl --request GET \
              --url https://YOUR_DOMAIN/oauth/authorize?\
                client_id=sg48C...9j1H& \
                scope=openid%20email%20phone%20profile& \
                redirect_uri=REDIRECT_URI& \
                response_type=id_token \
              --header 'Content-Type: application/json' \
              --header 'Authorization: Bearer eyJ0eX...ll4Q2NT'
        - lang: "cURL 5"
          source: |
            # Silent authentication.
            curl --request GET \
              --url https://YOUR_DOMAIN/oauth/authorize?\
                client_id=sg48C...9j1H& \
                scope=openid%20email%20phone%20profile& \
                redirect_uri=REDIRECT_URI& \
                response_type=id_token \
                prompt=none \
              --header 'Content-Type: application/json' \
              --header 'Authorization: Bearer eyJ0eX...ll4Q2NT'
    # post:
  # /consent:
  # /.well-known/openid-configuration:
  # /.well-known/apple-developer-domain-association.txt:
  # /jwks.json:
  /identity/v1/sso/data:
    # https://app.asana.com/0/1128361015731305/1161956488230322 !!!
    get:
      # same as Get session info (checksession)
      summary: Get SSO Data
      # tags:
      #   - SSO
      description: Get session Info from SSO.
      operationId: getSSOData
      parameters:
        - in: query
          name: client_id
          required: true
          schema:
            type: string
          description: ReachFive client ID
        - in: cookie
          name: SESSION
          required: false
          schema:
            type: string
          description: Session cookie
      responses:
        "200":
          description: OK
          content:
            application/json:
              example:
                value:
                  {
                    "country_code": "FR",
                    "password_policy":
                      {
                        "minLength": 8,
                        "minStrength": 2,
                        "specialCharacters": null,
                        "uppercaseCharacters": null,
                        "lowercaseCharacters": null,
                        "digitCharacters": null,
                      },
                    "social_providers": ["google"],
                    "custom_fields":
                      [
                        {
                          "path": "selectionchiffre",
                          "scope": ["full_write"],
                          "name": "selectionchiffre",
                          "data_type": "select",
                          "id": "selectionchiffre",
                          "selectable_values":
                            [
                              {
                                "translations": [],
                                "label": "chiffre1",
                                "value": "1",
                              },
                              {
                                "translations": [],
                                "label": "chiffre2",
                                "value": "2",
                              },
                              {
                                "translations": [],
                                "label": "chiffre3",
                                "value": "3",
                              },
                            ],
                        },
                      ],
                    "scope": "address email events full_write offline_access openid phone profile",
                    "consents":
                      [
                        {
                          "translations": [],
                          "description": "",
                          "title": "Newsletter",
                          "key": "newsletter",
                          "consent_type": "opt-in",
                        },
                      ],
                    "language": "en",
                    "pkce_enabled": true,
                    "sso": true,
                  }
      x-codeSamples:
        - lang: "cURL"
          source: |
            curl --request GET \
              --url https://YOUR_DOMAIN/identity/v1/sso/data?\
                client_id=sg48C...9j1H \
              --header 'Content-Type: application/json' \
              --header 'Authorization: Bearer eyJ0eX...ll4Q2NT'
  /identity/v1/me:
    get:
      # Check separate Authorization section is present (user is identified with access token)
      summary: Get a user profile
      tags:
        - User Profile
      description: |
        **Note**: The endpoint `/identity/v1/me` is deprecated.

        Use [/identity/v1/userinfo/](#operation/getUserProfile) wherever possible.
      operationId: getUserProfileMe
      deprecated: true
      parameters:
        - $ref: "#/components/parameters/Authorization"
        - in: query
          name: fields
          schema:
            type: string
            example: [id, given_name, family_name, email, birthdate] # https://github.com/Redocly/redoc/issues/1010
          allowReserved: true # https://github.com/Redocly/redoc/issues/1010
          description: Fields to retrieve. Defaults to `id`, `name`, `email`.
      responses:
        "200":
          description: OK
          content:
            application/json:
              example:
                {
                  "id": "AVqvOB58Fg6nZfQ0ZqXt",
                  "given_name": "John",
                  "family_name": "Doe",
                  "email": "john.doe@example.com",
                  "birthdate": "1983-11-13",
                }
      x-codeSamples:
        - lang: "cURL"
          source: |
            curl --request POST \
              --url https://YOUR_DOMAIN/identity/v1/me?\
                fields=id,given_name,family_name,email,birthdate \
              --header 'Content-Type: application/json' \
              --header 'Authorization: Bearer eyJ0eX...ll4Q2NT' \
              --data '{
                  "id": "AVqvOB58Fg6nZfQ0ZqXt",
                  "given_name": "John",
                  "family_name": "Doe",
                  "email": "john.doe@example.com",
                  "birthdate": "1983-11-13"
                }'
  /identity/v1/userinfo:
    get:
      # Check separate Authorization section is present (user is identified with access token)
      summary: Get a user profile
      tags:
        - User Profile
      description: |
        Retrieves the user profile information for the identity client.

        > **User language note**:
        > 
        > If you are using the ReachFive SDK, the user `lang` attribute is taken from the browser language. If you are calling ReachFive API endpoints **directly**, the `lang` attribute is taken from the information sent in the [Accept-Language header](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept-Language).
        > 
        > See [User language](#section/User-language) for more details.
      operationId: getUserProfile
      parameters:
        - $ref: "#/components/parameters/Authorization"
        - $ref: "#/components/parameters/fields"
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                type: object
              example:
                {
                  "id": "AVqvOB58Fg6nZfQ0ZqXt",
                  "given_name": "John",
                  "family_name": "Doe",
                  "email": "john.doe@example.com",
                  "birthdate": "1983-11-13",
                }
      x-codeSamples:
        - lang: "cURL"
          source: |
            curl --request POST \
              --url https://YOUR_DOMAIN/identity/v1/userinfo?\
                fields=id,given_name,family_name,email,birthdate\
              --header 'Content-Type: application/json' \
              --header 'Authorization: Bearer eyJ0eX...ll4Q2NT' \
              --data '{
                  "id": "AVqvOB58Fg6nZfQ0ZqXt",
                  "given_name": "John",
                  "family_name": "Doe",
                  "email": "john.doe@example.com",
                  "birthdate": "1983-11-13"
                }'
  /identity/v1/signup/data:
    post:
      summary: Get signup data with verification_code
      tags:
        - User Profile
      description: |
        Get lite profile information by using the `verification_code` received via email or SMS after a signup invitation.

        > Tip: See [signup-invitations](/openapi/management.html#operation/signupInvitation) to send signup invitations via email or SMS.
      operationId: getSignupDataPost
      requestBody:
        content:
          application/json:
            schema:
              oneOf:
                - $ref: "#/components/schemas/GetSignUpDataRequestBodyVerCode"
                - $ref: "#/components/schemas/GetSignUpDataRequestBodyToken"
      responses:
        "200":
          description: Successfully completed the signup flow with the `verification_code`.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ProfileFields"
      x-codeSamples:
        - lang: "cURL"
          source: |
            curl --request POST \
                 --url https://YOUR_DOMAIN/identity/v1/signup \
                 --header 'Content-Type: application/json' \
                 --data '{
                     "client_id": "IDENTITY_CLIENT_ID",
                     "verification_code": "882914",
                     "identifier": "+353875550002"
                   }'
    get:
      # Check separate Authorization section is present (user is identified with access token)
      summary: Get signup data
      tags:
        - User Profile
      description: |
        Get lite profile information by using the token received via email or SMS after a signup invitation.

        > Tip: See [signup-invitations](/openapi/management.html#operation/signupInvitation) to send signup invitations via email or SMS.

        > **User language note**:
        > 
        > If you are using the ReachFive SDK, the user `lang` attribute is taken from the browser language. If you are calling ReachFive API endpoints **directly**, the `lang` attribute is taken from the information sent in the [Accept-Language header](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept-Language).
        > 
        > See [User language](#section/User-language) for more details.
      operationId: getSignupData
      parameters:
        - in: query
          name: client_id
          required: true
          schema:
            type: string
          description: Your ReachFive client ID
        - in: query
          name: token
          required: true
          schema:
            type: string
          description: Token received after a signup invitation. Usable only once.

      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                type: object
                properties:
                  sub:
                    type: string
                    description: ReachFive user ID.
                  name:
                    type: string
                    description: Full user name.
                  givenName:
                    type: string
                    description: Given name(s) or first name(s).
                  familyName:
                    type: string
                    description: Surname(s) or last name(s).
                  middleName:
                    type: string
                    description: Middle name(s).
                  nickname:
                    type: string
                    description: Casual name that may or may not be the same as the given_name.
                  profile:
                    type: string
                    description: URL of one of the user’s profile page (usually a social provider’s page).
                  picture:
                    type: string
                    description: URL of one of the user’s profile picture. This URL refers to an image file (for example, a PNG, JPEG, or GIF image file).
                  email:
                    type: string
                    description: User’s primary email address.
                  email_verified:
                    type: boolean
                    description: |
                      `true` if the user’s email address has been verified.
                  gender:
                    type: string
                    description: User’s gender.
                  birthdate:
                    type: string
                    description: User’s birthdate, represented as an ISO 8601 YYYY-MM-DD format.
                  phoneNumber:
                    type: string
                    description: User’s primary phone number.
                  phoneNumber_verified:
                    type: boolean
                    description: |
                      `true` if the user’s phone number has been verified.
                  addresses:
                    type: array
                    description: Array of Address objects. User’s postal addresses.
                  updated_at:
                    type: string
                    description: Date when the user was last updated.
                required:
                  - sub
                  - updated_at
              example:
                {
                  "id": "AVqvOB58Fg6nZfQ0ZqXt",
                  "given_name": "John",
                  "family_name": "Doe",
                  "email": "john.doe@example.com",
                  "birthdate": "1983-11-13",
                }
      x-codeSamples:
        - lang: "cURL"
          source: |
            curl --request GET \
                 --url https://YOUR_DOMAIN/identity/v1/signup/data?client_id=CLIENT_ID&token=TOKEN \
                 --header 'Content-Type: application/json' \
  # /identity/v1/me/update:
  #   post:
  #     # Check separate Authorization section is present (user is identified with access token)
  #     security:
  #       - OAuth2:
  #         - 'full_write'
  #     summary: Update user's profile
  #     description: |
  #       * Email and password fields are not modifiable with this endpoint, expect for a new user without email (generally when not provided by the social provider).

  #       * The `phone_number` field is not modifiable if the SMS verification code is enabled on the account settings.

  #       * Fields not required can be deleted by using null value, except for custom fields and consents.
  #     operationId: updateUserProfileMe
  #     parameters:
  #       - in: query
  #         name: fields
  #         schema:
  #           type: string
  #           example: [birthdate, lite_only, providers] # https://github.com/Redocly/redoc/issues/1010
  #         allowReserved: true # https://github.com/Redocly/redoc/issues/1010
  #         description: Fields to retrieve. Defaults to `id`, `name`, `email`. # or all???
  #     requestBody:
  #       description: Fields to update.
  #       required: true
  #       content:
  #         application/json:
  #           schema:
  #             type: object
  #             example:
  #               birthdate: '1981-10-13'
  #     responses:
  #       '200':
  #         description: Queried profile fields
  #         content:
  #           application/json:
  #             schema:
  #               type: object
  #             example: {
  #               "birthdate": '1981-10-13',
  #               "lite_only": false,
  #               "providers": []
  #             }
  /identity/v1/update-profile:
    post:
      security:
        - OAuth2:
            - "full_write"
      summary: Update a user profile
      tags:
        - User Profile
      description: |
        Updates a user's profile.

        > Email and password fields are not modifiable with this endpoint, except for a new user without email (generally when not provided by the social provider).

        > The `phone_number` field is not modifiable if the SMS verification code is enabled on the account settings.

        > Fields not required can be deleted by using the `null` value, except for custom fields and consents.

        > **External IDs**:
        >
        > You cannot value the `external_id` field with this endpoint.

      operationId: updateUserProfile
      parameters:
        - $ref: "#/components/parameters/Authorization"
        - $ref: "#/components/parameters/fields"
        # - in: query
        #   name: fields
        #   schema:
        #     type: string
        #     example: [birthdate, lite_only, providers] # https://github.com/Redocly/redoc/issues/1010
        #   allowReserved: true # https://github.com/Redocly/redoc/issues/1010
        #   description: Fields to retrieve. Defaults to `id`, `name`, `email`. # or all???
      requestBody:
        description: Fields to update.
        required: true
        content:
          application/json:
            example:
              birthdate: "1981-10-13"
      responses:
        "200":
          description: Queried profile fields
          content:
            application/json:
              schema:
                type: object
              example:
                {
                  "birthdate": "1981-10-13",
                  "lite_only": false,
                  "providers": [],
                }
      x-codeSamples:
        - lang: "cURL"
          source: |
            curl --request POST \
              --url https://YOUR_DOMAIN/identity/v1/update-profile? \
                fields=id,given_name,family_name,email,birthdate \
              --header 'Content-Type: application/json' \
              --header 'Authorization: Bearer eyJ0eX...ll4Q2NT' \
              --data '{
                  "birthdate": '1981-10-13',
                  "lite_only": false,
                  "providers": []
                }'
  /identity/v1/update-email:
    post:
      security:
        - OAuth2:
            - "full_write"
      summary: Update an email address
      tags:
        - Email
      description: |
        Update the profile's email address and send a verification email. It is required to configure and to enable the [Email update template](https://developer.reachfive.com/docs/email-templates.html) in the account’s settings.

        > **Note**: The access token must have been generated in the last 5 minutes.

        > **User language note**:
        > 
        > If you are using the ReachFive SDK, the user `lang` attribute is taken from the browser language. If you are calling ReachFive API endpoints **directly**, the `lang` attribute is taken from the information sent in the [Accept-Language header](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept-Language).
        > 
        > See [User language](#section/User-language) for more details.
      operationId: updateEmailAddress
      parameters:
        - $ref: "#/components/parameters/Authorization"
      requestBody:
        description: ""
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                email:
                  description: |
                    The email address of the profile. The new email address must be different from the old one.

                    > **Note**: If the email being updated is unverified, the email is automatically updated. If the email being updated
                    > is verified, the user needs to go through the update email flow.
                    >
                    > For more on this topic, see [Email address management](https://developer.reachfive.com/docs/email-address-management.html#changing-email-address-when-logged-in) in our docs.
                  type: string
                  example: user+1@reach5.co
                redirect_url:
                  description: The URL sent in the verification email to which the profile is redirected. This URL must be whitelisted in the `Allowed Callback URLs` field of your ReachFive client settings.
                  type: string
                  example: https://example-email-update.com
                captcha_token:
                  description: The reCAPTCHA v3 response token. See [Google's documentation on how to obtain it](https://developers.google.com/recaptcha/docs/v3).
                  type: string
                  example: ")£i93DkD19£..£lsdZ9"
              required:
                - email
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                type: object
              example:
                {
                  "auth_types": ["password"],
                  "sub": "AW7ay94KBQkplD8WGJXu",
                  "birthdate": "1981-10-13",
                  "birth_month": 10,
                  "birth_date": "1981-10-12T23:00:00.000Z",
                  "lite_only": false,
                  "created_at": "2019-12-06T10:40:24.071Z",
                  "local_friends_count": 0,
                  "social_identities": [],
                  "likes_friends_ratio": 0,
                  "birth_year": 1981,
                  "logins_count": 52,
                  "provider_details": [],
                  "emails":
                    { "verified": [], "unverified": ["user+1@reach5.co"] },
                  "uid": "AW7ay94KBQkplD8WGJXu",
                  "identities":
                    [
                      {
                        "updated_at": "2019-12-26T15:28:42.423Z",
                        "provider": "local",
                        "provider_variant": "default",
                        "user_id": "AW7ay94KBQkplD8WGJXu",
                        "created_at": "2019-12-06T10:40:24.071Z",
                        "id": "local:AW7ay94KBQkplD8WGJXu",
                      },
                    ],
                  "updated_at": "2019-12-26T15:57:29.889Z",
                  "origins": [],
                  "id": "AW7ay94KBQkplD8WGJXu",
                  "first_name": "François",
                  "email": "user+1@reach5.co",
                  "has_password": true,
                  "email_verified": false,
                  "devices": ["desktop"],
                  "last_login": "2019-12-26T15:49:46.037Z",
                  "last_name": "Violette",
                  "last_login_provider": "password",
                  "given_name": "François",
                  "first_login": "2019-12-06T10:40:24.440Z",
                  "birth_day": 13,
                  "last_login_type": "password",
                  "full_name": "User Name",
                  "has_managed_profile": true,
                  "name": "User Name",
                  "family_name": "Violette",
                  "login_summary":
                    {
                      "total": 52,
                      "devices": ["desktop"],
                      "last_login": 1577375386037,
                      "last_provider": "password",
                      "origins": [],
                      "first_login": 1575628824440,
                    },
                  "providers": [],
                  "age": 38,
                }
        "400":
          description: Bad Request
          content:
            application/json:
              schema:
                type: object
              examples:
                Valid email required:
                  value:
                    {
                      "error_id": "hd0wvi33YS",
                      "error_details":
                        [
                          {
                            "code": "invalid",
                            "field": "email",
                            "message": "Valid email required",
                          },
                        ],
                      "error_description": "Invalid form",
                      "error_message_key": "error.invalidForm",
                      "error": "invalid_request",
                      "error_user_msg": "Invalid form",
                    }
                Email already in use:
                  value:
                    {
                      "error_id": "FL6OQIQtiF",
                      "error_description": "Email already in use",
                      "error_message_key": "error.email.alreadyInUse",
                      "error": "email_already_exists",
                      "error_user_msg": "Email already in use",
                    }
        "401":
          description: Unauthorized; access token is not fresh enough
          content:
            application/json:
              schema:
                type: object
              example:
                {
                  "error_id": "Kf9KFZqLUE",
                  "error_description": "Access token is not fresh enough.",
                  "error_message_key": "error.accessToken.freshness",
                  "error": "invalid_grant",
                  "error_user_msg": "Access token is not fresh enough.",
                }
        "404":
          description: Not Found; no resource found (check endpoint is correct)
          content:
            application/json:
              schema:
                type: object
              example:
                {
                  "error_id": "XOKD6EK5DW",
                  "error_description": "No resource found at '/identity/v1/update-emails' for method POST",
                  "error_message_key": "error.resource.notFound",
                  "error": "resource_not_found",
                  "error_user_msg": "No resource found at '/identity/v1/update-emails' for method POST",
                }
      x-codeSamples:
        - lang: "cURL"
          source: |
            curl --request POST \
              --url https://YOUR_DOMAIN/identity/v1/update-email \
              --header 'Content-Type: application/json' \
              --header 'Authorization: Bearer eyJ0eX...ll4Q2NT' \
              --data '{
                  "email": "user+1@reach5.co",
                  "redirect_url": "https://example-email-update.com",
                  "captcha_token": ")£i93DkD19£..£lsdZ9"
                }'
  # {
  #   "error_id": "ZHUeKZiSfV",
  #   "error_description": "This feature is not available",
  #   "error": "access_denied"
  # }
  # => must activate the "SMS" feature in the console
  /identity/v1/update-phone-number:
    post:
      security:
        - OAuth2:
            - "full_write"
            - "phone"
      summary: Update a phone number
      tags:
        - Phone number
      description: |
        Update a user's phone number. The number becomes active once the user validates the SMS.

        To use this endpoint, the SMS feature *must be enabled*; if it's not enabled, you can use the [update a user profile endpoint](#operation/updateUserProfile).

        > **Important**: The access token must have been generated in the last **5** minutes.

        > **MFA Notes**: If the phone number on the user's profile is updated, the `phone_number` MFA credential is also updated (so long as they match).
        > 
        > The access token must contain the `mfa` `amr` if you want to update a phone number that is used as a second factor for MFA. This means you need to do a [stepup operation](#operation/stepup) before you can update the MFA phone number.

      operationId: updatePhoneNumber
      parameters:
        - $ref: "#/components/parameters/Authorization"
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                phone_number:
                  description: The user's phone number.
                  type: string
                  example: "353875550001"
      responses:
        "200":
          description: The updated identity profile.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ProfileFields"
      x-codeSamples:
        - lang: "cURL"
          source: |
            curl --request POST \
              --url https://YOUR_DOMAIN/identity/v1/update-phone-number \
              --header 'Content-Type: application/json' \
              --header 'Authorization: Bearer eyJ0eX...ll4Q2NT' \
              --data '{
                  "phone_number": "0633344044"
                }'
  # {
  #   "error_id": "ZHUeKZiSfV",
  #   "error_description": "This feature is not available",
  #   "error": "access_denied"
  # }
  # => must activate the "SMS" feature in the console
  /identity/v1/verify-phone-number:
    post:
      security:
        - OAuth2:
            - "full_write"
      summary: Verify a phone number
      tags:
        - Phone number
      description: |
        Verify the user's phone number with the verification code sent by SMS. The access token must be generated in the last 5 minutes.

        See also [Request verification of the phone number](#operation/sendPhoneNumberVerification).
      operationId: verifyPhoneNumber
      parameters:
        - $ref: "#/components/parameters/Authorization"
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                phone_number:
                  description: Phone number
                  type: string
                verification_code:
                  description: Verification code.
                  type: integer
                  pattern: "[0-9]{6}"
              example:
                { "phone_number": "0633344044", "verification_code": "12***6" }
      responses:
        "204":
          description: Phone number is verified
      x-codeSamples:
        - lang: "cURL"
          source: |
            curl --request POST \
              --url https://YOUR_DOMAIN/identity/v1/verify-phone-number \
              --header 'Content-Type: application/json' \
              --header 'Authorization: Bearer eyJ0eX...ll4Q2NT' \
              --data '{
                  "phone_number": "0633344044",
                  "verification_code": "12***6"
                }'
  /identity/v1/unlink:
    post:
      security:
        - OAuth2:
            - "full_write"
      summary: Unlink social account
      tags:
        - User Profile
      description: |
        Unlink a specific social account from the current user.

        > Returns the updated profile.

        > **Note**: The access token must have been generated in the last 5 minutes.
      operationId: unlinkSocialAccount
      parameters:
        - $ref: "#/components/parameters/Authorization"
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                identity_id:
                  description: |
                    Unique id of the social provider identity to remove.
                  type: string
                  example: facebook:110907046768170
      responses:
        "200":
          description: The updated identity profile.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ProfileFields"
        "404":
          description: Identity profile not found
      x-codeSamples:
        - lang: "cURL"
          source: |
            curl --request POST \
              --url https://YOUR_DOMAIN/identity/v1/unlink \
              --header 'Content-Type: application/json' \
              --header 'Authorization: Bearer eyJ0eX...ll4Q2NT' \
              --data '{
                  "identity_id": "facebook:110907046768170"
                }'
  /identity/v1/userevents:
    get:
      security:
        - OAuth2:
            - "events"
      summary: Search user events
      tags:
        - Events
      description: Searches and retrieves user events.
      operationId: searchUserEvents
      parameters:
        - $ref: "#/components/parameters/Authorization"
        - $ref: "#/components/parameters/fields"
        - in: query
          name: filter
          schema:
            type: string
            example: type=="login"
          description: Fields to match on.
        # - in: query
        #   name: fields
        #   description: Fields to retrieve in the response.
        #   schema:
        #     type: array
        #     items:
        #       type: string
        - in: query
          name: page
          description: Page number
          schema:
            type: integer
            example: 2
            default: 1
        - in: query
          name: count
          description: Number of items per page.
          schema:
            type: integer
            example: 10
            default: 20
        - in: query
          name: sort
          description: |
            Sorting parameter.

            Use `field:order` where order is `asc` for ascending and `desc` for descending.
          schema:
            type: string
            example: "date:desc" # https://github.com/Redocly/redoc/issues/1010
          allowReserved: true # https://github.com/Redocly/redoc/issues/1010
      responses:
        "200":
          description: OK. Returns the [User Event Object](https://developer.reachfive.com/docs/models-user-events.html#the-user-event-object).
          content:
            application/json:
              schema:
                type: object
              example:
                {
                  "total": 2,
                  "items":
                    [
                      {
                        "date": "2019-06-17T08:57:13.000Z",
                        "auth_type": "password",
                        "ip": "127.0.0.1",
                        "type": "login",
                        "client_id": "YOUR_CLIENT_ID",
                        "provider": "password",
                        "user_id": "YOUR_PROFILE_ID",
                        "profile_id": "YOUR_PROFILE_ID",
                        "login_time": "2019-06-17T08:57:13.000Z",
                        "host": "https://YOUR_DOMAIN",
                        "id": "AWsnrYqDxUXWdPYi1aPI",
                        "device": "desktop",
                        "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:69.0) Gecko/20100101 Firefox/69.0",
                      },
                      {
                        "date": "2019-06-19T10:12:13.000Z",
                        "auth_type": "password",
                        "ip": "127.0.0.1",
                        "type": "login",
                        "client_id": "YOUR_CLIENT_ID",
                        "provider": "password",
                        "user_id": "YOUR_PROFILE_ID",
                        "profile_id": "YOUR_PROFILE_ID",
                        "login_time": "2019-06-19T12:12:13.385Z",
                        "host": "https://YOUR_DOMAIN",
                        "id": "AWtvptgcRsnAuaJCTBdT",
                        "device": "desktop",
                        "user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:69.0) Gecko/20100101 Firefox/69.0",
                      },
                    ],
                }
      x-codeSamples:
        - lang: "cURL"
          source: |
            curl --request GET \
              --url https://YOUR_DOMAIN/identity/v1/userevents?filter=type=="login" \
              --header 'Content-Type: application/json' \
              --header 'Authorization: Bearer eyJ0eX...ll4Q2NT'
  /identity/v1/signup:
    post:
      summary: Sign up a new user
      tags:
        - Login/Signup
      description: |
        Registers a new user and sends a verification code or token to the provided email address and/or phone number.

        > **Tip**: Users should activate their account via the activation link sent to ensure their credentials are verified. However, users do not need verification to log in.

        > **User language note**:
        > 
        > If you are using the ReachFive SDK, the user `lang` attribute is taken from the browser language. If you are calling ReachFive API endpoints **directly**, the `lang` attribute is taken from the information sent in the [Accept-Language header](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept-Language).
        > 
        > See [User language](#section/User-language) for more details.
      operationId: signup
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                client_id:
                  description: Your ReachFive client ID.
                  type: string
                scope:
                  description: |
                    Space-delimited list of permissions.<br>
                    The required permissions are documented for each API endpoint.
                  type: string
                data:
                  description: Attributes of the user, for example the email or phone number (or both) and password. This can also contain a custom identifier.
                  type: object
                redirect_url:
                  description: The URL sent in the signup email to which the profile is redirected. This URL must be whitelisted in the `Allowed Callback URLs` field of your ReachFive client settings.
                  type: string
                captcha_token:
                  description: The reCAPTCHA v3 response token. See [Google's documentation on how to obtain it](https://developers.google.com/recaptcha/docs/v3).
                  type: string
            example:
              client_id: k3ShTUsHgVE5aWu5uW0i
              scope: openid profile email
              data:
                email: jean42@example.com
                custom_identifier: JeanIsSuperFly42
                password: DoNotMakeN3wPasswordsTooEasyToGuess
              redirect_url: "https://example-email-signup.com"
      responses:
        "200":
          description: User successfully created.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/signUpNewUserSuccess"
        "400":
          description: Bad Request
          content:
            application/json:
              schema:
                type: object
              examples:
                Password too weak:
                  value:
                    {
                      "error_id": "nvgbxzmRqP",
                      "error_details":
                        [
                          {
                            "code": "invalid",
                            "field": "data.password",
                            "message": "Password too weak",
                          },
                          {
                            "code": "invalid",
                            "field": "data.password",
                            "message": "Minimum length is 8",
                          },
                        ],
                      "error_description": "Validation failed",
                      "error": "invalid_request",
                    }
                Email already in use:
                  value:
                    {
                      "error_id": "rxwJNjsnz1",
                      "error_description": "Email already in use",
                      "error_message_key": "error.email.alreadyInUse",
                      "error": "email_already_exists",
                      "error_user_msg": "Email already in use",
                    }
                Invalid email address:
                  value:
                    {
                      "error_id": "K90O847Bxv",
                      "error_details":
                        [
                          {
                            "code": "invalid",
                            "field": "data.email",
                            "message": "Must be a valid email",
                          },
                        ],
                      "error_description": "Validation failed",
                      "error": "invalid_request",
                    }
                Invalid redirect URL:
                  value:
                    {
                      "error_id": "A8YVdoAXaP",
                      "error_details":
                        [
                          {
                            "code": "invalid",
                            "field": "redirect_url",
                            "message": "Must be a valid url",
                          },
                        ],
                      "error_description": "Validation failed",
                      "error": "invalid_request",
                    }
        "401":
          description: Unauthorized
          content:
            application/json:
              schema:
                type: object
              examples:
                Client authentication failed:
                  value:
                    {
                      "error_id": "4UV0uzmpF0",
                      "error_description": "Client authentication failed",
                      "error": "invalid_client",
                    }
      x-codeSamples:
        - lang: "cURL"
          source: |
            curl --request POST \
              --url https://YOUR_DOMAIN/identity/v1/signup \
              --header 'Content-Type: application/json' \
              --header 'Authorization: Bearer eyJ0eX...ll4Q2NT' \
              --data '{
                  "client_id": "k3ShTUsHgVE5aWu5uW0i",
                  "scope": "openid profile email",
                  "data": {
                    "email": "anewuser@mailbox.com",
                    "password": "DoNotMakeN3wPasswordsTooEasyToGuess"
                  },
                  "redirect_url": "https://example-email-signup.com"
              }'
  /identity/v1/verify-auth-code:
    post:
      summary: Verify an SMS auth code
      tags:
        - Phone number
      description: |
        Used to check the validity of the code in your front-end, before calling the next call which will redirect the user. This does not consume the single-use code.
      operationId: verifyAuthCodeSMS
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                phone_number:
                  description: The phone number receiving the SMS
                  type: string
                verification_code:
                  description: The code sent by SMS
                  type: integer
                state:
                  description: Always `passwordless`
                  type: string
                redirect_uri:
                  description: The absolute URI the user-agent will be redirected to following flow completion. Depending on the response type, it will either carry the token response, the authorization code, or the appropriate error in any other case.
                  type: string
                client_id:
                  description: Your ReachFive client ID
                  type: string
                response_type:
                  description: OAuth2 grant type
                  type: string
                  enum:
                    - code
                    - token
              required:
                - phone_number
                - verification_code
                - state
                - redirect_uri
                - client_id
                - response_type
              example:
                {
                  "phone_number": "+33111111113",
                  "verification_code": "521525",
                  "state": "passwordless",
                  "redirect_uri": "reachfive://callback",
                  "client_id": "k6ShTTsHfVE5aXu5uW0i",
                  "response_type": "code",
                }
      responses:
        "204":
          description: Code is validated
      x-codeSamples:
        - lang: "cURL"
          source: |
            curl --request POST \
              --url https://YOUR_DOMAIN/identity/v1/verify-auth-code \
              --header 'Content-Type: application/json' \
              --header 'Authorization: Bearer eyJ0eX...ll4Q2NT' \
              --data '{
                  "phone_number": "+3362938475",
                  "verification_code": "608275"
              }'
  /identity/v1/signup-token:
    # Used in Cordova (Ouibus only)
    post:
      #       {
      #     "error_id": "gwSUh9EGVV",
      #     "error_description": "Email already in use",
      #     "error": "email_already_exists",
      #     "error_user_msg": "Another account with the same email address already exists"
      # }
      summary: Sign up a new user and return a token
      tags:
        - Login/Signup
      description: |
        Registers a new user and sends a verification code to the email address provided.

        > **User language note**:
        > 
        > If you are using the ReachFive SDK, the user `lang` attribute is taken from the browser language. If you are calling ReachFive API endpoints **directly**, the `lang` attribute is taken from the information sent in the [Accept-Language header](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept-Language).
        > 
        > See [User language](#section/User-language) for more details.
      operationId: signupToken
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                client_id:
                  description: Your ReachFive client ID
                  type: string
                client_secret:
                  description: Your client Secret. Required if your Client’s authorization method is POST.
                  type: string
                scope:
                  description: |
                    Space-delimited list of permissions.<br>
                    The required permissions are documented for each API endpoint.
                  type: string
                data:
                  description: Attributes of the user, for example the email and password.
                  type: object
                redirect_url:
                  description: The URL sent in the verification email to which the profile is redirected. This URL must be whitelisted in the `Allowed Callback URLs` field of your ReachFive client settings.
                  type: string
              required:
                - client_id
                - client_secret
            example:
              client_id: k3ShTUsHgVE5aWu5uW0i
              scope: openid profile email
              data:
                email: anewuser@mailbox.com
                password: DoNotMakeN3wPasswordsTooEasyToGuess
              redirect_url: "https://example-email-verification.com"
      responses:
        "200":
          description: User successfully created (returns ID and tkn... used?)
          content:
            application/json:
              schema:
                type: object
              example:
                {
                  "id_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJBVzlESC1KcmxBS2R5aW9STk1QSiIsImF1ZCI6WyJrNlNoVFRzSGZWRTVhWHU1dVcwaSJdLCJhdXRoX3R5cGUiOiJwYXNzd29yZCIsIm5ld191c2VyIjp0cnVlLCJlbWFpbF92ZXJpZmllZCI6ZmFsc2UsInVwZGF0ZWRfYXQiOiIyMDE5LTEyLTI2VDE2OjUyOjQwLjgyN1oiLCJjdXN0b21fZmllbGRzIjp7fSwiYXV0aF90aW1lIjoxNTc3Mzc5MTYwLCJpc3MiOiJodHRwczovL3Rlc3QtamMucmVhY2g1Lm5ldCIsImV4cCI6MTU3NzQ2NTU2MCwiaWF0IjoxNTc3Mzc5MTYwLCJlbWFpbCI6ImZyYW5jb2lzK3NpZ251cHRva2VuQHJlYWNoNS5jbyJ9.L2LHcWjCIHpKnP9P8facsfAfx0QdILTeYfXpw3IlEc4",
                  "access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwczovL3Rlc3QtamMucmVhY2g1Lm5ldCIsInN1YiI6IkFXOURILUpybEFLZHlpb1JOTVBKIiwiYXVkIjpbImh0dHBzOi8vdGVzdC1qYy5yZWFjaDUubmV0L2lkZW50aXR5Il0sImV4cCI6MTU3NzQ2NTU2MCwiaWF0IjoxNTc3Mzc5MTYwLCJzY29wZSI6ImVtYWlsIG9wZW5pZCBwcm9maWxlIiwiZW5mb3JjZXNfc2NvcGUiOnRydWUsImF1dGhfdGltZSI6MTU3NzM3OTE2MCwiYXpwIjoiazZTaFRUc0hmVkU1YVh1NXVXMGkifQ.FGfwIEdCYFnjxXNregJQNjnrcXoE9rolY1aINZ-OqQo",
                  "expires_in": 86400,
                  "token_type": "Bearer",
                }
        "400":
          description: Another account with the same email address already exists
      x-codeSamples:
        - lang: "cURL"
          source: |
            curl --request POST \
              --url https://YOUR_DOMAIN/identity/v1/signup-token \
              --header 'Content-Type: application/json' \
              --data '{
                  "client_id": "{{identity_client_id}}",
                  "client_secret": "{{identity_client_secret}}",
                  "scope": "openid profile email",
                  "data": {
                    "email": "giverandomtoken51@reach5.co",
                    "password": ",sou9D3UrihFIE"
                  },
                  "redirect_url": "https://example-email-verification.com"

              }'
  /identity/v1/password/login:
    post:
      summary: Login with password
      tags:
        - Login/Signup
      description: |
        User logs in with a password.

        If a user reaches the configured login attempt threshold, they are locked out for the time you have configured in the ReachFive console.

        > **Tip**: For more information see [Account lockout: failed login attempts](https://developer.reachfive.com/docs/user-account-lockout.html) on the main docs section.

        > **User language note**:
        > 
        > If you are using the ReachFive SDK, the user `lang` attribute is taken from the browser language. If you are calling ReachFive API endpoints **directly**, the `lang` attribute is taken from the information sent in the [Accept-Language header](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept-Language).
        > 
        > See [User language](#section/User-language) for more details.
        >
        > **MFA login flow**:
        >
        > When a second factor (2FA) is needed to complete the flow, you'll receive the `mfa_required: true` as part of the API response. For more on the MFA login flow, see [here](https://developer.reachfive.com/docs/mfa.html#require-mfa-for-login).
      operationId: loginWithPassword
      parameters:
        - $ref: "#/components/parameters/attackProtectionBypass"
        - $ref: "#/components/parameters/trueClientIp"
        - $ref: "#/components/parameters/trueClientIpKey"
        - $ref: "#/components/parameters/userAgent"
        - $ref: "#/components/parameters/hostedTrustedDeviceIdHeader"
      requestBody:
        content:
          application/json:
            schema:
              oneOf:
                - $ref: "#/components/schemas/loginWithEmail"
                - $ref: "#/components/schemas/loginWithPhoneNumber"
                - $ref: "#/components/schemas/loginWithCustomIdentifier"
      responses:
        "200":
          description: Return a one-time use authentication token
          content:
            application/json:
              schema:
                type: object
                properties:
                  tkn:
                    type: string
                    description: The one-time use authentication token
                    example: "xhNGxw...70zx32"
                  mfa_required:
                    type: boolean
                    description: |
                      A boolean that denotes whether a second factor is required to complete the flow or not.

                      - `true` = MFA is required (2FA needed)

                      > **Note**: If 2FA is not required, `mfa_required` is not present in the response.
        "400":
          description: Bad request. This can occur when an account is temporarily suspended.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorFields"
              examples:
                Suspended account:
                  value:
                    {
                      "error_id": "6...ea",
                      "error_description": "Account suspended",
                      "error_message_key": "error.account.temporarilySuspended",
                      "error": "invalid_grant",
                      "error_user_msg": "Your account has been disabled for security reasons. Please reset your password by clicking the link sent by email or SMS or contact the site administrator to reactivate it. You can receive a new password reset link by clicking on 'Forgot Password'.",
                    }
        "401":
          description: Invalid credentials or client id
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorFields"
              examples:
                Invalid credentials:
                  value:
                    {
                      "error_id": "65ckVW5hda",
                      "error_description": "Invalid email or password",
                      "error": "invalid_grant",
                      "error_user_msg": "Invalid email or password",
                    }
                Invalid client id:
                  value:
                    {
                      "error_id": "1oyuulLIjb",
                      "error_description": "Invalid client id",
                      "error": "invalid_client",
                    }
        "403":
          description: Forbidden; account is not accessible.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorFields"
              examples:
                Account locked:
                  value:
                    {
                      "error_id": "3g...dp",
                      "error_description": "Your account has been locked after multiple consecutive login attempts",
                      "error_message_key": "error.accountBlockedAfterMultipleLoginAttempts",
                      "error": "access_denied",
                      "error_user_msg": 'Your account is locked for 1 minutes due to multiple consecutive failed login attempts. You can unlock it now by reseting your password by clicking on "Forgot Password".',
                    }
                Unverified identifier (if block unverified option is enabled):
                  value:
                    {
                      "error_id": "tFw...rxF",
                      "error_description": "Unverified identifier account. To login, please verify your identifier with the email or the SMS that you received.",
                      "error_message_key": "error.unverifiedLogin",
                      "error": "unverified_identifier",
                      "error_user_msg": "Unverified identifier account. To login, please verify your identifier with the email or the SMS that you received.",
                    }
    x-codeSamples:
      - lang: "cURL"
        source: |
          curl --request POST \
            --url https://YOUR_DOMAIN/identity/v1/password/login \
            --header 'Content-Type: application/json' \
            --data '{
                "client_id": "MY_CLIENT_ID",
                "username": "myusername@client.com",
                "password": "MY_PASSWORD",
            }'
  /identity/v1/password/callback:
    # Signup callback - do NOT document as separate endpoint
    get:
      summary: Callback password
      tags:
        - Login/Signup
      description: Exchange a one-time use authentication token for an access token (implicit flow) or an authorization code (code flow).
      operationId: passwordCallback
      parameters:
        - in: query
          name: client_id
          required: true
          schema:
            type: string
            example: k6ShTOsHfVE5aXu4uW0i
          description: Your ReachFive client ID
        - in: query
          name: tkn
          required: true
          schema:
            type: string
            example: lW1sihJwqfRRKyyjFsR1xF1x_M...
          description: The one-time use authentication token
        - in: query
          name: response_type
          required: true
          schema:
            type: string
            enum:
              - token
              - code
          description: Expected response type depending on the chosen OAuth2 flow.
        - in: query
          name: redirect_uri
          required: true
          schema:
            type: string
            example: https://mybrand.com/login/callback
          description: The absolute URI the user-agent will be redirected to following flow completion. Depending on the response type, it will either carry the token response, the authorization code, or the appropriate error in any other case.
        - in: query
          name: scope
          schema:
            type: string
            example: openid email phone profile
          description: |
            List of space-delimited, case-sensitive strings representing the requested scope.

            **Caution**: If the Enforce Scope setting is enabled, the scope here is ignored. The scope set in the [Login with password operation](#operation/loginWithPassword) overrides any scope set here.
        - in: query
          name: display
          schema:
            type: string
            enum:
              - page
              - popup
          description: |
            Specifies how to display the user interaction interface for authentication and authorization.

            - `page` = redirected in the same page
            - `popup` = popup window
        - in: query
          name: response_mode
          schema:
            type: string
            enum:
              - query
              - fragment
              - web_message
          description: |
            How the result of the authorization request is formatted:
              - `query`: `302 Found` and a redirection (for the authorization code grant)
              - `fragment`: `302 Found` and a redirection (for the implicit grant)
              - `web_message`: `200 OK` and it uses HTML5 web messaging (for silent authentication)
      responses:
        "200":
          description: A response containing the access token or a code as query param of `redirect_uri`.
        "303":
          description: Redirection to the provided `redirect_uri` containing a token response or an authorization code in either a query string or a fragment depending on the flow or `response_mode` if passed.
        "401":
          description: Invalid client id
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorFields"
              examples:
                Invalid client id:
                  value:
                    {
                      "error_id": "1oyuulLIjb",
                      "error_description": "Invalid client id",
                      "error": "invalid_client",
                    }

  /identity/v1/send-email-verification:
    post:
      security:
        - OAuth2:
            - "none"
      summary: Request verification of the email address
      tags:
        - Email
      description: |
        Request the verification of the email address of a profile.
        If there is an email address configured in the profile that was not already verified, sends an email to verify it.

      operationId: sendEmailVerification
      parameters:
        - $ref: "#/components/parameters/Authorization"
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                redirect_url:
                  description: The URL sent in the verification email to which the profile is redirected. This URL must be whitelisted in the `Allowed Callback URLs` field of your ReachFive client settings.
                  type: string
                return_to_after_email_confirmation:
                  description: Returned in the `redirect_url` as a query parameter, this parameter is used as the post-email confirmation URL. It must be a valid URL.
                  type: string
      responses:
        "200":
          description: User receives an email to verify their email address.
          content:
            application/json:
              schema:
                type: object
                properties:
                  verification_email_sent:
                    type: boolean
                    description: Whether the email was sent (`false` if the email address was already verified)
                example: { "verification_email_sent": true }
      x-codeSamples:
        - lang: "cURL"
          source: |
            curl --request POST \
              --url https://YOUR_DOMAIN/identity/v1/send-email-verification \
              --header 'Authorization: Bearer eyJ0eX...ll4Q2NT'
              --data '{
                "redirect_url": "https://example-email-verification.com"
            }'
  /identity/v1/send-phone-number-verification:
    post:
      security:
        - OAuth2:
            - "none"
      summary: Request verification of the phone number
      tags:
        - Phone number
      description: |
        Request the verification of the phone number of a profile.
        If there is a phone number configured in the profile that was not already verified, and the SMS feature is activated, sends an SMS to verify it.

        For the next step in the process see [Verify a phone number](#operation/verifyPhoneNumber).
      operationId: sendPhoneNumberVerification
      parameters:
        - $ref: "#/components/parameters/Authorization"
      responses:
        "200":
          description: User receives an SMS to verify their phone number.
          content:
            application/json:
              schema:
                type: object
                properties:
                  verification_code_sent:
                    type: boolean
                    description: Whether the SMS was sent (`false` if the phone number was already verified)
                example: { "verification_code_sent": true }
      x-codeSamples:
        - lang: "cURL"
          source: |
            curl --request POST \
              --url https://YOUR_DOMAIN/identity/v1/send-phone-number-verification \
              --header 'Authorization: Bearer eyJ0eX...ll4Q2NT'
  /identity/v1/forgot-password:
    post:
      summary: Request password reset
      tags:
        - Password
      description: |
        Request a password reset for a profile. It will send an email if the email address is provided and an SMS if the phone number is given.

        If while sending an email or SMS, the provider responds with an error after **3** tries, a failure event is generated. For more
        on these and other user events, check out our [User events page](https://developer.reachfive.com/docs/models-user-events.html) for more information.

        > **User language note**:
        > 
        > If you are using the ReachFive SDK, the user `lang` attribute is taken from the browser language. If you are calling ReachFive API endpoints **directly**, the `lang` attribute is taken from the information sent in the [Accept-Language header](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept-Language).
        > 
        > See [User language](#section/User-language) for more details.
      operationId: requestPasswordReset
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                client_id:
                  description: Your ReachFive client ID.
                  type: string
                email:
                  description: Email address.
                  type: string
                phone_number:
                  description: The phone number receiving the reset password SMS.
                  type: string
                redirect_url:
                  description: The URL sent in the password reset email or SMS to which the profile is redirected. This URL must be whitelisted in the `Allowed Callback URLs` field of your ReachFive client settings.
                  type: string
                captcha_token:
                  description: The reCAPTCHA v3 response token. See [Google's documentation on how to obtain it](https://developers.google.com/recaptcha/docs/v3).
                  type: string
            examples:
              Send a password reset email:
                value:
                  {
                    "client_id": "k6ShTTsHfVE5aXu5uV0i",
                    "email": "newuser@company.com",
                    "redirect_url": "https://example-email-password-reset.com",
                  }
              Send a password reset SMS:
                value:
                  {
                    "client_id": "k6ShTTsHfVE5aXu5uV0i",
                    "phone_number": "+33633445566",
                    "redirect_url": "https://example-email-password-reset.com",
                  }

      responses:
        "204":
          description: User receives an email or a SMS to reset their password
      x-codeSamples:
        - lang: "cURL"
          source: |
            curl --request POST \
              --url https://YOUR_DOMAIN/identity/v1/forgot-password \
              --header 'Content-Type: application/json' \
              --data '{
                  "client_id": "k6ShTTsHfVE5aXu5uV0i",
                  "email": "newuser@company.com",
                  "redirect_url": "https://example-email-password-reset.com"
              }'
  /identity/v1/update-password:
    post:
      security:
        - OAuth2:
            - "full_write"
      summary: Update a password
      tags:
        - Password
      description: |
        Updates user's password.

        Using a valid access token?

        In this case, the `client_id` and `phone_number` or `email` is not required. 
        Logged-in users can update their password by providing:

        - Their `old_password` (current) and the new `password`.
          <br/>
            or
          <br/>
        - If the access token was generated in the **last 5 minutes**, the new `password`.

        Updating based off of a [password reset request](#operation/requestPasswordReset)?
        In this case, the `client_id` and a valid `phone_number` or `email` are required. 

        If so, you can send the verification code instead (without the `access_token`).
        You can get the verification code (as a query parameter) from the link sent in the [password reset request](#operation/requestPasswordReset).

        > **User language note**:
        > 
        > If you are using the ReachFive SDK, the user `lang` attribute is taken from the browser language. If you are calling ReachFive API endpoints **directly**, the `lang` attribute is taken from the information sent in the [Accept-Language header](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept-Language).
        > 
        > See [User language](#section/User-language) for more details.
      operationId: updatePassword
      parameters:
        - $ref: "#/components/parameters/Authorization_optional"
      requestBody:
        content:
          application/json:
            schema:
              oneOf:
                - $ref: "#/components/schemas/updatePasswordEmail"
                - $ref: "#/components/schemas/updatePasswordPhone"
            examples:
              Provide current and new passwords - email:
                value:
                  {
                    "client_id": "YOUR_CLIENT_ID",
                    "email": "user@company.com",
                    "old_password": "oldStup1dPassword",
                    "password": "DoN0tMakeUpdatedPa55wordsTooEasyToGuess",
                  }
              Provide current and new passwords - phone:
                value:
                  {
                    "client_id": "YOUR_CLIENT_ID",
                    "phone_number": "+353871445555",
                    "old_password": "oldStup1dPassword",
                    "password": "DoN0tMakeUpdatedPa55wordsTooEasyToGuess",
                  }
              Force new password with 5-minute fresh Access Token:
                value:
                  {
                    "client_id": "YOUR_CLIENT_ID",
                    "email": "user@company.com",
                    "password": "DoN0tMakeUpdatedPa55wordsTooEasyToGuess",
                  }
      responses:
        "204":
          description: Users receive an email to notify a change of password
        "400":
          description: The new password should be different from the current password
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorFields"
              examples:
                The new password is the same as the current:
                  value:
                    {
                      "error_id": "Gc1Zu9TTp1",
                      "error_description": "New password should be different from the old password",
                      "error_message_key": "error.updateSamePassword",
                      "error": "invalid_request",
                      "error_user_msg": "New password should be different from the old password",
                    }
                Insufficient number of special characters:
                  value:
                    {
                      "error_id": "53AYNTE7WI",
                      "error_description": "Minimum special characters required is 1",
                      "error_message_key": "error.password.special.characters",
                      "error": "invalid_request",
                      "error_user_msg": "Minimum special characters required is 1",
                    }
                Insufficient number of uppercase characters:
                  value:
                    {
                      "error_id": "93AYDHE7OI",
                      "error_description": "Minimum uppercase characters required is 1",
                      "error_message_key": "error.password.uppercase.characters",
                      "error": "invalid_request",
                      "error_user_msg": "Minimum uppercase characters required is 1",
                    }
                Insufficient number of digit characters:
                  value:
                    {
                      "error_id": "28BYLKO7OI",
                      "error_description": "Minimum digit characters required is 1",
                      "error_message_key": "error.password.digit.characters",
                      "error": "invalid_request",
                      "error_user_msg": "Minimum digit characters required is 1",
                    }
                Access token is not fresh enough (> 5 minutes):
                  value:
                    {
                      "error_id": "owqwf9TSDH",
                      "error_description": "Access token is not fresh enough.",
                      "error_message_key": "error.accessToken.freshness",
                      "error": "invalid_grant",
                      "error_user_msg": "Access token is not fresh enough.",
                    }
                Missing scope:
                  value:
                    {
                      "error_id": "mWj850HYnk",
                      "error_description": "The token does not contain the required scope: full_write",
                      "error_message_key": "error.accessToken.scope.required",
                      "error": "insufficient_scope",
                      "error_user_msg": "The token does not contain the required scope: full_write",
                    }
      x-codeSamples:
        - lang: "cURL"
          source: |
            curl --request POST \
              --url https://YOUR_DOMAIN/identity/v1/update-password \
              --header 'Content-Type: application/json' \
              --header 'Authorization: Bearer eyJ0eX...ll4Q2NT' \
              --data '{
                  "client_id": "k6ShTTsHfVE5aXu5uV0i",
                  "email": "newuser@company.com",
                  "password": "DoN0tMakeUpdatedPa55wordsTooEasyToGuess"
              }'
  /identity/v1/mfa/credentials/emails:
    post:
      summary: Enable email for MFA
      tags:
        - MFA
      security:
        - OAuth2:
            - "mfa"
      operationId: startEmailRegistration
      description: |
        Starts the activation of the user's identifier email as an MFA credential (second factor). If you do not have an email as an identifier, one must be added before using this route.

        **Important**: If the identifier email is *verified*, this route directly enables the email for MFA as noted in the response. If the email is unverified,
        an email will be sent to then verify the email.

        **Note**: You must have a fresh access token (issued in the last 5 minutes) to start the flow.

        > #### <i class="fa fa-gear fa-spin fa-2x" style="color: #00c24a"></i> What Next?
        > Use the `verification_code` received by the user as the request payload for [verifying MFA registration](#operation/verifyEmailRegistration) or as a [query parameter](#operation/verifyEmailRegistrationQuery).
      parameters:
        - $ref: "#/components/parameters/Authorization"
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                redirect_url:
                  description: |
                    The URL to redirect the user verifying the email address.

                    **Note**: This is not required if you have set the *Redirect to* field in the console.
                    However, if you have not done this, you must pass the `redirect_url` in the request body.
                  type: string
                  example: "https://www.example.com/redirect"
      responses:
        "200":
          description: For verified emails. A success with enabled credentials.
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    description: Specifies the status. In this case, `enabled` when it is a `200` response.
                    example: "enabled"
                  credential:
                    type: object
                    description: Contains the credentials that have been enabled.
                    properties:
                      created_at:
                        type: string
                        description: The time at which the credential was created.
                        example: "2022-02-01T14:37:15.845Z"
                      email:
                        type: string
                        description: The user's identifier email.
                        example: "dude@example.com"
                      friendly_name:
                        type: string
                        description: The friendly name of the email.
                        example: "identifier"
                      type:
                        type: string
                        description: The type of credential.
                        example: "email"
        "202":
          description: For unverified emails. A success confirming the email was sent.
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    description: The status of whether the email was sent or not.
                    example: "email_sent"
      x-codeSamples:
        - lang: "cURL"
          source: |
            curl --request POST \
              --url https://YOUR_DOMAIN/identity/v1/mfa/credentials/emails \
              --header 'Content-Type: application/json' \
              --header 'Authorization: Bearer eyJ0eX...ll4Q2NT' \
              --data '{
                  "redirect_url": "https://www.example.com/redirect"
              }'
    delete:
      summary: Delete an MFA credential (email)
      tags:
        - MFA
      security:
        - OAuth2:
            - "mfa"
      description: |
        Delete the email that has been added as an MFA credential (second factor).

        > **Note**: You must have a fresh access token (issued in the last 5 minutes) to use this endpoint.

        > **Stepup**: The access token must contain the `mfa` `amr` if you want to delete the credential. This means you need to do a [stepup operation](#operation/stepup) before you can delete the credential.
      operationId: deleteEmailCredential
      parameters:
        - $ref: "#/components/parameters/Authorization"
      responses:
        "204":
          description: Deleted the email for use as MFA credential from the user profile.
      x-codeSamples:
        - lang: "cURL"
          source: |
            curl --request DELETE \
              --url https://YOUR_DOMAIN/identity/v1/mfa/credentials/emails \
              --header 'Authorization: Bearer eyJ0eX...ll4Q2NT' \
  /identity/v1/mfa/credentials/emails/verify:
    get:
      summary: Verify email as an MFA credential (query)
      tags:
        - MFA
      security:
        - OAuth2:
            - "none"
      operationId: verifyEmailRegistrationQuery
      description: |
        Verify the registration of an email as an MFA credential (second factor) with query parameters.

        > #### <i class="fa fa-gear fa-spin fa-2x" style="color: #00c24a"></i> What Next?
        > Once a user's email is verified for MFA, the email can be used as a second factor to initiate the [step up flow](#operation/stepup).
      parameters:
        - in: query
          name: t
          required: true
          schema:
            type: string
            example: "0irYKCv3VnjfpwfnhMlIFvd1iVPNxXOzx_710B8Lr"
          description: |
            Opaque token containing the request parameters (link clicked in the email).
        - in: query
          name: c
          required: true
          schema:
            type: string
            example: "123456"
          description: |
            The `verification_code` as `c`.
      responses:
        "200":
          description: The email used as a second factor has been successfully verified.
      x-codeSamples:
        - lang: "cURL"
          source: |
            curl --request GET \
              --url https://YOUR_DOMAIN/identity/v1/mfa/credentials/emails/verify \
              --header 'Content-Type: application/json' \
              --header 'Authorization: Bearer eyJ0eX...ll4Q2NT' \
              --data '{
                  "verification_code": "123456"
              }'
    post:
      summary: Verify email as an MFA credential
      tags:
        - MFA
      security:
        - OAuth2:
            - "mfa"
      operationId: verifyEmailRegistration
      description: |
        Verify the registration of an email as an MFA credential (second factor).

        > #### <i class="fa fa-gear fa-spin fa-2x" style="color: #00c24a"></i> What Next?
        > Once a user's email is verified for MFA, the email can be used as a second factor to initiate the [step up flow](#operation/stepup).
      parameters:
        - $ref: "#/components/parameters/Authorization"
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                verification_code:
                  description: The verification code sent by email.
                  type: integer
                  pattern: "[0-9]{6}"
                  example: 123456
              required:
                - verification_code
      responses:
        "204":
          description: The email used as a second factor has been successfully verified.
      x-codeSamples:
        - lang: "cURL"
          source: |
            curl --request POST \
              --url https://YOUR_DOMAIN/identity/v1/mfa/credentials/emails/verify \
              --header 'Content-Type: application/json' \
              --header 'Authorization: Bearer eyJ0eX...ll4Q2NT' \
              --data '{
                  "verification_code": "123456"
              }'
  /identity/v1/mfa/credentials/phone-numbers:
    post:
      summary: Start the registration of a phone number as an MFA credential
      tags:
        - MFA
      security:
        - OAuth2:
            - "mfa"
      description: |
        Start the registration of a phone number as an MFA credential (second factor).

        **Note**: You must have a fresh access token (issued in the last 5 minutes) to start the flow.

        > #### <i class="fa fa-gear fa-spin fa-2x" style="color: #00c24a"></i> What Next?
        > If the user already has a verified phone number as an identifier in their account, no additional verification code is sent. If the user has an unverified phone number, it's automatically verified during [MFA registration](#operation/verifyPhoneNumberRegistration).
        > Use the `verification_code` received by the user as the request payload for [verifying MFA registration](#operation/verifyPhoneNumberRegistration).
      operationId: startPhoneNumberRegistration
      parameters:
        - $ref: "#/components/parameters/Authorization"
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                phone_number:
                  description: The phone number used as a second factor. It doesn't have to be the same as the identifier.
                  type: string
                  example: "+33612345678"
              required:
                - phone_number
      responses:
        "204":
          description: Sends a verification code to the provided phone number.
      x-codeSamples:
        - lang: "cURL"
          source: |
            curl --request POST \
              --url https://YOUR_DOMAIN/identity/v1/mfa/credentials/phone-numbers \
              --header 'Content-Type: application/json' \
              --header 'Authorization: Bearer eyJ0eX...ll4Q2NT' \
              --data '{
                  "phone_number": "+33612345678"
              }'
    delete:
      summary: Delete an MFA credential (phone number)
      tags:
        - MFA
      security:
        - OAuth2:
            - "mfa"
      description: |
        Delete the phone number that has been added as an MFA credential (second factor).

        **Note**: You must have a fresh access token (issued in the last 5 minutes) to use this endpoint.
      operationId: deletePhoneNumberCredential
      parameters:
        - $ref: "#/components/parameters/Authorization"
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                phone_number:
                  description: The phone number used as a second factor. It doesn't have to be the same than the identifier.
                  type: string
                  example: "+33612345678"
              required:
                - phone_number
      responses:
        "204":
          description: Delete the MFA credential from the user profile.
      x-codeSamples:
        - lang: "cURL"
          source: |
            curl --request DELETE \
              --url https://YOUR_DOMAIN/identity/v1/mfa/credentials/phone-numbers \
              --header 'Content-Type: application/json' \
              --header 'Authorization: Bearer eyJ0eX...ll4Q2NT' \
              --data '{
                  "phone_number": "+33612345678"
              }'
  /identity/v1/mfa/credentials/phone-numbers/verify:
    post:
      summary: Verify the phone number used as an MFA credential.
      tags:
        - MFA
      security:
        - OAuth2:
            - "mfa"
      description: |
        Finish the registration of the phone number used as an MFA credential (second factor) by verifying it with the code received by SMS.

        > #### <i class="fa fa-gear fa-spin fa-2x" style="color: #00c24a"></i> What Next?
        > Once a user's number is verified for MFA, the number can be used as a second factor to initiate the [step up flow](#operation/stepup).

      operationId: verifyPhoneNumberRegistration
      parameters:
        - $ref: "#/components/parameters/Authorization"
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                verification_code:
                  description: The verification code sent by SMS.
                  type: integer
                  pattern: "[0-9]{6}"
                  example: 123456
              required:
                - verification_code
      responses:
        "204":
          description: Verify the phone number used as a second factor.
      x-codeSamples:
        - lang: "cURL"
          source: |
            curl --request POST \
              --url https://YOUR_DOMAIN/identity/v1/mfa/credentials/phone-numbers/verify \
              --header 'Content-Type: application/json' \
              --header 'Authorization: Bearer eyJ0eX...ll4Q2NT' \
              --data '{
                  "verification_code": "123456"
              }'
  /identity/v1/mfa/credentials:
    get:
      summary: List MFA credentials
      tags:
        - MFA
      security:
        - OAuth2:
            - "mfa"
      parameters:
        - $ref: "#/components/parameters/Authorization"
      description: |
        List the credentials that have been added as a second factor to the profile.

        > Note: You must have a fresh access token (issued in the last 5 minutes) to use this endpoint.
      operationId: listCredentials
      responses:
        "200":
          description: Returns an object containing an array of credentials.
          content:
            application/json:
              schema:
                type: object
                properties:
                  credentials:
                    description: Credentials
                    type: array
                    items:
                      type: object
                      properties:
                        created_at:
                          type: string
                          format: date-time
                          description: Credential timestamp.
                          example: 2021-10-04T12:33:29.823Z
                        phone_number:
                          type: string
                          description: The phone number used as a second factor.
                          example: "+33612345678"
                        friendly_name:
                          type: string
                          description: Credential friendly name.
                          example: "+33612345678"
                        email:
                          type: string
                          description: The email used as a second factor.
                          example: "dude@example.org"
                        type:
                          type: string
                          enum:
                            - "sms"
                            - "email"
                          description: Second factor type.
                          example: sms
      x-codeSamples:
        - lang: "cURL"
          source: |
            curl --request GET \
              --url https://YOUR_DOMAIN/identity/v1/mfa/credentials\
              --header 'Content-Type: application/json' \
              --header 'Authorization: Bearer eyJ0eX...ll4Q2NT' \
  /identity/v1/mfa/stepup:
    post:
      summary: Initiate the stepup flow
      tags:
        - MFA
      description: |
        Initiate the stepup flow.

        > **Note**: This can be done in one of three ways:
        > 1. Using an existing SSO session cookie. In this case, there's no need for the `tkn` in the request body or an `access_token` in the header.
        > 2. Passing a valid `tkn` in the request body. In this case, there's no need for the session cookie or an `access_token` in the header.
        > 3. **Not recommended** Passing the `{access_token}` in the Authorization header. In this case, there's no need for a session cookie or a `tkn` in the request body.
        > 
        > For more details, see [Using the stepup endpoint guide](https://developer.reachfive.com/docs/mfa.html#using-the-stepup-endpoint) in our main docs.

        > #### <i class="fa fa-gear fa-spin fa-2x" style="color: #00c24a"></i> What Next?
        > Use the `token` received in the stepup response as the `step_up` request parameter in the [startPasswordless MFA flow](#operation/startPasswordlessFlow).

      operationId: stepup
      parameters:
        - $ref: "#/components/parameters/access_token"
        - in: cookie
          name: SESSION
          required: false
          schema:
            type: string
          description: |
            Session cookie *(1)*
             > **Note**: In this case, there's no need for the `tkn` in the request body or an `access_token` in the header.
      requestBody:
        content:
          application/json:
            schema:
              oneOf:
                - $ref: "#/components/schemas/OAuth2Params"
                - $ref: "#/components/schemas/OAuth2Params_noTkn"
      responses:
        "200":
          description: Stepup flow successfully initiated.
          content:
            application/json:
              schema:
                type: object
                properties:
                  amr:
                    type: array
                    description: List of available `amr`s on the profile (`sms` if a phone number MFA credential has been added on the profile).
                    items:
                      type: string
                      enum:
                        - "sms"
                        - "email"
                  token:
                    type: string
                    description: The one-time use stepup token used to continue the flow.
                example:
                  {
                    "amr": ["sms"],
                    "token": "cf21S_kHIzh3cF_CHWHGYcL77Fl29D9ALon2etU....C2PQhSAhbVk9FJVt_bVO7ombTt58Dju7Ic",
                  }
        "403":
          description: Forbidden - MFA credential must be available
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    description: Technical error code
                  error_description:
                    type: string
                    description: Source of error
                  error_id:
                    type: string
                    description: Generated error ID
                  error_message_key:
                    type: string
                    description: Message error
                  error_user_msg:
                    type: string
                    description: User-friendly message error
              example:
                {
                  "error_id": "ZjH9WW9P6c",
                  "error_description": "This action is unavailable",
                  "error_message_key": "error.authn.mfa.stepup.unavailable",
                  "error": "interaction_required",
                  "error_user_msg": "This action is unavailable",
                }
      x-codeSamples:
        - lang: "cURL"
          source: |
            curl --request POST \
              --url https://YOUR_DOMAIN/identity/v1/mfa/stepup \
              --header 'Content-Type: application/json' \
              --header 'Authorization: Bearer eyJ0eX...ll4Q2NT' \
              --data '{
                  "response_type":"code",
                  "client_id": "nvR2y0ks...EgCW2dqy",
                  "redirect_uri":"https://redirect_uri.com/",
                  "scope": "openid phone address profile mfa"
              }'
  /identity/v1/mfa/trusteddevices:
    get:
      summary: Get trusted devices
      tags:
        - MFA
      security:
        - OAuth2:
            - "mfa"
      description: |
        Retrieves trusted device(s) for the user.
      operationId: getTrustedDevices
      parameters:
        - $ref: "#/components/parameters/Authorization"
      responses:
        "200":
          description: Success. Shows trusted devices associated with the user.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/getTrustedDevicesResponse"
      x-codeSamples:
        - lang: "cURL"
          source: |
            curl --request GET \
              --url https://YOUR_DOMAIN/identity/v1/mfa/trusteddevices \
              --header 'Authorization: Bearer eyJ0eX...ll4Q2NT' \
  /identity/v1/mfa/trusteddevices/{trusted_device_id}:
    delete:
      summary: Delete trusted device
      tags:
        - MFA
      security:
        - OAuth2:
            - "mfa"
      description: |
        Deletes trusted device for the user.
      operationId: deleteTrustedDevices
      parameters:
        - $ref: "#/components/parameters/Authorization"
        - $ref: "#/components/parameters/trusted_device_id"
      responses:
        "202":
          description: Success. Device removed.
      x-codeSamples:
        - lang: "cURL"
          source: |
            curl --request DELETE \
              --url https://YOUR_DOMAIN/identity/v1/mfa/trusteddevices/TRUSTED_DEVICE_ID \
              --header 'Authorization: Bearer eyJ0eX...ll4Q2NT' \
  /identity/v1/passwordless/start:
    post:
      summary: Start passwordless flow
      tags:
        - Passwordless
      description: |
        Starts the passwordless flow by sending an email or SMS to the user with a single-use auth code or access token (depending on the response type).

        ReachFive recommends using the authorization code flow to ensure a more secure connection.

        To send an SMS, the SMS feature must be activated for your ReachFive account.

        **Note**: The Passwordless feature must be activated for your ReachFive account.

        > #### <i class="fa fa-gear fa-spin fa-2x" style="color: #00c24a"></i> What Next? *MFA/Step-up flow*
        > Use the `challenge_id` received in the PasswordlessMFA response as the `challenge_id` request parameter in the [verifyPasswordless mobile flow](#operation/verifyPasswordlessPost) to verify the step-up authentication.

        > **User language note**:
        > 
        > If you are using the ReachFive SDK, the user `lang` attribute is taken from the browser language. If you are calling ReachFive API endpoints **directly**, the `lang` attribute is taken from the information sent in the [Accept-Language header](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept-Language).
        > 
        > See [User language](#section/User-language) for more details.
      operationId: startPasswordlessFlow
      requestBody:
        content:
          application/json:
            schema:
              oneOf:
                - $ref: "#/components/schemas/PasswordlessEmail"
                - $ref: "#/components/schemas/PasswordlessSMS"
                - $ref: "#/components/schemas/PasswordlessMFA"
            examples:
              Send an email:
                value:
                  {
                    "client_id": "YOUR_CLIENT_ID",
                    "response_type": "code",
                    "scope": "openid profile email phone",
                    "display": "page",
                    "redirect_uri": "https://mybrand.com/login/callback",
                    "email": "batman@gmail.com",
                    "state": "ABC123xyzPOP",
                    "origin": "https://example.com"
                  }
              Send an SMS:
                value:
                  {
                    "client_id": "YOUR_CLIENT_ID",
                    "response_type": "code",
                    "scope": "openid profile email phone",
                    "display": "page",
                    "redirect_uri": "https://mybrand.com/login/callback",
                    "phone_number": "+33633445566",
                    "state": "ABC123xyzPOP",
                    "origin": "https://example.com"
                  }
              SMS with MFA:
                value:
                  {
                    "step_up": "+3y8...fJKRyZw9iuF2ele9LCuk-IVy",
                    "auth_type": "sms",
                    "state": "ABC123xyzPOP"
                  }
      responses:
        "204":
          description: An email or SMS will be sent to the specified address/number.
          content:
            application/json:
              schema:
                type: object
                properties:
                  challenge_id:
                    type: string
                    description: The challenge ID.
                    example: nvR2...snWaPUqTrz
        "400":
          description: Bad request
          content:
            application/json:
              schema:
                type: object
                properties:
                  error_id:
                    type: string
                    description: Generated error ID
                    example: "kp7RN4XdSP"
                  error_description:
                    type: string
                    description: Source of error
                    example: "Cannot deserialize the request body"
                  error_message_key:
                    type: string
                    description: Message error
                    example: "error.requestDeserialization"
                  error:
                    type: string
                    description: Technical error code
                    example: "invalid_request"
                  error_user_msg:
                    type: string
                    description: User-friendly message error
                    example: "Cannot deserialize the request body"
        "401":
          description: Unauthorized; Client authentication failed
          content:
            application/json:
              schema:
                type: object
                properties:
                  error_id:
                    type: string
                    description: Generated error ID
                    example: "4VjRIN0C0J"
                  error_description:
                    type: string
                    description: Source of error
                    example: "Client authentication failed"
                  error:
                    type: string
                    description: Technical error code
                    example: "invalid_client"
        "403":
          description: Forbidden; Redirect URL is not allowed
          content:
            application/json:
              schema:
                type: object
                properties:
                  error_id:
                    type: string
                    description: Generated error ID
                    example: "9Wgj72IpcL"
                  error_description:
                    type: string
                    description: Source of error
                    example: "The redirect url is not allowed."
                  error_message_key:
                    type: string
                    description: Message error
                    example: "error.client.redirectUrlNotAllowed"
                  error:
                    type: string
                    description: Technical error code
                    example: "access_denied"
                  error_user_msg:
                    type: string
                    description: User-friendly message error
                    example: "The redirect url is not allowed."
      x-codeSamples:
        - lang: "cURL"
          source: |
            curl --request POST \
              --url https://YOUR_DOMAIN/identity/v1/passwordless/start \
              --header 'Content-Type: application/json' \
              --header 'Authorization: Bearer eyJ0eX...ll4Q2NT' \
              --data '{
                  "client_id": "YOUR_CLIENT_ID",
                  "response_type": "code",
                  "scope": "openid profile email phone",
                  "display": "page",
                  "redirect_uri": "https://mybrand.com/login/callback",
                  "email": "batman@gmail.com"
              }'
  /identity/v1/passwordless/verify:
    get:
      summary: Verify passwordless
      tags:
        - Passwordless
      description: |
        Log in a user by initiating the authentication code flow using the verification code (*via SMS or email*) or by clicking on the link provided in the email.

        **Notes**:
        - You must ensure the `redirect_uri` provided at the start of the flow points to a page where the ReachFive SDK is running.
        - If you are unable to support the code flow, you can set the `response_type` to `token` at the start of the flow to obtain an access token - but this is not recommended.

        > **Warning**: The Passwordless feature must be enabled on your ReachFive account.
      operationId: verifyPasswordless
      parameters:
        - in: query
          name: verification_code
          required: true
          schema:
            type: integer
            pattern: "[0-9]{6}"
          description: |
            Specifies the passwordless verification code.

            **Note**: The `c` parameter also works here. Note that `c` is used by magic links to shorten the URL size.
        - in: query
          name: t
          required: true
          schema:
            type: string
            example: 0irYKCv3VnjfpwfnhMlIFvd1iVPNxXOzx_710B8Lr
          description: |
            Opaque token containing the request parameters.
      responses:
        "303":
          $ref: "#/components/responses/303redirect"
        "401":
          description: Invalid client id
      x-codeSamples:
        - lang: "cURL"
          source: |
            curl --request GET \
              --url https://YOUR_DOMAIN/identity/v1/passwordless/verify?email=bruce.wayne@wayne.com&scope=openid%20email%20phone%20profile&redirect_uri=https://mybrand.com/login/callback&client_id=k6ShTOsHfVE5aXu4uW0i&verification_code=121516&response_type=code&display=page \
              --header 'Content-Type: application/json' \
              --header 'Authorization: Bearer eyJ0eX...ll4Q2NT'
    post:
      summary: Verify passwordless
      tags:
        - Passwordless
      description: |
        Log in a user by initiating the authentication code flow using the verification code which is received either via SMS or email.
        The `verification_code` is invalid after *3* failed attempts.

        **Note**: If you are unable to support the code flow, you can set the `response_type` to `token` at the start of the flow to obtain an access token - but this is not recommended.

        > **Warning**: The Passwordless feature must be activated for your ReachFive account.
      operationId: verifyPasswordlessPost
      parameters:
        - $ref: "#/components/parameters/attackProtectionBypass"
        - $ref: "#/components/parameters/trueClientIp"
        - $ref: "#/components/parameters/trueClientIpKey"
        - $ref: "#/components/parameters/userAgent"
      requestBody:
        content:
          application/json:
            schema:
              oneOf:
                - $ref: "#/components/schemas/PasswordlessVerify"
                - $ref: "#/components/schemas/PasswordlessVerifyEmail"
                - $ref: "#/components/schemas/PasswordlessVerifyMFA"
      responses:
        "200":
          description: |
            Success. 
            
            This applies to `PasswordlessVerifyMFA` only. If `trust_device` is `true`, the trusted device cookie (`__Host-trusted-device-id`) is returned in the response header to send to the User-Agent.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/verifyPasswordlessPostResponse"
          headers:
            __Host-trusted-device-id:
              schema:
                type: string
              description: |
                The trusted device cookie. This can then be used as a header cookie parameter when logging in.

                `Set-Cookie: __Host-trusted-device-id=00112233-4455-6677-8899-aabbccddeeff`

                This is only applicable when `trust_device` is set to `true` in the request.
        "400":
          description: Invalid client id
      x-codeSamples:
        - lang: "cURL"
          source: |
            curl --request POST \
              --url https://YOUR_DOMAIN/identity/v1/passwordless/verify \
              --header 'Content-Type: application/json' \
              --header 'Authorization: Bearer eyJ0eX...ll4Q2NT' \
              --data '{
                  "phone_number": "+33111111113",
                  "verification_code": "521525"
              }'
  /identity/v1/logout:
    get:
      summary: Log out of SSO session
      tags:
        - Login/Signup
      description: This operation destroys a Single Sign-On (SSO) session and optionally redirects you to a specified URL.
      operationId: destroySSOsession
      parameters:
        # - $ref: '#/components/parameters/Authorization'
        - in: cookie
          name: SESSION
          schema:
            type: string
          description: Session cookie
        - in: query
          name: redirect_to
          required: false
          schema:
            type: string
            example: https://www.example.com/welcome-back
          description: |
            Optional; specifies the URL to redirect the client after the SSO session is destroyed.

            This URL must be whitelisted in the `Allowed logout callback URLs` field of your ReachFive SSO settings (`Security` => `SSO` on the console).
            Whitelisted URLs can be used with all account clients. 

            **Note**: If no `redirect_to` parameter is passed, the user is not redirected and receives a `204` HTTP response code (if successful).
      responses:
        "204":
          description: Successfully logged out of the SSO session; no redirect.
        "303":
          description: Successfully logged out of the SSO session; redirected to the URL specified in `redirect_to`.
        "400":
          description: Invalid `redirect_to` URL
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorFields"
      x-codeSamples:
        - lang: "cURL"
          source: |
            curl --request GET \
              --url https://YOUR_DOMAIN/identity/v1/logout?\
                redirect_to=https://...e.com/welcome-back \
              --header 'Authorization: Bearer eyJ0eX...ll4Q2NT'
  /oauth/introspect:
    post:
      security:
        - OAuth2:
            - "none"
      summary: Introspect a token
      tags:
        - OAuth
      description: |
        This endpoint returns the content of an access, or refresh token.

        The client must belong to the same account as the token.

        In addition, third-party clients can only read tokens which they generated.<br>
        First-party clients can read access tokens from any other identity client of the account.

        To decode tokens, read [this page](../docs/decode-tokens.html).

        See [RFC 7662](https://tools.ietf.org/html/rfc7662) for more details.
      operationId: introspectToken
      requestBody:
        content:
          application/x-www-form-urlencoded:
            schema:
              type: object
              properties:
                client_id:
                  type: string
                  description: ReachFive client ID
                client_secret:
                  type: string
                  description: ReachFive client secret
                token:
                  type: string
                  description: The Access or Refresh Token to introspect
              required:
                - client_id
                - client_secret
                - token
      responses:
        "200":
          description: Return properties of the token
          content:
            application/json:
              examples:
                Access token:
                  value:
                    {
                      "sub": "AW9Hh3OaBQkplD8WGLh4",
                      "aud": ["https://client-account.reach5.net/identity"],
                      "scope": "address email full_write offline_access openid profile",
                      "iss": "https://client-account.reach5.net",
                      "active": true,
                      "token_type": "access_token",
                      "exp": 1582383467,
                      "iat": 1582297067,
                      "client_id": "k6ShTTsHfVE5aXu5uW0i",
                    }
                Refresh token:
                  value:
                    {
                      "sub": "AW9Hh3OaBQkplD8WGLh4",
                      "aud": ["https://client-account.reach5.net/identity"],
                      "scope": "address email full_write offline_access openid profile",
                      "iss": "https://client-account.reach5.net",
                      "active": true,
                      "token_type": "refresh_token",
                      "exp": 1582383467,
                      "iat": 1582297067,
                      "client_id": "k6ShTTsHfVE5aXu5uW0i",
                    }
      x-codeSamples:
        - lang: "cURL"
          source: |
            curl --request POST \
              --url https://YOUR_DOMAIN/oauth/introspect \
              --header 'Content-Type: application/x-www-form-urlencoded' \
              --data 'client_id=CLIENT_ID1&client_secret=CLIENT_SECRET&token=TOKEN'
  /identity/v1/grants:
    get:
      security:
        - OAuth2:
            - "none"
      summary: Get user grants
      tags:
        - Grants
      description: Get user grants on all third-party clients.
      operationId: getUserGrants
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                type: object
                properties:
                  grants:
                    description: User grants
                    type: array
                    items:
                      type: object
                      properties:
                        date:
                          type: string
                          format: date-time
                          description: Grant timestamp.
                        scope:
                          type: string
                          description: List of space-delimited, case-sensitive strings representing the requested scope.
                        client_name:
                          type: string
                          description: Third-party client name.
                        client_id:
                          type: string
                          description: Third-party client ID.
                        logo:
                          type: string
                          description: Third-party client logo path.
                  scope_definitions:
                    description: Custom scope definitions
                    type: object
                    properties:
                      name:
                        description: Scope name.
                        type: string
                      translations:
                        type: array
                        description: Scope translations.
                        items:
                          type: object
                          properties:
                            lang_code:
                              type: string
                              description: Two-letter locale code in the [ISO 639-1](https://en.wikipedia.org/wiki/ISO_639-1) format.
                              maxLength: 2
                              minLength: 2
                            description:
                              type: string
                              description: The localized scope description.
                            label:
                              type: string
                              description: The localized scope label.
                example:
                  {
                    "grants":
                      [
                        {
                          "date": "2020-03-17T09:02:41.266Z",
                          "scope": "email openid phone profile",
                          "client_name": "My Third-party client",
                          "client_id": "oQPfSupG0...O487Y",
                          "logo": "filepath/logo/my_third_party_logo.png",
                        },
                        {
                          "date": "2020-03-18T15:58:05.375Z",
                          "scope": "email openid registration",
                          "client_name": "My Third-party client 2",
                          "client_id": "VLJwJJ6W...0IyFT",
                          "logo": "filepath/logo/my_third_party_2_logo.png",
                        },
                      ],
                    "scope_definitions":
                      [
                        {
                          "translations":
                            [
                              {
                                "lang_code": "en",
                                "description": "Read the fidelity card ID",
                                "label": "fidelity_card",
                              },
                            ],
                          "name": "fidelity_card",
                        },
                      ],
                  }
      x-codeSamples:
        - lang: "cURL"
          source: |
            curl --request GET \
              --url https://YOUR_DOMAIN/identity/v1/grants\
              --header 'Content-Type: application/json' \
              --header 'Authorization: Bearer eyJ0eX...ll4Q2NT' \
  /identity/v1/grants/{clientId}:
    get:
      security:
        - OAuth2:
            - "none"
      summary: Get user grants by client ID
      tags:
        - Grants
      description: Get user grants on a specific third-party client.
      operationId: getClientUserGrants
      responses:
        "200":
          description: OK
          content:
            application/json:
              schema:
                type: object
                properties:
                  grants:
                    description: User grants
                    type: array
                    items:
                      type: object
                      properties:
                        date:
                          type: string
                          format: date-time
                          description: Grant timestamp.
                        scope:
                          type: string
                          description: List of space-delimited, case-sensitive strings representing the requested scope.
                        client_name:
                          type: string
                          description: Third-party client name.
                        client_id:
                          type: string
                          description: Third-party client ID.
                        logo:
                          type: string
                          description: Third-party client logo path.
                  scope_definitions:
                    description: Custom scope definitions
                    type: object
                    properties:
                      name:
                        description: Scope name
                        type: string
                      translations:
                        type: array
                        description: Scope translations.
                        items:
                          type: object
                          properties:
                            lang_code:
                              type: string
                              description: Two-letter locale code in the [ISO 639-1](https://en.wikipedia.org/wiki/ISO_639-1) format.
                              maxLength: 2
                              minLength: 2
                            description:
                              type: string
                              description: The localized scope description.
                            label:
                              type: string
                              description: The localized scope label.
                example:
                  {
                    "grants":
                      [
                        {
                          "date": "2020-03-17T09:02:41.266Z",
                          "scope": "email openid phone profile fidelity_card",
                          "client_name": "My Third-party client",
                          "client_id": "oQPfSupG0...O487Y",
                          "logo": "filepath/logo/my_third_party_logo.png",
                        },
                      ],
                    "scope_definitions":
                      [
                        {
                          "translations":
                            [
                              {
                                "lang_code": "en",
                                "description": "Read the fidelity card ID",
                                "label": "fidelity_card",
                              },
                            ],
                          "name": "fidelity_card",
                        },
                      ],
                  }
      x-codeSamples:
        - lang: "cURL"
          source: |
            curl --request GET \
              --url https://YOUR_DOMAIN/identity/v1/grants/CLIENT_ID\
              --header 'Content-Type: application/json' \
              --header 'Authorization: Bearer eyJ0eX...ll4Q2NT'
    delete:
      security:
        - OAuth2:
            - "none"
      summary: Delete user grants for a client ID
      tags:
        - Grants
      description: |
        Delete user grants for a specific third-party client.
      operationId: deleteClientUserGrants
      responses:
        "204":
          description: "No content"
      x-codeSamples:
        - lang: "cURL"
          source: |
            curl --request DELETE \
              --url https://YOUR_DOMAIN/identity/v1/grants/CLIENT_ID \
              --header 'Content-Type: application/json' \
              --header 'Authorization: Bearer eyJ0eX...ll4Q2NT'
  /identity/v1/webauthn/signup-options:
    post:
      security:
        - OAuth2:
            - "none"
      summary: Create new options for user signup
      tags:
        - FIDO2
      description: |
        The user requests to register a new account for the first time.

        **IMPORTANT**: 
        - You must activate the **WebAuthn** feature in your ReachFive console.
        - You must whitelist the `origin` URL in your WebAuthn settings.

        See [the ReachFive FIDO2 documentation](https://developer.reachfive.com/docs/fido2.html) for more details on doing this in the console.
      operationId: createSignupOptions
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                client_id:
                  description: Your ReachFive client's identifier.
                  type: string
                origin:
                  type: string
                  description: The domain of the origin. It must be a valid URL.
                friendly_name:
                  type: string
                  description: The name of the new device.
                profile:
                  type: object
                  description: The user attributes, for example the email and birthdate.
                scope:
                  type: string
                  description: |
                    Space-delimited list of permissions.<br>
                    **NOTE**
                    - The required permissions are documented for each API endpoint.
                redirect_url:
                  description: The URL sent in the verification email to which the profile is redirected.
                  type: string
                return_to_after_email_confirmation:
                  description: Returned in the `redirect_url` as a query parameter, this parameter is used as the post-email confirmation URL. It must be a valid URL.
                  type: string
              required:
                - client_id
                - origin
                - friendly_name
                - profile
              example:
                {
                  "client_id": "k3ShTUsHgVE5aWu5uW0i",
                  "origin": "https://demo.reachfive.com",
                  "friendly_name": "SamsungS7",
                  "profile":
                    {
                      "given_name": "John",
                      "family_name": "Doe",
                      "email": "john.doe@example.com",
                      "birthdate": "1983-11-13",
                    },
                  "scope": "openid email phone profile full_write",
                  "redirect_url": "https://example-email-verification.com",
                }
      responses:
        "200":
          description: OK - Return the signup options
          content:
            application/json:
              schema:
                type: object
                properties:
                  friendly_name:
                    type: string
                    description: The name of the new device.
                  options:
                    type: object
                    description: The signup options.
                    properties:
                      public_key:
                        description: Public key
                        type: object
                        properties:
                          attestation:
                            type: string
                            enum:
                              - "none"
                              - "indirect"
                              - "direct"
                            description: |
                              - `none` means the relying party is not interested in authenticator attestation.
                              - `indirect` indicates the relying party prefers a verifiable attestation statement but allows the client to decide how to obtain it. 
                              - `direct` indicates the relying party wants to receive the attestation statement.
                          authenticator_selection:
                            type: object
                            description: Specify authenticator requirements
                            properties:
                              # authenticator_attachement:
                              #   type: string
                              #   enum:
                              #     - "platform"
                              #     - "cross-platform"
                              #   description: |
                              #     Filters eligible authenticator by type:
                              #     - `platform` indicates a platform authenticator, such as Windows Hello.
                              #     - `cross-platform` value indicates a roaming authenticator, such as a security key.
                              # require_resident_key:
                              #   type: boolean
                              #   description: When `true`, the authenticator must create a client side resident private key.
                              resident_key:
                                type: string
                                enum:
                                  - preferred
                                description: |
                                  The relying party's requirements for resident credentials:
                                  
                                  - `preferred`: this value indicates the relying party prefers creating a resident credential, but will accept a non-resident credential.
                              user_verification:
                                type: string
                                enum:
                                  - "preferred"
                                description: |
                                  The relying party's requirements regarding user verification. Eligible authenticators are filtered to only those capable of satisfying this requirement:

                                  - `preferred`: this value indicates that the relying party prefers user verification for the operation if possible, but will not fail if the response does not have the user_verification flag set.

                          challenge:
                            type: string
                            description: Should be randomly generated by the relying party in order to prevent replay attacks.
                          exclude_credentials:
                            type: array
                            description: Limits creation of multiple credentials for the same account on a single authenticator.
                            items:
                              type: object
                              properties:
                                id:
                                  type: string
                                  description: The identifier of the credential.
                                type:
                                  type: string
                                  description: The type of the credential. Only one type `public-key`.
                                transports:
                                  type: array
                                  description: List of transports the client can use to find the credential.
                                  items:
                                    type: string
                          pub_key_cred_params:
                            type: array
                            description: Specifies which cryptographic algorithms the relying party supports.
                            items:
                              type: object
                              properties:
                                alg:
                                  type: integer
                                  description: Cryptographic signature algorithm preference specified by COSE Algorithms registry.
                                type:
                                  type: string
                                  description: Only one type `public-key`.
                          rp:
                            type: object
                            description: Relying party information.
                            properties:
                              id:
                                type: string
                                description: Must equal the domain of the origin seen by the client, or the origin must be a subdomain of the id. If `id` is omitted, then origins effective domain is used.
                              name:
                                type: string
                                description: The relying party's name set in the ReachFive console.
                          timeout:
                            type: integer
                            description: Time, in milliseconds, that the caller is willing to wait for the call to complete.
                          user:
                            type: object
                            description: Data about the user account.
                            properties:
                              id:
                                type: string
                                description: Generated by the relying party and used to uniquely identify a user.
                              name:
                                type: string
                                description: Traditional username
                              display_name:
                                type: string
                                description: User-friendly name which may be displayed to the user.
                example:
                  {
                    "friendly_name": "SamsungS7",
                    "option":
                      {
                        "public_key":
                          {
                            "attestation": "direct",
                            "authenticator_selection":
                              {
                                "resident_key": "preferred",
                                "user_verification": "preferred"
                              },
                            "challenge": "qNqrdXUrk5S7dCM1MAYH3qSVDXznb-6prQoGqiACR10=",
                            "exclude_credentials": [],
                            "pub_key_cred_params":
                              [{ "alg": -7, "type": "public-key" }],
                            "rp":
                              {
                                "id": "demo.reachfive.com",
                                "name": "ReachFive Demo",
                              },
                            "timeout": 120000,
                            "user":
                              {
                                "name": "anewuser@reachfive.io",
                                "display_name": "ReachFive demo user",
                                "id": "bz9ZDfHzOBLycqISTAdWwWIZt8VO-6mT3hBNXS5jwmY=",
                              },
                          },
                      },
                  }
        "403":
          description: Forbidden - WebAuthn feature must be enabled
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    description: Technical error code
                  error_description:
                    type: string
                    description: Source of error
                  error_id:
                    type: string
                    description: Generated error ID
                  error_message_key:
                    type: string
                    description: Message error
                  error_user_msg:
                    type: string
                    description: User-friendly message error
              example:
                {
                  "error_id": "6wqEIKLK3L",
                  "error": "error.webauthn.featureDisabled",
                  "error_description": "The Webauthn must be enabled to register access WebAuthn functionalities",
                }
  /identity/v1/webauthn/signup:
    post:
      security:
        - OAuth2:
            - "none"
      summary: Sign up a new user
      tags:
        - FIDO2
      description: |
        The server verifies the signup data, registers a new user, and sends a verification code or token to the email address provided.

        **IMPORTANT**: 
        - You must activate the **WebAuthn** feature in your ReachFive console.

      operationId: signupWithCredentials
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                public_key_credential:
                  description: The credential object returned by the WebAuthn API containing the public key and other attributes used to validate the sign up events.
                  properties:
                    id:
                      type: string
                      description: Credential identifier.
                    raw_id:
                      type: string
                      description: An `ArrayBuffer` that holds the globally unique identifier for this public key credentials.
                    type:
                      type: string
                      description: The type of the credential. Only one type `public-key`.
                    response:
                      type: object
                      description: Contains the credential public key, and metadata which can be used by the relying party to assess the characteristics of the credential.
                      properties:
                        attestation_object:
                          type: string
                          description: Contains the authenticator data and attestation statement.
                        client_data_JSON:
                          type: string
                          description: Contains the JSON-serialized data passed to the authenticator by the client in order to generate the credential.
                webauthn_id:
                  type: string
                  description: The user identifier returned in the signup options.
              required:
                - public_key_credential
                - webauthn_id
              example:
                {
                  "public_key_credential":
                    {
                      "id": "Ab0o1IJ4Yt96JAVuaEGpxZL...VDbomoDHi5enCMU38NA",
                      "raw_id": "Ab0o1IJ4Yt96JxZLNq-nc8sPNh...k5yforHpGaUNqUA6MJkGvsVDbomoDHi5enCMU38NA",
                      "type": "public-key",
                      "response":
                        {
                          "client_data_json": "eyJ0eXBlIjoid2ViYXV0a...28uZ2wveWFiUGV4In0",
                          "attestation_object": "o2NmbXRkbm9uZWdhdHRTdG10oGhhdXRoRGF0YVjxSZYN5YgOjGh0NBcPZHZgW4_...EF9gU_OdtQ",
                        },
                    },
                  "webauthn_id": "4r-H44Wn7KuZ5KaO6Yiv4YSL7Jqe5bSP4bi445WM45G17Iqy4qax47mE6KyQ6JmX",
                }
      responses:
        "200":
          description: OK - Returns an authentication token
          content:
            application/json:
              schema:
                type: object
                properties:
                  tkn:
                    type: string
                    description: The one-time use authentication token
                example: { "tkn": "xhNGxw...70zx32" }
        "403":
          description: Forbidden - WebAuthn is not enabled.
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    description: Technical error code
                  error_description:
                    type: string
                    description: Source of error
                  error_id:
                    type: string
                    description: Generated error ID
                  error_message_key:
                    type: string
                    description: Message error
                  error_user_msg:
                    type: string
                    description: User-friendly message error
              example:
                {
                  "error_id": "6wqEIKLK3L",
                  "error": "error.webauthn.featureDisabled",
                  "error_description": "The Webauthn must be enabled to register access WebAuthn functionalities",
                }
  /identity/v1/webauthn/registration-options:
    post:
      security:
        - OAuth2:
            - "full_write"
      summary: Create new options for registration
      tags:
        - FIDO2
      description: |
        The user requests to create a new account.

        **Note**: The access token must have been generated in the **last 5 minutes**,. The authentication token will contain the ReachFive client ID and the user's identifier.

        **Warning**: 
        - The WebAuthn feature must be activated for your ReachFive account.
        - The `origin` URL must be whitelisted in the WebAuthn settings.
        - A user cannot register different credentials for the same device.
      operationId: createRegistrationOptions
      parameters:
        - $ref: "#/components/parameters/Authorization"
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                origin:
                  type: string
                  description: The domain of the origin.
                friendly_name:
                  type: string
                  description: The name of the new device.
              required:
                - origin
                - friendly_name
              example:
                { "origin": "demo.reachfive.com", "friendly_name": "SamsungS7" }
      responses:
        "200":
          description: OK - Return the registration options
          content:
            application/json:
              schema:
                type: object
                properties:
                  friendly_name:
                    type: string
                    description: The name of the new device.
                  options:
                    type: object
                    description: The registration options.
                    properties:
                      public_key:
                        description: Public key
                        type: object
                        properties:
                          attestation:
                            type: string
                            enum:
                              - "none"
                              - "indirect"
                              - "direct"
                            description: |
                              - `none` means the relying party is not interested in authenticator attestation.
                              - `indirect` indicates the relying party prefers a verifiable attestation statement but allows the client to decide how to obtain it. 
                              - `direct` indicates the relying party wants to receive the attestation statement.
                          authenticator_selection:
                            type: object
                            description: Specify authenticator requirements
                            properties:
                              # authenticator_attachement:
                              #   type: string
                              #   enum:
                              #     - "platform"
                              #     - "cross-platform"
                              #   description: |
                              #     Filters eligible authenticator by type:
                              #     - `platform` indicates a platform authenticator, such as Windows Hello.
                              #     - `cross-platform` value indicates a roaming authenticator, such as a security key.
                              # require_resident_key:
                              #   type: boolean
                              #   description: When `true`, the authenticator must create a client side resident private key.
                              resident_key:
                                type: string
                                enum:
                                  - preferred
                                description: |
                                  The relying party's requirements for resident credentials:

                                  - `preferred`: this value indicates the relying party prefers creating a resident credential, but will accept a non-resident credential.
                              user_verification:
                                type: string
                                enum:
                                  - "preferred"
                                description: |
                                  The relying party's requirements regarding user verification. Eligible authenticators are filtered to only those capable of satisfying this requirement:

                                  - `preferred`: this value indicates that the relying party prefers user verification for the operation if possible, but will not fail if the response does not have the user_verification flag set.
                          challenge:
                            type: string
                            description: Should be randomly generated by the relying party in order to prevent replay attacks.
                          exclude_credentials:
                            type: array
                            description: Limits creation of multiple credentials for the same account on a single authenticator.
                            items:
                              type: object
                              properties:
                                id:
                                  type: string
                                  description: The identifier of the credential.
                                type:
                                  type: string
                                  description: The type of the credential. Only one type `public-key`.
                                transports:
                                  type: array
                                  description: List of transports the client can use to find the credential.
                                  items:
                                    type: string
                          pub_key_cred_params:
                            type: array
                            description: Specifies which cryptographic algorithms the relying party supports.
                            items:
                              type: object
                              properties:
                                alg:
                                  type: integer
                                  description: Cryptographic signature algorithm preference specified by COSE Algorithms registry.
                                type:
                                  type: string
                                  description: Only one type `public-key`.
                          rp:
                            type: object
                            description: Relying party information.
                            properties:
                              id:
                                type: string
                                description: Must equal the domain of the origin seen by the client, or the origin must be a subdomain of the id. If `id` is omitted, then origins effective domain is used.
                              name:
                                type: string
                                description: The relying party's name set in the ReachFive console.
                          timeout:
                            type: integer
                            description: Time, in milliseconds, that the caller is willing to wait for the call to complete.
                          user:
                            type: object
                            description: Data about the user account.
                            properties:
                              id:
                                type: string
                                description: Generated by the relying party and used to uniquely identify a user.
                              name:
                                type: string
                                description: Traditional username
                              display_name:
                                type: string
                                description: User-friendly name which may be displayed to the user.
                example:
                  {
                    "friendly_name": "SamsungS7",
                    "option":
                      {
                        "public_key":
                          {
                            "attestation": "direct",
                            "authenticator_selection":
                              {
                                "resident_key": "preferred",
                                "user_verification": "preferred"
                              },
                            "challenge": "qNqrdXUrk5S7dCM1MAYH3qSVDXznb-6prQoGqiACR10=",
                            "exclude_credentials": [],
                            "pub_key_cred_params":
                              [{ "alg": -7, "type": "public-key" }],
                            "rp":
                              {
                                "id": "demo.reachfive.com",
                                "name": "ReachFive Demo",
                              },
                            "timeout": 120000,
                            "user":
                              {
                                "name": "anewuser@reachfive.io",
                                "display_name": "ReachFive demo user",
                                "id": "bz9ZDfHzOBLycqISTAdWwWIZt8VO-6mT3hBNXS5jwmY=",
                              },
                          },
                      },
                  }
        "400":
          description: Bad request - Device already associated to credential
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    description: Technical error code
                  error_description:
                    type: string
                    description: Source of error
                  error_id:
                    type: string
                    description: Generated error ID
                  error_message_key:
                    type: string
                    description: Message error
                  error_user_msg:
                    type: string
                    description: User-friendly message error
              example:
                {
                  "error_id": "aMDG5lIAks",
                  "error_description": "Friendly name 'MacIntel' already associated to credential 'AValy7JUf5YjmYBdgP_xv5ZNJfyy0MNz8gHDJI6jQfqONDVfTza7Eq-ICNk6vcBKVT2NOavKTMRSiTjduwN7dAs_EcF3j9Zadb5EIBYq3KZgUw=='",
                  "error_message_key": "Friendly name 'MacIntel' already associated to credential 'AValy7JUf5YjmYBdgP_xv5ZNJfyy0MNz8gHDJI6jQfqONDVfTza7Eq-ICNk6vcBKVT2NOavKTMRSiTjduwN7dAs_EcF3j9Zadb5EIBYq3KZgUw=='",
                  "error": "invalid_request",
                  "error_user_msg": "Friendly name 'MacIntel' already associated to credential 'AValy7JUf5YjmYBdgP_xv5ZNJfyy0MNz8gHDJI6jQfqONDVfTza7Eq-ICNk6vcBKVT2NOavKTMRSiTjduwN7dAs_EcF3j9Zadb5EIBYq3KZgUw=='",
                }
        "401":
          description: Unauthorized
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    description: Technical error code
                  error_description:
                    type: string
                    description: Source of error
                  error_id:
                    type: string
                    description: Generated error ID
                  error_message_key:
                    type: string
                    description: Message error
                  error_user_msg:
                    type: string
                    description: User-friendly message error
              examples:
                Access token missing:
                  value:
                    {
                      "error": "invalid_request",
                      "error_description": "Access token missing",
                      "error_id": "nikHDzD0gt",
                      "error_message_key": "error.accessToken.missing",
                      "error_user_msg": "Access token missing",
                    }
                Access token is not fresh enough.:
                  value:
                    {
                      "error": "invalid_grant",
                      "error_description": "Access token is not fresh enough.",
                      "error_id": "4BfgB3uaVc",
                      "error_message_key": "error.accessToken.freshness",
                      "error_user_msg": "Access token is not fresh enough.",
                    }
        "403":
          description: Forbidden - WebAuthn feature must be enabled
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    description: Technical error code
                  error_description:
                    type: string
                    description: Source of error
                  error_id:
                    type: string
                    description: Generated error ID
                  error_message_key:
                    type: string
                    description: Message error
                  error_user_msg:
                    type: string
                    description: User-friendly message error
              example:
                {
                  "error_id": "6wqEIKLK3L",
                  "error": "error.webauthn.featureDisabled",
                  "error_description": "The Webauthn must be enabled to register access WebAuthn functionalities",
                }
      x-codeSamples:
        - lang: "cURL"
          source: |
            curl --request POST \
              --url https://YOUR_DOMAIN/identity/v1/webauthn/makeCredentials \
              --header 'Content-Type: application/json' \
              --header 'Authorization: Bearer eyJ0eX...ll4Q2NT'
  /identity/v1/webauthn/registration:
    post:
      security:
        - OAuth2:
            - "full_write"
      summary: Register new credential
      tags:
        - FIDO2
      description: |
        This endpoint registers new credentials for an *existing* user. The server then verifies the registration data.

        **Note**: The access token must have been generated in the **last 5 minutes**,. The authentication token will contain the ReachFive client ID and the user's identifier.

        **Important**: The WebAuthn feature must be activated for your ReachFive account.
      operationId: registerWithCredentials
      parameters:
        - $ref: "#/components/parameters/Authorization"
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                id:
                  type: string
                  description: Credential identifier.
                raw_id:
                  type: string
                  description: An `ArrayBuffer` that holds the globally unique identifier for this public key credentials.
                type:
                  type: string
                  description: The type of the credential. Only one type `public-key`.
                response:
                  type: object
                  description: Contains the credential public key, and metadata which can be used by the relying party to assess the characteristics of the credential.
                  properties:
                    attestation_object:
                      type: string
                      description: Contains the authenticator data and attestation statement.
                    client_data_JSON:
                      type: string
                      description: Contains the JSON-serialized data passed to the authenticator by the client in order to generate the credential.
              required:
                - id
                - raw_id
                - type
                - response
              example:
                {
                  "id": "X9FrwMfmzj...",
                  "raw_id": "X9FrwMfmzj...",
                  "type": "public-key",
                  "response":
                    {
                      "attestation_object": "o2NmbXRoZmlk...",
                      "client_data_JSON": "eyJjaGFsbGVuZ...",
                    },
                }
      responses:
        "200":
          description: Credentials registered
        "401":
          description: Unauthorized
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    description: Technical error code
                  error_description:
                    type: string
                    description: Source of error
                  error_id:
                    type: string
                    description: Generated error ID
                  error_message_key:
                    type: string
                    description: Message error
                  error_user_msg:
                    type: string
                    description: User-friendly message error
              examples:
                Access token missing:
                  value:
                    {
                      "error": "invalid_request",
                      "error_description": "Access token missing",
                      "error_id": "nikHDzD0gt",
                      "error_message_key": "error.accessToken.missing",
                      "error_user_msg": "Access token missing",
                    }
                Access token is not fresh enough.:
                  value:
                    {
                      "error": "invalid_grant",
                      "error_description": "Access token is not fresh enough.",
                      "error_id": "4BfgB3uaVc",
                      "error_message_key": "error.accessToken.freshness",
                      "error_user_msg": "Access token is not fresh enough.",
                    }
        "403":
          description: Forbidden - WebAuthn feature must be enabled
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    description: Technical error code
                  error_description:
                    type: string
                    description: Source of error
                  error_id:
                    type: string
                    description: Generated error ID
                  error_message_key:
                    type: string
                    description: Message error
                  error_user_msg:
                    type: string
                    description: User-friendly message error
              example:
                {
                  "error_id": "6wqEIKLK3L",
                  "error": "error.webauthn.featureDisabled",
                  "error_description": "The Webauthn must be enabled to register access WebAuthn functionalities",
                }
      x-codeSamples:
        - lang: "cURL"
          source: |
            curl --request POST \
              --url https://YOUR_DOMAIN/identity/v1/webauthn/credentials \
              --header 'Content-Type: application/json' \
              --header 'Authorization: Bearer eyJ0eX...ll4Q2NT'-
    get:
      security:
        - OAuth2:
            - "profile"
      summary: Get the credentials of a user
      tags:
        - FIDO2
      description: |
        Get all registered user's credentials. 

        **Note**: The access token must have been generated in the **last 5 minutes**,. The authentication token will contain the ReachFive client ID and the user's identifier.

        **Warning**: The WebAuthn feature must be activated for your ReachFive account.
      operationId: getCredentials
      parameters:
        - $ref: "#/components/parameters/Authorization"
      responses:
        "200":
          description: OK - Return the credentials of the user
          content:
            application/json:
              schema:
                type: array
                description: List of the registred credentials of the user.
                items:
                  type: object
                  properties:
                    friendly_name:
                      type: string
                      description: The name of the device.
                    id:
                      type: string
                      description: The identifier of the credential.
                example:
                  [
                    {
                      "friendly_name": "SamsungS7",
                      "id": "AValy7JUf5YjmYBdgP_xv5ZNJfyy0MNz8gHDJI6jQfqONDVfTza7Eq-ICNk6vcBKVT2NOavKTMRSiTjduwN7dAs_EcF3j9Zadb5EIBYq3KZgUw==",
                    },
                    {
                      "friendly_name": "IphoneX",
                      "id": "BTmfo12gEoLtvk0gQNbh3ne95nsXe1aBeGmZisFXyvPJU21XOre-9UIpj36b9yazrkNEbgraCjJLFRQQezStR8OAewN6GpssqNm40VwMGfrKjL==",
                    },
                  ]
        "401":
          description: Unauthorized
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    description: Technical error code
                  error_description:
                    type: string
                    description: Source of error
                  error_id:
                    type: string
                    description: Generated error ID
                  error_message_key:
                    type: string
                    description: Message error
                  error_user_msg:
                    type: string
                    description: User-friendly message error
              examples:
                Access token missing:
                  value:
                    {
                      "error": "invalid_request",
                      "error_description": "Access token missing",
                      "error_id": "nikHDzD0gt",
                      "error_message_key": "error.accessToken.missing",
                      "error_user_msg": "Access token missing",
                    }
                Access token is not fresh enough.:
                  value:
                    {
                      "error": "invalid_grant",
                      "error_description": "Access token is not fresh enough.",
                      "error_id": "4BfgB3uaVc",
                      "error_message_key": "error.accessToken.freshness",
                      "error_user_msg": "Access token is not fresh enough.",
                    }
        "403":
          description: Forbidden - WebAuthn feature must be enabled
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    description: Technical error code
                  error_description:
                    type: string
                    description: Source of error
                  error_id:
                    type: string
                    description: Generated error ID
                  error_message_key:
                    type: string
                    description: Message error
                  error_user_msg:
                    type: string
                    description: User-friendly message error
              example:
                {
                  "error_id": "6wqEIKLK3L",
                  "error": "error.webauthn.featureDisabled",
                  "error_description": "The Webauthn must be enabled to register access WebAuthn functionalities",
                }
      x-codeSamples:
        - lang: "cURL"
          source: |
            curl --request POST \
              --url https://YOUR_DOMAIN/identity/v1/webauthn/credentials \
              --header 'Content-Type: application/json' \
              --header 'Authorization: Bearer eyJ0eX...ll4Q2NT'-
  /identity/v1/webauthn/registration/{id}:
    get:
      security:
        - OAuth2:
            - "profile"
      summary: Get a credential of a user
      tags:
        - FIDO2
      description: |
        Get specific registered user's credentials. 

        **Note**: The access token must have been generated in the **last 5 minutes**,. The authentication token will contain the ReachFive client ID and the user's identifier.

        **Warning**: The WebAuthn feature must be activated for your ReachFive account.
      operationId: getCredential
      parameters:
        - $ref: "#/components/parameters/Authorization"
        - in: path
          name: id
          required: true
          schema:
            type: string
            example: AValy7JUf5YjmYBdgP_xv5ZNJfyy0MNz8gHDJI6jQfqONDVfTza7Eq-ICNk6vcBKVT2NOavKTMRSiTjduwN7dAs_EcF3j9Zadb5EIBYq3KZgUw==
          description: The identifier of the credential.
      responses:
        "200":
          description: OK - Return the credential of the user
          content:
            application/json:
              schema:
                type: object
                description: The registred credential of the user.
                properties:
                  friendly_name:
                    type: string
                    description: The name of the device.
                    example: "Samsung57"
                  id:
                    type: string
                    description: The identifier of the credential.
                    example: "AValy7JUf5YjmY...3j9Zadb5EIBYq3KZgUw=="
        "401":
          description: Unauthorized
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    description: Technical error code
                  error_description:
                    type: string
                    description: Source of error
                  error_id:
                    type: string
                    description: Generated error ID
                  error_message_key:
                    type: string
                    description: Message error
                  error_user_msg:
                    type: string
                    description: User-friendly message error
              examples:
                Access token missing:
                  value:
                    {
                      "error": "invalid_request",
                      "error_description": "Access token missing",
                      "error_id": "nikHDzD0gt",
                      "error_message_key": "error.accessToken.missing",
                      "error_user_msg": "Access token missing",
                    }
                Access token is not fresh enough.:
                  value:
                    {
                      "error": "invalid_grant",
                      "error_description": "Access token is not fresh enough.",
                      "error_id": "4BfgB3uaVc",
                      "error_message_key": "error.accessToken.freshness",
                      "error_user_msg": "Access token is not fresh enough.",
                    }
        "403":
          description: Forbidden - WebAuthn feature must be enabled
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    description: Technical error code
                  error_description:
                    type: string
                    description: Source of error
                  error_id:
                    type: string
                    description: Generated error ID
                  error_message_key:
                    type: string
                    description: Message error
                  error_user_msg:
                    type: string
                    description: User-friendly message error
              example:
                {
                  "error_id": "6wqEIKLK3L",
                  "error": "error.webauthn.featureDisabled",
                  "error_description": "The Webauthn must be enabled to register access WebAuthn functionalities",
                }
      x-codeSamples:
        - lang: "cURL"
          source: |
            curl --request POST \
              --url https://YOUR_DOMAIN/identity/v1/webauthn/credentials \
              --header 'Content-Type: application/json' \
              --header 'Authorization: Bearer eyJ0eX...ll4Q2NT'-
    delete:
      security:
        - OAuth2:
            - "none"
      summary: Delete a credential of a user
      tags:
        - FIDO2
      description: |
        Delete a specific user's registered crendential.

        **Note**: The access token must have been generated in the **last 5 minutes**,. The authentication token will contain the ReachFive client ID and the user's identifier.

        **Warning**: The WebAuthn feature must be activated for your ReachFive account.
      operationId: deleteCredential
      parameters:
        - $ref: "#/components/parameters/Authorization"
        - in: path
          name: id
          required: true
          schema:
            type: string
            example: AValy7JUf5YjmYBdgP_xv5ZNJfyy0MNz8gHDJI6jQfqONDVfTza7Eq-ICNk6vcBKVT2NOavKTMRSiTjduwN7dAs_EcF3j9Zadb5EIBYq3KZgUw==
          description: The identifier of the credential.
      responses:
        "200":
          description: Credentials deleted
        "401":
          description: Unauthorized
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    description: Technical error code
                  error_description:
                    type: string
                    description: Source of error
                  error_id:
                    type: string
                    description: Generated error ID
                  error_message_key:
                    type: string
                    description: Message error
                  error_user_msg:
                    type: string
                    description: User-friendly message error
              examples:
                Access token missing:
                  value:
                    {
                      "error": "invalid_request",
                      "error_description": "Access token missing",
                      "error_id": "nikHDzD0gt",
                      "error_message_key": "error.accessToken.missing",
                      "error_user_msg": "Access token missing",
                    }
                Access token is not fresh enough.:
                  value:
                    {
                      "error": "invalid_grant",
                      "error_description": "Access token is not fresh enough.",
                      "error_id": "4BfgB3uaVc",
                      "error_message_key": "error.accessToken.freshness",
                      "error_user_msg": "Access token is not fresh enough.",
                    }
        "403":
          description: Forbidden - WebAuthn feature must be enabled
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    description: Technical error code
                  error_description:
                    type: string
                    description: Source of error
                  error_id:
                    type: string
                    description: Generated error ID
                  error_message_key:
                    type: string
                    description: Message error
                  error_user_msg:
                    type: string
                    description: User-friendly message error
              example:
                {
                  "error_id": "6wqEIKLK3L",
                  "error": "error.webauthn.featureDisabled",
                  "error_description": "The Webauthn must be enabled to register access WebAuthn functionalities",
                }
      x-codeSamples:
        - lang: "cURL"
          source: |
            curl --request POST \
              --url https://YOUR_DOMAIN/identity/v1/webauthn/credentials \
              --header 'Content-Type: application/json' \
              --header 'Authorization: Bearer eyJ0eX...ll4Q2NT'-
  /identity/v1/webauthn/authentication-options:
    post:
      security:
        - OAuth2:
            - "none"
      summary: Create new options for authentication
      tags:
        - FIDO2
      description: |
        A user with an already registered credential visits a website and wants to authenticate using the credential.

        **Warning**: The WebAuthn feature must be activated for your ReachFive account.
      operationId: createAuthenticationOptions
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                client_id:
                  description: Your ReachFive client's identifier.
                  type: string
                origin:
                  type: string
                  description: The domain of the origin.
                email:
                  type: string
                  description: The email address of the user.
                phone_number:
                  type: string
                  description: The phone number of the user.
                scope:
                  type: string
                  description: |
                    Space-delimited list of permissions.<br>
                    The required permissions are documented for each API endpoint.
              required:
                - client_id
                - origin
                - email
                - phone_number
              example:
                Authenticate with email:
                  {
                    "client_id": "k3ShTUsHgVE5aWu5uW0i",
                    "origin": "demo.reachfive.com",
                    "email": "anewuser@reachfive.io",
                    "scope": "openid email phone profile full_write",
                  }
                Authenticate with phone number:
                  {
                    "client_id": "k3ShTUsHgVE5aWu5uW0i",
                    "origin": "demo.reachfive.com",
                    "phone_number": "0633344044",
                    "scope": "openid email phone profile full_write",
                  }
      responses:
        "200":
          description: OK - Return the public key of the user.
          content:
            application/json:
              schema:
                type: object
                properties:
                  public_key:
                    description: Public key
                    type: object
                    properties:
                      challenge:
                        type: string
                        description: Random value generated by the relying party from the authenticator to sign as part of the authentication assertion.
                      timeout:
                        type: integer
                        description: Time, in milliseconds, that the caller is willing to wait for the call to complete.
                      rp_id:
                        type: string
                        description: Relying party identifier claimed by the caller. This must exactly match the `rp.id` specified during registration.
                      user_verification:
                        type: string
                        enum:
                          - required
                          - preferred
                          - discouraged
                        description: |
                          - `required`: the client will only use an authenticator capable of user verification.
                          - `preferred`: the client will use an authenticator capable of user verification if possible.
                          - `discouraged`: the authenticator is not asked to perform user verification but may do so at its discretion.
                      allow_credentials:
                        type: array
                        description: List of public key credentials acceptable to the relying party. Credentials can be omitted in username-less authentication scenario.
                        items:
                          type: object
                          properties:
                            id:
                              type: string
                              description: The identifier of the credential.
                            type:
                              type: string
                              description: The type of the credential. Only one type `public-key`.
                            transports:
                              type: array
                              description: List of transports the client can use to find the credential.
                              items:
                                type: string
                example:
                  {
                    "public_key":
                      {
                        "allow_credentials":
                          [{ "id": "X9FrwMfmzj...", "type": "public-key" }],
                        "challenge": "kYhXBWX0HO5GstIS02yPJVhiZ0jZLH7PpC4tzJI-ZcA=",
                        "rp_id": "demo.reachfive.com",
                        "timeout": 120000,
                        "user_verification": "discouraged",
                      },
                  }
        "400":
          description: Bad request - Invalid form
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    description: Technical error code
                  error_description:
                    type: string
                    description: Source of error
                  error_id:
                    type: string
                    description: Generated error ID
                  error_message_key:
                    type: string
                    description: Message error
                  error_user_msg:
                    type: string
                    description: User-friendly message error
              example:
                {
                  "error_id": "LytX6Xbkx5",
                  "error_details":
                    [
                      {
                        "code": "missing",
                        "field": "client_id",
                        "message": "This field is required",
                      },
                      {
                        "code": "missing",
                        "field": "origin",
                        "message": "This field is required",
                      },
                    ],
                  "error_description": "Invalid form",
                  "error_message_key": "error.invalidForm",
                  "error": "invalid_request",
                  "error_user_msg": "Invalid form",
                }
        "401":
          description: Unauthorized - Invalid client id
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    description: Technical error code
                  error_description:
                    type: string
                    description: Source of error
                  error_id:
                    type: string
                    description: Generated error ID
                  error_message_key:
                    type: string
                    description: Message error
                  error_user_msg:
                    type: string
                    description: User-friendly message error
              example:
                {
                  "error_id": "MlKz2Fd7Tx",
                  "error_description": "Invalid client id",
                  "error": "invalid_client",
                }
        "403":
          description: Forbidden
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    description: Technical error code
                  error_description:
                    type: string
                    description: Source of error
                  error_id:
                    type: string
                    description: Generated error ID
                  error_message_key:
                    type: string
                    description: Message error
                  error_user_msg:
                    type: string
                    description: User-friendly message error
              examples:
                WebAuthn feature must be enabled:
                  value:
                    {
                      "error_id": "6wqEIKLK3L",
                      "error": "error.webauthn.featureDisabled",
                      "error_description": "The Webauthn must be enabled to register access WebAuthn functionalities",
                    }
                Unauthorized client:
                  value:
                    {
                      "error_id": "uIA0UM2AnQ",
                      "error_description": "Not a first-party identity client",
                      "error_message_key": "error.client.notFirstParty",
                      "error": "unauthorized_client",
                      "error_user_msg": "Not a first-party identity client",
                    }
                Missing WebAuthn credentials:
                  value:
                    {
                      "error_id": "G8q2CjvH7z",
                      "error_description": "Missing webauthn credentials ",
                      "error": "access_denied",
                    }
      x-codeSamples:
        - lang: "cURL"
          source: |
            curl --request POST \
              --url https://YOUR_DOMAIN/identity/v1/webauthn/makeCredentials \
              --header 'Content-Type: application/json' \
              --header 'Authorization: Bearer eyJ0eX...ll4Q2NT'
  /identity/v1/webauthn/authentication:
    post:
      security:
        - OAuth2:
            - "none"
      summary: Authenticate a user
      tags:
        - FIDO2
      description: |
        A user authenticates using the credential.

        **Warning**: The WebAuthn feature must be activated for your ReachFive account.
      operationId: authenticateWithCredentials
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                id:
                  type: string
                  description: Credential identifier.
                raw_id:
                  type: string
                  description: An `ArrayBuffer` that holds the globally unique identifier for this public key credentials.
                type:
                  type: string
                  description: The type of the credential. Only one type `public-key`.
                response:
                  type: object
                  description: Contains the credential public key and metadata which can be used by the relying party to assess the characteristics of the credential.
                  properties:
                    authenticator_data:
                      type: string
                      description: Contains the authenticator data and attestation statement.
                    client_data_JSON:
                      type: string
                      description: Contains the JSON-serialized data passed to the authenticator by the client in order to generate the credential.
                    signature:
                      type: string
                      description: Raw signature returned from the authenticator.
                    user_handle:
                      type: string
                      description: Contains the user handle returned from the authenticator, or null if the authenticator did not return a user handle.
              required:
                - id
                - raw_id
                - type
                - response
              example:
                {
                  "id": "X9FrwMfmzj...",
                  "raw_id": "X9FrwMfmzj...",
                  "type": "public-key",
                  "response":
                    {
                      "authenticator_data": "o2NmbXRoZmlk...",
                      "client_data_JSON": "eyJjaGFsbGVuZ...",
                      "signature": "aGFsbGVu...",
                      "user_handle": "ZGfssGfu...",
                    },
                }
      responses:
        "200":
          description: OK - Return an authentication token
          content:
            application/json:
              schema:
                type: object
                properties:
                  tkn:
                    type: string
                    description: The one-time use authentication token
                example: { "tkn": "xhNGxw...70zx32" }
        "403":
          description: Forbidden - WebAuthn feature must be enabled
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    description: Technical error code
                  error_description:
                    type: string
                    description: Source of error
                  error_id:
                    type: string
                    description: Generated error ID
                  error_message_key:
                    type: string
                    description: Message error
                  error_user_msg:
                    type: string
                    description: User-friendly message error
              example:
                {
                  "error_id": "6wqEIKLK3L",
                  "error": "error.webauthn.featureDisabled",
                  "error_description": "The Webauthn must be enabled to register access WebAuthn functionalities",
                }
      x-codeSamples:
        - lang: "cURL"
          source: |
            curl --request POST \
              --url https://YOUR_DOMAIN/identity/v1/webauthn/makeCredentials \
              --header 'Content-Type: application/json' \
              --header 'Authorization: Bearer eyJ0eX...ll4Q2NT'
  # /identity/v1/logout: // Ne marche pas => OUT (supprime cookie de session)
  # /identity/v1/token: // old mobile SDK (deprecated)
  # provider - voir QA collection in Postman
  # /identity/v1/token/access-token: // generate new AT from AT (in the context of AT). Refresh token in core SDK
  # /identity/v1/oauth/provider/token: // LEGACY? sdk mobile - connection à FB sans passer par ReachFive
  # /identity/v1/custom-token/login: // sdk mobile
  # /api/v1/webhooks:
  # /api/v1/webhooks/post/{key}:
  # /api/v1/webhooks/pre:
  # /api/v1/webhooks/pre/{key}:
components:
  responses:
    303redirect:
      description: |
        **Valid Code**: The user now begins a classic code or implicit flow from this point and is redirected to the specified `redirect_uri` with an access token.

        **Invalid Code**: The user is redirected to the specified `redirect_uri` where the error response is present as a *query parameter*. **Example**: `<redirect_uri>?error=invalid_grant&error_description=Invalid+Verification+Code&error_message_key=error.invalidVerificationCode`.
  schemas:
    verifyPasswordlessPostResponse:
      type: object
      properties:
        code:
          type: string
          description: The authorization code.
          example: "JhOsI..0NlJmheL"
    signUpNewUserSuccess:
      type: object
      properties:
        tkn:
          type: string
          description: The one-time use authentication token.
          example: "JhOsI..0NlJmh"
        id:
          type: string
          description: The new user's unique ID.
          example: "AW9DB..8WGLhc"
    getTrustedDevicesResponse:
      type: object
      properties:
        trusted_devices:
          type: array
          description: An array of trusted devices.
          items:
            type: object
            properties:
              id:
                description: The ID of the trusted device.
                type: string
                example: "k6ShT...Xu5uV0i"
              metadata:
                description: Information about the trusted device.
                type: object
                properties:
                  ip:
                    description: The device's IP address.
                    type: string
                    example: "185.209.222.60"
                  operatingSystem:
                    description: The operation system of the device.
                    type: string
                    example: "Windows 11"
                  userAgent:
                    description: The device's user agent information.
                    type: string
                    example: "Mozilla/5.0 (platform; rv:geckoversion) Gecko/geckotrail Firefox/firefoxversion"
                  deviceClass:
                    description: The device class.
                    type: string
                    example: "deviceClass"
                  deviceName:
                    description: The device name.
                    type: string
                    example: "deviceName"
              userId:
                description: The user's ID.
                type: string
                example: "teSh2...Wu5bV5L"
              createdAt:
                description: When the trusted device was added.
                type: string
                example: "2023-03-17T09:01:41.146Z"
    GetSignUpDataRequestBodyVerCode:
      type: object
      properties:
        client_id:
          description: Your ReachFive client ID
          type: string
          example: "k6ShT...Xu5uV0i"
        verification_code:
          description: The verification code received by text (SMS) or email.
          type: string
          pattern: "[0-9]{6}"
          example: "882401"
        identifier:
          description: The identifier for the user. This can be either a phone number or an email address.
          type: string
          example: "+353875550002"
    GetSignUpDataRequestBodyToken:
      type: object
      properties:
        client_id:
          description: Your ReachFive client ID
          type: string
          example: "k6ShT...Xu5uV0i"
        token:
          description: Token received after a signup invitation. This is usable only once.
          type: string
          example: "1pz032..32Ld0a"
        identifier:
          description: The identifier for the user. This can be either a phone number or an email address.
          type: string
          example: "+353875550002"
    loginWithCustomIdentifier:
      type: object
      properties:
        client_id:
          description: Your ReachFive client ID
          type: string
          example: "k6ShT...Xu5uV0i"
        custom_identifier:
          description: |
            The custom identifier. This is typically something like a username, customer number, or loyalty number.

            **Important**: It cannot be an email or phone number.
          type: string
          example: "JeanIsSuperFly42"
        password:
          description: Your password.
          type: string
          example: "NoMakeTooEasyPlease123"
        captcha_token:
          description: The reCAPTCHA v3 response token. See [Google's documentation on how to obtain it](https://developers.google.com/recaptcha/docs/v3).
          type: string
          example: ")£i93DkD19£..£lsdZ9"
        scope:
          description: |
            List of space-delimited, case-sensitive strings representing the requested _enforced_ scope. If no scope is specified, the enforced scope defaults to `openId`.

            **Important**: If Enforce Scope is enabled, the `scope` in this operation overrides the `scope` in the [password callback](#operation/passwordCallback) operation.

            **Tip**: To enable Enforce Scope, check the _Enforce Scope_ box at the bottom of the [First-party Identity client settings page](https://developer.reachfive.com/docs/clients.html) on your ReachFive console.
          type: string
          example: "openid email phone profile full_write"
      required:
        - client_id
        - custom_identifier
        - password
    loginWithEmail:
      type: object
      properties:
        client_id:
          description: Your ReachFive client ID
          type: string
          example: "k6ShT...Xu5uV0i"
        email:
          description: Your email address.
          type: string
          example: "marie@example.com"
        password:
          description: Your password.
          type: string
          example: "NoMakeTooEasyPlease123"
        captcha_token:
          description: The reCAPTCHA v3 response token. See [Google's documentation on how to obtain it](https://developers.google.com/recaptcha/docs/v3).
          type: string
          example: ")£i93DkD19£..£lsdZ9"
        scope:
          description: |
            List of space-delimited, case-sensitive strings representing the requested _enforced_ scope. If no scope is specified, the enforced scope defaults to `openId`.

            **Important**: If Enforce Scope is enabled, the `scope` in this operation overrides the `scope` in the [password callback](#operation/passwordCallback) operation.

            **Tip**: To enable Enforce Scope, check the _Enforce Scope_ box at the bottom of the [First-party Identity client settings page](https://developer.reachfive.com/docs/clients.html) on your ReachFive console.
          type: string
          example: "openid email phone profile full_write"
      required:
        - client_id
        - email
        - password
    loginWithPhoneNumber:
      type: object
      properties:
        client_id:
          description: Your ReachFive client ID
          type: string
          example: "k6ShT...Xu5uV0i"
        phone_number:
          description: The phone number used to sign up.
          type: string
          example: "+353981384130"
        password:
          description: Your password.
          type: string
          example: "NoMakeTooEasyPlease123"
        captcha_token:
          description: The reCAPTCHA v3 response token. See [Google's documentation on how to obtain it](https://developers.google.com/recaptcha/docs/v3).
          type: string
          example: ")£i93DkD19£..£lsdZ9"
        scope:
          description: |
            List of space-delimited, case-sensitive strings representing the requested _enforced_ scope. If no scope is specified, the enforced scope defaults to `openId`.

            **Important**: If Enforce Scope is enabled, the `scope` in this operation overrides the `scope` in the [password callback](#operation/passwordCallback) operation.

            **Tip**: To enable Enforce Scope, check the _Enforce Scope_ box at the bottom of the [First-party Identity client settings page](https://developer.reachfive.com/docs/clients.html) on your ReachFive console.
          type: string
          example: "openid email phone profile full_write"
      required:
        - client_id
        - phone_number
        - password
    updatePasswordPhone:
      type: object
      properties:
        client_id:
          description: Your ReachFive client ID.
          type: string
        phone_number:
          description: The user's mobile number.
          type: string
        verification_code:
          description: Verification code.
          type: integer
          pattern: "[0-9]{6}"
        old_password:
          description: The current active password.
          type: string
        password:
          description: The new password, different from `old_password`.
          type: string
      required:
        - password
    updatePasswordEmail:
      type: object
      properties:
        client_id:
          description: Your ReachFive client ID.
          type: string
        email:
          description: Email address.
          type: string
        verification_code:
          description: Verification code.
          type: integer
          pattern: "[0-9]{6}"
        old_password:
          description: The current active password.
          type: string
        password:
          description: The new password, different from `old_password`.
          type: string
      required:
        - password
    retrieveAccessToken:
      type: object
      properties:
        grant_type:
          description: Must be set to authorization_code.
          type: string
          example: authorization_code
        client_id:
          description: Your client ID.
          type: string
          example: slNIt...yKzQM
        client_secret:
          description: Your client Secret. Required if your Client’s authorization method is POST.
          type: string
          example: dYEa3...3z2m2
        code:
          description: The authorization code received from the initial authorization call.
          type: string
          example: XpcgV...5sSY5
        redirect_uri:
          description: The absolute URI the user-agent will be redirected to following flow completion. Depending on the response type, it will either carry the token response, the authorization code, or the appropriate error in any other case.
          type: string
          example: https://example.com/callback
        code_verifier:
          description: The cryptographically-random key (verifier) for the PKCE request. The app generates this before the authorization request.
          type: string
          example: NNxsS1YB...49kuHyhlAqrH
        return_provider_token:
          description: Specifies whether you should return the provider access token.
          type: boolean
          example: true
      required:
        - grant_type
        - client_id
        - client_secret
        - code
        - redirect_uri
        - scope
    retrieveAccessTokenWithRefresh:
      type: object
      properties:
        grant_type:
          description: Must be set to refresh_token.
          type: string
          example: refresh_token
        client_id:
          description: Your client ID.
          type: string
          example: slNIt...yKzQM
        client_secret:
          description: Your client Secret. Required if your Client’s authorization method is POST.
          type: string
          example: dYEa3...3z2m2
        scope:
          description: |
            Optional. Space-delimited list of permissions.

            > **Note**: If no `scope` is specified, the refresh token's `scope` is used.
            > If `scope` is specified, it must be equal or narrower than the refresh token's original `scope`.
            > 
            > For example:
            > 
            > Refresh token's scope: `email` `profile` `phone_number` `offline_access`
            > 
            >  - Ok: `email` `profile` `phone_number`
            >  - Ok: `email` `profile` `offline_access`
            >  - Error: `email` `profile` `phone_number` `offline_access` `full_write`
          type: string
          example: openid profile email phone full_write
        refresh_token:
          type: string
          description: |
            The refresh token used to get a new access token.

            > **Note**:
            >
            > This is only possible when the `offline_access` scope is requested.
          example: aYIc1...2n1m2
      required:
        - grant_type
        - client_id
        - client_secret
        - refresh_token
    ErrorFields:
      type: object
      properties:
        error_id:
          type: string
          description: The technical ID of the error.
        error_description:
          type: string
          description: The default description message for the error.
        error:
          type: string
          description: Specifies the main error category.
        error_user_msg:
          type: string
          description: The user friendly error message. This should be displayed in the UI and can be overloaded in some configurations. This is bound to a specific `i18n` translation.
        error_message_key:
          type: string
          description: The error message key that can be used to bind specific behaviors on other services. This also acts as the `i18n` translation key.
    signupFields:
      type: object
      description: |
        The user attributes you want to pass when signing up a user.

        **Tip**: *Expand `data >` to see all possible fields.*
      properties:
        email:
          type: string
          description: The primary email address of the profile.
        password:
          type: string
          description: |
            The profile password.

            **Important**: The password must meet [zxcvbn](https://github.com/dropbox/zxcvbn) standards.
        phoneNumber:
          type: string
          description: |
            The primary phone number for the profile.

            **Note**: Both international format and the national conventions of the account’s country are accepted if configured in the ReachFive account settings.
        givenName:
          type: string
          description: The given name (first name) for the profile.
        middleName:
          type: string
          description: The middle name for the profile.
        familyName:
          type: string
          description: The family name (surname/last name) for the profile.
        name:
          type: string
          description: The full name for the profile.
        nickname:
          type: string
          description: The nickname for the profile.
        profileURL:
          type: string
          description: |
            The URL of one of the user’s profile page.

            **Tip**: This is typically a social provider’s page.
        picture:
          type: string
          description: |
            The URL of one of the profile pictures for the profile. 

            **Note**: This URL refers to an image file (`PNG`, `JPEG`, or `GIF` image file).
        username:
          type: string
          description: The username (login name) for the profile.
        gender:
          type: string
          description: |
            The gender for the profile.

            **Note**: Currently allowed values are:

            - `female`
            - `male`
            - `other`
        company:
          type: string
          description: The company name for the profile.
        addresses:
          type: string
          description: A list of strings that contain the profile's postal addresses.
        locale:
          type: string
          description: |
            The profile’s language code in lowercase and country code in uppercase.

            **Note**: This is separated by a dash. For example: `fr-FR`.
        customFields:
          type: object
          description: |
            Any applicable custom fields for the profile.

            For example: `loyalty_card_number`
        bio:
          type: string
          description: The profile's bio information.
        consents:
          type: object
          description: |
            The consents granted to the profile.

            **Note**: This is a map of string keys with the associated consent object.
    ProfileFields:
      type: object
      properties:
        email:
          type: string
          description: Email
          example: theGreatest@example.com
        phone_number:
          type: string
          description: The user's phone number.
          example: "353875550001"
        external_id:
          type: string
          description: External ID
          example: "saEK39..23KADKd2"
        email_verified:
          type: boolean
          description: "`true` if the email has been verified."
          example: true
        phone_number_verified:
          type: boolean
          description: "`true` if the phone number has been verified."
          example: true
        given_name:
          type: string
          description: Given name(s) or first name(s).
          example: Thierry
        middle_name:
          type: string
          description: Middle name(s).
          example: Jose
        family_name:
          type: string
          description: Surname(s) or last name(s).
          example: Rodriguez
        name:
          type: string
          description: Full user name.
          example: Thierry Jose Rodriguez
        nickname:
          type: string
          description: Casual name that may or may not be the same as the `given_name`.
          example: Dumpy
        username:
          type: string
          description: Username
          example: DumpyMan4200
        birthdate:
          type: string
          description: User’s birthdate, represented as an ISO 8601 YYYY-MM-DD format.
          example: 1989-12-30
        gender:
          type: string
          description: User’s gender.
          enum:
            - female
            - male
            - other
          example: male
        addresses:
          type: object
          description: User postal addresses.
        picture:
          type: string
          description: URL to the profile picture
        company:
          type: string
          description: User company name.
          example: The Hat Company
        custom_fields:
          type: object
          description: Custom fields.
        consents:
          type: object
          description: Consents.
    LiteProfilePhone:
      type: object
      required:
        - phone_number
      properties:
        phone_number:
          type: string
          description: Phone Number
        ProfileFields:
          $ref: "#/components/schemas/ProfileFields"
    LiteProfileEmail:
      type: object
      required:
        - email
      properties:
        email:
          type: string
          description: Email
        ProfileFields:
          $ref: "#/components/schemas/ProfileFields"
    PasswordlessEmail:
      allOf:
        - properties:
            email:
              description: Email address
              type: string
          required: [email]
        - $ref: "#/components/schemas/PasswordlessFields"
        - type: object
    PasswordlessVerifyEmail:
      allOf:
        - properties:
            email:
              description: The email receiving the code.
              type: string
              example: dude@example.com
            verification_code:
              description: The verification code sent by email.
              type: string
              example: "121516"
        - required: [verification_code, email]
    PasswordlessVerify:
      allOf:
        - properties:
            phone_number:
              description: The phone number receiving the SMS.
              type: string
              example: +0633344044
            verification_code:
              description: The verification code sent by SMS.
              type: string
              example: "121516"
        - required: [verification_code, phone_number]
    PasswordlessVerifyMFA:
      allOf:
        - properties:
            challenge_id:
              description: The challenge ID.
              type: string
              example: nvR2y0k...up4BDbZ
            verification_code:
              description: The verification code sent by SMS.
              type: string
              example: "121516"
            trust_device:
              description: |
                Boolean denoting whether the device is trusted (`true`) or not (`false`).

                If set to to `true`, the response contains the trusted device cookie.

                > **Important**: This is only relevant for [Risk-based authentication (RBA)](https://developer.reachfive.com/docs/rba.html).
              type: boolean
              example: true
        - required: [verification_code, challenge_id]
    PasswordlessMFA:
      allOf:
        - properties:
            step_up:
              description: The token obtained from the step-up operation.
              type: string
            auth_type:
              description: Second factor type.
              type: string
              enum:
                - sms
                - email
            state:
              description: |
                An opaque value used to maintain `state` between the request itself and the callback.

                > **Note**: The authorization server includes this value when redirecting the user-agent back to the client.
              type: string
              example: ABC123xyzPOP
            captcha_token:
              description: The reCAPTCHA v3 response token. See [Google's documentation on how to obtain it](https://developers.google.com/recaptcha/docs/v3).
              type: string
              example: "sjda3ADS39...23AKD91349"
          required: [step_up, auth_type]
        - type: object
    PasswordlessSMS:
      allOf:
        - properties:
            phone_number:
              type: string
              description: Phone Number
          required: [phone_number]
        - $ref: "#/components/schemas/PasswordlessFields"
        - type: object
    OAuth2Params:
      type: object
      properties:
        client_id:
          description: Your ReachFive client ID
          type: string
          example: eXEcR...682i3
        response_type:
          description: OAuth2 grant type
          type: string
          enum:
            - code
            - token
        scope:
          description: List of space-delimited, case-sensitive strings representing the requested scope.
          type: string
        redirect_uri:
          description: The absolute URI the user-agent will be redirected to following flow completion. Depending on the response type, it will either carry the token response, the authorization code, or the appropriate error in any other case.
          type: string
        tkn:
          type: string
          description: |
            The one-time use authentication token. *(2)*

            > **Note**: In this case, there's no need for the session cookie or an access_token in the header.
      required:
        - client_id
        - response_type
        - scope
        - redirect_uri
      example:
        client_id: nvR2y0ks...EgCW2dqy
        response_type: code
        scope: openid phone address profile mfa
        redirect_uri: https://redirect_uri.com/
        tkn: xhNGxw...70zx32
    OAuth2Params_noTkn:
      type: object
      properties:
        client_id:
          description: Your ReachFive client ID
          type: string
          example: eXEcR...682i3
        response_type:
          description: OAuth2 grant type
          type: string
          enum:
            - code
            - token
        scope:
          description: List of space-delimited, case-sensitive strings representing the requested scope.
          type: string
        redirect_uri:
          description: The absolute URI the user-agent will be redirected to following flow completion. Depending on the response type, it will either carry the token response, the authorization code, or the appropriate error in any other case.
          type: string
      required:
        - client_id
        - response_type
        - scope
        - redirect_uri
      example:
        client_id: nvR2y0ks...EgCW2dqy
        response_type: code
        scope: openid phone address profile mfa
        redirect_uri: https://redirect_uri.com/
    PasswordlessFields:
      type: object
      properties:
        client_id:
          description: Your ReachFive client ID
          type: string
          example: eXEcR...682i3
        response_type:
          description: OAuth2 grant type
          type: string
          enum:
            - code
            - token
        scope:
          description: List of space-delimited, case-sensitive strings representing the requested scope.
          type: string
        display:
          description: Always `page`
          type: string
          example: page
        redirect_uri:
          description: The absolute URI the user-agent will be redirected to following flow completion. Depending on the response type, it will either carry the token response, the authorization code, or the appropriate error in any other case.
          type: string
          example: https://mybrand.com/login/callback
        state:
          description: |
            An opaque value used to maintain `state` between the request itself and the callback.

            > **Note**: The authorization server includes this value when redirecting the user-agent back to the client.
          type: string
          example: ABC123xyzPOP
        origin:
          description: The domain from which your application sends requests.
          type: string
          example: https://example.com
        captcha_token:
          description: The reCAPTCHA v3 response token. See [Google's documentation on how to obtain it](https://developers.google.com/recaptcha/docs/v3).
          type: string
          example: "sjda3ADS39...23AKD91349"
      required:
        - client_id
        - response_type
        - scope
        - display
        - redirect_uri
  parameters:
    session_cookie:
      name: SESSION
      in: cookie
      schema:
        type: string
      description: |
        The user's session cookie.
    client_id_auth:
      name: client_id
      in: query
      required: true
      schema:
        type: string
        example: k6ShTOsHfVE5aXu4uW0i
      description: |
        Your ReachFive client ID.

        This should be your First-party Identity client unless it is for the OaaS flow.
    scope:
      name: scope
      in: query
      required: true
      schema:
        type: string
        example: "openid email phone profile"
      description: |
        A space-separated list of scopes. Scopes determine the level of access for a request.
    response_type:
      name: response_type
      in: query
      required: true
      schema:
        type: string
        enum:
          - id_token
          - code
          - token
      description: |
        The expected response type depending on the OAuth flow.

        > **Warning**: The `token` response type is used for implicit flows and should be avoided where possible.
    redirect_uri:
      name: redirect_uri
      in: query
      required: true
      schema:
        type: string
        example: https://mybrand.com/login/callback
      description: The absolute URI the user-agent is redirected to following flow completion. Depending on the response type, it carries the token response, the authorization code, or the appropriate error in any other case.
    code_challenge:
      name: code_challenge
      in: query
      schema:
        type: string
        example: token
      description: |
        The code challenge. This is a generated string created by the client application.

        This is **required** if PKCE is enforced.
    code_challenge_method:
      name: code_challenge_method
      in: query
      schema:
        type: string
        example: S256
      description: |
        The code challenge method. This specifies the method used to transform the `code_challenge` into a proper verified.

        This is **required** if PKCE is enforced.
    max_age:
      name: max_age
      in: query
      schema:
        type: string
        example: 600
      description: |
        The maximum age allowed for the session. If the session is older than the specified `max_age`, it forces re-authentication for the user.

        > **NOTE**: This applies to the Login with session flow where a session cookie is provided.

        > **NOTE**: If you set `max_age` to `0`, this forces the user to reauthenticate since the session would always be older than `0`.
    provider:
      name: provider
      in: query
      schema:
        type: string
        example: paypal
      description: |
        A string that you can pass that specifies the provider you want to login with.

        This is **required** when performing social login authentication.
    access_token_auth:
      name: access_token
      in: query
      schema:
        type: string
        example: d3L3..2AD9t
      description: |
        The credential that represents the authorization granted to a client application to access specific resources on behalf of a user.

        This is **required** when linking a social provider to an existing authenticated profile.
    origin:
      name: origin
      in: query
      schema:
        type: string
        description: The domain from which your application sends requests.
        example: https://example.com
    tkn:
      name: tkn
      in: query
      schema:
        type: string
        description: |
          The one-time use authentication token.

          This is **required** when exchanging for an access token.
        example: "xhNGxw...70zx32"
    prompt:
      name: prompt
      in: query
      schema:
        type: string
        enum:
          - none
          - login
      description: |
        The `prompt` parameter specifies whether or not to explicitly prompt the user for reauthentication or not.

        > If `none`, there is no authentication prompt. This is typically used for silently checking for existing authentication.

        > If `login`, the user is prompted for authentication. The existing session is invalidated and the user is redirected to the `redirect_uri` or client-configured login URL (if no `redirect_uri` is specified).

        > **NOTE**: This applies to the Login with session flow where a session cookie is provided.

        > **NOTE**: In a Social Login (SLO) flow, the session management is partially delegated to the target OIDC provider (OP) and hence, `prompt` is handled by the OP and we redirect to the OP because of this.

    trusted_device_id:
      name: trusted_device_id
      in: path
      schema:
        type: string
      required: true
      description: ID for the trusted device.
      example: "trusted_device_id"
    hostedTrustedDeviceIdHeader:
      name: __Host-trusted-device-id
      in: cookie
      schema:
        type: string
      description: |
        The trusted device cookie.

        This is set from the response of [verifyPasswordlessPost MFA](#operation/verifyPasswordlessPost) if `trust_device` is set to `true`.

      example: "00112233-4455-6677-8899-aabbccddeeff"
    attackProtectionBypass:
      name: Attack-Protection-Bypass
      in: header
      schema:
        type: string
      description: An optional header field; the generated bypass header for those using the [Attack Protection Bypass header](https://developer.reachfive.com/docs/ifp.html#attack-protection-bypass-header).
      example: "Isdaf03#@Rasdfj!j3jkl"
    trueClientIp:
      name: True-Client-IP
      in: header
      schema:
        type: string
      description: |
        An optional header field; IP to protect requests from the backend.

        **Note**: For more details, see [Identity Fraud Protection](https://developer.reachfive.com/docs/ifp.html#enable-true-client-ip-key).

      example: "224.136.62.167"
    trueClientIpKey:
      name: True-Client-IP-Key
      in: header
      schema:
        type: string
      description: |
        An optional header field; the secret that must match the True-Client-IP-Key generated in the ReachFive console.

        **Note**: For more details, see [Identity Fraud Protection](https://developer.reachfive.com/docs/ifp.html#enable-true-client-ip-key).

      example: "Isdaf03#@Rasdfj!j3jkl"
    userAgent:
      name: User-Agent
      in: header
      schema:
        type: string
      description: |
        An optional header field; the [User-Agent](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/User-Agent) request header. The User-Agent request header allows brands to provide end-user device details in case of the implementation of the [RBA](https://developer.reachfive.com/docs/rba.html) feature in a full back-end integration.
      example: "Mozilla/5.0 (platform; rv:geckoversion) Gecko/geckotrail Firefox/firefoxversion"
    Authorization:
      name: Authorization
      in: header
      schema:
        type: string
      required: true
      description: Bearer `{token}` for a valid OAuth token.
    CustomLocaleHeader:
      name: Custom-Locale_HEADER
      in: header
      schema:
        type: string
      description: Optional parameter to pass the user's locale (country).
    access_token:
      name: Authorization
      in: header
      schema:
        type: string
      description: |
        Bearer `{access_token}` for a valid OAuth token. *(3)*

        > **Note**: The `access_token` is not required if you are passing the `tkn` as part of the request body or are using an active SSO session by passing the session cookie.
      example: 1pz032..32Ld0a
    fields:
      name: fields
      in: query
      description: |
        Fields to retrieve in the response.

        **Note**: See the [user profile object](https://developer.reachfive.com/docs/models-user-profile.html#the-user-profile-object) for a full list of fields to query.
      schema:
        type: array
        items:
          type: string
      explode: false
      example: [name, email, gender, emails.unverified] # https://github.com/Redocly/redoc/issues/1010
      allowReserved: true # https://github.com/Redocly/redoc/issues/1010
    Authorization_optional:
      name: Authorization
      in: header
      schema:
        type: string
      required: false
      description: Bearer `{token}` for a valid OAuth token.
  #     limitParam:
  #     in: query
  #     name: limit
  #     required: false
  #     schema:
  #       type: integer
  #       minimum: 1
  #       maximum: 50
  #       default: 20
  #     description: The numbers of items to return.
  #   requestBodies:
  securitySchemes:
    OpenID:
      type: openIdConnect
      openIdConnectUrl: https://YOUR_DOMAIN/.well-known/openid-configuration
    OAuth2:
      type: oauth2
      flows:
        authorizationCode:
          authorizationUrl: /oauth/authorize
          tokenUrl: /oauth/token
          refreshUrl: /oauth/token # optional
          scopes:
            none: No particular scope is required.
            openid: Used to ask for an ID token.
            profile: Access to most personal information (gender, age, profile picture, etc).
            email: Access to email information (email addresses and their verification status).
            phone: Access to phone information (phone numbers and their verification status).
            address: Access to geographical information (postal address, region, geolocalisation, etc).
            events: Access to user events.
            full_write: |
              Ability to update any information on the profile. Not available to third-party clients.
            offline_access: Ability to request refresh tokens.
            mfa: Ability to implement MFA flow.
        implicit:
          authorizationUrl: /oauth/authorize
          scopes:
            none: No particular scope is required.
            openid: Used to ask for an ID token.
            profile: Access to email information (email addresses and their verification status).
            email: Access to phone information (phone numbers and their verification status).
            phone: Access to geographical information (postal address, region, geolocalisation, etc).
            address: Access to most personal information (gender, age, profile picture, etc).
            events: Access to user events.
            full_write: |
              Ability to update any information on the profile. Not available to third-party clients.
            offline_access: Ability to request refresh tokens.
#   examples:
