Accounts

Accounts are the entities that hold the balances of your clients. Each account is connected to a single service provider. A unique identifier, called the Ledger Number, is assigned to each account regardless of the provider or type of account.

Account Alias

The alias of an account is optional and can be set at creation. It's there for labelling and differentiation between more than one account in the same currency. For example, one use case might be setting the alias of the first EUR account as "Salary Account" and setting the second one as "Investment Funds". Note: Aliases do not have to be unique. If an alias is not set when creating an account it is set to default to "{currency} Account" (e.g. "EUR Account").

Create an Account

POST /accounts
There is a single workflow to create an account.

1. Issuing: You can ask for an account to be opened at a specific service provider of your choice. If this is the first account created for this client at the selected service provider, the client might be required to be created at the service provider first depending on the service provider’s workflows.

{
  "workflow": {
    "code": "client.issuing"
  },
  "data": {
    "account": {
        "clientId": "00000000-0000-0000-0000-000000000000",
        "currency": "EUR",
        "alias": "EUR Account"
    }
  },
  "connect": {
    "type": "explicit",
    "serviceProvider": "railsbank"
  },
  "metadata": {}
}
{
  "workflow": {
    "code": "client.issuing"
  },
  "data": {
    "account": {
      "id": "00000000-0000-0000-0000-000000000000",
      "clientId": "00000000-0000-0000-0000-000000000000",
      "status": "pending",
      "country": "GB",
      "currency": "EUR",
      "alias": "EUR Account",
      "routingCodes": {},
      "iban": null,
      "accountNumber": null,
      "ledgerNumber": "12345678",
      "availableBalance": 0,
      "serviceProvider": "railsbank",
      "accountHolderName": ""
    }
  },
  "connect": {
    "type": "explicit",
    "serviceProvider": "railsbank"
  },
  "metadata": {}
}
  1. Migration: You can migrate an existing account at a service provider. To migrate an account, the client must be migrated first and then the account must be created in an active state. If the service provider has an equivalent resource to the client, the account is validated if it's owned by the client in the migration request. The migration endpoint also asks for the currency of the account to validate it against the currency available at the service provider.
{
  "workflow": {
    "code": "client.migration"
  },
  "data": {
    "account": {
        "clientId": "00000000-0000-0000-0000-000000000000",
        "currency": "EUR",
        "alias": "EUR Account"
    },
    "sourceId": "00000000-0000-0000-0000-000000000000"
  },
  "connect": {
    "type": "explicit",
    "serviceProvider": "railsbank"
  },
  "metadata": {}
}
{
  "workflow": {
    "code": "client.migration"
  },
  "data": {
    "account": {
      "id": "00000000-0000-0000-0000-000000000000",
      "clientId": "00000000-0000-0000-0000-000000000000",
      "status": "active",
      "country": "GB",
      "currency": "EUR",
      "alias": "EUR Account",
      "routingCodes": {},
      "iban": null,
      "accountNumber": null,
      "ledgerNumber": "12345678",
      "availableBalance": 0,
      "serviceProvider": "railsbank",
      "accountHolderName": ""
    }
  },
  "connect": {
    "type": "explicit",
    "serviceProvider": "railsbank"
  },
  "metadata": {}
}

Update an Account

PATCH /accounts/{accountId}
There is a single workflow to update an account

  1. Direct: Alias can be updated using the direct workflow.
{
  "workflow": {
    "code": "direct"
  },
  "data": {
    "account": {
        "alias": "EUR Account"
    }
  },
  "connect": {},
  "metadata": {}
}

Get an Account

Endpoints with GET do not include workflows, however you can use metadata parameters to shape the response.

GET /accounts/{accountId}?metadata.include=connect.connection

{
  "workflow": {},
  "data": {
    "account": {
      "id": "00000000-0000-0000-0000-000000000000",
      "clientId": "00000000-0000-0000-0000-000000000000",
      "status": "active",
      "country": "GB",
      "currency": "EUR",
      "alias": "EUR Account",
      "routingCodes": {},
      "iban": null,
      "accountNumber": null,
      "ledgerNumber": "12345678",
      "availableBalance": 0,
      "serviceProvider": "railsbank",
      "accountHolderName": ""
    }
  },
  "connect": {
    "connection": {
      "id": "5ffc8b9c-3073-4625-a55b-4ae69d657cc3",
      "serviceProvider": "railsbank"
    }
  },
  "metadata": {}
}

