Skip to content

Connect a bank feed

Provisional

Bank feeds are gated by a bank_feeds feature flag — the API router returns 404 on community installs that do not have the flag enabled. Real bank data requires completing SISS onboarding through the feeds.saebooks.com.au relay; until onboarding is complete the relay operates in stub mode. See Bank feeds for the broader context.

This guide describes the intended end-to-end flow. Where a step isn't yet automated, we say so.

What you're going to do

  1. Complete relay onboarding (one-off NDA + provisioning via SAE Engineering)
  2. Create a connection — the consumer redirects to their bank, approves CDR consent
  3. Wait for the relay to sync (or force a sync via the API)
  4. Confirm transactions are landing in bank_statement_lines
  5. Tune matching rules

1. Aggregator credentials

CDR access in Australia goes through an accredited aggregator (currently SISS Data Services). SAE Books connects to SISS via the feeds.saebooks.com.au relay service — the relay holds your ADR credentials; you do not manage SISS client secrets directly on your instance. On the SISS / relay side you need:

  • An accredited data recipient (ADR) registration or a contract riding on theirs
  • An NDA with SISS
  • Onboarding through the SAE Books relay (provisioned by SAE Engineering; contact support)
curl -X POST "$SAEBOOKS_API_BASE/bank-feeds/connections" \
  -H "Authorization: Bearer $JWT" \
  -H "Content-Type: application/json" \
  -d '{
    "bank": "anz-au",
    "account_label": "ANZ Business Cheque"
  }'

Response:

{
  "id": "<local-connection-uuid>",
  "consent_url": "https://...",
  "status": "pending_consent"
}

Send the consent_url to the consumer — they authenticate at their bank, approve the consent, and the bank redirects them back to the relay. The relay updates the connection status and schedules the first transaction pull.

Stub mode

While SISS onboarding is in progress the relay operates in stub mode and returns a deterministic stub response (no real bank data). The status field will read pending_consent and consent_url may be a placeholder. This is expected — the local connection row is created so the UI's in-flight list works.

3. First sync

By default a sync runs on the relay's schedule. Force one:

curl -X POST "$SAEBOOKS_API_BASE/bank-feeds/sync" \
  -H "Authorization: Bearer $JWT" \
  -H "Content-Type: application/json" \
  -d '{"connection_id": "<local-connection-uuid>"}'

Response includes inserted (count of new statement lines) and next_cursor. Transactions land in GET /api/v1/bank_statement_lines?bank_account_id=....

4. Matching

Each transaction lands with status UNMATCHED. Auto-create rules process them — see Modules → Bank feeds. Matching rules that auto-post set auto_create: true; others queue for manual review.

Tune matching rules:

curl -X POST "$SAEBOOKS_API_BASE/bank_rules" \
  -H "Authorization: Bearer $JWT" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Officeworks",
    "match_pattern": "OFFICEWORKS",
    "match_type": "CONTAINS",
    "account_id": "<uuid-of-6000>",
    "tax_code": "GST",
    "auto_create": true
  }'

Failure modes

  • Consent expired. CDR consent caps at 12 months. When consent lapses the connection status transitions to revoked; revoke the local row with DELETE /api/v1/bank-feeds/connections/{id} and start a new consent flow. No transactions are lost — syncs just pause.
  • Relay unavailable. The GET /api/v1/bank-feeds/connections list endpoint serves from the local mirror and remains usable when the relay is unreachable. Sync calls return 503 and should be retried; the next successful sync catches up.
  • Stub mode. While SISS onboarding is incomplete the relay returns 501 stub responses. The API surfaces these as 200 with "stub": true in the response body so the UI can show a banner rather than an error. No real transactions are inserted in stub mode.

Next