Skip to main content
Practically speaking, a webhook is a POST request to a url of your choice, triggered by an internal event of a remote service. The benefit of webhooks is to receive desired type of notifications to your systems from remote services without regular polling. The Ebury Events System Webhooks API allows you to add your subscriptions (i.e. HTTP endpoints) to receive Events Systems’ notifications.

Usage

1. GraphQL query
2. Corresponding HTTP request
The Webhooks API is using GraphQL. This means that your queries will look like this:
  1. in GraphQL (example #1)
  2. as an HTTP POST request (example #2)
Your already existing infrastructure can be used to send HTTP requests as usual, and the response will be serialized as JSON data. In addition, detailed data schema information is also provided, helpful to improve tooling on your side.

Notification History

Every notification attempt is stored on our side. On top of the notification details, we also store the status code, headers and body returned by your subscription in response. Notifications history, including failed attempts will be available for you to review anytime.

Authentication

Authentication is managed as usual for Ebury API services. You have to provide Authorization: Bearer $access_token as described in the Authentication chapter. Please note that the client_id parameter is still mandatory. However it could be provided in two different ways.
  1. as a query parameter (as usual)
  2. as an X-Client-ID HTTP header field
We are allowing for this second option in order to be more respectful with the GraphQL standards (see: Webhook Examples).

GraphQL: differences from REST

You can think of the Webhooks API as any traditional (REST) API. However having said that, if you want to make use of a better user experience you may want to consider the following resources: The Webhooks API has one single endpoint (/webhooks/graphql), supporting uniquely POST requests. Due to this reason, interacting with the API is a bit different from what you may be used to. (The Webhook Examples section should help you to get used to required payloads.)

Retrieving information

Instead of GET queries, now we will have to send a POST request when aiming to retrieve information. The JSON payload requires two fields
  • query: the query as a string
  • variables (optional): further information to be passed with the request, as a JSON dictionary.

Add/modify/delete

GraphQL allows for data modifications via internal objects called mutations, referring to GraphQL functions on the Webhooks API database. A number of mutation functions belong to each data structure, one for each data manipulation action (create, update, delete). Your HTTP request has to refer to the one specific to your needs. The JSON payload will require
  • query field
    • embedding the mutation function signature
      • embedding the mutation function data
  • variables: potential variables

Error Reporting

The returned HTTP response may (or may not) contain an error entry. This is a non-empty list of errors, thus only shipped when errors were encountered. Each entry in the errors list is a map, containing a message string field. Please note that the message is intended for the developer. (see GraphQL Errors Specification).

Great developer tools

This feature is not yet fully available in the initial Webhooks API release. However you may find it useful despite the limited functionality.
As a part of the Webhooks API, an interactive GraphiQL interface is available (at the Webhooks API url root), which facilitates the construction of request payloads enormously. It allows you to write and execute your queries live, get a description of functionalities available for the schema (with detailed help messages on each), provides embedded text completion for writing syntactically valid queries etc. Especially in case you are new to GraphQL we strongly recommend you to take a look at this feature. It allows for an easy and natural introduction to the GraphQL syntax. It is extremely helpful, intuitive, self-explaining… and fun.

Securing your webhooks

Ebury will put a signature in every HTTP request sent so you can verify if you can trust the payload. The header X-Ebury-Signature will contain the sha3 HMAC hexdigest of the URL concatenated with the body payload. The secret to be used as key in the HMAC computation can be stored and retrieved alongside other fields of the subscription. If you don’t set a secret, the empty string will be used as a key. For an url url, body body and a secret secret, you can expect a header X-Ebury-Signature to be exactly sha3-256=52cecc9451d6279c3ef1d345c76edb320782203f876d19396fc9baeafbcbf81f.

Webhook Request Headers

Every webhook request sent by Ebury includes the following headers: Headers
string
Identifies which client is the stakeholder of the webhook call
string
Contains the sha3 HMAC hexdigest for payload verification
string
Identifies the type of notification being received
string
Idempotency key for the notification
string
Randomly generated UUID for each request
string
Counter for the number of attempts
string
Set to application/json

Idempotency Headers

The idempotency headers allow clients to differentiate between retries of the same notification and similar independent notifications:
  • X-Ebury-Notification-Id: This is the idempotency key that remains constant for all attempts of the same notification
  • X-Ebury-Delivery-Id: A unique UUID generated for each individual request attempt
  • X-Ebury-Attempt-Number: An incremental counter showing which attempt this is (starts at 1)

Custom Headers

In order to help with cases where the server that is receiving the Ebury notifications expect certain headers on the request, the subscriptions can be created with extraHeaders. The extraHeaders are going to define the static name and value of custom headers that will be added to all webhook notifications that go to the subscription URL.
  • There is a limit of 5 custom headers per subscription.
  • The header name cannot be longer than 128 characters and needs to start with x-.
  • The header value cannot be longer than 256 characters.
The extraHeaders syntax on the create subscription GraphQL request works as follows:

Webhooks Traceability

To simplify the developer experience, a contact can subscribe several clients to the same url. If this is the case, you will need that the webhook receiver can identify which client is the stakeholder of a particular call. You can do that by checking the value of the header X-Ebury-Client-Id.

Webhooks Types

Ebury supports several types of events, which you can see in the table below. You can subscribe to one specific event or to all of them. In every webhook POST call, you will receive a JSON payload as body. You can identify which type of notification you are receiving, by checking the X-Ebury-Webhook header.

Query all types

You can get a list of all currently supported types by using the custom function webhookTypes.
Response

List of types

This is the current (growing) list of notifications you can receive using the Webhooks API.

TradeStatusChange

This model is a representation of the webhook for a status change on a trade. Fields
array
Always present. A list of BookedTrade

PaymentStatusChange

This model is a representation of the webhook for a status change for a payment. Fields
array
Always present. A list of Payment
array
Always present. A list of PaymentWebhookStatus

CreditTransaction

This model is a representation of the webhook for a credit transaction. Fields
array
Always present. A list of Transaction

Payment Webhook Status

Status of the payment’s webhook Values

OnboardingStatusChange

Will give notification about the change of status during onboarding a client. Example of onboarding message is on a side, more information about onboarding can be found on onboarding documentation.
Note: Ebury Mass Payments customers will not receive notifications for the ONBOARDING_STATUS_CHANGE webhook type. Please take this limitation into account.

Webhook Examples

Scenarios presented in this section should be considered as examples. Feel free to modify them to better fit your needs. Most of the examples will only contain the GraphQL query. As explained earlier, this becomes the string value of the query field in the HTTP POST request payload . When you create your subscription you should specify which type of notification you are interested in. You can always change it by patching the subscription. As a reminder, the first example includes both the query and the related HTTP request.

Create a subscription

Response
In order to receive notifications, the first step is to create a subscription. Make sure to only include active: true in the payload if you want to receive notifications right after creation. Otherwise you can enable the subscription later. Once a subscription is active, notifications related to the client will be sent to the specified URL. Note that the secret is optional and will be used as a key to sign the payload. The extraHeaders field is also optional and will be used to add static headers into all the subscription requests. Note that the types must be present and will specify which type of notification you want to receive. If you are not sure which types of notification you want to receive you can specify all of them and update them later on by patching the subscription. As mentioned earlier, we will have to use a so-called mutation. The corresponding GraphQL function is createSubscription, requiring subscription URL and status as parameters.
  1. GraphQL query (example snippet #1)
  2. The query embedded into a HTTP request payload (example #2)
  3. The HTTP response object (example #3)

Ping a subscription

Response
If you need to check the connectivity of a subscription, even if it is disabled, you can send a ping event. To do that, you only need to POST, with all the usual headers, the path /webhooks/ping/:subscription_id:. This endpoint does not require a body as input and neither does it return anything: it is only a POST call that will generate a 204 response. Calling the endpoint will generate a ping event to simulate the workflow of a regular webhook, triggering a notification for the configured URL. The Ping webhook is a special one since it is sent to specific subscriptions. You can expect the communication between this API and your webhook receiver to follow the same rules as other types of webhooks. The header X-Ebury-Client-Id will be populated, and X-Ebury-Webhook will contain the special value Ping. The payload will be a valid json without any specific schema, apart from being signed in X-Ebury-Signature as usual.

Example webhook request format

When Ebury sends a webhook to your endpoint, the request will include headers similar to:

Get the list of subscriptions

Two example usages, to
  • query the list of all subscriptions (example #1),
  • or filter only for the active ones (example #2),

Delete a subscription

To delete a subscription you will need to send a mutation object, invoking the deleteSubscription GraphQL function. In this example, we create a query with an input variable, and then we send the value of the variable. To make it easier to follow, we include
  1. GraphQL query and internal variable definition (example #1a + #1b)
  2. HTTP request with all embedded in the payload (example #2)

Enable a subscription

If you want to change the status (active property) of a subscription, you need to apply a mutation invoking the updateSubscription GraphQL function.

Disable a subscription

Disabling a subscription goes just the same.

Get the last notification of every subscription

The power of GraphQL relies on the ability to navigate across data relationships. This will allow us to efficiently retrieve a list of subscriptions, with the latest notification belonging to each. Note that we are using a combination of two options to get the latest notification.
  • orderBy attribute making sure that the first notification attempt is the newest
  • first: 1: to get no more but the first (one) notification attempt

Patch a subscription

Patching a subscription is a useful way to change the scope of your notification by changing the types of event you are interested in. When you are not sure which types of events are important for you, you can subscribe for all and then unsubscribe undesired events by patching your subscription. When changing the types, you need to specify the whole new list of types. Few examples of patching your type values:
  • types: [] subscribe to none types of events, will have similar effect like disable the subscription by setting Active to False.
  • types: [TRADE_STATUS_CHANGE, PAYMENT_STATUS_CHANGE, CREDIT_INCOMING_TRANSACTION, CREDIT_MARGIN_TRANSACTION, CREDIT_PAYMENT_RETURNED_TRANSACTION, ONBOARDING_STATUS_CHANGE, CREDIT_TRANSACTION, DEBIT_TRANSACTION] subscribe to all types of events
  • types: [TRADE_STATUS_CHANGE, CREDIT_INCOMING_TRANSACTION]] subscription to only 2 events type
If you want to change the url and event types of a subscription, you need to update it as such:

Responses

Response

Success

A successful request will return a 200 OK response with a map. This map will include an entry with
  • a data field
    • that will further include the requested operation
      • that will further include fields that were requested for the response.

Failure

See Error Reporting for details of unsuccessful requests.