Quickstart
Make a bounded request and understand the data you receive.
Start with parsed analytics
Use the analytics API for parsed transactions, operations, asset activity and contract events. REST and typed GraphQL share the same warehouse query services. You do not need to decode raw ledger files to use these endpoints.
The examples use the public API at https://api.stellaratlas.io. Use the GraphQL runner or the operations reference to execute a request. No wallet signature or private key is needed for these reads.
Each command below allows five seconds to connect and thirty seconds for the whole request, without automatic retries. A client timeout is a failed read, not evidence that rows are absent or that server work stopped. Continue only after a successful response.
For a wallet or token project, follow the KALE, wallet balances and asset holders quickstart.
1. Check the available ledger ranges
curl --fail-with-body --connect-timeout 5 --max-time 30 'https://api.stellaratlas.io/v1/analytics/datasets'The dataset catalog includes table names, column types and coverage. Choose a small interval inside coverage.completedRanges. Backfill can contain a contiguous historical range plus separate completed intervals; the highest imported ledger does not imply everything before it is available.
2. Read payment operations
Run this command in Bash with curl 7.84 or newer, jq and GNU coreutils. It replaces operations-page-1.json after a live HTTP success containing a JSON object. If it fails, any existing file is from a previous run. Wait for a successful save before using the file in step 3.
(
trap - EXIT INT TERM
trap 'exit 130' INT
trap 'exit 143' TERM
temporary=$(mktemp './operations-page-1.json.partial.XXXXXX') || exit
trap 'rm -f -- "$temporary"' EXIT
status=$(curl -q --fail-with-body --connect-timeout 5 --max-time 30 \
--write-out '%{http_code}:%header{x-stellaratlas-fallback}' \
'https://api.stellaratlas.io/v1/operations?min_ledger=63490364&max_ledger=63490365&type=payment&limit=10&offset=0' --output "$temporary") || exit
if [[ $status != 2[0-9][0-9]: ]]; then
printf '%s\n' "Expected a live HTTP success, got $status" >&2
exit 22
fi
jq -es 'length == 1 and (.[0] | type == "object")' "$temporary" >/dev/null || exit
mv -fT -- "$temporary" './operations-page-1.json'
)This two-ledger window is an example, not a promise of current coverage. Replace it with a range from your catalog response. The result contains rows, window, coverageStatus and nextOffset. Operations include their type, source account, decoded details and transaction relationship.
After the request succeeds, read these fields together:
windowidentifies the ledger interval actually queried. Check it against the range you selected.coverageStatus: completemeans the selected window is covered; it does not mean all chain history is available. Forpartial_or_unknown, choose a completed interval from the catalogue before drawing conclusions from missing rows.- An empty
rowsarray can be a valid result for your filters. It is different from a failed request. A non-nullnextOffsetcontinues this query;nullends it.
If the request fails, follow error handling before trying a larger query. For the next workflow, use publication notices for refreshing a view or history downloads for offline analysis.
3. Follow a result, then paginate
Open a returned transaction hash with GET /v1/analytics/transactions/{hash}?view=typed. Supply ledger_sequence when known to narrow the lookup. The typed response has separately paginated operations, effects and events.
Follow the typed transaction walkthrough to inspect the response and continue each relation independently.
For the operations list, repeat the same filters with the returned nextOffset. Stop when it is null. Check coverage before interpreting an empty result as absence.
With jq installed, continue the saved response only when it supplies a nextOffset:
offset=$(jq -er '.nextOffset // empty' operations-page-1.json) &&
curl --fail-with-body --connect-timeout 5 --max-time 30 --get 'https://api.stellaratlas.io/v1/operations?min_ledger=63490364&max_ledger=63490365&type=payment&limit=10' \
--data-urlencode "offset=$offset"Keep the first request’s window, filters and limit in the second URL. Use the returned offset rather than calculating it from row count. These offset pages can change during backfill; for long results, narrow the window instead of exceeding the route’s offset limit. See pagination rules.