Usage
1. GraphQL query- in GraphQL (example #1)
- as an HTTP POST request (example #2)
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 provideAuthorization: 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.
- as a query parameter (as usual)
- as an
X-Client-IDHTTP header field
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 is following the GraphQL specs
- Each endpoint supports Schema Introspection. This allows you to validate your queries, determine the type of result data, etc.
- Pagination goes according to the Relay Cursors Connections Specification. (Consistent pagination and ordering via cursors.)
/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
query: the query as a stringvariables(optional): further information to be passed with the request, as a JSON dictionary.
Add/modify/delete
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
queryfield- embedding the
mutationfunction signature- embedding the mutation function data
- embedding the
variables: potential variables
Error Reporting
The returned HTTP response may (or may not) contain anerror 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.
Securing your webhooks
Ebury will put a signature in every HTTP request sent so you can verify if you can trust the payload. The headerX-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: Headersstring
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/jsonIdempotency 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 withextraHeaders. 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.
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 headerX-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 theX-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
array
Always present. A list of BookedTrade
PaymentStatusChange
array
Always present. A list of PaymentWebhookStatus
CreditTransaction
array
Always present. A list of Transaction
Payment Webhook Status
Status of the payment’s webhook ValuesOnboardingStatusChange
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 thequery 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
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.
- GraphQL query (example snippet #1)
- The query embedded into a HTTP request payload (example #2)
- The HTTP response object (example #3)
Ping a subscription
Response
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
- query the list of all subscriptions (example #1),
- or filter only for the active ones (example #2),
Delete a subscription
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
- GraphQL query and internal variable definition (example #1a + #1b)
- HTTP request with all embedded in the payload (example #2)
Enable a subscription
active property) of a subscription, you need to apply a mutation invoking the updateSubscription GraphQL function.
Disable a subscription
Get the last notification of every subscription
orderByattribute making sure that the first notification attempt is the newestfirst: 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
Responses
Response
Success
A successful request will return a200 OK response with a map.
This map will include an entry with
- a
datafield- that will further include the requested operation
- that will further include fields that were requested for the response.
- that will further include the requested operation