Developer Docs
Resolve nimimo handles to blockchain addresses from any app, website, or service. One endpoint, three chains, zero authentication required.
How it works
Every nimimo user has a human-readable handle like @neat-gecko. Behind that handle are receiving addresses for Bitcoin, Ethereum, and Solana. The resolution API lets you look up those addresses programmatically so your users can send to a name instead of a raw address.
Public
No API key or auth required
Cross-origin
CORS enabled for browser use
Rate limited
30 requests per 60 seconds
Base URL
https://nimimo.com/api/v1All endpoints are versioned. The current version is v1.
Endpoints
/resolve?handle={handle}Resolve a handle to all registered addresses
/resolve?handle={handle}&chain={chain}Resolve a handle to a specific chain address
bitcoin, ethereum, solanaTry it
Test the API right here. The default handle neat-gecko is a real nimimo identity — hit send and see the live response.
Resolve all chains
GET https://nimimo.com/api/v1/resolve?handle=neat-gecko{
"handle": "neat-gecko",
"addresses": {
"bitcoin": "bc1qz3yaratxc9z6wz2pj2k97nzl00l4cucpvcquq9",
"ethereum": "0x874a40B1857B006d46b80c9e6badCEF3BA3B705C",
"solana": "9rhN3eug2LbqZKCtbkGRKjRq9BVa4Y5VE4Puf2p4HCRk"
}
}Resolve a single chain
GET https://nimimo.com/api/v1/resolve?handle=neat-gecko&chain=bitcoin{
"handle": "neat-gecko",
"chain": "bitcoin",
"address": "bc1qz3yaratxc9z6wz2pj2k97nzl00l4cucpvcquq9"
}Quick start
async function resolveHandle(handle) {
const res = await fetch(
`https://nimimo.com/api/v1/resolve?handle=${handle}`
)
if (!res.ok) throw new Error("Resolution failed")
return res.json()
}
const { addresses } = await resolveHandle("neat-gecko")
console.log(addresses.bitcoin)
// "bc1qz3yaratxc9z6wz2pj2k97nzl00l4cucpvcquq9"import requests
def resolve_handle(handle, chain=None):
params = {"handle": handle}
if chain:
params["chain"] = chain
r = requests.get("https://nimimo.com/api/v1/resolve", params=params)
r.raise_for_status()
return r.json()
result = resolve_handle("neat-gecko")
print(result["addresses"]["ethereum"])
# "0x874a40B1857B006d46b80c9e6badCEF3BA3B705C"curl "https://nimimo.com/api/v1/resolve?handle=neat-gecko"
# Single chain
curl "https://nimimo.com/api/v1/resolve?handle=neat-gecko&chain=solana"Error responses
All errors return a JSON object with error and message fields.
| Status | Error | Meaning |
|---|---|---|
| 400 | invalid_handle | Handle is malformed or empty |
| 400 | invalid_chain | Chain not supported (use bitcoin, ethereum, or solana) |
| 404 | not_found | Handle does not exist |
| 404 | no_address | Handle exists but has no address for the requested chain |
| 429 | — | Rate limit exceeded (30 req / 60s) |
{
"error": "not_found",
"message": "Handle not found"
}Handle format
Handles are lowercase alphanumeric strings with optional hyphens. They always start with a letter. When displayed to users, prefix with @.
neat-geckolucky-mountain-42123-badCool-WaterRate limiting
The resolution API allows 30 requests per 60 seconds per IP address. Rate limit headers are included in every response:
X-RateLimit-Limit: 30
X-RateLimit-Remaining: 28
X-RateLimit-Reset: 1712073600000If you need higher limits for production integrations, reach out to us.
TypeScript SDK
The official SDK wraps the resolution API with typed responses, automatic retries, caching, and payment helpers. Zero dependencies, ~3KB gzipped, dual ESM/CJS.
npm install @nimimo/resolveInitialize
import { NimimoClient } from "@nimimo/resolve"
const nimimo = new NimimoClient()
// Optional: custom config
const nimimo = new NimimoClient({
baseUrl: "https://nimimo.com/api/v1", // default
cacheTtl: 30_000, // 30s in-memory cache (default)
})Resolve handles
const { handle, addresses } = await nimimo.resolve("neat-gecko")
console.log(addresses.bitcoin)
// "bc1qz3yaratxc9z6wz2pj2k97nzl00l4cucpvcquq9"
console.log(addresses.ethereum)
// "0x874a40B1857B006d46b80c9e6badCEF3BA3B705C"
console.log(addresses.solana)
// "9rhN3eug2LbqZKCtbkGRKjRq9BVa4Y5VE4Puf2p4HCRk"const { address } = await nimimo.resolve("neat-gecko", "bitcoin")
// "bc1qz3yaratxc9z6wz2pj2k97nzl00l4cucpvcquq9"const results = await nimimo.resolveMany(["neat-gecko", "lucky-mountain"])
// [
// { handle: "neat-gecko", addresses: { bitcoin: "bc1q...", ... } },
// { handle: "lucky-mountain", addresses: { bitcoin: "bc1q...", ... } }
// ]const exists = await nimimo.exists("neat-gecko") // true
const nope = await nimimo.exists("nonexistent") // falsePayment intents
Generate wallet-ready payment objects from a handle. The SDK resolves the address and converts the amount to the chain's native unit (wei, satoshis, lamports). You sign with whatever wallet you already use.
const intent = await nimimo.paymentIntent("neat-gecko", {
chain: "ethereum",
amount: "0.05", // ETH
})
// intent = {
// to: "0x874a40B1857B006d46b80c9e6badCEF3BA3B705C",
// value: "50000000000000000", // wei
// chain: "ethereum",
// handle: "neat-gecko",
// }
// Use with ethers.js
await signer.sendTransaction({ to: intent.to, value: intent.value })
// Use with wagmi/viem
await sendTransaction({ to: intent.to, value: intent.value })const intent = await nimimo.paymentIntent("neat-gecko", {
chain: "bitcoin",
amount: "0.001", // BTC
})
// intent.to → "bc1qz3yaratxc9z6wz2pj2k97nzl00l4cucpvcquq9"
// intent.value → "100000" (satoshis)Pay URLs
Generate shareable payment links. No SDK needed on the receiving end — the link opens the nimimo profile with a pre-filled payment flow.
const url = nimimo.payUrl("neat-gecko", {
chain: "ethereum",
amount: "0.05",
})
// "https://nimimo.com/@neat-gecko?pay=0.05&chain=ethereum"
// Drop it in an invoice, a bio, or a chat message.
// Anyone who clicks it can pay from any wallet.Error handling
import { NimimoClient, HandleNotFound, NoAddress, RateLimited } from "@nimimo/resolve"
try {
const result = await nimimo.resolve("nonexistent-handle")
} catch (err) {
if (err instanceof HandleNotFound) {
console.log("Handle doesn't exist")
} else if (err instanceof NoAddress) {
console.log("No address for this chain")
} else if (err instanceof RateLimited) {
console.log("Too many requests — SDK auto-retries with backoff")
}
}SDK features
- Full TypeScript types for all responses and errors
- Automatic retry with exponential backoff on 429
- In-memory cache with configurable TTL (default 30s)
- Batch resolution for multiple handles in one call
- Payment intents with unit conversion (ETH to wei, BTC to sat, SOL to lamports)
- Pay URL generation for zero-code payment links
- Typed error classes:
HandleNotFound,NoAddress,InvalidHandle,InvalidChain,RateLimited - ~3KB gzipped, zero dependencies, dual ESM/CJS
Use cases
Payment integrations
Let users pay to a @handle instead of copying a raw address. Resolve the handle, show the address, and initiate the transaction.
Contact books
Store nimimo handles as contacts and resolve addresses on demand. Addresses update automatically when users rotate keys.
Verification
Verify that a given blockchain address belongs to a specific nimimo identity via reverse lookup.
Multi-chain apps
Resolve a single handle to Bitcoin, Ethereum, and Solana addresses simultaneously. No chain selection needed from the user.
This API is provided as-is. nimimo reserves the right to adjust rate limits or deprecate endpoints with reasonable notice.