On-demand Funding
Overview
On-demand funding is a card product feature that allows financial accounts to maintain a $0 balance until authorization and receive real-time funding as needed.
On-demand funding uses a source financial account for funding account holder financial accounts. When an account holder initiates a transaction, Highnote moves funds from the source financial account into the account holder's financial account to cover the cost of the transaction.
Enable on-demand funding
For prepaid and debit card products, you can enable and test on-demand funding features in your Test environment. Highnote must enable the feature for your card product in the Live environment.
When enabling on-demand funding, you can optionally choose to enable pseudo balance.
Use the following mutation to enable on-demand funding and use a boolean value to optionally enable pseudo balance in your Test environment:
EnableOnDemandFundingFeature
Query
mutation EnableOnDemandFundingFeature(
$input: EnableOnDemandFundingFeatureInput!
) {
enableOnDemandFundingFeature(input: $input) {
__typename
... on CardProduct {
id
features {
__typename
enabled
... on OnDemandFundingCardProductFeature {
pseudoBalanceEnabled
}
}
}
... on UserError {
errors {
errorPath
code
description
}
}
}
}
Variables
{ "input": { "cardProductId": "CARD_PRODUCT_ID", "pseudoBalanceEnabled": true } }
Result
{
"data": {
"enableOnDemandFundingFeature": {
"__typename": "CardProduct",
"id": "CARD_PRODUCT_ID",
"features": [
{
"__typename": "OnDemandFundingCardProductFeature",
"enabled": true,
"pseudoBalanceEnabled": true
}
]
}
},
"extensions": {
"requestId": "REQUEST_ID"
}
}
Issue source financial account
Before issuing a financial account with an on-demand funding source, you must have a source financial account. A source financial account is a pre-funded account that links to the account holder's financial account for funding.
The following accounts can be used as source financial accounts:
- A financial account issued against an application
- A product funding account
- A financial account that exists at the account holder level
Source financial accounts can be existing accounts or new accounts. To issue a new financial account as your source financial account, use the following mutation:
IssueFundingFinancialAccountForApplication
Query
mutation IssueFundingFinancialAccountForApplication(
$input: IssueFundingFinancialAccountForApplicationInput!
) {
issueFundingFinancialAccountForApplication(input: $input) {
... on FinancialAccount {
id
name
createdAt
updatedAt
application {
id
createdAt
}
cardProduct {
id
vertical
}
}
}
}
Variables
{ "input": { "applicationId": "APPLICATION_ID", "name": "On-demand funding source account" } }
Result
{
"data": {
"issueFinancialAccountForApplication": {
"id": "APPLICATION_ID",
"name": "On-demand funding source account",
"createdAt": "2021-12-28T18:20:49.932Z",
"updatedAt": "2021-12-28T18:20:49.960Z",
"application": {
"id": "APPLICATION_ID",
"createdAt": "2021-12-20T17:59:33.570Z"
},
"cardProduct": {
"id": "CARD_PRODUCT_ID",
"vertical": "GENERAL_PURPOSE_RELOADABLE"
}
}
}
}
Issue a financial account with on-demand funding source
When an account holder's application is approved, you can issue the account holder a financial account with an on-demand funding source.
Use the following mutation to issue a financial account with an on-demand funding source:
IssueFinancialAccountForApplicationWithOnDemandFundingSource
Query
mutation IssueFinancialAccountForApplicationWithOnDemandFundingSource(
$input: IssueFinancialAccountForApplicationWithOnDemandFundingSourceInput!
) {
issueFinancialAccountForApplicationWithOnDemandFundingSource(input: $input) {
... on FinancialAccount {
id
externalId
name
createdAt
updatedAt
application {
id
createdAt
}
cardProduct {
id
vertical
}
features {
__typename
enabled
createdAt
updatedAt
... on OnDemandFundingFinancialAccountFeature {
sourceFinancialAccountId
}
}
directDepositDetails {
id
restrictedDetails {
__typename
... on DirectDepositDetailRestrictedDetails {
number
routingNumber
bank {
name
}
}
}
}
owner {
__typename
... on USPersonAccountHolder {
id
}
}
}
}
}
Variables
{ "input": { "applicationId": "APPLICATION_ID", "name": "Financial Account", "externalId": "YOUR_EXTERNAL_ID", "sourceFinancialAccountId": "FINANCIAL_ACCOUNT_ID" } }
Result
{
"data": {
"IssueFinancialAccountForApplicationWithOnDemandFundingSource": {
"id": "FINANCIAL_ACCOUNT_ID",
"externalId": "ABC123456",
"name": "John Doe - Account",
"createdAt": "2021-12-28T18:20:49.932Z",
"updatedAt": "2021-12-28T18:20:49.960Z",
"application": {
"id": "APPLICATION_ID",
"createdAt": "2021-12-20T17:59:33.570Z"
},
"cardProduct": {
"id": "CARD_PRODUCT_ID",
"vertical": "GENERAL_PURPOSE_RELOADABLE"
},
"features": [
{
"__typename": "DirectDepositFinancialAccountFeature",
"enabled": true,
"createdAt": "2021-12-28T18:20:49.933Z",
"updatedAt": "2021-12-28T18:20:49.933Z"
},
{
"__typename": "DebitPaymentCardFinancialAccountFeature",
"enabled": true,
"createdAt": "2021-12-28T18:20:49.933Z",
"updatedAt": "2021-12-28T18:20:49.933Z"
},
{
"__typename": "OnDemandFundingFinancialAccountFeature",
"enabled": true,
"createdAt": "2021-12-28T18:20:49.933Z",
"updatedAt": "2021-12-28T18:20:49.933Z",
"sourceFinancialAccountId": "FINANCIAL_ACCOUNT_ID"
}
],
"directDepositDetails": {
"id": "FINANCIAL_ACCOUNT_ID",
"restrictedDetails": {
"__typename": "AccessDeniedError"
}
},
"owner": {
"__typename": "USPersonAccountHolder",
"id": "ACCOUNT_HOLDER_ID"
}
}
}
}
Lookup source financial account
Once a financial account is issued, you can look up the source financial account using the following query:
FindSourceFinancialAccount
Query
query FindSourceFinancialAccount($id: ID!) {
node(id: $id) {
__typename
... on FinancialAccount {
__typename
id
name
features {
__typename
enabled
createdAt
updatedAt
... on OnDemandFundingFinancialAccountFeature {
sourceFinancialAccountId
}
}
}
}
}
Variables
{
"id": "FINANCIAL_ACCOUNT_ID"
}
Result
{
"data": {
"node": {
"__typename": "FinancialAccount",
"id": "FINANCIAL_ACCOUNT_ID",
"name": "My Financial Account Name",
"features": [
{
"__typename": "DirectDepositFinancialAccountFeature",
"enabled": true,
"createdAt": "2023-04-25T22:12:10.118Z",
"updatedAt": "2023-04-25T22:12:10.118Z"
},
{
"__typename": "PrePaidPaymentCardFinancialAccountFeature",
"enabled": true,
"createdAt": "2023-04-25T22:12:10.118Z",
"updatedAt": "2023-04-25T22:12:10.118Z"
},
{
"__typename": "OnDemandFundingFinancialAccountFeature",
"enabled": true,
"createdAt": "2023-04-25T22:12:10.118Z",
"updatedAt": "2023-04-25T22:12:10.118Z",
"sourceFinancialAccountId": "SOURCE_FINANCIAL_ACCOUNT_ID"
}
]
}
},
"extensions": {
"requestId": "REQUEST_ID"
}
}
Manage pseudo limit and balance
Enable pseudo balance by setting pseudoBalanceEnabled to true on the OnDemandFundingCardProductFeature.
Each financial account is linked to a source financial account. A card product can have multiple source accounts, but each financial account has exactly one. An account holder can have multiple financial accounts, each with its own independent limit.
These mutations let you allocate spending limits from a source account to individual financial accounts and manage their available balances.
Card Product
├── Source Account A
│ ├── Financial Account 1 (limit: $500)
│ ├── Financial Account 2 (limit: $300)
│ └── Financial Account 3 (limit: $200)
│ ALLOCATED_PSEUDO_LIMIT = $1,000
│
└── Source Account B
├── Financial Account 4 (limit: $400)
└── Financial Account 5 (limit: $600)
ALLOCATED_PSEUDO_LIMIT = $1,000
Limit and balance are two separate concepts on different ledgers:
- Limit (
ACCOUNT_HOLDER_PSEUDO_LIMITledger) — the maximum spending ceiling for an individual financial account. When you set a limit, Highnote also debitsALLOCATED_PSEUDO_LIMITon the source account, which tracks the sum of all allocations across its linked financial accounts. - Balance (
PSEUDO_AVAILABLE_CASHledger) — the current available amount a cardholder can spend.
Highnote declines transactions that would exceed the available balance. These mutations support incremental adjustments (add or subtract amounts) and automatic resets on a configurable cadence.
| Mutation | What it does |
|---|---|
setPseudoLimit | Set the spending limit to an absolute amount. Optionally configure auto-reset cadence. |
updatePseudoLimit | Increment or decrement the spending limit. |
updatePseudoBalance | Increment or decrement the available balance. |
resetPseudoBalance | Reset the balance to zero. Configure auto-reset cadence. |
Set pseudo limit
Use setPseudoLimit to set the maximum allowable amount that the pseudo balance can reach before rejecting transactions. This sets the ALLOCATED_PSEUDO_LIMIT ledger value.
You can optionally configure automatic resets by providing a cadence and resetTime. When resetAvailableBalance is set to true, the available balance resets according to the specified cadence. For cadence options, see Reset pseudo balance.
setPseudoLimit
Query
mutation SetPseudoLimit($input: SetPseudoLimitInput!) {
setPseudoLimit(input: $input) {
... on InterFinancialAccountTransfer {
toFinancialAccount {
id
features {
... on ResetBalanceFinancialAccountFeature {
cadence
createdAt
effectiveFrom
effectiveThrough
enabled
resetTime
updatedAt
}
}
}
fromFinancialAccount {
id
ledgers {
name
nextBalanceResetAt
debitBalance {
value
}
}
}
}
... on UserError {
errors {
path
code
description
}
}
}
}
Variables
{ "input": { "amount": { "value": 10000, "currencyCode": "USD" }, "resetAvailableBalance": true, "cadence": "DAILY", "resetTime": "2026-01-27T01:23:45.000Z", "financialAccountId": "FINANCIAL_ACCOUNT_ID" } }
Result
{
"data": {
"setPseudoLimit": {
"toFinancialAccount": {
"id": "ac_2",
"features": [
{
"cadence": "DAILY",
"createdAt": "2026-01-26T23:19:03.950Z",
"effectiveFrom": "2026-01-26T23:19:03.950Z",
"effectiveThrough": null,
"enabled": true,
"resetTime": "2026-01-27T01:23:45.000Z",
"updatedAt": "2026-01-26T23:21:23.251Z"
}
]
},
"fromFinancialAccount": {
"id": "ac_3",
"ledgers": [
{
"name": "ALLOCATED_PSEUDO_LIMIT",
"nextBalanceResetAt": null,
"debitBalance": {
"value": 10000
}
}
]
}
}
}
}
Update pseudo limit
Use updatePseudoLimit to increment or decrement the ALLOCATED_PSEUDO_LIMIT.
- Increment by setting
signtoPOSITIVE - Decrement by setting
signtoNEGATIVE
updatePseudoLimit
Query
mutation UpdatePseudoLimit($input: UpdatePseudoLimitInput!) {
updatePseudoLimit(input: $input) {
... on InterFinancialAccountTransfer {
fromFinancialAccount {
ledgers {
__typename
name
debitBalance {
value
}
creditBalance {
value
}
}
}
}
... on UserError {
errors {
path
code
description
}
}
}
}
Variables
{ "input": { "amount": { "value": 1500, "currencyCode": "USD" }, "financialAccountId": "FINANCIAL_ACCOUNT_ID", "sign": "POSITIVE" } }
Result
{
"data": {
"updatePseudoLimit": {
"fromFinancialAccount": {
"ledgers": [
{
"__typename": "Ledger",
"name": "AVAILABLE_CASH",
"debitBalance": {
"value": 0
},
"creditBalance": {
"value": 100000
}
},
{
"__typename": "Ledger",
"name": "ALLOCATED_PSEUDO_LIMIT",
"debitBalance": {
"value": 50000
},
"creditBalance": {
"value": 0
}
}
]
}
}
}
}
Update pseudo balance
Use updatePseudoBalance to increment or decrement the PSEUDO_BALANCE on a financial account.
- Increment by setting
signtoPOSITIVE - Decrement by setting
signtoNEGATIVE
updatePseudoBalance
Query
mutation UpdatePseudoBalance($input: UpdatePseudoBalanceInput!) {
updatePseudoBalance(input: $input) {
... on InterFinancialAccountTransfer {
fromFinancialAccount {
id
ledgers {
name
creditBalance {
value
}
debitBalance {
value
}
}
features {
__typename
... on ResetBalanceFinancialAccountFeature {
cadence
createdAt
effectiveFrom
effectiveThrough
enabled
resetAvailableBalance
resetTime
updatedAt
}
}
}
}
... on UserError {
errors {
path
code
description
}
}
}
}
Variables
{ "input": { "amount": { "value": 20, "currencyCode": "USD" }, "financialAccountId": "FINANCIAL_ACCOUNT_ID", "sign": "POSITIVE" } }
Result
{
"data": {
"updatePseudoBalance": {
"fromFinancialAccount": {
"id": "ac_1",
"ledgers": [
{
"name": "PSEUDO_AVAILABLE_CASH",
"creditBalance": {
"value": 60000
},
"debitBalance": {
"value": 0
}
},
{
"name": "ACCOUNT_HOLDER_PSEUDO_LIMIT",
"creditBalance": {
"value": 60000
},
"debitBalance": {
"value": 0
}
},
{
"name": "PSEUDO_CASH",
"creditBalance": {
"value": 0
},
"debitBalance": {
"value": 60000
}
}
],
"features": [
{
"__typename": "ResetBalanceFinancialAccountFeature",
"cadence": "DAILY",
"createdAt": "2026-01-09T17:00:00.000Z",
"effectiveFrom": "2026-01-09T17:00:00.000Z",
"effectiveThrough": null,
"enabled": true,
"resetAvailableBalance": true,
"resetTime": "2026-01-10T00:00:00.000Z",
"updatedAt": "2026-01-09T17:00:00.000Z"
}
]
}
}
}
}
Reset pseudo balance
Use resetPseudoBalance to reset the pseudo balance to zero. Set resetAvailableBalance to true and provide a cadence to configure automatic resets.
The following cadence options are available:
| Cadence | Description |
|---|---|
DAILY | Resets daily at the time specified in resetTime. |
WEEKLY | Resets weekly on the same weekday and time as resetTime. |
MONTHLY | Resets monthly on the same day-of-month and time as resetTime. |
NINETY_DAYS | Resets every 90 calendar days from the resetTime date and time. |
QUARTERLY | Resets quarterly (every 3 months) on the same day and time as resetTime. |
YEARLY | Resets annually on the same date and time as resetTime. |
LIFETIME | Never resets automatically. Manual reset via resetPseudoBalance required. |
resetPseudoBalance
Query
mutation ResetPseudoBalance($input: ResetPseudoBalanceInput!) {
resetPseudoBalance(input: $input) {
... on InterFinancialAccountTransfer {
fromFinancialAccount {
id
ledgers {
name
creditBalance {
value
}
debitBalance {
value
}
}
features {
__typename
... on ResetBalanceFinancialAccountFeature {
cadence
createdAt
effectiveFrom
effectiveThrough
enabled
resetAvailableBalance
resetTime
updatedAt
}
}
}
toFinancialAccount {
id
ledgers {
name
creditBalance {
value
}
debitBalance {
value
}
}
}
}
... on UserError {
errors {
path
code
description
}
}
}
}
Variables
{ "input": { "financialAccountId": "FINANCIAL_ACCOUNT_ID", "cadence": "DAILY", "resetAvailableBalance": true } }
Result
{
"data": {
"resetPseudoBalance": {
"fromFinancialAccount": {
"id": "ac_1",
"ledgers": [
{
"name": "AVAILABLE_CASH",
"creditBalance": {
"value": 60000
},
"debitBalance": {
"value": 0
}
},
{
"name": "CASH",
"creditBalance": {
"value": 0
},
"debitBalance": {
"value": 60000
}
},
{
"name": "ALLOCATED_PSEUDO_LIMIT",
"creditBalance": {
"value": 0
},
"debitBalance": {
"value": 25000
}
}
],
"features": []
},
"toFinancialAccount": {
"id": "ac_1",
"ledgers": [
{
"name": "PSEUDO_AVAILABLE_CASH",
"creditBalance": {
"value": 0
},
"debitBalance": {
"value": 0
}
},
{
"name": "ACCOUNT_HOLDER_PSEUDO_LIMIT",
"creditBalance": {
"value": 25000
},
"debitBalance": {
"value": 0
}
},
{
"name": "PSEUDO_CASH",
"creditBalance": {
"value": 0
},
"debitBalance": {
"value": 0
}
}
]
}
}
}
}