Liquidity API

GraphQL reference for Rails Yield earnings and balances — funds, balance and revenue charts, transaction history, stats, and per-asset balances under user.liquidity_provider.

All yield data — current balances, revenue, charts, transactions, asset balances — lives under user.liquidity_provider. The single-field query accepts a LiquidityProviderInput to scope by node and date range.

Authorization: Bearer $AMBOSS_DASHBOARD_TOKEN

LiquidityProviderInput

FieldTypeDefaultDescription
node_idStringAll team nodes aggregatedUUID of the node to query.
fromString30 days agoISO-8601 start of the window.
toStringnowISO-8601 end of the window.

Date range determines the aggregation bucket on charts (see AggregateInterval below). Omit node_id for an aggregated view across all the team's nodes.


Funds (current state)

funds is the live snapshot: total, available, reserved, and lifetime earnings, each in sats and USD.

query Funds($input: LiquidityProviderInput) {
  user {
    id
    liquidity_provider(input: $input) {
      id
      node_id
      funds {
        total     { sats usd }
        available { sats usd }
        reserved  { sats usd }
        earnings  { sats usd }
      }
    }
  }
}
curl -X POST https://rails.amboss.tech/graphql \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $AMBOSS_DASHBOARD_TOKEN" \
  -d '{
    "query": "query($input: LiquidityProviderInput) { user { liquidity_provider(input: $input) { funds { total { sats usd } available { sats usd } reserved { sats usd } earnings { sats usd } } } } }",
    "variables": { "input": { "node_id": "<NODE_ID>" } }
  }'
const { user } = await client.request(FUNDS, {
  input: { node_id: process.env.NODE_ID },
});
console.log(user.liquidity_provider.funds.total.sats);
FieldMeaning
totalOn-chain + channel balances (including pending channel openings).
availableWithdrawable without closing channels.
reservedLocked in open channels.
earningsLifetime routing + liquidity revenue minus on-chain costs.

Balances (historical snapshots)

balances.balances returns time-stamped snapshots within [from, to], plus financial_changes for the deltas between the start and end of the window.

query Balances($input: LiquidityProviderInput) {
  user {
    liquidity_provider(input: $input) {
      balances {
        balances {
          id
          created_at
          balance   { sats usd }
          principal { sats usd }
          earnings  { sats usd }
          available { sats usd }
          reserved  { sats usd }
          alltime_routing_revenue { sats usd }
          alltime_leasing_revenue { sats usd }
          alltime_onchain_costs   { sats usd }
        }
        financial_changes {
          routing_revenue_change { sats usd }
          leasing_revenue_change { sats usd }
          onchain_costs_change   { sats usd }
        }
      }
    }
  }
}

principal is the total amount deposited so far — use it as the denominator when computing APY against earnings.


Charts

Two chart sub-fields cover the most common dashboards: balance over time and revenue over time, both already bucketed by an AggregateInterval.

Balance chart

query BalanceChart($input: LiquidityProviderInput) {
  user {
    liquidity_provider(input: $input) {
      charts {
        balance {
          interval
          chart { period balance { sats usd } }
        }
      }
    }
  }
}

Revenue chart

query RevenueChart($input: LiquidityProviderInput) {
  user {
    liquidity_provider(input: $input) {
      charts {
        revenue {
          interval
          chart {
            period
            routing   { sats usd }
            liquidity { sats usd }
          }
        }
      }
    }
  }
}

Chart aggregation

interval is selected by the server from the size of the from/to window:

Window lengthAggregateInterval value
>= 1 yearYEAR
2 months to 1 yearMONTH
< 2 monthsWEEK

period is the ISO-8601 timestamp at the start of each bucket.


Revenue (current totals)

revenue is the all-time split when you don't need a chart.

query Revenue {
  user {
    liquidity_provider {
      revenue {
        liquidity { sats usd }
        routing   { sats usd }
      }
    }
  }
}

Stats

stats exposes Magma sales counts, current routing volume, and the date of the first deposit (useful for time-weighted APY calculations).

query Stats($input: LiquidityProviderInput) {
  user {
    liquidity_provider(input: $input) {
      stats {
        liquidity {
          sales
          partners
          provided_liquidity
        }
        routing {
          payment_count
          payment_value { sats usd }
        }
        deposits {
          first_deposit
        }
      }
    }
  }
}

Transaction list

Paginated transaction history. Filter by one or more TransactionType values.

query Transactions(
  $liquidityProviderInput: LiquidityProviderInput
  $transactionInput: TransactionInput
) {
  user {
    liquidity_provider(input: $liquidityProviderInput) {
      transaction_list(input: $transactionInput) {
        total_count
        pagination { limit offset }
        list {
          id
          type
          status
          confirmed
          cost_basis
          date
          amount { sats usd }
          fee    { sats usd }
          metadata {
            type
            amount_routed { sats usd }
          }
        }
      }
    }
  }
}

TransactionType values:

ValueWhat it is
DEPOSITOn-chain deposit into the node.
WITHDRAWOn-chain withdrawal out of the node.
CHANNEL_SALEChannel sold on the Magma marketplace.
CHANNEL_PURCHASEChannel bought on the Magma marketplace.
CHANNEL_OPENChannel opened directly (not via Magma).
CHANNEL_CLOSEChannel closure.
ROUTINGHTLC forward. metadata.amount_routed carries the payment value; amount carries the earned fee.

TransactionStatus is either SENT or RECEIVED from the node's perspective.


Per-asset balances

When Taproot Assets are enabled, query assets.list.balances for the per-asset breakdown. See Assets for the schema and example.


SatoshiAmount

Almost every monetary field in this API returns a SatoshiAmount:

type SatoshiAmount {
  id: String!
  sats: String!  # integer-like string (avoid JS Number truncation past 2^53)
  usd: Float!    # via Amboss price oracle, refreshed often
}

sats is a string to preserve precision for amounts above 2^53. Parse it with BigInt (or your language's arbitrary-precision integer type) if you plan to arithmetic against it.