FRAGMENT supports querying a Ledger Account for its latest balances, historical balances and balance changes.
a. Latest
#Use the ledgerAccount query to look up a Ledger Account's balance.
query GetBalance(
$ledgerAccount: LedgerAccountMatchInput!
) {
ledgerAccount(ledgerAccount: $ledgerAccount) {
balance
}
}{
"ledgerAccount": {
"path": "assets/banks/user-cash",
"ledger": {
"ik": "quickstart-ledger"
}
}
}b. Aggregated
#Ledger Accounts have three balances:
ownBalanceis the sum of all Ledger Lines posted to the Ledger Account, excluding Ledger Lines in child Ledger AccountschildBalanceis the sum of all Ledger Lines posted to the children of this Ledger Accountbalanceis the sum of all Ledger Lines posted to this Ledger Account and its children
query GetAggregatedBalances(
$ledgerAccount: LedgerAccountMatchInput!
) {
ledgerAccount(ledgerAccount: $ledgerAccount) {
childBalance
balance
}
}{
"ledgerAccount": {
"path": "liabilities/users"
}
}c. Consistent
#Balance reads are eventually consistent by default. This means that the balance may not reflect all the Ledger Lines in the account.
To read a strongly consistent balance, a Ledger Account must have its balances updated in a strongly consistent manner. This is set in the Schema on a Ledger Account's consistencyConfig:
{
"key": "strongly-consistent-ledger-accounts",
"name": "Strongly consistent Ledger Accounts",
"chartOfAccounts": {
"defaultCurrency": { "code": "USD" },
"accounts": [
{
"key": "liabilities",
"type": "liability",
"children": [
{
"key": "users",
"template": true,
"consistencyConfig": {
"totalBalanceUpdates": "strong"
},
"children": [
{
"key": "available",
"consistencyConfig": {
"totalBalanceUpdates": "strong"
}
},
{
"key": "pending"
},
{
"key": "blocked"
}
]
}
]
}
]
}
}Once a Ledger Account's balance is updated consistently, set the consistencyMode on balance queries to determine the consistency of the read you issue.
query GetStronglyConsistentBalance(
$ledgerAccount: LedgerAccountMatchInput!
) {
ledgerAccount(ledgerAccount: $ledgerAccount) {
balance(consistencyMode: strong)
}
}consistencyMode can be set to:
strongto perform a strongly consistent balance readeventualto perform an eventually consistent balance readuse_accountto use the Schema value of the Ledger Account'sconsistencyConfig.totalBalanceUpdatessetting
{
"ledgerAccount": {
"path": "liabilities/users:user-1/available",
"ledger": {
"ik": "quickstart-ledger"
}
}
}See the Configure consistency section to learn more about consistency modes.
d. Point in time
#To query the balance of a Ledger Account at a particular point in time use the at argument:
query GetHistoricalBalances(
$ledgerAccount: LedgerAccountMatchInput!
) {
ledgerAccount(ledgerAccount: $ledgerAccount) {
end_of_year: balance(at: "1969")
end_of_month: balance(at: "1969-07")
end_of_day: balance(at: "1969-07-21")
end_of_hour: balance(at: "1969-07-21T02")
}
}If you don't specify at, you'll get the latest balance. at is supported for all balances and works granularly to the hour.
e. Net change
#You can also query the net change on a Ledger Account over a specific reporting period. This can be useful for generating financial statements.
Similar to balances, there are three types of balance changes:
ownBalanceChange, how muchownBalancechangedchildBalanceChange, how muchchildBalancechangedbalanceChange, how muchbalancechanged
Balance change queries require you to specify a period. This can be a year, quarter, month, day or hour.
query GetBalanceChanges(
$ledgerAccount: LedgerAccountMatchInput!
) {
ledgerAccount(ledgerAccount: $ledgerAccount) {
ownBalanceChange(period: "1969")
childBalanceChange(period: "1969")
balanceChange(period: "1969")
currentYear: balanceChange(period: "1969")
lastYear: balanceChange(period: "1968")
lastYearQ4: balanceChange(period: "1968-Q4")
lastYearDecember: balanceChange(period: "1968-12")
lastYearChristmas: balanceChange(period: "1968-12-25")
lastYearLastHour: balanceChange(period: "1968-12-31T23")
}
}You can also perform multiple balance queries using aliases.
{
"ledgerAccount": {
"path": "liabilities/users:user-1/available",
"ledger": {
"ik": "quickstart-ledger"
}
}
}f. Over a period
#FRAGMENT provides two queries for tracking balances and balance changes over time: balancesDuring and balanceChangesDuring. You can use them to analyze balance history at different granularities.
ownBalancesDuringandownBalanceChangesDuringfor a Ledger Account's own balancechildBalancesDuringandchildBalanceChangesDuringfor a Ledger Account's child balancebalancesDuringandbalanceChangesDuringfor a Ledger Account's total balance
To query a Ledger Account's balances, or balance changes, over a period, you must provide:
startTime, a date string in UTC that specifies the first moment of the periodduration, the length of the time period. Duration can be either positive or negative. When negative, the response will be balances, or balance changes, fordurationperiod before (not including)startTimegranularity, which specifies the unit forduration. Valid values arehourly,daily, ormonthly
The granularity must have a finer time resolution than the start time string.
| Start Time | Example Start Time | Valid Granularity |
|---|---|---|
| Year | "2021" | monthly, daily, hourly |
| Quarter | "2021-Q1" | monthly, daily, hourly |
| Month | "2021-01" | monthly, daily, hourly |
| Day | "2021-01-01" | daily, hourly |
| Hour | "2021-01-01T00" | hourly |
The maximum absolute value for the duration is granularity dependent. Values outside the ranges defined below will be rejected.
| Granularity | Maximum Duration | Time Period |
|---|---|---|
| monthly | 240 | 20 years |
| daily | 731 | 2 years including a leap year |
| hourly | 744 | 31 days |
query GetBalanceHistory(
$ledgerAccount: LedgerAccountMatchInput!
) {
ledgerAccount(ledgerAccount: $ledgerAccount) {
# Get monthly balances for a year
yearlyBalances: balancesDuring(
startTime: "2021"
duration: 12
granularity: monthly
) {
startTime
endTime
granularity
nodes {
at
amount {
currency {
code
}
amount
}
}
}
# Get daily balances for January 2021
monthlyBalances: balancesDuring(
startTime: "2021-01"
duration: 31
granularity: daily
) {
startTime
endTime
granularity
nodes {
at
amount {
currency {
code
}
amount
}
}
}
# Get daily balances changes for the two weeks
# before the start of Q4 of 2021
quarterlyChanges: balanceChangesDuring(
startTime: "2021-Q4"
duration: -14
granularity: daily
) {
startTime
endTime
granularity
nodes {
period
amount {
currency {
code
}
amount
}
}
}
# Get hourly balanceChanges for the 48 hour
# period starting on August 9th, 2024 at
# 11:00am UTC
hourlyChanges: balanceChangesDuring(
startTime: "2024-08-09T11"
duration: 48
granularity: hourly
) {
startTime
endTime
granularity
nodes {
period
amount {
currency {
code
}
amount
}
}
}
}
}The format of the response is:
startTime: The start of the period being queried as an ISO Time stringendTime: The last time in the period being queried as an ISO Time stringgranularity: The granularity of the data (monthly, daily, or hourly)nodes: an array of either HistoricalBalance or BalanceChangeDuring objects
For multi-currency Ledger Accounts, you must specify the currency you want to query:
query GetMultiCurrencyBalanceHistory(
$ledgerAccount: LedgerAccountMatchInput!
) {
ledgerAccount(ledgerAccount: $ledgerAccount) {
usdBalances: balancesDuring(
startTime: "2021"
duration: 12
granularity: monthly
currency: { code: USD }
) {
nodes {
at
amount {
amount
}
}
}
gbpChanges: balanceChangesDuring(
startTime: "2021"
duration: 100
granularity: daily
currency: { code: GBP }
) {
nodes {
period
amount {
amount
}
}
}
}
}g. Multi-currency mode
#For Ledger Accounts using currencyMode: multi, you can either:
- Use the
currencyargument to query the balance in a specific currency - Use plural field names (e.g.
balances) to query all currency balances
query GetMultiCurrencyBalances(
$ledgerAccount: LedgerAccountMatchInput!
) {
ledgerAccount(ledgerAccount: $ledgerAccount) {
# Query specific currency
latestUSDBalance: balance(currency: { code: USD })
latestGBPBalance: balance(currency: { code: GBP })
# Query all currencies
balances {
nodes {
currency {
code
}
amount
}
}
}
}{
"ledgerAccount": {
"path": "liabilities/users:user-1/available",
"ledger": {
"ik": "quickstart-ledger"
}
}
}See Handle currencies for a full list of multi-currency balance queries.
h. Timezone offsets
#Balance queries respect the Ledger's balanceUTCOffset when specifying periods and times. This field is specified when creating the Ledger using the createLedger mutation:
mutation CreateLedger(
$ik: SafeString!
$ledger: CreateLedgerInput!
$schema: SchemaMatchInput
) {
createLedger(
ik: $ik,
ledger: $ledger,
schema: $schema
) {
... on CreateLedgerResult {
ledger {
ik
name
created
balanceUTCOffset
schema {
key
}
}
}
... on Error {
code
message
}
}
}{
"ik": "quickstart-ledger",
"ledger": {
"name": "Quickstart Ledger",
"balanceUTCOffset": "-08:00"
},
"schema": {
"key": "quickstart-schema"
}
}The balanceUTCOffset is specified as a UTCOffset string in the format "±HH:00". All hour-aligned offsets from -11:00 to +12:00 are supported. For example:
"-08:00"for Pacific Time (UTC-8)"-05:00"for Eastern Time (UTC-5)"+00:00"for UTC"+01:00"for Central European Time (UTC+1)
If not specified, the Ledger will use UTC (offset of "+00:00") for balance calculations.
When querying balances, the offset affects how periods and times are interpreted:
- If a Ledger has an offset of
-08:00, then queryingbalance(at: "1969-01-31")returns the balance at midnight PT on that date, or 8am on 1969-02-01 UTC. - Querying
balanceChange(period: "1969")returns the net change between 8am on 1969-01-01 UTC and 8am on 1970-01-01 UTC. This gives you the net change between midnights local time. - Daylight savings is ignored, so every day throughout the year has exactly 24 hours.