Skip to main content

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

test prepaid and debit cards

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
  }
}
⚠️ Please login to execute queries. Visit the dashboard to authenticate.
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"
  }
}
⚠️ Please login to execute queries. Visit the dashboard to authenticate.
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"
  }
}
⚠️ Please login to execute queries. Visit the dashboard to authenticate.
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"
}
⚠️ Please login to execute queries. Visit the dashboard to authenticate.
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

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.

Source account and financial account relationship
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_LIMIT ledger) — the maximum spending ceiling for an individual financial account. When you set a limit, Highnote also debits ALLOCATED_PSEUDO_LIMIT on the source account, which tracks the sum of all allocations across its linked financial accounts.
  • Balance (PSEUDO_AVAILABLE_CASH ledger) — 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.

MutationWhat it does
setPseudoLimitSet the spending limit to an absolute amount. Optionally configure auto-reset cadence.
updatePseudoLimitIncrement or decrement the spending limit.
updatePseudoBalanceIncrement or decrement the available balance.
resetPseudoBalanceReset 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"
  }
}
⚠️ Please login to execute queries. Visit the dashboard to authenticate.
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 sign to POSITIVE
  • Decrement by setting sign to NEGATIVE
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"
  }
}
⚠️ Please login to execute queries. Visit the dashboard to authenticate.
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 sign to POSITIVE
  • Decrement by setting sign to NEGATIVE
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"
  }
}
⚠️ Please login to execute queries. Visit the dashboard to authenticate.
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:

CadenceDescription
DAILYResets daily at the time specified in resetTime.
WEEKLYResets weekly on the same weekday and time as resetTime.
MONTHLYResets monthly on the same day-of-month and time as resetTime.
NINETY_DAYSResets every 90 calendar days from the resetTime date and time.
QUARTERLYResets quarterly (every 3 months) on the same day and time as resetTime.
YEARLYResets annually on the same date and time as resetTime.
LIFETIMENever 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
  }
}
⚠️ Please login to execute queries. Visit the dashboard to authenticate.
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
}
}
]
}
}
}
}