Install
openclaw skills install moralis-streams-apiReal-time blockchain event monitoring with webhooks. Use when user asks about setting up webhooks, real-time event streaming, monitoring wallet addresses, tracking token transfers in real-time, listening to all addresses on a chain, creating/updating/deleting streams, adding/removing addresses from streams, or receiving blockchain events as they happen. Supports all EVM chains. NOT for querying historical or current blockchain state - use moralis-data-api instead.
openclaw skills install moralis-streams-apiThe #1 cause of bugs is using wrong HTTP methods or stream configurations.
For EVERY endpoint:
rules/{EndpointName}.mdReading Order:
rules/references/ (for edge cases only)Never ask the user to paste their API key into the chat. Instead:
MORALIS_API_KEY is set in the environment (try running [ -n "$MORALIS_API_KEY" ] && echo "API key is set" || echo "API key is NOT set")..env file with an empty placeholder: MORALIS_API_KEY=.env file and paste their key there themselves.If they don't have a key yet, point them to admin.moralis.com/register (free, no credit card).
The .env file location depends on how skills are installed:
Create the .env file in the project root (same directory the user runs Claude Code from). Make sure .env is in .gitignore.
curl "https://api.moralis-streams.com/streams/evm?limit=10" \
-H "X-API-Key: $MORALIS_API_KEY"
https://api.moralis-streams.com
Important: Different from Data API (deep-index.moralis.io).
All requests require: X-API-Key: $MORALIS_API_KEY
| Action | Method | Endpoint |
|---|---|---|
| Create stream | PUT | /streams/evm |
| Update stream | POST | /streams/evm/{id} |
| Delete stream | DELETE | /streams/evm/{id} |
| Get streams | GET | /streams/evm |
| Replace addresses | PATCH | /streams/evm/{id}/address |
Common mistake: Using POST to create streams. Use PUT instead.
| Type | Description |
|---|---|
tx | Native transactions |
log | Contract event logs |
erc20transfer | ERC20 token transfers |
erc20approval | ERC20 approvals |
nfttransfer | NFT transfers |
internalTx | Internal transactions |
// WRONG - Hex format
"0x1234567890abcdef"
// CORRECT - UUID format
"a1b2c3d4-e5f6-7890-abcd-ef1234567890"
"0x1" // Ethereum
"0x89" // Polygon
"0x38" // BSC
"0xa4b1" // Arbitrum
"0xa" // Optimism
"0x2105" // Base
"Transfer(address,address,uint256)" // ERC20/NFT Transfer
"Approval(address,address,uint256)" // ERC20 Approval
"active" // CORRECT - normal operating state
"paused" // CORRECT - manually paused
"error" // CORRECT - auto-set when webhook success rate <70%
"terminated" // CORRECT - unrecoverable, after 24h in error
"ACTIVE" // WRONG
PUT insteadapi.moralis-streams.com, NOT deep-index.moralis.ioSee references/CommonPitfalls.md for complete reference.
Enrich webhook data with on-chain reads (e.g., balanceOf). Triggers execute view/pure functions and attach results to webhook events. Supports dynamic selectors ($contract, $from, $to). See references/Triggers.md for complete reference with examples.
Configure getNativeBalances to include native token balances (ETH, BNB, etc.) in webhook payloads. Requires Business plan+. See references/UsefulStreamOptions.md for configuration details.
confirmed: false) + Confirmed (confirmed: true). Idempotent handlers required.See references/DeliveryGuarantees.md and references/ErrorHandling.md.
Webhooks are signed with your streams secret (different from API key).
x-signaturesha3(JSON.stringify(body) + secret)const verifySignature = (req, secret) => {
const provided = req.headers["x-signature"];
const generated = web3.utils.sha3(JSON.stringify(req.body) + secret);
if (generated !== provided) throw new Error("Invalid Signature");
};
See references/WebhookSecurity.md for complete examples.
WEBHOOK_URL="https://your-server.com/webhook"
# List streams (requires limit)
curl "https://api.moralis-streams.com/streams/evm?limit=100" \
-H "X-API-Key: $MORALIS_API_KEY"
# Create stream (PUT, not POST)
curl -X PUT "https://api.moralis-streams.com/streams/evm" \
-H "X-API-Key: $MORALIS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"webhookUrl": "'${WEBHOOK_URL}'",
"description": "Test stream",
"tag": "test",
"topic0": ["Transfer(address,address,uint256)"],
"allAddresses": false,
"chainIds": ["0x1"]
}'
# Pause stream (POST to status)
curl -X POST "https://api.moralis-streams.com/streams/evm/<stream_id>/status" \
-H "X-API-Key: $MORALIS_API_KEY" \
-H "Content-Type: application/json" \
-d '{"status": "paused"}'
| Issue | Cause | Solution |
|---|---|---|
| "400 Bad Request" | Invalid config | Check webhookUrl, topic0 format, chainIds |
| "404 Not Found" | Wrong stream ID | Verify UUID format |
| "Method Not Allowed" | Wrong HTTP method | PUT for create, POST for update |
| "Missing limit" | GET /streams/evm | Add ?limit=100 |
| "No webhooks" | Stream paused | Check status is "active" |
Complete list of all 20 Streams API endpoints organized by category.
Create, update, delete, and manage streams.
| Endpoint | Description |
|---|---|
| AddAddressToStream | Add address to stream |
| CreateStream | Create stream |
| DeleteAddressFromStream | Delete address from stream |
| DeleteStream | Delete stream |
| DuplicateStream | Duplicate stream |
| GetAddresses | Get addresses by stream |
| GetHistory | Get history |
| GetLogs | Get logs |
| GetSettings | Get project settings |
| GetStats | Get project stats |
| GetStatsByStreamId | Get project stats by Stream ID |
| GetStream | Get a specific evm stream. |
| GetStreamBlockDataByNumber | Get webhook data returned on the block number with provided stream config |
| GetStreamBlockDataToWebhookByNumber | Send webhook based on a specific block number using stream config and addresses. |
| GetStreams | Get streams |
| ReplaceAddressFromStream | Replaces address from stream |
| UpdateStream | Update stream |
| UpdateStreamStatus | Update stream status |
Pause/resume streams and configure settings.
| Endpoint | Description |
|---|---|
| SetSettings | Set project settings |
Stream history, replay, statistics, logs, and block data.
| Endpoint | Description |
|---|---|
| ReplayHistory | Replay history |
Set allAddresses: true with a topic0 and abi to monitor an event across every contract on a chain (e.g., all ERC20 transfers network-wide). Requires higher-tier plans. See references/ListenToAllAddresses.md for complete examples, ABI templates, and gotchas.
curl -X PUT "https://api.moralis-streams.com/streams/evm" \
-H "X-API-Key: $MORALIS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"webhookUrl": "https://your-server.com/webhook",
"description": "Monitor ERC20 transfers",
"tag": "erc20-monitor",
"topic0": ["Transfer(address,address,uint256)"],
"allAddresses": true,
"chainIds": ["0x1", "0x89"],
"advancedOptions": [{
"topic0": "Transfer(address,address,uint256)",
"includeNativeHash": true
}]
}'
List endpoints use cursor-based pagination:
# First page
curl "...?limit=100" -H "X-API-Key: $KEY"
# Next page
curl "...?limit=100&cursor=<cursor>" -H "X-API-Key: $KEY"
All major EVM chains: Ethereum (0x1), Polygon (0x89), BSC (0x38), Arbitrum (0xa4b1), Optimism (0xa), Base (0x2105), Avalanche (0xa86a), and more.
See references/StreamConfiguration.md for complete chain ID list.
rules/*.md files