Stellar testnet and mainnet
Stellar events,
delivered.
Subscribe to contract events and payments once. Pier watches every ledger and delivers each match to webhooks, live streams, the pull API, message queues, chat apps, your laptop or an AI agent, with retries, replay and a dashboard. No poller to write.
npx pier-cli login
Sign in with GitHub. Testnet, and mainnet with a daily cap. The console is live: switch a stream off, then back on.
Try the exchange deposit demo → A real testnet payment with a memo, delivered by Pier to RabbitMQ and credited by the exchange.
Delivers to
- Webhooks
- Server-Sent Events
- Pull API
- Your laptop
- Discord
- Slack
- Telegram
- Apache Kafka
- RabbitMQ
- NATS JetStream
- Amazon SQS
- Google Pub/Sub
- Azure Service Bus
- Azure Event Hubs
- Azure Event Grid
- AI agents (MCP)
From zero to events in three commands.
Get a key on the dashboard (GitHub sign-in), then pick your tool. Needs Node.js 20.19 or newer.
# 1. log in with the key from the dashboard
npx pier-cli login --key pier_… --api https://136-112-187-130.sslip.io
# 2. subscribe: XLM transfers on testnet (add --network mainnet for mainnet)
npx pier-cli subscribe --contract CDLZFC3SYJYDZT7K67VZ75HPJVIEUVNIXF47ZG2FB2RMQQVU2HHGCYSC --topic sym:transfer,**
# 3. forward every match to a local server, resuming where you stopped
npx pier-cli listen <subscription-id> --forward http://localhost:3000/webhook
// npm install @wmendes/pier-sdk
import { Pier, filters } from "@wmendes/pier-sdk";
const pier = new Pier({ apiKey: process.env.PIER_API_KEY!, apiUrl: "https://136-112-187-130.sslip.io" });
const sub = await pier.subscriptions.create({
filter: filters.payments("G…your account", "in"),
});
for await (const event of pier.stream(sub.id)) {
console.log(event.position, event.decoded.topic, event.decoded.value);
}
# a subscription that also posts each match to your webhook (signed, retried)
curl -X POST https://136-112-187-130.sslip.io/v1/subscriptions \
-H "x-api-key: $PIER_API_KEY" -H "content-type: application/json" \
-d '{"filter":{"type":"payment","account":"G…","direction":"in"},
"webhook":{"url":"https://example.com/pier"}}'
# or pull: every match after a cursor
curl -H "x-api-key: $PIER_API_KEY" "https://136-112-187-130.sslip.io/v1/subscriptions/<id>/events?after=0"
# Claude Code: add the Pier MCP server, then ask for the events you need
claude mcp add pier -e PIER_API_KEY=pier_… -e PIER_API_URL=https://136-112-187-130.sslip.io -- npx -y @wmendes/pier-mcp
# any agent: point it at the docs written for agents
https://136-112-187-130.sslip.io/llms.txt
https://136-112-187-130.sslip.io/skill.md
Send events where your code already is.
Up to five destinations per subscription, added from the dashboard or the API. Credentials are stored encrypted and never shown again.
Your code
- WebhooksSigned with Standard Webhooks; each event retried on its own with backoff.
- Server-Sent EventsA live stream that resumes from the last event you handled.
- Pull APIEvery match after a cursor, page by page, for 7 days.
- Your laptop
pier-cli listen --forwardposts to localhost. No public URL, no tunnel.
Queues and streams
- Apache KafkaKeyed by subscription; TLS and SASL (PLAIN, SCRAM).
- RabbitMQPersistent messages with publisher confirms.
- NATS JetStreamMessage ids let the stream drop a re-sent event.
- Amazon SQSStandard or FIFO; FIFO also drops a re-send within 5 minutes.
- Google Pub/SubAttributes carry the position and event id.
- Azure Service BusQueues and topics; the event id as message id drops a re-send.
- Azure Event HubsPartitioned by subscription.
- Azure Event GridEvent Grid schema or CloudEvents, on topics and namespaces.
People and agents
- Discord, Slack, TelegramOne readable line per event in a channel.
- AI agentsAn MCP server, a Pier skill and llms.txt: agents subscribe instead of writing a poller.
- DashboardFilter builder with a preview, live events, delivery health and usage.
The parts you would otherwise build.
Filters, previewed
Contract events by contract and topic, or payments to and from an account. The dashboard shows what a filter would have matched on recent ledgers before you save it.
Testnet and mainnet
One API for both networks. On mainnet, filters name their contracts or account and each team matches up to 10,000 events a day.
Retries and resume
Each failed delivery is retried with exponential backoff, up to 200 attempts. A destination that keeps failing stops and can be resumed with one click.
Replay from any position
Every event has a position. Pull or stream from any position in the last 7 days, and resume from the last position you handled.
Delivery health
Per destination: delivered, waiting, last error and daily counts, in the dashboard and the API.
Decoded, and raw
Each event comes with its raw XDR and a decoded JSON view, plus ledger, transaction and contract.
Limits and guarantees.
What Pier does today, plainly.
| Delivery | At least once. Pushed destinations don't preserve order: order by position and de-duplicate by event id. Pull and streams return events by position. |
|---|---|
| Retries | Exponential backoff from 5 seconds to 10 minutes, up to 200 attempts per event; up to 4 deliveries in flight per destination. |
| Retention | 7 days of events, for replay and pull. |
| Networks | Testnet; mainnet with filters that name contracts or an account, and 10,000 matched events per team per day. |
| Per team | 20 subscriptions, 5 destinations each, 10 open streams, 120 API requests a minute. |
| If Pier is down | Your cursor waits for you, and you can always read Stellar RPC getEvents directly. |
Questions.
What is a position?
Every event Pier stores gets a position: a number that only grows. It is the cursor for pull and streams, the SSE event id, and part of each webhook's id, so you can order and de-duplicate what you receive.
Do I need my own RPC node?
No. Pier reads Stellar RPC for you and matches every event against your filters; you only receive what matches.
What happens when my endpoint is down?
Each event is retried with backoff while other events keep flowing. After 200 failed attempts the destination stops; resume it from the dashboard or the API when you're ready.
Can I keep my API key in a browser app?
No. Keep it on a server. For browser apps, read the stream on your server and pass events on.
Where are the docs?
llms.txt covers the API, filters and destination bodies; the Pier skill walks through wiring events into an app. The npm packages each have a README.
Coming later
Coming later: backfill from the ledger archive and Terraform.
Start on testnet now.
npx pier-cli login