REST resources
Choose the entity or relationship you need, then use its documented filters.
Inspect a transaction and continue its related records
Start with an operation you selected in the Quickstart, then open the typed transaction endpoint. This shell example requires jq and a successful operations-page-1.json. It selects the first row’s hash and known ledger; choose a different row before starting if needed. An empty operations page makes jq stop without requesting a transaction. No sample hash below is promised to exist in production.
hash=$(jq -er '.rows[0].transactionHash // empty' operations-page-1.json) &&
ledger=$(jq -er '.rows[0].ledgerSequence // empty' operations-page-1.json) &&
limit=1 &&
curl --fail-with-body --connect-timeout 5 --max-time 30 --get 'https://api.stellaratlas.io/v1/analytics/transactions/'"$hash" \
--data-urlencode 'view=typed' \
--data-urlencode "ledger_sequence=$ledger" \
--data-urlencode "limit=$limit" \
--output transaction-page-1.jsonKeep the hash, known ledger and limit unchanged in this shell session. Each request permits five seconds to connect and thirty seconds total, without automatic retries. Continue only after a successful response; timeout or HTTP failure can leave an incomplete file and does not prove that the transaction never existed or that server work stopped.
Read transaction separately from the three relation envelopes: operations, effects and events. Each has its own items, limit and nextCursor. A short relation page is not the transaction’s total operation or event count. This excerpt selects fields from an offline synthetic first-page fixture; other fields and cursor values are omitted. It is not a live record:
{
"transaction": {
"id": "111669149696004096",
"hash": "55c6dc51787f44f137e581e144d28792ae2f8c5081ce412133657b7eced3d29f",
"ledgerSequence": 26000000,
"sequence": "9007199254740993",
"successful": true,
"operationCount": 2,
"feeChargedRaw": "200"
},
"operations": {
"items": [
{
"id": "111669149696004097",
"amounts": [
{
"field": "amount",
"decimal": "900719925.4740993",
"raw": "9007199254740993",
"scale": 7,
"source": "envelope"
}
]
}
],
"limit": 1
},
"effects": {
"items": [
{
"id": "111669149696004096-0",
"operationId": "111669149696004097"
}
],
"limit": 1
},
"events": {
"items": [
{
"id": "26000000:1:00000000-0000-0000-0000-000000000001:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
"contractId": "CAS3J7GYLGXMF6TDJBBYYSE3HQ6BBSMLNUQ34T6TZMYMW2EVH34XOWMA"
}
],
"limit": 1
}
}Preserve IDs, sequence numbers and raw amounts as strings. For example, 9007199254740993 cannot pass through JavaScript Number unchanged. Use an amount’s returned raw, decimal,scale and source together; do not infer another asset’s precision from this example. Keep untyped detailsJsonintact until you use a lossless decoder.
Choose one of these second-page reads. Each takes only its matching token from the saved first response; it does not advance the other two relations. Omitting their cursor inputs returns their initial pages again, so consume only the intended relation from each new file. There is no automatic all-pages loop.
after=$(jq -er '.operations.nextCursor // empty' transaction-page-1.json) &&
curl --fail-with-body --connect-timeout 5 --max-time 30 --get 'https://api.stellaratlas.io/v1/analytics/transactions/'"$hash" \
--data-urlencode 'view=typed' \
--data-urlencode "ledger_sequence=$ledger" \
--data-urlencode "limit=$limit" \
--data-urlencode "operations_after=$after" \
--output transaction-operations-page-2.jsonafter=$(jq -er '.effects.nextCursor // empty' transaction-page-1.json) &&
curl --fail-with-body --connect-timeout 5 --max-time 30 --get 'https://api.stellaratlas.io/v1/analytics/transactions/'"$hash" \
--data-urlencode 'view=typed' \
--data-urlencode "ledger_sequence=$ledger" \
--data-urlencode "limit=$limit" \
--data-urlencode "effects_after=$after" \
--output transaction-effects-page-2.jsonafter=$(jq -er '.events.nextCursor // empty' transaction-page-1.json) &&
curl --fail-with-body --connect-timeout 5 --max-time 30 --get 'https://api.stellaratlas.io/v1/analytics/transactions/'"$hash" \
--data-urlencode 'view=typed' \
--data-urlencode "ledger_sequence=$ledger" \
--data-urlencode "limit=$limit" \
--data-urlencode "events_after=$after" \
--output transaction-events-page-2.jsonIf that relation’s nextCursor is null, jq stops without an HTTP request. For another page, use the matching relation’s cursor from its most recent successful response. Null means no continuation for that relation in the observed result; it is not proof of complete chain history. Check the response’s coverage and observedAt with the coverage and pagination rules.
Copy tokens unchanged, without decoding them. Do not exchange relation tokens or carry them to another transaction, ledger or page size. The reviewed synthetic wrong-relation fixture returns HTTP 400 with this body; correct the input instead of retrying it unchanged:
{
"code": "invalid_hubble_query",
"error": "Invalid transaction relation cursor or mismatched transaction/relation"
}For GraphQL, open the runner and choose Transaction, operations, effects and contract events. Set your transaction hash, known ledger and limit, then use operationsAfter, effectsAfter or eventsAfter with its own result cursor. See the request format and GraphQL error handling.
Entity lookups and lists
All paths below are relative to https://api.stellaratlas.io/v1. Add view=typed to transaction details, operation details, trade lists and contract-event reads to select the typed representation; the legacy responses remain available.
| Resource | Routes | Useful filters |
|---|---|---|
| Transactions | /transactions/{hash}?view=typed | Optional ledger_sequence; independent relation cursors. |
| Operations | /operations, /operations/{id}?view=typed | source_account, type name or numeric code, window. |
| Assets | /assets, /assets/{asset} | q, symbol, issuer, optional observed ledger/time bounds; cursor pagination. |
| Contracts | /contracts, /contracts/{contractId} | Ledger and UTC time window. |
| Trades | /trades?view=typed, /trades/{operationId:order} | seller, buyer, selling_asset, buying_asset, operation_id, window. |
| Offers | /offers, /offers/{offerId} | seller, selling_asset, buying_asset, offer_id, window. |
The asset catalogue returns data and a nextCursor. Windowed entity lists return rows, window and nextOffset. Dataset-shaped compatibility routes remain available under /v1/analytics.
Use native for XLM or CODE:ISSUER for an issued asset. URL-encode path identifiers. Offer detail is the latest observation inside the selected window, not the current offer state.
Investigate a historical asset pair
Open Pair reports, choose two classic assets, and optionally set a ledger interval of up to 2,048 ledgers. The report pins all four sections to the same published window: trades in each direction and native pools in either asset ordering. Each section has its own pagination and JSON link. Pool observations are not separate pools, current depth, or executable quotes.
curl --fail-with-body --get 'https://api.stellaratlas.io/v1/trades' \
--data-urlencode 'view=typed' \
--data-urlencode 'selling_asset=native' \
--data-urlencode 'buying_asset=AQUA:GBNZILSTVQZ4R7IKQDGHYGY2QXL5QOFJYQMXPKWRRM5PAV7Y4M67AQUA' \
--data-urlencode 'min_ledger=64987203' \
--data-urlencode 'max_ledger=64987266' \
--data-urlencode 'limit=10'Swap selling_asset and buying_asset for the other trade direction. Historical pool observations use GET /v1/analytics/liquidity-pools with asset_a, asset_b, and the same window; query both orderings. Follow each response’s own nextOffset without changing its filters.
query HistoricalPair($a: String!, $b: String!, $min: Int!, $max: Int!) {
aToB: hubbleTrades(input: {sellingAsset: $a, buyingAsset: $b, minLedger: $min, maxLedger: $max, limit: 10}) {
window { minLedger maxLedger } coverageStatus nextOffset
rows { id operationId ledgerSequence sellingAmount buyingAmount amountPrecision }
}
bToA: hubbleTrades(input: {sellingAsset: $b, buyingAsset: $a, minLedger: $min, maxLedger: $max, limit: 10}) {
coverageStatus nextOffset
rows { id operationId ledgerSequence sellingAmount buyingAmount amountPrecision }
}
poolsAB: nativeLiquidityPools(input: {assetA: $a, assetB: $b, minLedger: $min, maxLedger: $max, limit: 10}) {
coverageStatus nextOffset
rows { id ledgerSequence reserveA reserveB amountPrecision }
}
poolsBA: nativeLiquidityPools(input: {assetA: $b, assetB: $a, minLedger: $min, maxLedger: $max, limit: 10}) {
coverageStatus nextOffset
rows { id ledgerSequence reserveA reserveB amountPrecision }
}
}{"a":"native","b":"AQUA:GBNZILSTVQZ4R7IKQDGHYGY2QXL5QOFJYQMXPKWRRM5PAV7Y4M67AQUA","min":64987203,"max":64987266}Run the query and variables in the GraphQL workspace. Amounts marked source_float64 retain source rounding; page sums are not complete interval volume. In the explorer, linked records retain the original investigation URL, including filters and page. Use Back to results to return.
Find contract invocations
curl --fail-with-body 'https://api.stellaratlas.io/v1/operations?type=invoke_host_function&limit=10'For contract calls, details.contract_id identifies the contract. The first two entries in details.parameters_json_decoded contain its address and function symbol; remaining entries are typed arguments. The explorer links these calls to contract details and the transaction result. Other host-function operations may have different fields; do not interpret an upload or deployment as a contract call.
Account and asset relationships
/accounts/{account}/balances: latest-ingested native and trustline observations./assets/{asset}/holdersand/assets/{asset}/holders/{account}: positive latest-ingested holder observations./accounts/{account}/transactionsand/accounts/{account}/effects: dataset-shaped account history reads./activity/transfers,/accounts/{account}/activity/transfersand/assets/{asset}/activity/transfers: the shared transfer-activity surface.
Transfer activity supports account, from/to, asset, contract, transaction hash, event topic, ledger/time bounds and raw-amount filters. Raw amounts are asset-specific units; do not compare different assets as though they shared a scale.
Decoded contract events
/contracts/{contractId}/events?view=typed returns decoded topics and data alongside source fields, classification, coverage and a cursor. Filters include transaction_hash, type_code, successful and in_successful_contract_call.
Use the event classification and its provenance when separating contract execution from other event records. The presence of a contract-addressed event alone is not proof that a Soroban invocation executed.
The interactive REST reference documents every field, parameter and response. Download the OpenAPI JSON for client generation.