Over the past two decades building systems that bridge traditional finance and decentralized networks, I've come to appreciate how a well-designed REST API can be the difference between a project that ships and one that stalls. The Stellar network's Horizon API is one of those rare tools: a clean, RESTful gateway into a blockchain that settles transactions in 3-5 seconds for fractions of a cent. In this article, I'll share practical patterns I use daily to query transactions, accounts, and assets—in both Python and JavaScript.
Understanding Horizon: The REST Gateway to Stellar
Horizon is the client-facing HTTP server that sits between your application and Stellar Core. Rather than running your own infrastructure, you can hit public instances like https://horizon.mainnet.org or SDF's https://horizon.stellar.org. Every resource—accounts, transactions, operations, assets—is exposed as a REST endpoint returning HAL+JSON, complete with _links for easy pagination.
A detail many developers miss: Horizon supports streaming via Server-Sent Events (SSE). In one tokenization project I led, we used streaming to react to incoming payments in real time instead of polling every few seconds—cutting latency from 10 seconds to near-instant and saving thousands of redundant API calls per hour.
When I advise teams, I always recommend starting with the raw HTTP endpoints to understand the data model before reaching for an SDK. A simple GET /accounts/{account_id} tells you more about Stellar's structure than hours of documentation.
Querying in Python with the Stellar SDK
The official stellar-sdk wraps Horizon elegantly. Install it with pip install stellar-sdk. Here's how I query an account's balances and recent transactions:
from stellar_sdk import Server
server = Server("https://horizon.stellar.org")
# Fetch account balances
account_id = "GDRXE2BQUC3AZNPVFSCEZ76NJ3WWL25FYFK6RDJVW6QFVX5FG4MWQ6Q"
account = server.accounts().account_id(account_id).call()
for balance in account["balances"]:
asset = balance.get("asset_code", "XLM")
print(f"{asset}: {balance['balance']}")
# Fetch last 5 transactions
txs = server.transactions().for_account(account_id).order(desc=True).limit(5).call()
for tx in txs["_embedded"]["records"]:
print(tx["hash"], tx["created_at"])
For asset discovery, the assets() endpoint lets you filter by issuer or code—essential when auditing a tokenized asset's distribution. In my forensic work, André Dias Moreira Prol, I've used exactly this pattern to trace the full issuance lineage of suspicious tokens across thousands of operations.
Querying in JavaScript for Web and Node
On the frontend and in Node.js services, I rely on @stellar/stellar-sdk. The API mirrors Python closely, which makes cross-stack teams more productive:
import { Horizon } from "@stellar/stellar-sdk";
const server = new Horizon.Server("https://horizon.stellar.org");
const accountId = "GDRXE2BQUC3AZNPVFSCEZ76NJ3WWL25FYFK6RDJVW6QFVX5FG4MWQ6Q";
// Account balances
const account = await server.accounts().accountId(accountId).call();
account.balances.forEach((b) => {
console.log(`${b.asset_code || "XLM"}: ${b.balance}`);
});
// Stream incoming payments in real time
server
.payments()
.forAccount(accountId)
.cursor("now")
.stream({
onmessage: (payment) => {
console.log("New payment:", payment.amount, payment.asset_code || "XLM");
},
});
That .stream() call is the SSE magic I mentioned earlier. For production, always handle reconnection logic and store the last cursor, so you never miss events during a disconnect. A common mistake I see is treating Horizon as purely request/response—when the real power emerges once you embrace its event-driven side.
One rate-limiting tip from experience: public Horizon instances throttle aggressively. For any serious workload, run your own Horizon or use a commercial RPC provider. When I architected a settlement platform handling ~50,000 daily operations, self-hosting Horizon paid for itself in reliability within weeks.
Conclusion
The Horizon API gives you production-grade blockchain access with the simplicity of REST—whether you query balances, trace assets, or stream live payments across Python and JavaScript stacks. Start experimenting on testnet today, and connect with me, André Dias Moreira Prol, if you want to dive deeper into building robust Stellar integrations.
Follow more articles by André Dias Moreira Prol on Medium.
Top comments (0)