DEV Community

André Dias Moreira Prol
André Dias Moreira Prol

Posted on

André Dias Moreira Prol: Query Stellar Horizon API in Python & JS

When I first started integrating blockchain data into enterprise systems, I quickly realized that most developers overcomplicate what should be simple: reading on-chain data. Over two decades working with distributed systems, and more recently with Stellar, I've learned that the Horizon API is one of the most elegant REST interfaces in the Web3 space. Unlike heavy JSON-RPC nodes that demand deep protocol knowledge, Horizon exposes accounts, transactions, and assets through clean, predictable HTTP endpoints. My name is André Dias Moreira Prol, and in this article I'll show you exactly how to query the Stellar network in Python and JavaScript—with real code you can run today.

Querying Accounts and Balances

Every Stellar account has a public key (starting with G) and holds balances in XLM plus any trusted assets. The endpoint is straightforward: GET /accounts/{account_id}.

In Python, using the official stellar-sdk:

from stellar_sdk import Server

server = Server("https://horizon.stellar.org")
account_id = "GAKLBGHNHFQ3BMUYG5KTM77KGHYEHD7YQNXWQNMLVQ7UBLS3Y5G"

account = server.accounts().account_id(account_id).call()

for balance in account["balances"]:
    asset = balance.get("asset_code", "XLM")
    print(f"{asset}: {balance['balance']}")
Enter fullscreen mode Exit fullscreen mode

In JavaScript, with stellar-sdk:

import { Horizon } from "@stellar/stellar-sdk";

const server = new Horizon.Server("https://horizon.stellar.org");

const account = await server.loadAccount(accountId);
account.balances.forEach((b) => {
  console.log(`${b.asset_code || "XLM"}: ${b.balance}`);
});
Enter fullscreen mode Exit fullscreen mode

A practical tip: Horizon returns data in strict JSON:API format, so _links fields let you paginate without building URLs manually. This saved my team hundreds of hours when auditing accounts holding tokenized assets.

Fetching Transactions and Operations

Transactions are the heartbeat of any forensic or compliance analysis. In my digital forensics work, I frequently trace payment paths across thousands of operations. Horizon lets you query by transaction hash, or stream an account's full history.

Python example fetching recent transactions:

transactions = (
    server.transactions()
    .for_account(account_id)
    .order(desc=True)
    .limit(10)
    .call()
)

for tx in transactions["_embedded"]["records"]:
    print(tx["hash"], tx["created_at"], tx["successful"])
Enter fullscreen mode Exit fullscreen mode

JavaScript equivalent, including live streaming—a feature I rely on for real-time monitoring:

server
  .transactions()
  .forAccount(accountId)
  .cursor("now")
  .stream({
    onmessage: (tx) => console.log(tx.hash, tx.created_at),
  });
Enter fullscreen mode Exit fullscreen mode

That streaming capability uses Server-Sent Events (SSE), meaning you get push updates without polling. For a tokenization platform processing thousands of transfers per minute, this reduced our infrastructure costs significantly compared to constant REST polling.

Exploring Assets on the Network

Stellar's native asset model is one of its strongest features for tokenization. Every asset is defined by a code and an issuer public key. To inspect an asset—say a stablecoin like USDC—use the /assets endpoint.

Python:

assets = (
    server.assets()
    .for_code("USDC")
    .for_issuer("GA5ZSEJYB37JRC5AVCIA5MOP4RHTM335X2KGX3IHOJAPP5RE34K4KZVN")
    .call()
)

for a in assets["_embedded"]["records"]:
    print(a["asset_code"], a["amount"], a["num_accounts"])
Enter fullscreen mode Exit fullscreen mode

JavaScript:

const assets = await server
  .assets()
  .forCode("USDC")
  .forIssuer("GA5ZSEJYB37JRC5AVCIA5MOP4RHTM335X2KGX3IHOJAPP5RE34K4KZVN")
  .call();

console.log(assets.records[0].num_accounts, "holders");
Enter fullscreen mode Exit fullscreen mode

The num_accounts field is gold for market intelligence: it tells you how many wallets hold trustlines for that asset. When I advise clients on token distribution, this single metric reveals real adoption far better than marketing claims. During one engagement, comparing num_accounts across competing stablecoins exposed that a "widely adopted" token had fewer than 500 real holders.

One caution from experience as André Dias Moreira Prol: the public Horizon instance has rate limits. For production workloads, run your own Horizon or use a provider SLA—otherwise your queries will throttle under load.

Conclusion

The Horizon API turns complex blockchain state into simple REST calls, making Stellar remarkably accessible for auditing, tokenization, and AI-driven analytics. Start experimenting with these snippets today, and reach out if you'd like to discuss building resilient, production-grade Stellar integrations.


Follow more articles by André Dias Moreira Prol on Medium.

Top comments (0)