Up Bank Integration (Australian Neobank) - Node-Red w/ Home Assistant

Here in Australia one of our neobanks, Up, recently released an API. It seemed like a fun weekend project to get it integrated into my Home Assistant/Node Red setup. I’m still learning the ropes with all these systems, so wanted to share what I’d done to help other Up users and get some feedback on my setup. I hope I’ve managed to make the core functionality really easy to deploy for anyone using HA/NR.

The first step is to register for the Up API and obtain your bearer token. Their guide gives steps on doing this with curl, I used Postman, you can do this however you like. If you want to use webhooks, you’ll need to register your webhook endpoint via the Up API, also following the steps in their guide. My flow uses “/api/up” for the endpoint but you can use whatever you want. The webhook is optional though, you can rely exclusively on the inject node for periodic updates if you prefer.

Then you’ll need to deploy the following NR flow, and put your bearer into the Set Bearer and Inject Bearer nodes.

[
   {
      "id":"d7911825.3f6ad8",
      "type":"http in",
      "z":"1a80a0df.9dc3ff",
      "name":"Up Webhook",
      "url":"/api/up",
      "method":"post",
      "upload":true,
      "swaggerDoc":"",
      "x":110,
      "y":80,
      "wires":[
         [
            "53dfbba1.6f7794",
            "43a8fb96.292274",
            "9fbed058.18f4c"
         ]
      ]
   },
   {
      "id":"53dfbba1.6f7794",
      "type":"http response",
      "z":"1a80a0df.9dc3ff",
      "name":"HTTP  Res",
      "statusCode":"",
      "headers":{

      },
      "x":330,
      "y":80,
      "wires":[

      ]
   },
   {
      "id":"43a8fb96.292274",
      "type":"debug",
      "z":"1a80a0df.9dc3ff",
      "name":"Webhook Debug",
      "active":true,
      "tosidebar":true,
      "console":false,
      "tostatus":false,
      "complete":"true",
      "targetType":"full",
      "x":350,
      "y":40,
      "wires":[

      ]
   },
   {
      "id":"9fbed058.18f4c",
      "type":"change",
      "z":"1a80a0df.9dc3ff",
      "name":"Set Bearer",
      "rules":[
         {
            "t":"set",
            "p":"payload.bearer",
            "pt":"msg",
            "to":"up:yeah:YOURBEARERHERE",
            "tot":"str"
         }
      ],
      "action":"",
      "property":"",
      "from":"",
      "to":"",
      "reg":false,
      "x":110,
      "y":120,
      "wires":[
         [
            "bc8e510a.051df"
         ]
      ]
   },
   {
      "id":"db8688c.78b8878",
      "type":"inject",
      "z":"1a80a0df.9dc3ff",
      "name":"Inject Bearer",
      "topic":"",
      "payload":"{\"bearer\":\"up:yeah:YOURBEARERHERE\"}",
      "payloadType":"json",
      "repeat":"60",
      "crontab":"",
      "once":true,
      "onceDelay":0.1,
      "x":120,
      "y":200,
      "wires":[
         [
            "bc8e510a.051df"
         ]
      ]
   },
   {
      "id":"bc8e510a.051df",
      "type":"function",
      "z":"1a80a0df.9dc3ff",
      "name":"Create Request",
      "func":"msg.headers = {\n    \"Authorization\": \"Bearer \" + msg.payload.bearer\n}\n\nreturn msg;\n\n",
      "outputs":1,
      "noerr":0,
      "x":120,
      "y":160,
      "wires":[
         [
            "dcac08db.5827c8",
            "6df2aa1c.339524"
         ]
      ]
   },
   {
      "id":"dcac08db.5827c8",
      "type":"http request",
      "z":"1a80a0df.9dc3ff",
      "name":"Requesting  Balances",
      "method":"GET",
      "ret":"obj",
      "paytoqs":false,
      "url":"https://api.up.com.au/api/v1/accounts",
      "tls":"",
      "proxy":"",
      "authType":"",
      "x":360,
      "y":120,
      "wires":[
         [
            "b9239811.41a128",
            "e581b9dc.690de8"
         ]
      ]
   },
   {
      "id":"6df2aa1c.339524",
      "type":"http request",
      "z":"1a80a0df.9dc3ff",
      "name":"Request Transactions",
      "method":"GET",
      "ret":"obj",
      "paytoqs":false,
      "url":"https://api.up.com.au/api/v1/transactions",
      "tls":"",
      "proxy":"",
      "authType":"",
      "x":360,
      "y":160,
      "wires":[
         [
            "b9239811.41a128",
            "e581b9dc.690de8"
         ]
      ]
   },
   {
      "id":"b9239811.41a128",
      "type":"join",
      "z":"1a80a0df.9dc3ff",
      "name":"",
      "mode":"custom",
      "build":"array",
      "property":"payload",
      "propertyType":"msg",
      "key":"topic",
      "joiner":"\\n",
      "joinerType":"str",
      "accumulate":false,
      "timeout":"",
      "count":"2",
      "reduceRight":false,
      "reduceExp":"",
      "reduceInit":"",
      "reduceInitType":"",
      "reduceFixup":"",
      "x":590,
      "y":160,
      "wires":[
         [
            "163d9ac.639fe65"
         ]
      ]
   },
   {
      "id":"163d9ac.639fe65",
      "type":"function",
      "z":"1a80a0df.9dc3ff",
      "name":"Create Account Name Array",
      "func":"msg.acctNameIndex = {\n    \"acct1\": {\n        \"id\": msg.payload[0].data[0].id,\n        \"name\": msg.payload[0].data[0].attributes.displayName\n    },\n    \"acct2\": {\n        \"id\": msg.payload[0].data[1].id,\n        \"name\": msg.payload[0].data[1].attributes.displayName\n    },\n}\n\n\nreturn msg;\n ",
      "outputs":1,
      "noerr":0,
      "x":380,
      "y":200,
      "wires":[
         [
            "577763df.17851c"
         ]
      ]
   },
   {
      "id":"577763df.17851c",
      "type":"function",
      "z":"1a80a0df.9dc3ff",
      "name":"Append Acct Names to Transactions Loop",
      "func":"for (i = 0; i < 19; i++) {\n\nif (msg.payload[1].data[i].relationships.account.data.id == msg.acctNameIndex.acct1.id) {\n  msg.payload[1].data[i].acctName = msg.acctNameIndex.acct1.name;\n} else if (msg.payload[1].data[i].relationships.account.data.id == msg.acctNameIndex.acct2.id) {\n  msg.payload[1].data[i].acctName = msg.acctNameIndex.acct2.name;\n} else {\n  msg.payload[1].data[i].acctName = \"Error\";\n}\n\n}\n\nreturn msg;",
      "outputs":1,
      "noerr":0,
      "x":480,
      "y":240,
      "wires":[
         [
            "cde892e9.a3f6d",
            "dc80980b.90e738",
            "f5cb89bb.4fa188",
            "18507de1.38bf82",
            "95d1ec6d.a99c5",
            "70580ffc.43591",
            "adfb6c91.38004"
         ]
      ]
   },
   {
      "id":"e581b9dc.690de8",
      "type":"http response",
      "z":"1a80a0df.9dc3ff",
      "name":"",
      "statusCode":"",
      "headers":{

      },
      "x":590,
      "y":120,
      "wires":[

      ]
   },
   {
      "id":"cde892e9.a3f6d",
      "type":"ha-entity",
      "z":"1a80a0df.9dc3ff",
      "name":"Up Balance 1",
      "server":"788025f4.1f0d8c",
      "version":1,
      "debugenabled":false,
      "outputs":1,
      "entityType":"sensor",
      "config":[
         {
            "property":"name",
            "value":"Up Balance 1"
         },
         {
            "property":"device_class",
            "value":""
         },
         {
            "property":"icon",
            "value":"mdi:piggy-bank"
         },
         {
            "property":"unit_of_measurement",
            "value":"AUD"
         }
      ],
      "state":"payload[0].data[0].attributes.balance.value",
      "stateType":"msg",
      "attributes":[
         {
            "property":"displayName",
            "value":"payload[0].data[0].attributes.displayName",
            "valueType":"msg"
         },
         {
            "property":"accountType",
            "value":"payload[0].data[0].attributes.accountType",
            "valueType":"msg"
         },
         {
            "property":"currencyCode",
            "value":"payload[0].data[0].attributes.balance.currencyCode",
            "valueType":"msg"
         },
         {
            "property":"balance",
            "value":"payload[0].data[0].attributes.balance.value",
            "valueType":"msg"
         }
      ],
      "resend":true,
      "outputLocation":"",
      "outputLocationType":"none",
      "inputOverride":"allow",
      "x":840,
      "y":40,
      "wires":[
         [
            "9fa1be87.aed34"
         ]
      ]
   },
   {
      "id":"f5cb89bb.4fa188",
      "type":"ha-entity",
      "z":"1a80a0df.9dc3ff",
      "name":"Up Transaction 1",
      "server":"788025f4.1f0d8c",
      "version":1,
      "debugenabled":false,
      "outputs":1,
      "entityType":"sensor",
      "config":[
         {
            "property":"name",
            "value":"Up Transaction 1"
         },
         {
            "property":"device_class",
            "value":""
         },
         {
            "property":"icon",
            "value":"mdi:piggy-bank"
         },
         {
            "property":"unit_of_measurement",
            "value":""
         }
      ],
      "state":"payload[1].data[0].attributes.amount.value",
      "stateType":"msg",
      "attributes":[
         {
            "property":"status",
            "value":"payload[1].data[0].attributes.status",
            "valueType":"msg"
         },
         {
            "property":"amount",
            "value":"payload[1].data[0].attributes.amount.value",
            "valueType":"msg"
         },
         {
            "property":"description",
            "value":"payload[1].data[0].attributes.description",
            "valueType":"msg"
         },
         {
            "property":"message",
            "value":"payload[1].data[0].attributes.message",
            "valueType":"msg"
         },
         {
            "property":"foreignAmount",
            "value":"payload[1].data[0].attributes.foreignAmount",
            "valueType":"msg"
         },
         {
            "property":"settledAt",
            "value":"payload[1].data[0].attributes.settledAt",
            "valueType":"msg"
         },
         {
            "property":"createdAt",
            "value":"payload[1].data[0].attributes.createdAt",
            "valueType":"msg"
         },
         {
            "property":"currencyCode",
            "value":"payload[1].data[0].attributes.amount.currencyCode",
            "valueType":"msg"
         },
         {
            "property":"acctName",
            "value":"payload[1].data[0].acctName",
            "valueType":"msg"
         }
      ],
      "resend":true,
      "outputLocation":"",
      "outputLocationType":"none",
      "inputOverride":"allow",
      "x":850,
      "y":120,
      "wires":[
         [
            "9fa1be87.aed34"
         ]
      ]
   },
   {
      "id":"dc80980b.90e738",
      "type":"ha-entity",
      "z":"1a80a0df.9dc3ff",
      "name":"Up Balance 2",
      "server":"788025f4.1f0d8c",
      "version":1,
      "debugenabled":false,
      "outputs":1,
      "entityType":"sensor",
      "config":[
         {
            "property":"name",
            "value":"Up Balance 2"
         },
         {
            "property":"device_class",
            "value":""
         },
         {
            "property":"icon",
            "value":"mdi:piggy-bank"
         },
         {
            "property":"unit_of_measurement",
            "value":"AUD"
         }
      ],
      "state":"payload[0].data[1].attributes.balance.value",
      "stateType":"msg",
      "attributes":[
         {
            "property":"displayName",
            "value":"payload[0].data[1].attributes.displayName",
            "valueType":"msg"
         },
         {
            "property":"accountType",
            "value":"payload[0].data[1].type",
            "valueType":"msg"
         },
         {
            "property":"currencyCode",
            "value":"payload[0].data[1].attributes.balance.currencyCode",
            "valueType":"msg"
         },
         {
            "property":"balance",
            "value":"payload[0].data[1].attributes.balance.value",
            "valueType":"msg"
         }
      ],
      "resend":true,
      "outputLocation":"",
      "outputLocationType":"none",
      "inputOverride":"allow",
      "x":840,
      "y":80,
      "wires":[
         [
            "9fa1be87.aed34"
         ]
      ]
   },
   {
      "id":"9fa1be87.aed34",
      "type":"debug",
      "z":"1a80a0df.9dc3ff",
      "name":"Up Debug",
      "active":true,
      "tosidebar":true,
      "console":false,
      "tostatus":false,
      "complete":"true",
      "targetType":"full",
      "x":1120,
      "y":160,
      "wires":[

      ]
   },
   {
      "id":"18507de1.38bf82",
      "type":"ha-entity",
      "z":"1a80a0df.9dc3ff",
      "name":"Up Transaction 2",
      "server":"788025f4.1f0d8c",
      "version":1,
      "debugenabled":false,
      "outputs":1,
      "entityType":"sensor",
      "config":[
         {
            "property":"name",
            "value":"Up Transaction 2"
         },
         {
            "property":"device_class",
            "value":""
         },
         {
            "property":"icon",
            "value":"mdi:piggy-bank"
         },
         {
            "property":"unit_of_measurement",
            "value":""
         }
      ],
      "state":"payload[1].data[1].attributes.amount.value",
      "stateType":"msg",
      "attributes":[
         {
            "property":"status",
            "value":"payload[1].data[1].attributes.status",
            "valueType":"msg"
         },
         {
            "property":"amount",
            "value":"payload[1].data[1].attributes.amount.value",
            "valueType":"msg"
         },
         {
            "property":"description",
            "value":"payload[1].data[1].attributes.description",
            "valueType":"msg"
         },
         {
            "property":"message",
            "value":"payload[1].data[1].attributes.message",
            "valueType":"msg"
         },
         {
            "property":"foreignAmount",
            "value":"payload[1].data[1].attributes.foreignAmount",
            "valueType":"msg"
         },
         {
            "property":"settledAt",
            "value":"payload[1].data[1].attributes.settledAt",
            "valueType":"msg"
         },
         {
            "property":"createdAt",
            "value":"payload[1].data[1].attributes.createdAt",
            "valueType":"msg"
         },
         {
            "property":"currencyCode",
            "value":"payload[1].data[1].attributes.amount.currencyCode",
            "valueType":"msg"
         },
         {
            "property":"acctName",
            "value":"payload[1].data[1].acctName",
            "valueType":"msg"
         }
      ],
      "resend":true,
      "outputLocation":"",
      "outputLocationType":"none",
      "inputOverride":"allow",
      "x":850,
      "y":160,
      "wires":[
         [
            "9fa1be87.aed34"
         ]
      ]
   },
   {
      "id":"95d1ec6d.a99c5",
      "type":"ha-entity",
      "z":"1a80a0df.9dc3ff",
      "name":"Up Transaction 3",
      "server":"788025f4.1f0d8c",
      "version":1,
      "debugenabled":false,
      "outputs":1,
      "entityType":"sensor",
      "config":[
         {
            "property":"name",
            "value":"Up Transaction 3"
         },
         {
            "property":"device_class",
            "value":""
         },
         {
            "property":"icon",
            "value":"mdi:piggy-bank"
         },
         {
            "property":"unit_of_measurement",
            "value":""
         }
      ],
      "state":"payload[1].data[2].attributes.amount.value",
      "stateType":"msg",
      "attributes":[
         {
            "property":"status",
            "value":"payload[1].data[2].attributes.status",
            "valueType":"msg"
         },
         {
            "property":"amount",
            "value":"payload[1].data[2].attributes.amount.value",
            "valueType":"msg"
         },
         {
            "property":"description",
            "value":"payload[1].data[2].attributes.description",
            "valueType":"msg"
         },
         {
            "property":"message",
            "value":"payload[1].data[2].attributes.message",
            "valueType":"msg"
         },
         {
            "property":"foreignAmount",
            "value":"payload[1].data[2].attributes.foreignAmount",
            "valueType":"msg"
         },
         {
            "property":"settledAt",
            "value":"payload[1].data[2].attributes.settledAt",
            "valueType":"msg"
         },
         {
            "property":"createdAt",
            "value":"payload[1].data[2].attributes.createdAt",
            "valueType":"msg"
         },
         {
            "property":"currencyCode",
            "value":"payload[1].data[2].attributes.amount.currencyCode",
            "valueType":"msg"
         },
         {
            "property":"acctName",
            "value":"payload[1].data[2].acctName",
            "valueType":"msg"
         }
      ],
      "resend":true,
      "outputLocation":"",
      "outputLocationType":"none",
      "inputOverride":"allow",
      "x":850,
      "y":200,
      "wires":[
         [
            "9fa1be87.aed34"
         ]
      ]
   },
   {
      "id":"70580ffc.43591",
      "type":"ha-entity",
      "z":"1a80a0df.9dc3ff",
      "name":"Up Transaction 4",
      "server":"788025f4.1f0d8c",
      "version":1,
      "debugenabled":false,
      "outputs":1,
      "entityType":"sensor",
      "config":[
         {
            "property":"name",
            "value":"Up Transaction 4"
         },
         {
            "property":"device_class",
            "value":""
         },
         {
            "property":"icon",
            "value":"mdi:piggy-bank"
         },
         {
            "property":"unit_of_measurement",
            "value":""
         }
      ],
      "state":"payload[1].data[3].attributes.amount.value",
      "stateType":"msg",
      "attributes":[
         {
            "property":"status",
            "value":"payload[1].data[3].attributes.status",
            "valueType":"msg"
         },
         {
            "property":"amount",
            "value":"payload[1].data[3].attributes.amount.value",
            "valueType":"msg"
         },
         {
            "property":"description",
            "value":"payload[1].data[3].attributes.description",
            "valueType":"msg"
         },
         {
            "property":"message",
            "value":"payload[1].data[3].attributes.message",
            "valueType":"msg"
         },
         {
            "property":"foreignAmount",
            "value":"payload[1].data[3].attributes.foreignAmount",
            "valueType":"msg"
         },
         {
            "property":"settledAt",
            "value":"payload[1].data[3].attributes.settledAt",
            "valueType":"msg"
         },
         {
            "property":"createdAt",
            "value":"payload[1].data[3].attributes.createdAt",
            "valueType":"msg"
         },
         {
            "property":"currencyCode",
            "value":"payload[1].data[3].attributes.amount.currencyCode",
            "valueType":"msg"
         },
         {
            "property":"acctName",
            "value":"payload[1].data[3].acctName",
            "valueType":"msg"
         }
      ],
      "resend":true,
      "outputLocation":"",
      "outputLocationType":"none",
      "inputOverride":"allow",
      "x":850,
      "y":240,
      "wires":[
         [
            "9fa1be87.aed34"
         ]
      ]
   },
   {
      "id":"adfb6c91.38004",
      "type":"ha-entity",
      "z":"1a80a0df.9dc3ff",
      "name":"Up Transaction 5",
      "server":"788025f4.1f0d8c",
      "version":1,
      "debugenabled":false,
      "outputs":1,
      "entityType":"sensor",
      "config":[
         {
            "property":"name",
            "value":"Up Transaction 5"
         },
         {
            "property":"device_class",
            "value":""
         },
         {
            "property":"icon",
            "value":"mdi:piggy-bank"
         },
         {
            "property":"unit_of_measurement",
            "value":""
         }
      ],
      "state":"payload[1].data[4].attributes.amount.value",
      "stateType":"msg",
      "attributes":[
         {
            "property":"status",
            "value":"payload[1].data[4].attributes.status",
            "valueType":"msg"
         },
         {
            "property":"amount",
            "value":"payload[1].data[4].attributes.amount.value",
            "valueType":"msg"
         },
         {
            "property":"description",
            "value":"payload[1].data[4].attributes.description",
            "valueType":"msg"
         },
         {
            "property":"message",
            "value":"payload[1].data[4].attributes.message",
            "valueType":"msg"
         },
         {
            "property":"foreignAmount",
            "value":"payload[1].data[4].attributes.foreignAmount",
            "valueType":"msg"
         },
         {
            "property":"settledAt",
            "value":"payload[1].data[4].attributes.settledAt",
            "valueType":"msg"
         },
         {
            "property":"createdAt",
            "value":"payload[1].data[4].attributes.createdAt",
            "valueType":"msg"
         },
         {
            "property":"currencyCode",
            "value":"payload[1].data[4].attributes.amount.currencyCode",
            "valueType":"msg"
         },
         {
            "property":"acctName",
            "value":"payload[1].data[4].acctName",
            "valueType":"msg"
         }
      ],
      "resend":true,
      "outputLocation":"",
      "outputLocationType":"none",
      "inputOverride":"allow",
      "x":850,
      "y":280,
      "wires":[
         [
            "9fa1be87.aed34"
         ]
      ]
   },
   {
      "id":"788025f4.1f0d8c",
      "type":"server",
      "z":"",
      "name":"Home Assistant",
      "legacy":false,
      "addon":false,
      "rejectUnauthorizedCerts":true,
      "ha_boolean":"y|yes|true|on|home|open",
      "connectionDelay":true,
      "cacheJson":true
   }
]

