Public API for querying ENS domain data. All endpoints return JSON.
Pass your key via the X-API-Key header. Sign up to get a key with 1,000 free credits.
Pay per request using the MPP protocol. No account needed — pay directly from your wallet.
No authentication is needed to try the API - unauthenticated requests are limited to 5 per minute. Sign up for unlimited access.
/api endpoints. You can call these from any origin.Look up a domain.
Returns domain data with ownership, expiry, resolver, wrapped status, and availability information.
| Name | Type | Description |
|---|---|---|
| name | string | Full ENS name (e.g. vitalik.eth) |
{
"name": "vitalik.eth",
"display": "Vitalik.eth",
"label": "vitalik",
"labelhash": "0xaf2caa1c...",
"token_id": "7960091...",
"namehash": "0xee6c4522...",
"parent_node": "0x93cdeb7...",
"parent_name": "eth",
"expiry_timestamp": "1754000000",
"ownership": {
"is_wrapped": false,
"owner": "0xd8dA6BF2...",
"registry": "0xd8dA6BF2...",
"registrar": "0xd8dA6BF2..."
},
"resolver": {
"status": "indexed",
"chain": "mainnet",
"address": "0x231b0ee1..."
},
"availability_status": "registered",
"query": "vitalik.eth",
"source": "indexed"
}
| Name | Type | Description |
|---|---|---|
| names | string[] | Array of full ENS names (e.g. ["vitalik.eth", "nick.eth"]). Optional if namehashes is provided. |
| namehashes | string[] | Array of namehash hex strings (0x + 64 hex chars). Optional if names is provided. |
At least one of names or namehashes must be provided. Both can be used together in a single request.
{
"names": ["vitalik.eth", "nick.eth"],
"namehashes": ["0xee6c4522aab0003e8d14cd40a6af439055fd2577951148c14b6cea9a53475835"]
}
{
"results": [
{
"query": "vitalik.eth",
"name": "vitalik.eth",
"display": "Vitalik.eth",
"label": "vitalik",
"expiry_timestamp": "1754000000",
"ownership": { "..." },
"resolver": { "..." },
"availability_status": "registered",
"source": "indexed"
},
{
"query": "nonexistent.eth",
"availability_status": "available",
"source": "indexed"
}
],
"summary": {
"total": 2,
"registered": 1,
"grace": 0,
"premium": 0,
"available": 1,
"unknown": 0,
"expiring_30d": 0
}
}
Search domains with filters.
| Name | Type | Description |
|---|---|---|
| q | string | Search query (matches label by default) |
| search_full_name | string | Set to true to search full_name instead of label |
| availability_status | string | Filter: registered, grace, premium, available |
| min_length | integer | Minimum label length |
| max_length | integer | Maximum label length |
| registrar_owner | string | Filter by registrar owner address (exact, case-insensitive) |
| wrapper_owner | string | Filter by wrapper owner address (exact, case-insensitive) |
| registry_owner | string | Filter by registry owner address (exact, case-insensitive) |
| resolver | string | Filter by resolver address (exact, case-insensitive) |
| expiry_from | integer | Minimum expiry (unix timestamp) |
| expiry_to | integer | Maximum expiry (unix timestamp) |
| is_wrapped | string | true or false |
| sort_by | string | full_name (default), label, expiry_timestamp, effective_owner_address |
{
"results": [
{
"name": "vitalik.eth",
"display": "Vitalik.eth",
"label": "vitalik",
"expiry_timestamp": "1754000000",
"ownership": {
"owner": "0xd8dA6BF2...",
"is_wrapped": false
}
}
],
"stats": {
"expired": 12,
"expiring_30d": 3,
"expiring_90d": 8,
"wrapped": 210,
"wrapped_pct": 39.5
},
"total": 532,
"page": 1,
"page_size": 25
}
Get all on-chain events for a domain. Only non-null fields are included in each event object.
| Name | Type | Description |
|---|---|---|
| name | string | Full ENS name (e.g. vitalik.eth) |
{
"events": [
{
"contract": "CONTROLLER_9380470",
"event_type": "NameRegistered",
"block_number": 9380471,
"transaction_hash": "0xabc...",
"owner_address": "0xd8dA6BF2...",
"cost_wei": "3200000000000000",
"expiry_timestamp": "1754000000"
},
{
"contract": "REGISTRY",
"event_type": "NewOwner",
"block_number": 9380471,
"transaction_hash": "0xabc...",
"owner_address": "0xd8dA6BF2..."
}
]
}
List direct subdomains of a domain.
| Name | Type | Description |
|---|---|---|
| name | string | Parent domain name (e.g. vitalik.eth) |
| Name | Type | Description |
|---|---|---|
| sort_by | string | full_name (default) |
{
"domain": "vitalik.eth",
"results": [
{
"name": "sub.vitalik.eth",
"label": "sub",
"expiry_timestamp": null,
"ownership": {
"owner": "0xd8dA6BF2...",
"is_wrapped": false
},
"resolver": {
"address": "0x231b0Ee1..."
}
}
],
"total": 3,
"page": 1,
"page_size": 25
}
Registration and renewal history for a domain.
| Name | Type | Description |
|---|---|---|
| name | string | Full ENS name (e.g. vitalik.eth) |
| merged | string | true (default) merges events from the same transaction; false returns individual events with a contract field |
{
"domain": "vitalik.eth",
"registrations": [
{
"event_type": "NameRegistered",
"block_number": 9380471,
"transaction_hash": "0xabc...",
"cost_wei": "3200000000000000",
"cost_eth": "0.003200",
"expiry_timestamp": "1754000000",
"owner_address": "0xd8dA..."
}
],
"renewals": []
}
Returns current resolver records for a domain: text records, multi-chain addresses, and contenthash.
| Name | Type | Description |
|---|---|---|
| name | string | Full ENS name (e.g. vitalik.eth) |
| Name | Type | Description |
|---|---|---|
| types | string | Comma-separated: text, addr, contenthash (default: all) |
{
"domain": "vitalik.eth",
"resolver": {
"status": "indexed",
"chain": "mainnet",
"address": "0x231b0ee1..."
},
"records": {
"texts": {
"com.twitter": "VitalikButerin",
"avatar": "eip155:1/..."
},
"addresses": {
"60": "0xd8dA6BF2..."
},
"contenthash": null
},
"source": "indexed"
}
Look up a single text record for a domain.
| Name | Type | Description |
|---|---|---|
| name | string | Full ENS name (e.g. vitalik.eth) |
| key | string | Text record key (e.g. com.x, avatar) |
{
"domain": "vitalik.eth",
"resolver": {
"status": "indexed",
"chain": "mainnet",
"address": "0x231b0ee1..."
},
"key": "com.x",
"value": "VitalikButerin",
"block_number": 18500000,
"transaction_hash": "0xabc...",
"source": "indexed"
}
Effective ownership history for a domain, derived from on-chain events.
Returns ownership periods with the resolved effective owner at each point in time.
| Name | Type | Description |
|---|---|---|
| name | string | Full ENS name (e.g. vitalik.eth) |
| audit | string | true to include per-contract breakdown (registry, registrar, wrapper arrays). Default false |
{
"history": [
{
"address": "0xd8dA6BF2...",
"reason": "registrar",
"from_block": 9500000,
"from_tx": "0xdef456...",
"to_block": null,
"to_tx": null
}
]
}
Resolver change history derived from stored on-chain events. Each entry represents a period where a specific resolver contract was active for the domain.
| Name | Type | Description |
|---|---|---|
| name | string | Full ENS name (e.g. vitalik.eth) |
{
"history": [
{
"address": "0x4976fb03...",
"from_block": 9412610,
"from_tx": "0xdef456...",
"to_block": 16773775,
"to_tx": "0x789abc..."
},
{
"address": "0x231b0Ee1...",
"from_block": 16773775,
"from_tx": "0x789abc...",
"to_block": null,
"to_tx": null
}
]
}
Change history for a specific text record. Only includes changes from the domain's active resolver at the time - records set on non-active resolvers are excluded. Resolver changes are included as null-value boundaries.
| Name | Type | Description |
|---|---|---|
| name | string | Full ENS name (e.g. vitalik.eth) |
| key | string | Text record key (e.g. avatar, com.twitter) |
{
"domain": "vitalik.eth",
"key": "avatar",
"history": [
{
"value": "eip155:1/...",
"block_number": 18500000,
"resolver": "0x231b0ee1...",
"source": "indexed",
"transaction_hash": "0xabc..."
},
{
"value": null,
"block_number": 16773775,
"source": "resolver_change"
},
{
"value": "old-avatar",
"block_number": 15000000,
"resolver": "0x4976fb03...",
"source": "indexed",
"transaction_hash": "0xdef..."
}
]
}
Each entry's source indicates provenance:
indexed - from an on-chain TextChanged eventresolver_change - the resolver changed, invalidating the previous valuelive - current value from live on-chain resolutionLook up a domain by any hash. Tries namehash first (unique match), then falls back to labelhash (may match multiple domains).
| Name | Type | Description |
|---|---|---|
| hash | string | A 66-character hex string (0x + 64 hex chars) |
{
"type": "namehash",
"name": "vitalik.eth",
"display": "Vitalik.eth",
"label": "vitalik",
"token_id": "7960091...",
"namehash": "0xee6c4522...",
"labelhash": "0xaf2caa1c...",
"parent_name": "eth",
"parent_node": "0x93cdeb7...",
"expiry_timestamp": "1754000000",
"ownership": {
"owner": "0xd8dA6BF2...",
"is_wrapped": false
},
"resolver": {
"status": "indexed",
"chain": "mainnet",
"address": "0x231b0ee1..."
}
}
{
"type": "labelhash",
"domains": [
{
"name": "vitalik.eth",
"display": "Vitalik.eth",
"label": "vitalik",
"token_id": "7960091...",
"namehash": "0xee6c4522...",
"labelhash": "0xaf2caa1c...",
"parent_name": "eth",
"parent_node": "0x93cdeb7...",
"expiry_timestamp": "1754000000",
"ownership": {
"owner": "0xd8dA6BF2...",
"is_wrapped": false
},
"resolver": {
"status": "indexed",
"chain": "mainnet",
"address": "0x231b0ee1..."
}
}
]
}
{
"hash": "0xee6c4522...",
"indexed": false
}
Look up a single domain by its namehash. Returns full domain details including ownership, resolver, and wrapped status.
| Name | Type | Description |
|---|---|---|
| hash | string | Namehash - a 66-character hex string (0x + 64 hex chars) |
{
"name": "vitalik.eth",
"display": "Vitalik.eth",
"label": "vitalik",
"token_id": "7960091...",
"namehash": "0xee6c4522...",
"labelhash": "0xaf2caa1c...",
"parent_name": "eth",
"parent_node": "0x93cdeb7...",
"expiry_timestamp": "1754000000",
"ownership": {
"owner": "0xd8dA6BF2...",
"registry": "0xd8dA6BF2...",
"registrar": "0xd8dA6BF2...",
"is_wrapped": false
},
"resolver": {
"status": "indexed",
"chain": "mainnet",
"address": "0x231b0ee1..."
}
}
Look up domains by labelhash. A labelhash can match multiple domains across different parent names (e.g. vitalik.eth and vitalik.xyz share the same labelhash).
| Name | Type | Description |
|---|---|---|
| hash | string | Labelhash - a 66-character hex string (0x + 64 hex chars) |
{
"domains": [
{
"name": "vitalik.eth",
"display": "Vitalik.eth",
"label": "vitalik",
"token_id": "7960091...",
"namehash": "0xee6c4522...",
"labelhash": "0xaf2caa1c...",
"parent_name": "eth",
"parent_node": "0x93cdeb7...",
"expiry_timestamp": "1754000000",
"ownership": {
"owner": "0xd8dA6BF2...",
"is_wrapped": false
},
"resolver": {
"status": "indexed",
"chain": "mainnet",
"address": "0x231b0ee1..."
}
}
],
"total": 1,
"page": 1,
"page_size": 25
}
Is this ENS name an ERC-8004 agent?
We consider a name an agent when it has an on-chain binding in the Adapter8004 adapter.
The Integrating ENS Agents guide covers the trust model and how to render the profile safely.
| Name | Type | Description |
|---|---|---|
| name | string | Full ENS name (e.g. enswhois.eth) |
| Field | Type | Description |
|---|---|---|
| profile | object | The agent's ENSIP-26 records: context (agent-context) and endpoints.mcp/a2a/web. Self-asserted - treat as untrusted. |
| registrations[] | array | An array (for forward-compatability) of agent registration data. |
{
"name": "enswhois.eth",
"display": "ENSWhois.eth",
"namehash": "0x75aca3b6...",
"owner": "0xac50ce32...",
"is_wrapped": false,
"expiry_timestamp": 1812548051,
"is_expired": false,
"avatar": "https://...",
"profile": {
"context": "Agentic interface to ENSWhois.com...",
"endpoints": {
"mcp": "https://mcp.enswhois.com/mcp",
"a2a": null,
"web": "https://enswhois.com/"
}
},
"registrations": [
{
"registry": {
"caip10": "eip155:1:0x8004A169FB4a3325136EB29fA0ceB6D2e539a432",
"erc7930": "0x000100000101148004a169fb4a3325136eb29fa0ceb6d2e539a432"
},
"agent_id": "34339",
"has_ensip25_registration": true,
"is_bound": true,
"binding": {
"adapter": "0xde152afb7db5373f34876e1499fbd893a82dd336",
"token_standard": 0,
"token_contract": "0x57f1887a8bf19b14fc0df6fd9b2acc9af147ea85",
"token_id": "1073289...",
"token_uri": "https://...",
"agent_owner": "0xac50ce32...",
"registered_block": 25280217,
"registered_at": "2026-06-09T13:37:59.000Z",
"registered_by": "0xac50ce32..."
}
}
]
}
This endpoint returns all ENS agents. We consider a name an agent when it has an on-chain binding in the Adapter8004 adapter.
The Integrating ENS Agents guide covers the trust model and how to render the profile safely.
| Name | Type | Description |
|---|---|---|
| page | integer | Page number (25 per page) |
| q | string | Filter by name substring |
| sort | string | registered (default) or name |
| dir | string | asc or desc |
| has | string | Comma-separated filters: mcp, a2a, web, context (record presence), and ensip25 (has a valid conformant ENSIP-25 registration) |
{
"agents": [
{
"name": "enswhois.eth",
"display": "ENSWhois.eth",
"namehash": "0x75aca3b6...",
"owner": "0xac50ce32...",
"is_wrapped": false,
"expiry_timestamp": 1812548051,
"is_expired": false,
"avatar": "https://...",
"profile": {
"context": "Agentic interface to ENSWhois.com...",
"endpoints": { "mcp": "https://...", "a2a": null, "web": "https://..." }
},
"registrations": [
{
"registry": {
"caip10": "eip155:1:0x8004A169FB4a3325136EB29fA0ceB6D2e539a432",
"erc7930": "0x000100000101148004a169fb4a3325136eb29fa0ceb6d2e539a432"
},
"agent_id": "34339",
"has_ensip25_registration": true,
"is_bound": true,
"binding": {
"adapter": "0xde152afb...",
"token_standard": 0,
"token_contract": "0x57f1887a...",
"token_id": "1073289...",
"token_uri": null,
"agent_owner": null,
"registered_block": 25280217,
"registered_at": "2026-06-09T13:37:59.000Z",
"registered_by": "0xac50ce32..."
}
}
]
}
],
"total": 49,
"page": 1,
"page_size": 25
}
profile data safely, and the three integration patterns.