User-event webhooks

With user-event webhooks, you can register specific URLs to be called on specific user actions or events, such as a sign-up or deletion of an account.

ReachFive provides pre-event and post-event webhooks.

It is recommended to use post-event webhooks whenever possible.

Post-event webhooks

Post-event webhooks trigger after the event has been processed.

Post-event webhooks are asynchronous: the API returns a response and the user can continue browsing your application without waiting for an answer from the URL.

Pre-event webhooks

Pre-event webhooks trigger before an event is processed (save, deletion, or update of a user profile).

Pre-event webhooks can send a response with additional data, or prevent the event to proceed altogether.

This allows the webhook URL to send back a response with additional data, or to prevent the event to proceed altogether.

However, this means that pre-event webhooks will suspend the API response and keep the user waiting.

Therefore, you should set an appropriate timeout, to prevent users from being stuck.

The default timeout is 10 seconds.

When a pre-event webhook fails, ReachFive can either:

  • Continue processing the event, as if there was no webhook involved
    The user will not be stuck, but this might result in unsynchronized data.

  • Prevent the event from being processed, return an error message
    The user might wait for longer, but this ensures data is consistent on both sides.

You can set the behavior you wish when configuring the webhook.

Pre-event webhooks are currently limited to specific types of events:

  • signup

  • user_updated

  • email_updated

  • phone_number_updated

  • user_deleted

Webhooks setup

  1. In the ReachFive Console, navigate to Advanced Settings  Features and enable the Webhooks feature.

  2. Under Webhooks, select Pre-event webhooks or Post-event webhooks.

  3. Select New pre-event webhook or New post-event webhook.

  4. Specify the following information:

    • Key: a unique key in snake_case.

    • Event types: Events that trigger the webhook

      • login *

      • signup

      • user_updated

      • unlink *

      • user_deleted

      • email_updated

      • email_verified *

      • phone_number_updated

      • phone_number_verified *

      • password_reset_requested *

      • password_updated *

      • otp_sent *

        Event types with a * are only available for post-event webhooks.

    • Filter: specify conditions on the event or the profile - only events that match the filter will trigger the webhook. No filter means all events trigger the webhook

    • URL:

    • Fields: Event fields and User fields which can be sent in the request.

      User fields should be prefixed with user.: emailuser.email.
    • Timeout: timeout for the webhook (seconds)

    • Proceed anyway if the webook fails: whether the request proceeds in the webhook fails.

    • Priority: when multiple webhooks are triggered, additional data is merged, by order of priority.

    • HTTP Authorization value: …​

    • Use non-standard name for the Authorization header: …​

Fields

Check the following pages for the lists of possible values for:

Filters allow you to specify conditions on the event or the profile. Only events that match the filter will trigger the webhook. With no filter, all events will trigger the webhook.

Note that user fields should be prefixed with user., as the base object sent to the webhook is the event (the user will appear under user).

Endpoint Implementation

Request

On trigger, the endpoint will receive an HTTP POST request, with a JSON body. The body is a User Event object, with an extra user field.

Only the fields configured for this webhook will appear.

For instance:

{
  "type": "signup",
  "auth_type": "password",
  "device": "desktop",
  "date": "2018-10-14T16:05:23.354Z",
  "user": {
    "id": "AXIKcPAvIhFBrbvQqd2S",
    "email": "bruce@wayne.com",
    "given_name": "Bruce",
    "family_name": "Wayne",
    "gender": "male"
  }
}

The user field will contain the user profile post-handling the event, whether this is a post-event or a pre-event webhook.

For instance, if the users name is updated, the field user.name will reflect the updated name.

In case a user is deleted, the values will be those existing before deletion.

The header Accept-Language will contain the expected language for the end user, in case an error message is necessary.

Response

For a post-event webhook: The status code must be 204 (No Content), and the response body should be empty (it will be ignored).

For a pre-event webhook: The status code must be 200 (OK), and the response body must be valid JSON. It will be either an approval (the event is accepted and will be processed as normal), or a rejection (the event is rejected and the process will end immediately with an error).

For an approval, the JSON body will have the following fields:

  • proceed (mandatory): Must have the value true for an approval.

  • user (optional): Additional user data that will be merged into the user’s profile. It should follow the same format as when saving a user through the management API. If user is missing and proceed is true, the user’s profile will not be modified by the webhook.

{
  "proceed": true,
  "user": {
    "nickname": "Batman",
    "external_id": "458867"
  }
}

For a rejection, the JSON body will have the following fields:

  • proceed (mandatory): Must have the value false for a rejection.

  • error (mandatory): A code for the error, entirely up to you. If the webhook was triggered following an API call, the API response will contain this code, prefixed by external. to avoid any confusion with error codes used internally by ReachFive.

  • error_description (mandatory): Useful information for a developer. If the webhook was triggered following an API call, the API response will contain this message within a general description.

  • error_user_msg (mandatory): The message to display to the end user. Therefore, it needs to be localized using the Accept-Language HTTP header from the request.

{
  "proceed": false,
  "error": "account_locked",
  "error_description": "Account locked for profile: Profile(Bruce, Wayne, true)",
  "error_user_msg": "Sorry Mr. Wayne, your account has been locked."
}

Retrying behaviour

Any status code not matching the ones described above are considered a technical error (excepted 3xx redirect status codes, which are followed as normal). This includes all 4xx and 5xx status codes. Responses containing an unexpected body are also considered a technical error, and connection issues. On a technical error, ReachFive makes additional attempts on the endpoint until the timeout is reached. The first attempt will immediately follow the error, and further attempts will have a wait time to avoid spamming the endpoint.

If we eventually get a correct response, we go back to the normal case. If the timeout is reached without a successful response (either we got technical errors or the endpoint did not respond at all), the webhook fails.

Authentication

Only a static header-based authentication is implemented at this time. If configured, the Authorization header will be set on the request with the specified value. The value pattern depends on your authentication method; here are two typical examples:

  • for Basic authentication (RFC 7617), Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==

  • for an OAuth 2 bearer token (RFC 6750), Bearer mF_9.B5f-4.1JqM

You may set it with any pattern you wish, however we strongly recommend following the W3C standard of <Type> <Value>.

API Response for pre-event webhooks

If you use ReachFive’s API, you may want to handle programmatically the response. For this reason, this section describes how the API response looks when a triggered pre-event webhook fails or rejects the event. In both cases, the response will follow the usual error format.

As a reminder, post-event webhooks have no effect on the API response.

Event rejected

The API response will be have a 400 (Bad Request) status code, and the body will have the following fields:

  • error will contain the value of the error field from the webhook response, prefixed by external.

  • error_description will contain the value of the error_description field from the webhook response, prefixed by a local message precising which webhook failed

  • error_user_msg will contain exactly the same value as the error_user_msg field from the webhook response

Using the sample webhook response above, the API response would be:

{
  "error": "external.account_locked",
  "error_description": "Webhook lexcorp-crm-upload: Account locked for profile: Profile(Bruce, Wayne, true)",
  "error_user_msg": "Sorry Mr. Wayne, your account has been locked."
}

Webhook failure

If the webhook was configured with the "Proceed after failure" flag, a failing webhook will have no effect on the API response. Otherwise, the API response depends on the error type:

  • If the connection to the webhook fails, the status code will be 504 (Gateway Timeout), and the body’s error field will contain the value webhook_host_unreachable

  • If the webhook response is invalid, the status code will be 502 (Bad Gateway), and the body’s error field will contain the value webhook_invalid_response

In both cases, the error_description field might provide further information about the error, and the error_user_msg field will contain a generic, localized error message for the end user.