Forward Resolution
Resolve an ENS name into its address(es) and records. Given vitalik.eth, returns the address behind it, the avatar, the Twitter handle, and any other record. For the opposite direction (address → name), see Reverse Resolution
Endpoint
GET /ens/v2/resolveBase URL: https://api.justaname.id
Quick start
The endpoint is free when you supply your own RPC URL via the rpcUrl query parameter. No API key required. Rate-limited to 30 requests per 60 seconds per IP.
curl "https://api.justaname.id/ens/v2/resolve?ens=vitalik.eth&rpcUrl=https://eth.drpc.org"const url = new URL('https://api.justaname.id/ens/v2/resolve');
url.searchParams.append('ens', 'vitalik.eth');
url.searchParams.append('rpcUrl', process.env.RPC_URL!);
const res = await fetch(url);The caller's RPC pays for the on-chain reads. JustaName performs resolution through the ENS Universal Resolver with CCIP-Read support and returns the decoded records.
Autonomous clients without an RPC URL (AI agents, MCP servers, scripts) can pay per-request in USDC on Base instead of supplying
rpcUrl. See Programmatic access without an RPC URL.
Parameters
ens
string (repeatable)
Yes
ENS name to resolve. Repeat to batch up to 50 names (?ens=a.eth&ens=b.eth). Append @<chain> to scope to a single chain — see Interop addresses
rpcUrl
string
See below
HTTPS RPC URL used to perform the on-chain resolution.
Either rpcUrl must be present or the request must carry a valid payment header. Without either, the endpoint returns 402 with a payment challenge — see Programmatic access without an RPC URL.
Interop addresses
By default, resolution returns every address attached to the name across every chain in records.addresses. To scope the result to a single chain, append a chain suffix to the name:
vitalik.eth
Returns all addresses on all chains
vitalik.eth@ethereum
Returns only the Ethereum address
vitalik.eth@eip155:1
Returns only the Ethereum address
Both the human-readable chain name and the CAIP-2 form (eip155:<chainId>) are accepted. The suffix is per-name, so a batch can mix scoped and unscoped lookups:
When a suffix is present, records.addresses contains at most one entry — the address for the requested chain, or an empty array if the name has no record for that chain.
RPC URL requirements
Must be HTTPS.
Private, loopback, and link-local hosts are rejected.
Embedded credentials (
https://user:pass@host) are rejected.
Response
Returns a single object when one ens is requested, or an array (in input order, null for hard-failed slots) when multiple are requested.
Single name
Batch
Behavior
Resolution is performed through the on-chain ENS Universal Resolver with CCIP-Read support.
The caller supplies the RPC URL — the service does not pay for the on-chain reads.
Batch failures are localized: a hard-failed slot becomes
nullwhile the rest succeed.Unregistered names do not return
null. Wildcard resolvers return an object withrecords.addresses: [].Duplicate names in a batch are not deduplicated — each slot is resolved independently.
viaUniversalResolver: trueconfirms the ENSv2-ready resolver path was used.
Reading records
Pull the L1 wallet, avatar, and a social handle from a batch result:
Errors
400
rpcUrl not HTTPS, has embedded credentials, or resolves to a private/loopback host.
400
ens array empty or > 50 entries.
429
Rate limit (30 req / 60 s per IP) exceeded. Body includes retryAfterSeconds.
502 / 504
RPC provider error or CCIP-Read gateway timeout.
Payment-related statuses (402, 503) are documented in the paid path section.
Programmatic access without an RPC URL
For clients that don't manage their own RPC infrastructure — AI agents, MCP servers, autonomous scripts — the endpoint accepts per-request payment in place of rpcUrl. The service performs the on-chain reads and charges the caller in USDC on Base.
Two protocols are accepted on the same route. Clients pick whichever fits their stack:
x402 v2 — Coinbase's HTTP-payment protocol. See x402.org.
MPP-charge — IETF Internet-Draft
draft-httpauth-payment-00with EVM methoddraft-evm-charge-00. Co-authored by Tempo Labs and Stripe.
Both protocols settle identically — a signed EIP-3009 transferWithAuthorization submitted by a facilitator on Base. They differ only in HTTP envelope.
Chain
Base mainnet (eip155:8453)
Asset
USDC (0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913)
Price
1000 base units per request (0.001 USDC at 6 decimals)
402 challenge
A request without rpcUrl and without a payment header receives both challenges in one response. The headers are disjoint, so they coexist:
Decoded PAYMENT-REQUIRED (x402 v2):
Decoded WWW-Authenticate request= (MPP draft-evm-charge-00):
Paying
Sign an EIP-3009 transferWithAuthorization against the USDC contract on Base (e.g. viem's signTypedData with primaryType: "TransferWithAuthorization" and a fresh 32-byte nonce). Wrap the signed message in either envelope and retry the request:
x402 v2
PAYMENT-SIGNATURE: <base64 JSON>
PAYMENT-RESPONSE: <base64 JSON>
MPP-charge
Authorization: Payment <base64url-nopad JSON>
Payment-Receipt: <base64url-nopad JSON>
The facilitator submits the on-chain tx and pays gas — the payer only needs USDC, not ETH.
Idempotency, replay, validity
Set
Idempotency-Key: <uuid>on every retry. Without it, each retry is a fresh payment.(nonce, recipient)is locked in a 5-minute LRU. Always sign with a fresh randomnonce.validBeforeshould be ~10 min fromnow(). Longer windows risk re-sending stale signatures past expiry.A retriable failure (facilitator transient error) returns
503+Retry-After. Repeat the same request.A non-retriable failure (malformed payload, replay, network/asset mismatch) returns a fresh
402with the reason in the challenge.
Discovery
GET /ens/v2/pricing(free) — JSON list of paid routes:{ path, method, schemes, amount, asset, network, recipient }.GET /.well-known/x402.json(free) — x402 manifest (services[]+accepts[]) for catalog crawlers (Bazaar, x402scan).GET /openapi.json— OpenAPI document. Each paid operation carriesx-payment-info: { offers: [{ amount, currency, description, intent, method }] }perdraft-payment-discovery-00.
Payment-path errors
402
Request lacks rpcUrl and no payment header was supplied. PAYMENT-REQUIRED and WWW-Authenticate carry the challenge.
402
Payment proof was malformed, replayed, expired, or targeted the wrong network/asset.
503
Facilitator transient error during verify/settle. Retry-After set; repeat the same request.
Last updated