Real-time Synchronization

While it is possible to export daily batches of historical data to third-party data stores, we also allow third-parties to reliably synchronize their database of customer interactions with events as they happen within Alcmeon. The objective is to make sure that 99.99% of all notifications are reported within less than 10s of being generated.

Design

This functionality is provided through two APIs:

  • Realtime notification API: a third-party http endpoint is invoked whenever an event is processed within Alcméon. The payload is a fully-hydrated object which reports what happened, and the new state of the message being processed. Notification delivery is not guaranteed: failures (network, receiver or sender) trigger retries with increasing retry delays until 24h is elapsed after the first delivery failure.
  • Action synchronization API: the Alcméon application provides a GET https endpoint to retrieve all fully-hydrated actions since the last-received notification. This API is expected to be periodically polled by third-parties to check for any missing action.

Configuration

  1. Create an application
  2. The newly-created application is displayed on screen:
  • Edit the Name of the application to associate a human-readable, understandable name with this application
  • Check the "Action Synchronization API" checkbox
  • Check the "Realtime notification API " checkbox
  • Set the url of your webhook implementation in the "URL Webhook" field
  • Choose the minimum subset of notification types from the dropdown in order to get on time notifications
  • Set a valid email in the "Notification email in case of incident" field to be able to receive email notifications if your webhook fails, after it has been automatically disabled
  • Most importantly, save somewhere the application secret displayed below the application name: it will be used to authenticate, authorize, and verify API calls
  1. Click on the "Save" button located in the top-right corner.

Webhook implementation

Each notification is reported to the webhook endpoint as a POST with a json-formatted body which contains a single action object. The webhook is expected to return status 200 to report that it has correctly received the event.

Secure your webhook endpoint

When you receive a POST request on your webhook endpoint, you should verify that this request originates from our infrastructure. To do so, you should perform signature verification.

Failure notification

If your webhook does not return http status 200 we will:

  1. send retries at increasing intervals, with a minimum retry interval of one minute. These retries will be attempted up to 24 hours after the initial retry failure.
  2. If we detect a number of delivery failures higher than a certain ratio for one hour, we send a notification email.
  3. If we detect a number of delivery failures higher than a certain ratio for each of the previous 24 hours, we disable the webhook, drop all pending notifications, and stop sending newer notifications until you re-enable the webhook.

If you receive the notification email, and fail to fix the issue before the webhook is automatically disabled on our side, you will need to re-enable this webook. To do so:

  1. Click on the link received in the notification email,
  2. Check the "Active" toggle for this application's webhook
  3. Click on the "Save" button located in the top-right corner.

Debugging failed webhook delivery

If your webhook misteriously fails randomly, you can use our List recent errors API to obtain the list of the most recently failed notifications, together with the http status and a part of the response body we have received.

Fallback to the Action synchronization API

In case of webhook delivery failures, it is possible to perform error recovery by polling the Action Synchronization API with min_action_id set to the id of the last successfully received notification_id.

Matching notifications to users or conversations

Each notification can be matched to a unique user profile or conversation as follows:

userconversation
GET /actionsmessage.author.group.idconversation.id
POST /notifyaction.task.message.author.group.idaction.task.conversation.id