Skip to content
Developer home

Posting statements

  Less than to read

This walkthrough covers how to use the statements flow to upload transaction data to Banking Service through the Provider API. In this guide we will walk through the API calls made to and from Banking Service from your application and consuming product to demonstrate the posting statements flow detailed in our Postman collection.

Read our API flow overview before following this walkthrough. This covers any prerequisites and how to use our Postman collections.

API flow diagram

Flow diagram displaying the authorisation flow


1. Get an access token

Using the Provider API to complete requests requires a Sage ID bearer token and an API key to authenitcate the call.

An API key will be provided to you by Sage through the setup proccess. To Generate a Sage ID bearer token you can make a POST request to the token endpoint as detailed below. This token generally lasts 480 minutes but should be refreshed when receiving a 401 Unauthenticated responses from the API.

POST /oauth/token

Sage ID

This request should be sent with the following body:

Body Params Description
grant_type This should be set as client_credentails.
client_id This value identifies your client, and is tied to your provider; only tokens generated with your clientId can access resources associated with your provider.
client_Secret This value is required in order to generate SageId tokens. It should be handled as a secret and not shared.
audience This value identifies the Provider API and ensures that generated SageId tokens are targeted at the correct API.

These resources (keys) will be supplied by Sage.


2. Push transactions

The /statements POST endpoint is used to initialise processing of data for a single BankAccount. The body of the request can include up to 100 TransactionDetails objects, along with a single AccountDetails object. Some initial data validation checks will be performed; but full processing of the payload will happen asynchronously.

Transactions should be sent in the same order as they appear on the account statement. This means you should post the first 100 statements in date order and wait until this has been successful until moving onto the next 100. If an error occurs on this first POST, you would need to retry and confirm the status has been successful before moving on.

Processing progress can be tracked using the /statements/{statementId} GET endpoint.

:

Note: Any given BankAccount can only have a single statement in flight at any given time. This is to avoid any concurrency issues with the submission and validation of the data. This means consumers must await the response from the first request before making a second request.

When TransactionDetails are sent, the AccountDetail balances must represent the account balances after these transactions are applied. The status and balances can be updated independent of TransactionDetails by sending 0 TransactionDetails objects.

POST /statements

Provider API

Headers Description
x-api-key This value required in validating calls to the Provider API. It should be handled as a secret and not shared. Individual keys of the API may be throttled depending on usage agreements.
Authorization This is the value returned from your call to the /oauth/token endpoint.
Content-Type This should be set as application/json.

Descriptions of request body identifiers:

  • principalId – This is the unique identifier as it appears in Banking Service for the Bank Account this statement is for.
  • uniqueId – This is a unique identifier of this transaction. This uniqueId should never match another transaction and, if this transaction were to be posted again for any reason, the uniqueId MUST be the same.

Example request body:

{
    "data": {
        "accountDetails": [{
            "bankAccountId": "92c7bce5-3c01-4899-ab77-a5ecf85d6ff8",
            "status": "active",
            "ledgerBalance": 0,
            "ledgerBalanceDate":"2019-11-24T12:00:00.000Z",
            "availableBalance": 0,
            "availableBalanceDate":"2019-11-24T12:00:00.000Z"
        }],
        "transactionDetails": [{
            "uniqueId": "1",
            "bankAccountId": "92c7bce5-3c01-4899-ab77-a5ecf85d6ff8",
            "transactionAmount": 111,
            "transactionType": "CREDIT",
            "transactionStatus": "posted",
            "datePosted": "2019-11-02T23:00:12.000Z",
            "dateUserInitiated": "2019-11-04T22:54:00.000Z",
            "exchangeCurrency": "EUR",
            "exchangeAmount": 120,
            "checkNumber": "123456",
            "referenceNumber": "00000001",
            "description": "test_description",
            "payee": {
                "payeeDescription": "100001",
                "address1": "1 the something",
                "address2": "on some street",
                "address3": "on some estate",
                "city": "in a city",
                "state": "in a state",
                "postalCode": "MY POST CODE",
                "country": "GBR",
                "phoneNumber": "0091299291212",
                "payeeBankId": "123456",
                "payeeAccountId": "654321"
            },
            "coordinates": {
                "lat": 0.9812,
                "long": 1.0238
            },
            "narrative1": "narrative data",
            "narrative2": "extended narrative data",
            "category": {
                "topLevelCategory": "TopCategory",
                "subCategory": "SubCategory",  
                "categoryId": 12,
                "standardIndustrialCode": "9089"
            }
        }],
        "principalId":"92c7bce5-3c01-4899-ab77-a5ecf85d6ff8",
             "expected": {
              "transactionDetailsCount": 1,
              "accountDetailsCount": 1,
              "transactionCreditSum":111,
              "transactionDebitSum": 0
          }
    }
}

3. Poll until succeeded

After posting your transactions through the POST /statements endpoint. You should check to ensure the transactions have succesfully been processed. This can be done by continuing to poll the GET /statements request using the statement ID returned from the previous call to POST /statements. In the response to this GET request you will find the status property. This can be used to identify the current processing state.

If the status is set to succeeded the processing is complete and the consuming Sage product will be able to retrieve these transactions. If it’s set to processing the service is in the middle of handling this request. This may be down to being busy or handling a large number of transactions.

The following are the possible returned status results when attempting to push your transactions:

  • accepting: Banking Service is accepting accountDetail and transactionDetail parts. The delete statement endpoint can be called by the provider.
  • queued: The transaction post request is queued for processing, and can no longer accept parts.
  • processing: The batch is being processed.
  • succeeded: The batch was processed successfully with no errors (may still contain warnings).
  • failed: The batch failed to process successfully and has errors. The delete statement endpoint should be called by the provider.
  • deleted: The batch has been deleted by the provider.

GET /statements

Provider API

Headers Description
x-api-key This value required in validating calls to the Provider API. It should be handled as a secret and not shared. Individual keys of the API may be throttled depending on usage agreements.
Authorization This is the value returned from your call to the /oauth/token endpoint.
Content-Type This should be set as application/json.

Example response:

{
    "data": {
        "principalId": "fe5538b6-5570-4e67-8dde-f5ff5f2f4373",
        "expected": {
            "transactionDetailsCount": 1,
            "accountDetailsCount": 1,
            "transactionCreditSum": 111,
            "transactionDebitSum": 0
        },
        "actual": {
            "transactionDetailsCount": 1,
            "accountDetailsCount": 1,
            "transactionCreditSum": 111,
            "transactionDebitSum": 0
        },
        "status": "queued",
        "statusReason": "This Batch is queued for processing",
        "statusModifiedDate": "2019-11-27T07:55:34.021Z",
        "providerId": "fe5538b6-5570-4e67-8dde-f5ff5f2f4373",
        "_id": "d578ace1-920a-4988-9698-47e51ba3591e"
    },
    "links": {
        "self": ""
    },
    "meta": null,
    "error": null
}

The consuming Sage product can then make a request to the GET /transactions endpoint, allowing the customer to access these new transactions.


Recap

This walkthrough has covered the Banking Service flow for posting transactions. Covering how the provider can push transaction data into Banking Service through the /statements endpoint, and how to ensure they have been processed succesfully before posting the next batch. How the provider can authenticate their requests through the Provider API by retrieving a Sage ID bearer token has also been covered.


Next steps

Next, take a look at the offboarding flow. This covers how to disconnect an account.