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.