You can find a list of valid included parameters below

Key

Description

connect.connection

Includes information about provider connection of the account.

List Accounts

GET /accounts

{
  "workflow": {},
  "data": {
    "accounts": [{
      "id": "00000000-0000-0000-0000-000000000000",
      "clientId": "00000000-0000-0000-0000-000000000000",
      "status": "pending",
      "country": "GB",
      "currency": "EUR",
      "alias": "EUR Account",
      "routingCodes": {},
      "iban": null,
      "accountNumber": null,
      "ledgerNumber": "12345678",
      "availableBalance": 0,
      "serviceProvider": "railsbank",
      "accountHolderName": ""
    }]
  },
  "connect": {},
  "metadata": {
    "page": {
      "size": 10,
      "totalElements": 100,
      "totalPages": 10,
      "number": 0
    }
  }
}

Get Account Deposit Information

GET /accounts/{id}/deposit-information

Details of deposit information might be different from the information provided in the account itself. This usually occurs when the account is a pooled account and a reference is required for inbound transfers. The account itself doesn't show all the data from the pooled account since not all the information belongs to the client's accounts. To get that information for deposits, this endpoint needs to be queried.

IF accounts can be funded by using the deposit information provided for each scheme (defined below). The deposit information returns a JSON map where scheme codes are used as keys.

  1. SWIFT: Accounts can be funded using international transfers if the underlying service provider of the account supports inbound SWIFT transfers. The BIC (which is available in routing codes) and IBAN/Account Number (depending on the country) should be provided for international transfers.

  2. Local Transfer Schemes: Accounts can be funded using a local transfer method if the underlying service provider of the account supports inbound local transfers in the currency of the account. A local routing code (e.g. Sort-Code for UK, ABA for US) and IBAN/Account Number (depending on the country) should be provided for local transfers.

  3. Internal: Accounts can be funded using the IF internal transfers feature using the unique ledger number generated by the IF Platform.

{
  "workflow": {},
  "data": {
    "depositInformation": {
      "chaps": {
        "accountHolderName": "",
        "country": "GB",
        "currency": "GBP",
        "routingCodes": {
          "sort-code": "000000"
        },
        "accountNumber": "00000000",
        "iban": "GB99AAAA01234567890123",
        "ledgerNumber": null,
        "reference": null,
        "bankName": null,
        "bankAddress": null,
        "intermediaryAccount": null
      },
      "faster-payments": {
        "accountHolderName": "",
        "country": "GB",
        "currency": "GBP",
        "routingCodes": {
          "sort-code": "000000"
        },
        "accountNumber": "00000000",
        "iban": "GB99AAAA01234567890123",
        "ledgerNumber": null,
        "reference": null,
        "bankName": null,
        "bankAddress": null,
        "intermediaryAccount": null
      },
      "swift": {
        "accountHolderName": "",
        "country": "GB",
        "currency": "GBP",
        "routingCodes": {
          "bic": "AAAAGB20XXX"
        },
        "accountNumber": "00000000",
        "iban": "GB99AAAA01234567890123",
        "ledgerNumber": null,
        "reference": null,
        "bankName": "Payrnet",
        "bankAddress": null,
        "intermediaryAccount": {
          "accountHolderName": null,
          "country": "GB",
          "currency": "EUR",
          "routingCodes": {
            "bic": "AAAAGB22"
          },
          "accountNumber": null,
          "iban": null,
          "ledgerNumber": null,
          "reference": null,
          "bankName": "Example Bank",
          "bankAddress": null,
          "intermediaryAccount": null
        }
      },
      "internal": {
        "accountHolderName": "",
        "country": "GB",
        "currency": "GBP",
        "routingCodes": {},
        "accountNumber": null,
        "iban": null,
        "ledgerNumber": "12345678",
        "reference": null,
        "bankName": null,
        "bankAddress": null,
        "intermediaryAccount": null
      }
    }
  },
  "connect": {},
  "metadata": {}
}

Create Account Balance Adjustment

POST /accounts/{id}/balance-adjustments

Account balance adjustments update the account balance directly. There are various circumstances in which a Balance Adjustment may need to be created. It might be needed for example, to fix a system error or a user mistake (e.g a mistake in pricing definition) or to synchronize a transaction that has occurred outside of the IF Platform (e.g a non-integrated bank). Balance adjustments do not have different statuses. On creation of a balance adjustment the only status can be ‘Completed’.