Once deployed, if Home Assistant is properly connected to Node Red, you should see some sensors in HA with details in the attributes:

Once these appear, create a group in groups.yaml:

up_transactions:
  name: Up Transactions
  entities:
    - sensor.up_transaction_1
    - sensor.up_transaction_2
    - sensor.up_transaction_3
    - sensor.up_transaction_4
    - sensor.up_transaction_5

Once grouped, create a Lovelace card by copying this yaml into a Manual card:

cards:
  - content: '## Up Bank'
    type: markdown
  - cards:
      - detail: 2
        entity: sensor.up_balance_1
        graph: line
        hours_to_show: 72
        icon: 'mdi:cash'
        name: Spending
        type: sensor
      - entity: sensor.up_balance_2
        graph: line
        hours_to_show: 72
        name: Rounding
        type: sensor
    type: horizontal-stack
  - content: >
      #### Recent Transactions:

      {% for transaction in states.group.up_transactions.attributes.entity_id
      -%}


      {# Check if more than one day old, and apply formatting #}

      *{%- if ((as_timestamp(now()) -
      as_timestamp(state_attr(transaction,"settledat"))) / 60 / 60 / 24) |
      round(0) > 0 -%}
        {{ ((as_timestamp(now()) - as_timestamp(state_attr(transaction,"settledat"))) / 60 / 60 / 24) | round(0) }} day
          {#- Pluralise if not 1 -#}{% if ((as_timestamp(now()) - as_timestamp(state_attr(transaction,"settledat"))) / 60 / 60) | round(0) != 1  %}s{%- endif -%}

      {# Check if more than one hour old, and apply formatting #}

      {%- elif ((as_timestamp(now()) -
      as_timestamp(state_attr(transaction,"settledat"))) / 60 / 60) | round(0) >
      0 -%}
        {{ ((as_timestamp(now()) - as_timestamp(state_attr(transaction,"settledat"))) / 60 / 60) | round(0) }} hr
          {#- Pluralise if not 1 -#}{%- if ((as_timestamp(now()) - as_timestamp(state_attr(transaction,"settledat"))) / 60 / 60) | round(0) != 1  -%}s{%- endif -%}

      {# Otherwise, format age for minutes #}

      {%- else -%} {{ ((as_timestamp(now()) -
      as_timestamp(state_attr(transaction,"settledat"))) / 60) | round(0) }} min
        {#- Pluralise if not 1 -#}{%- if ((as_timestamp(now()) - as_timestamp(state_attr(transaction,"settledat"))) / 60 / 60) | round(0) != 1  -%}s{%- endif -%}
      {%- endif %} ago*


      {{- " " -}}



      {# Print amount value with bold formatting #}

      **${{- state_attr(transaction,'amount') | float | abs -}}**

      {{- " " -}}


      {# Change language for positive/negative #}

      {%- if state_attr(transaction, 'amount') | int  > 0 -%}
         came into
      {%- elif state_attr(transaction, 'amount') | int  < 0 -%}
         went out of
      {%- endif -%}

      {{- " " -}}


      {# Change language for positive/negative #}

      {{- state_attr(transaction,"acctname") }}

      {{ state_attr(transaction,'description') }} {{
      state_attr(transaction,'message') }}


      {% endfor %}
    type: markdown
type: vertical-stack

The result should look like this:

The webhook is very convenient for any kind of notifications you might want to integrate. This next example is a lot more dependent on my particular light/speaker configuration and won’t be as easy to drop into an existing config, but should show how simple it is to connect webhooks to a notification system.

Had to remove the code to fit within the character limit, but if anyone is interested I’ll put this flow in a Pastebin or something.

4 Likes

Love this!
I might try to tackle the same thing without NR (I don’t use NR for my automations).

Argh we need some NZ banks to get on board with this kind of thing!!!

Thanks for this- looks awesome. I’m looking forward to setting it up

I know this is an old thread, but seams to be the only one about Up.

Ive created a python integration for HA for Up, so no node red needed.

Thanks @Nassau for this great node red flow, your node-red version still has more features than mine does, but easier to set up for most people, and planning to add more features. Seeing this node red flow inspired me to do one in python