Skip to main content

Using webhooks

Webhooks

Our service provides a webhook mechanism, allowing an integrator to be notified of some business events. These events will be sent on a URL communicated by the integrator. This URL must be an https URL (mutual TLS can optionally be set up). The events will be sent with POST requests.

The events are serialized in json. The different fields are:

fielddescription
idThe unique id of the event.
event_typeThe type of event, among: UDPATED, CREATED, DELETED.

The event type specifies what happened on the resource the event is related to.

The only event type implemented for now is UPDATED.
resource_typeThe type of the resource this event is related to.

The only value for now is CONNECTIONS.
creation_dateCreation time of the event (timestamp in seconds).
channel_definition_idSee below (A).
resourceA representation of the resource this event is related to. See below (B).
new_transactionsA boolean field specifying whether the synchronization brought new transactions. This field is specific to CONNECTIONS UPDATED events.

(A) The channel_definition_id field was added as part of the changes of our API v2.1, made to handle PSD2 APIs and REDIRECT authentication. In API v2.1, a connection may have:

  • a REDIRECT channel, allowing getting payment accounts through PSD2 APIs
  • and/or an EMBEDDED channel, allowing getting other accounts through scraping (savings accounts, loans, etc).

A webhook event will be fired everytime a channel synchronization finishes. So, we will possibly have 2 events for a single synchronization of a connection. The channel_definition_id field is here to specify which channel the event is related to.

(B) For connection resources (the only resource type implemented for now), the resource field is very similar to connection resources returned by API endpoints 'GET /connections endpoint' or 'GET /connections/{connection_id}'.

The only difference is the presence of two additional fields:

fielddescription
account_countAn integer field specifying the number of accounts included in the connection.
This is the number of accounts returned by 'GET /accounts?connectionid={connection_id}'.
accountsAn array field, containing the accounts included in the connection, as they are returned by API endpoints 'GET /accounts' or 'GET /accounts/{connection_id}' .

Important note

When a connection has more than 100 accounts:

  • the accounts array field will be empty
  • the account_count field will contain the number of accounts included in the connection

It is up to the integrator to handle this specific case: API call(s) to 'get the whole account list' should be done (possibly several calls depending on pagination parameters). We strongly recommend not to hard code the 100 limit, which could change in the future. Having an account_count greater than 0 with an empty list of accounts is the right way to detect this case.

(C) The connection_updated field contains only one field, named new_transactions. This field is a boolean field specifying whether the synchronization brought new transactions.

Here is a full example of event, for a connection with 2 accounts:

{
"id": "abc123456",
"event_type" : "UPDATED",
"resource_type" : "CONNECTIONS",
"creation_date": 1509955448,
"channel_definition_id" : "24601",
"resource" : {
"id" : "123",
"user_id" : "321",
"provider_id" : "246",
"name" : "Caisse d'Epargne",
"status" : "SUCCESS",
"creation_date" : 1286641695,
"auto_sync" : true,
"logo_url" : "https://static.oxlin.io/common/pictures/providers_logos/246.png",
"channels" : [
{
"channel_definition_id" : "24600",
"mode" : "EMBEDDED",
"status" : "SUCCESS",
"last_success_date" : 1607106094,
"last_end_date" : 1607106094,
"credentials" : [
{
"id" : "2460000",
"masked_value" : "*****1234"
}
],
"account_types" : [ "CHECKINGS", "SAVINGS", "LOAN", "CREDIT_CARD" ],
"channel_definition_unavailable" : false
},
{
"channel_definition_id" : "24601",
"mode" : "REDIRECT",
"expires" : 1609943012,
"status" : "SUCCESS",
"last_success_date" : 1607106070,
"last_end_date" : 1607106070,
"credentials" : [ ],
"account_types" : [ "CHECKINGS", "CREDIT_CARD" ],
"channel_definition_unavailable" : false
}
],
"owner" : {
"name" : "M JEAN DUPONT"
},
"consent_per_account" : false,
"account_count" : 2,
"accounts" : [
{
"id": "222",
"connection_id": "123",
"name": "Compte Courant",
"currency": "EUR",
"balance": 1234.56,
"balance_date": 1607353181,
"iban": "FR7612345678901234567890123",
"status": "ACTIVE",
"type": "CHECKINGS",
"creation_date": 1286641717,
"account_number": "12345678901",
"owner": {
"name": "Mr Jean Dupont"
},
"usage": "PERSONAL",
"last_channel_definition_id": "24601"
},
{
"id": "111",
"connection_id": "123",
"name": "Livret A",
"currency": "EUR",
"balance": 10000,
"balance_date": 1607310062,
"iban": "FR7609876543210987654321098",
"status": "SUCCESS",
"type": "SAVINGS",
"creation_date": 1286641717,
"account_number": "09876543210",
"owner": {
"name": "Mr Jean Dupont"
},
"usage": "PERSONAL",
"savings": {
"type": "LIVA",
"savings_type": "LIQUID",
"yield_rate": 0.5
},
"last_channel_definition_id": "24600"
}
]
},
"connection_updated" : {
"new_transactions" : true
}
}

And another full example of event, for a connection with 102 accounts:

{
"id": "abc123456",
"event_type" : "UPDATED",
"resource_type" : "CONNECTIONS",
"creation_date": 1509955448,
"channel_definition_id" : "24601",
"resource" : {
"id" : "123",
"user_id" : "321",
"provider_id" : "246",
"name" : "Caisse d'Epargne",
"status" : "SUCCESS",
"creation_date" : 1286641695,
"auto_sync" : true,
"logo_url" : "https://static.oxlin.io/common/pictures/providers_logos/246.png",
"channels" : [
{
"channel_definition_id" : "24600",
"mode" : "EMBEDDED",
"status" : "SUCCESS",
"last_success_date" : 1607106094,
"last_end_date" : 1607106094,
"credentials" : [
{
"id" : "2460000",
"masked_value" : "*****1234"
}
],
"account_types" : [ "CHECKINGS", "SAVINGS", "LOAN", "CREDIT_CARD" ],
"channel_definition_unavailable" : false
},
{
"channel_definition_id" : "24601",
"mode" : "REDIRECT",
"expires" : 1609943012,
"status" : "SUCCESS",
"last_success_date" : 1607106070,
"last_end_date" : 1607106070,
"credentials" : [ ],
"account_types" : [ "CHECKINGS", "CREDIT_CARD" ],
"channel_definition_unavailable" : false
}
],
"owner" : {
"name" : "M JEAN DUPONT"
},
"consent_per_account" : false,
"account_count" : 102,
"accounts" : [
]
},
"connection_updated" : {
"new_transactions" : true
}
}

Using webhooks to get new transactions

Webhooks can be used to get new transactions on the fly: every time a "connection updated" event is received by the integrator, it can call the 'GET /transactions' endpoint. The integrator can use the new_transactions flag to know whether there are new transactions to get.

This has to be done on a per account basis. For each account, the integrator must use the import date of the last transaction the integrator previously got for this account.

Since there is one "connection updated" event per channel, for each event, the integrator can get the new transactions for the accounts currently attached to the channel of the event. The link between an account and a channel is specified by the last_channel_definition_id field in the accounts (see 'GET /accounts endpoint').

Example:

`GET /transactions?account_id=abc123&start_import_date=1574767574`

Limitation

Our current webhook implementation does not provide any retry mechanism. If a "connection updated" event is not received properly by the integrator, it is currently lost. It is thus important not to rely on the webhooks only to get new transactions.