There are two independent workflows of account balance adjustments:
1. Correction: There are two types of corrections; fee and unknown.
Fee corrections are treated as revenues of other transactions. If there is an automation to sweep the fees periodically, these corrections are included in those sweeps.
Unknown corrections are not reflected to underlying service provider.

{
  "workflow": {
    "code": "correction",
    "type": "fee",
    "transactionType": "incoming-transfer"
  },
  "data": {
    "balanceAdjustment": {
      "accountId": "00000000-0000-0000-0000-000000000000",
      "direction": "debit",
      "amount": 10,
      "currency": "GBP",
      "description": "free text"
    }
  },
  "connect": {},
  "metadata": {}
}
{
  "workflow": {
    "code": "correction",
    "type": "fee",
    "transactionType": "incoming-transfer"
  },
  "data": {
    "balanceAdjustment": {
      "id": "00000000-0000-0000-0000-000000000000",
      "accountId": "00000000-0000-0000-0000-000000000000",
      "direction": "debit",
      "transactionNumber": "20210414-ABCDEF",
      "amount": 10,
      "currency": "GBP",
      "description": "fee reversal"
    }
  },
  "connect": {},
  "metadata": {}
}
{
  "workflow": {
    "code": "correction",
    "type": "fee",
    "transactionType": "unconnected-service-provider"
  },
  "data": {
    "balanceAdjustment": {
      "accountId": "00000000-0000-0000-0000-000000000000",
      "direction": "debit",
      "amount": 10,
      "currency": "GBP",
      "description": "free text",
      "unconnectedServiceProvider": "gps"
    }
  },
  "connect": {},
  "metadata": {}
}
  1. Synchronization: This workflow reflects a transaction that physically occurred but wasn’t recorded on the IF Platform. type can only be unconnected-service-provider and code of unconnected service provider must be included in data section.
{
  "workflow": {
    "code": "synchronization",
    "type": "unconnected-service-provider"
  },
  "data": {
    "balanceAdjustment": {
      "accountId": "00000000-0000-0000-0000-000000000000",
      "direction": "debit",
      "amount": 10,
      "currency": "GBP",
      "description": "card payment",
      "unconnectedServiceProvider": "gps"
    }
  },
  "connect": {},
  "metadata": {}
}
{
  "workflow": {
    "code": "synchronization",
    "type": "unconnected-service-provider"
  },
  "data": {
    "balanceAdjustment": {
      "id": "00000000-0000-0000-0000-000000000000",
      "accountId": "00000000-0000-0000-0000-000000000000",
      "direction": "debit",
      "transactionNumber": "20210414-ABCDEF",
      "amount": 10,
      "currency": "GBP",
      "description": "card payment",
      "unconnectedServiceProvider": "gps"
    }
  },
  "connect": {},
  "metadata": {}
}

Webhooks

Account webhooks have "accounts" in the module field in the webhook container object.

There are 6 types of webhooks sent for accounts:

  • account-activated
  • account-inactivated
  • account-suspended
  • account-closed
  • account-declined
  • account-information-updated

These types are exposed in the webhook.type field.

The connection section is optional, it will be available if an account is created at a Service Provider successfully.

Fields listed below can only be updated if type of webhook is either account-activated or account-information-updated:

  • country
  • routingCodes (and content of it)
  • iban
  • accountNumber
{
  "webhook": {
    "module": "accounts",
    "type": "account-activated"
  },
  "data": {
    "account": {
      "id": "00000000-0000-0000-0000-000000000000",
      "clientId": "00000000-0000-0000-0000-000000000000",
      "status": "active",
      "country": "GB",
      "currency": "GBP",
      "alias": "GBP Account",
      "routingCodes": {
        "sort-code": "123456"
      },
      "iban": null,
      "accountNumber": "12345678",
      "ledgerNumber": "12345678",
      "availableBalance": 0,
      "serviceProvider": "railsbank",
      "accountHolderName": ""
    }
  },
  "connect": {
    "connection": {
      "id": "5ffc8b9c-3073-4625-a55b-4ae69d657cc3",
      "serviceProvider": "railsbank"
    }
  },
  "metadata": {}
}