Skip to main content

Vault Indexer API

The vault indexer is a public, read-only GraphQL API over Babylon Trustless Bitcoin Vaults (TBV) state. TBV lets native Bitcoin be used as collateral, and the indexer serves the resulting on-chain state: BTCVault lifecycle, operator sets and Aave position data, read from the vault contracts.

No API key. No authentication. Cross-origin requests are permitted.

Endpoint

URLhttps://babylon-vault-indexer-api.testnet.babylonlabs.io/
MethodPOST with Content-Type: application/json
Alternate path/graphql — identical behaviour
ExplorerOpen the GraphiQL playground
NetworkEthereum Sepolia (chain ID 11155111)
AuthNone
CORSOpen

Testnet only. There is no mainnet endpoint yet.

curl -s https://babylon-vault-indexer-api.testnet.babylonlabs.io/ \
-H 'Content-Type: application/json' \
-H 'User-Agent: my-app/1.0' \
-d '{"query":"{ statss(limit:1){ items{ totalAvailableSats availableVaultCount } } }"}'
Three things that will catch you out
  1. Set a User-Agent. The default one from requests, urllib or many HTTP clients gets a bare 403 from the edge.
  2. Query depth is capped at 10, so standard GraphQL tooling cannot introspect this endpoint.
  3. limit is capped at 1000. Page with offset.

All three are explained in Limits and gotchas. Read that page before you write a client.

What the API covers

The schema splits into two domains.

Core vault

The BTCVault lifecycle and the operators that secure it — Vault Providers, Universal Challengers and App Keepers — independent of any application: vault, vaultActivity, vaultProvider, vaultProviderStats, vaultKeeper, vaultKeeperApplication, universalChallenger, universalChallengerVersion, vaultFeeEscrow, feeConfig, application, token, stats and protocolState.

A BTCVault progresses through:

pending → signatures_collected → verified → available
├→ redeemed
├→ liquidated
├→ expired
├→ depositor_withdrawn
└→ invalid

status is the authority on where a BTCVault sits. Timestamps cover only part of the path, so do not expect one field per state:

StateField that dates it
pendingpendingAt
signatures_collectedpeginSigsPostedAt
verifiedverifiedAt
availableactivatedAt
expiredexpiredAt, with expirationReason
redeemed, liquidatednone on the vault — read vaultActivity
depositor_withdrawn, invalidnone — status is the only signal

Aave application

State for the Aave v4 integration, the first application built on TBV: aavePosition, aavePositionCollateral, aaveVaultStatus, aaveUserProxy, aaveReserve and aaveConfig.

A BTCVault used as Aave collateral appears in both domains — as a vault and as an aavePositionCollateral.

Query shape

Every entity has two resolvers.

FormExampleReturns
Singularvault(id: "0x…")One record, or null
Pluralvaults(where:, orderBy:, orderDirection:, limit:, offset:)A page

A page always carries items, totalCount and pageInfo. totalCount is the number of records matching the filter, not the number returned.

Numeric values typed BigInt — amounts, block numbers, timestamps — are returned as strings, and comparison filters on them take strings too.

Explorer

Use the Explorer on this site. It runs against the same endpoint and carries every documented example as a preset, so you can start from a working query rather than a blank editor.

You can also press Run on any query in these pages to open it directly.

The endpoint's own playground cannot load the schema

Opening the endpoint in a browser serves a GraphiQL playground, and queries execute there normally. Its Docs panel, however, shows Error fetching schema, and there is no autocomplete or in-editor validation. The depth cap is the reason: GraphiQL's introspection query is depth 21, and this deployment allows 10.

The Explorer on this site avoids that by reading the committed SDL instead of introspecting, so autocomplete, validation and the Docs panel all work.

Checking indexer freshness

The indexer trails the chain. _meta reports the last processed block.

{
_meta {
status
}
}

Compare that block number against a Sepolia chain head before treating any result as current.

Where to go next