Alchemy API Integration
Alchemy is not just an RPC provider. Beyond reliable node access (with automatic failover and 99.9% uptime SLA), they offer Enhanced APIs that solve problems normally requiring your own indexer: address transaction history, NFT data, token balances, decoded event logs. Proper Alchemy integration eliminates the need to run your own node for most dApps.
Setup and Keys
Alchemy SDK for TypeScript/JavaScript is the preferred interaction method:
npm install alchemy-sdk
import { Alchemy, Network, AlchemySettings } from "alchemy-sdk"
const settings: AlchemySettings = {
apiKey: process.env.ALCHEMY_API_KEY,
network: Network.ETH_MAINNET,
maxRetries: 5,
requestTimeout: 30000
}
const alchemy = new Alchemy(settings)
SDK automatically manages retry logic and rate limiting. For multiple chains—separate instances with different network values.
Enhanced APIs: What's Really Useful
NFT API
Getting all address NFTs without Alchemy means parsing Transfer events from genesis or depending on marketplace API. With Alchemy:
// All wallet NFTs
const nfts = await alchemy.nft.getNftsForOwner("0xAddress", {
contractAddresses: ["0xOptionalFilter"],
omitMetadata: false
})
// Owner of specific token
const owners = await alchemy.nft.getOwnersForNft(contractAddress, tokenId)
// All tokens in collection with metadata
const collection = await alchemy.nft.getNftsForContract(contractAddress, {
pageSize: 100
})
Token API
// All ERC-20 balances of address
const balances = await alchemy.core.getTokenBalances("0xAddress")
// Token metadata
const metadata = await alchemy.core.getTokenMetadata("0xTokenAddress")
// { name, symbol, decimals, logo }
Transaction History
eth_getTransactionByHash returns one transaction. For complete address transaction history, standard JSON-RPC has no method—this is one pain point without Enhanced APIs:
const history = await alchemy.core.getAssetTransfers({
fromAddress: "0xAddress",
category: ["external", "erc20", "erc721", "erc1155"],
withMetadata: true,
maxCount: 100
})
Result includes decoded transfers with amounts, token symbols, and addresses—ready for UI display.
Alchemy Notify: Webhooks
Polling is a poor way to watch on-chain events. Alchemy Notify is a webhook service that sends POST to your endpoint when an event occurs:
// Create webhook via Notify API
const webhook = await alchemy.notify.createWebhook(
"https://your-api.com/webhooks/alchemy",
WebhookType.ADDRESS_ACTIVITY,
{
addresses: ["0xWatchedAddress"],
network: Network.ETH_MAINNET
}
)
Webhook types: ADDRESS_ACTIVITY (any address activity), NFT_ACTIVITY (NFT Transfer events), MINED_TRANSACTION, DROPPED_TRANSACTION.
Webhook signature verification:
import { isValidWebhookSignature } from "alchemy-sdk"
app.post("/webhooks/alchemy", express.raw({ type: "application/json" }), (req, res) => {
const isValid = isValidWebhookSignature({
body: req.body.toString(),
signature: req.headers["x-alchemy-signature"] as string,
signingKey: process.env.ALCHEMY_WEBHOOK_SIGNING_KEY!
})
if (!isValid) return res.status(401).send("Unauthorized")
const event = JSON.parse(req.body.toString())
handleAlchemyEvent(event)
res.sendStatus(200)
})
WebSocket Subscription
For real-time data in browser or Node.js service:
// Subscribe to new blocks
alchemy.ws.on("block", (blockNumber) => {
console.log("New block:", blockNumber)
})
// Subscribe to pending transactions for specific address
alchemy.ws.on(
{ method: "alchemy_pendingTransactions", toAddress: contractAddress },
(tx) => handlePendingTx(tx)
)
// Subscribe to contract events
const filter = {
address: contractAddress,
topics: [ethers.id("Transfer(address,address,uint256)")]
}
alchemy.ws.on(filter, handleTransferEvent)
SDK automatically recovers WebSocket connection on break and skips missed events through polling.
Rate Limits and Optimization
Free plan: 300 compute units/sec. Each call costs different CU: eth_blockNumber—10 CU, eth_getTransactionReceipt—15 CU, alchemy_getAssetTransfers—150 CU.
Batching RPC requests via JSON-RPC batch:
// Parallel requests without extra HTTP round-trips
const [balance, nonce, gasPrice] = await Promise.all([
alchemy.core.getBalance("0xAddress"),
alchemy.core.getTransactionCount("0xAddress"),
alchemy.core.getGasPrice()
])
Promise.all at SDK level doesn't do HTTP-level batching—these are separate requests. For true batching via JSON-RPC batch, use low-level fetch directly to RPC endpoint.
Timeline
Basic SDK integration with NFT API, token balances, and webhook setup—1 business day. Including environment setup (mainnet + testnet), error handling, and rate limit monitoring.







