# ENS Resolver — Name to Address, Reverse Lookup, Avatar (`yadroo/ens-resolver`) Actor

Resolve Ethereum Name Service names to addresses and addresses to primary ENS names, with avatar, text records (email, url, twitter, github, description) and content hash. Bulk. Built for agent identity checks. No API key.

- **URL**: https://apify.com/yadroo/ens-resolver.md
- **Developed by:** [Samat Makatov](https://apify.com/yadroo) (community)
- **Categories:** Developer tools, AI
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.40 / 1,000 result items

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

Resolve Ethereum Name Service names in bulk: `name.eth` → address, address → primary name, with avatar, social handles,
any text record, multi-chain addresses, contenthash, registration/expiry dates and on-chain events. Also lists every
name an address owns and looks names up in the ENS index by label. Built for identity checks, CRM enrichment and
domain monitoring. Uses public Ethereum RPC and the Blockscout ENS index (enstate.rs only as a fallback) — no API key,
no proxy, no browser.

### Use cases

- **Counterparty identity check** — confirm that `acme.eth` really belongs to the wallet you are about to pay (`isPrimaryName`, `reverse_record_mismatch`).
- **CRM / lead enrichment** — turn a list of wallet addresses into ENS names, Twitter, GitHub, website and email.
- **Portfolio of names** — list every ENS name owned by or pointing to your treasury address, with expiry dates.
- **Renewal alerts** — daily run over your brand names; flag `expires_within_30d`, `expired_in_grace_period`.
- **Brand checks** — is your brand registered as an ENS name, who owns it and when does it expire (`uniswap` → `uniswap.eth`).
- **Cross-chain payouts** — read BTC / Solana / Base / Arbitrum address records set on a name before sending funds.

### Input

| Field | Type | Default | Allowed values / notes |
|---|---|---|---|
| `mode` | string | `resolve` | `resolve` (one item per query), `ownedBy` (one item per name owned by / resolving to an address), `search` (one item per registered name: an exact lookup of the label, `uniswap` → `uniswap.eth`, not a keyword search). Apify refuses any other value before the run starts, with the list of allowed values. |
| `queries` | string\[] | — (required) | `resolve`: ENS names (incl. subnames, `name.base.eth`, `name.cb.id`) and/or 0x addresses. `ownedBy`: 0x addresses (anything else is listed in `SUMMARY.errors`). `search`: a label or a full name (`uniswap`, `app.uniswap.eth`). Duplicates are looked up (and billed) once, compared after ENS normalisation: `Vitalik.ETH` = `vitalik.eth`, an address in any letter case, `uniswap` = `uniswap.eth` in search. |
| `textRecords` | string\[] | `avatar, url, email, com.twitter, com.github, description` | Any text-record key, or shortcuts `*standard`, `*services`, `*all` (see Reference); an unknown `*shortcut` fails the run with a suggestion |
| `coinTypes` | string\[] | `[]` | Keys from the coin-type table below (any letter case) or a numeric SLIP-44 coin type. An unknown key fails the run with a suggestion and the list of valid keys. |
| `includeRegistration` | boolean | `true` | Owner, registrant, wrapped owner, registration/expiry dates, days to expiry, grace period, resolver, NFT token id |
| `includeContenthash` | boolean | `true` | IPFS / IPNS / Arweave / Swarm contenthash, read from the name's resolver and returned as a URI |
| `verifyReverse` | boolean | `true` | For names: check the resolved address's primary name → `isPrimaryName` |
| `includeEvents` | boolean | `false` | Recent ENS events (registration, renewals, transfers, record updates) with tx hashes |
| `eventsLimit` | integer | `20` | 1–100 |
| `expiresWithinDays` | integer | `30` | 0–3650; adds flag `expires_within_<N>d` |
| `lookupOwnedBy` | boolean | `true` | `ownedBy`: include names owned (or wrapped-owned) by the address |
| `lookupResolvedTo` | boolean | `true` | `ownedBy`: include names whose ETH record points to the address |
| `onlyActive` | boolean | `true` | `ownedBy` / `search`: skip expired names |
| `maxNamesPerQuery` | integer | `50` | 1–500; the index is read 100 names per page, page after page up to this cap |
| `fields` | string\[] | `[]` | Keep only these top-level fields, in your order. `query`, `name`, `address`, `found`, `fetchedAt` are always kept and come first unless you list them. Letter case is forgiven; an unknown name fails the run with a suggestion; a field that only the other mode's rows have is left out with a note. |
| `rpcUrls` | JSON array | — | Your own Ethereum mainnet JSON-RPC URLs, tried before the public ones (optional, for large batches). A **secret** input: stored encrypted and never written to the log or `SUMMARY`, because such URLs usually carry a provider key. A malformed entry fails the run (its position is named, not its text). |

### Reference

#### Text-record shortcuts

| Shortcut | Keys |
|---|---|
| `*standard` | `avatar`, `description`, `display`, `email`, `keywords`, `mail`, `notice`, `location`, `phone`, `url`, `header`, `name` |
| `*services` | `com.twitter`, `com.github`, `com.discord`, `org.telegram`, `com.reddit`, `com.linkedin`, `com.youtube`, `io.keybase`, `eth.ens.delegate`, `com.farcaster`, `xyz.farcaster`, `com.instagram`, `com.warpcast`, `xyz.lens` |
| `*all` | both lists |

Any other key (e.g. `org.discourse`, `snapshot`) can be passed literally. Global keys are defined in [ENSIP-5](https://docs.ens.domains/ensip/5).

#### Coin types (`coinTypes`, ENSIP-9 / ENSIP-11)

| Key | Coin type | Chain |
|---|---|---|
| `btc` | 0 | Bitcoin |
| `ltc` | 2 | Litecoin |
| `doge` | 3 | Dogecoin |
| `eth` | 60 | Ethereum |
| `atom` | 118 | Cosmos |
| `xrp` | 144 | XRP |
| `trx` | 195 | Tron |
| `dot` | 354 | Polkadot |
| `sol` | 501 | Solana |
| `bnb` | 714 | BNB Beacon Chain |
| `optimism` | 2147483658 | OP Mainnet (EVM 10) |
| `bsc` | 2147483704 | BNB Smart Chain (EVM 56) |
| `gnosis` | 2147483748 | Gnosis (EVM 100) |
| `polygon` | 2147483785 | Polygon (EVM 137) |
| `zksync` | 2147483972 | ZKsync Era (EVM 324) |
| `base` | 2147492101 | Base (EVM 8453) |
| `arbitrum` | 2147525809 | Arbitrum One (EVM 42161) |
| `avalanche` | 2147526762 | Avalanche C-Chain (EVM 43114) |
| `linea` | 2147542792 | Linea (EVM 59144) |
| `scroll` | 2148018000 | Scroll (EVM 534352) |

EVM chains use `0x80000000 | chainId`; any other SLIP-44 number can be passed as a numeric string.

#### Flags (`flags[]`, mode=resolve)

| Flag | Meaning |
|---|---|
| `not_registered` | `.eth` name unknown to RPC and to the ENS index — such a name has nothing to return, so it is not an item: it is listed in `SUMMARY.notFound` |
| `no_forward_resolution` | Name exists but has no ETH address record |
| `no_primary_name` | Address has no reverse (primary) name — with nothing else resolved it is listed in `SUMMARY.notFound` instead of being an item |
| `reverse_record_mismatch` | Name points to an address whose primary name is a different name — treat as unverified identity |
| `no_reverse_record` | Name points to an address that has no primary name |
| `expires_within_<N>d` | Expires within `expiresWithinDays` |
| `expired_in_grace_period` / `expired` | Expired less / more than 90 days ago |
| `owner_differs_from_resolved_address` | Controller/owner is not the address the name points to |
| `wrapped_name`, `offchain_name`, `subname` | NameWrapper name; offchain (CCIP-read) name; subdomain |

### Examples

**1. Verify a payee before sending funds**

```json
{ "queries": ["nick.eth", "vitalik.eth"], "verifyReverse": true, "includeRegistration": true, "textRecords": ["url", "com.twitter"] }
```

**2. Enrich a list of wallet addresses for CRM**

```json
{ "queries": ["0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045", "0xb8c2C29ee19D8307cb7255e1Cd9CbDE883A267d5"], "textRecords": ["*standard", "*services"], "includeContenthash": false, "fields": ["reverseName", "twitter", "github", "url", "email", "description", "completeness"] }
```

**3. All names owned by our treasury, with expiry**

```json
{ "mode": "ownedBy", "queries": ["0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"], "lookupResolvedTo": false, "onlyActive": false, "maxNamesPerQuery": 100 }
```

**4. Renewal monitor with a 60-day window**

```json
{ "queries": ["uniswap.eth", "ens.eth"], "expiresWithinDays": 60, "textRecords": ["url"], "verifyReverse": false, "fields": ["registration", "flags"] }
```

**5. Brand check: is the name registered, by whom, until when**

```json
{ "mode": "search", "queries": ["uniswap", "app.uniswap.eth"], "onlyActive": false }
```

**6. Cross-chain payout addresses**

```json
{ "queries": ["vitalik.eth"], "coinTypes": ["btc", "sol", "base", "arbitrum"], "textRecords": ["avatar"] }
```

### Output

`mode: "resolve"` — one item per query (trimmed real example):

```json
{
  "query": "vitalik.eth", "kind": "name", "name": "vitalik.eth", "address": "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045",
  "found": true, "isPrimaryName": true, "reverseName": "vitalik.eth",
  "avatar": "https://euc.li/vitalik.eth", "avatarUrl": "https://euc.li/vitalik.eth",
  "header": "https://pbs.twimg.com/profile_banners/295218901/1638557376/1500x500", "display": null,
  "description": "mi pinxe lo crino tcati", "url": "https://vitalik.ca", "email": null,
  "twitter": "VitalikButerin", "github": "vbuterin", "discord": null, "telegram": null, "farcaster": null, "lens": null,
  "texts": { "avatar": "https://euc.li/vitalik.eth", "url": "https://vitalik.ca", "description": "mi pinxe lo crino tcati", "com.twitter": "VitalikButerin", "com.github": "vbuterin" },
  "addresses": {},
  "contenthash": "ipfs://bafybeigqyo555suvqi3scc2izft3mozskktbtkzs2xghoe2rpxetxbbdiq", "resolver": "0x231b0Ee14048e9dCcD1d247744d114a4EB5E8E63",
  "registration": { "owner": "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045", "registeredAt": "2017-06-18T08:39:14.000Z", "expiresAt": "2048-04-30T00:13:44.000Z", "daysToExpiry": 7880, "isExpired": false, "inGracePeriod": false, "isWrapped": false, "tokenId": "79233663829379634837589865448569342784712482819484549289560981379859480642508", "…": "…" },
  "events": [], "completeness": 85, "flags": [], "warnings": [], "sources": ["rpc", "bens"],
  "ensAppUrl": "https://app.ens.domains/vitalik.eth", "fetchedAt": "2026-10-02T19:09:22.058Z"
}
```

| Field | Description |
|---|---|
| `kind` | `name`, `address` or `invalid` |
| `name`, `address`, `found` | Normalized ENS name, resolved/queried address; `found` = both known (`false` only for a registered name without an address record, which still carries registration / records) |
| `isPrimaryName`, `reverseName` | Reverse-record verification (see flags) |
| `avatar`, `avatarUrl`, `header` | Raw avatar record and a fetchable URL (ipfs:// and NFT avatars mapped to gateways / ENS metadata service); the `header` (banner) record |
| `display`, `description`, `url`, `email`, `twitter`, `github`, `discord`, `telegram`, `farcaster`, `lens` | Common records, handles cleaned of URL prefixes and `@` |
| `query`, `fetchedAt` | The query as typed (trimmed); when the row was read (UTC) |
| `texts` | All requested text records that are set |
| `addresses` | Requested multi-chain address records (`null` when not set) |
| `contenthash`, `resolver` | Decentralised website hash as a URI (`ipfs://` CIDv1, `ipns://`, `bzz://`, `ar://`; an unknown namespace as raw hex); resolver contract |
| `registration` | Registration & expiry object (`null` if disabled or not indexed) |
| `events` | Recent ENS events: `txHash`, `timestamp`, `from`, `fromName`, `action` |
| `completeness` | 0–100 profile score (address, avatar, description, url, email, socials, contenthash, extra addresses) |
| `ensAppUrl` | Link to the name in the ENS app |
| `flags`, `warnings`, `sources` | Triage flags; failed sub-lookups (the row is still delivered); which sources answered (`rpc`, `bens`, `enstate`) |

`mode: "ownedBy"` / `"search"` — one item per name: `query`, `relation` (`owned`, `resolved_to`, `owned_and_resolved`; `null` in search), `name`, `address`, `owner`, `wrappedOwner`, `registeredAt`, `expiresAt`, `daysToExpiry`, `isExpired`, `inGracePeriod`, `isSubname`, `protocol`, `ensAppUrl`, `source`, `fetchedAt`. A query with no matches is not an item (not charged): it is listed in `SUMMARY.notFound`.

### Use it from code / agents

```bash
curl -X POST "https://api.apify.com/v2/acts/yadroo~ens-resolver/run-sync-get-dataset-items?token=$APIFY_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{"queries":["vitalik.eth","0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"]}'
```

```js
import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('yadroo/ens-resolver').call({ queries: ['vitalik.eth'], coinTypes: ['btc', 'sol'] });
const { items } = await client.dataset(run.defaultDatasetId).listItems();
```

```python
from apify_client import ApifyClient
client = ApifyClient(token)
run = client.actor("yadroo/ens-resolver").call(run_input={"mode": "ownedBy", "queries": ["0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"]})
items = client.dataset(run["defaultDatasetId"]).list_items().items
```

MCP: add `https://mcp.apify.com` to your MCP client (Claude, Cursor, …) and call the `yadroo/ens-resolver` tool with the same JSON.

### Pricing

Pay per event: **$0.001 per run start + $0.002 per dataset item**. Bronze −10 %, Silver −20 %, Gold and above −30 % on the item price; the start event is the same on every plan; platform usage is included. In `resolve` mode that is one item per query: resolving 100 names or addresses costs $0.201. In `ownedBy` / `search` every returned name is an item, so cap it with `maxNamesPerQuery` (e.g. an address with 50 names = $0.101). Queries with no result, invalid queries, duplicates and failed lookups are not dataset items and cost nothing — see `SUMMARY`.

The run never goes over your **Maximum cost per run**: it stops before the first item it could not pay for, ends with the status "Stopped at your spending limit: N rows delivered", and lists the queries it did not get to in `SUMMARY.notProcessed`.

### Limits & FAQ

- **Sources** — forward/reverse resolution, text and address records and the contenthash come from public Ethereum RPC nodes (ENS Universal Resolver, with fallback across several providers); registration, events, `ownedBy` and `search` come from the Blockscout ENS index (BENS). enstate.rs is asked only when an RPC record lookup failed, and is skipped for the rest of the run after two failures in a row.
- **Speed & capacity** — about 1.3–1.8 s per name in `resolve` mode with public RPCs and the default options (two runs of 334 names on Apify on 02.10.2026 took 7 and 10 minutes), so the default 15-minute run fits about 400–600 names; every extra coin type, text key or `includeEvents` adds a little. The run stops starting new queries shortly before its timeout (90 s before the default 15 minutes), saves what it has, ends SUCCEEDED with "Stopped before the run timeout" and lists the queries it did not get to in `SUMMARY.notProcessed`: run those again, or raise the run timeout. `ownedBy` / `search` read the index 100 names per page. Public RPCs rate-limit large batches; failed sub-lookups are listed in `warnings` and the item is still delivered. For large lists pass your own node in `rpcUrls`.
- **Restarts** — if Apify migrates or restarts the run, it continues after the last finished query; no item is stored or billed twice.
- **Freshness** — RPC data is live; the ENS index lags the chain by minutes.
- **Offchain names** (`*.cb.id`, `*.base.eth`, other CCIP-read names) resolve via RPC; registration data may be missing for them.
- **Search** is an exact lookup in the index: a bare label (`uniswap`, `uniswap.eth`) is checked under every TLD the index knows for Ethereum, a longer name (`app.uniswap.eth`) as given. It does not find names that merely contain the word.
- **Errors** — Apify refuses an off-list `mode` before the run starts. An unknown coin type, text-record shortcut or field name, a malformed `rpcUrls` entry or an empty `queries` list fails the run at once with a message that names it. Per-query problems never stop the run and are never charged: the `SUMMARY` record lists invalid names/addresses and failed lookups under `errors` (with a reason that says what is wrong: wrong length, non-hex character, missing TLD, which lookup failed) and queries with nothing to return under `notFound` (unregistered names, addresses without a primary name, no matches), with `errorCount` / `notFoundCount`. A query is reported as not found only when the sources answered; when a lookup failed it is an error. The run fails only when it saved no item and at least one query failed; a run where every query was simply not found succeeds with 0 items.
- **SUMMARY record** — `delivered` (items saved, also as `items`), `errors` / `errorCount`, `notFound` / `notFoundCount`, `notProcessed` / `notProcessedCount` (queries a stop left out), `queriesDone`, `duplicatesRemoved`, `notes` (input corrections), `stoppedBy` (`limit`, `timeout`, `aborted` or null) and the final `status`. Lists hold the first 100 entries; the counts are exact.
- **Address checksum** — mixed-case addresses must pass the EIP-55 checksum. A failed checksum almost always means a typo, so the query is rejected (`0x address fails the EIP-55 checksum`) instead of silently resolving a different wallet. All-lowercase addresses skip the check.
- **Roadmap** — L2 primary names (ENSIP-19), name history diffs for monitoring.

***

Made by **Yadroo**. Siblings: [wallet-intel](https://apify.com/yadroo/wallet-intel) · [base-token-intel](https://apify.com/yadroo/base-token-intel) · [dexscreener-tokens](https://apify.com/yadroo/dexscreener-tokens) · [bitcoin-mempool](https://apify.com/yadroo/bitcoin-mempool) · [x402-endpoints](https://apify.com/yadroo/x402-endpoints)

# Actor input Schema

## `mode` (type: `string`):

`resolve` = names → addresses and addresses → primary names, with profile records, multi-chain addresses, registration/expiry (one item per query). `ownedBy` = list every ENS name owned by / resolving to each address (one item per name). `search` = look a name up in the ENS index by its label: `uniswap` finds uniswap.eth — an exact lookup under every TLD the index knows, not a prefix or keyword search (one item per registered name). Apify refuses any other value before the run starts.

## `queries` (type: `array`):

For `resolve`: ENS names (vitalik.eth, sub.name.eth, offchain names like name.cb.id / name.base.eth) and/or 0x addresses. For `ownedBy`: 0x addresses. For `search`: a label or full name (e.g. "uniswap", "app.uniswap.eth"). Duplicates are looked up once, compared after ENS normalisation (`Vitalik.ETH` = `vitalik.eth`; addresses in any letter case). The default 15-minute run resolves about 400–600 names; the rest is listed in SUMMARY.notProcessed (see README → Limits).

## `textRecords` (type: `array`):

Text-record keys to read. Shortcuts: `*standard` (ENSIP-5 global keys: avatar, description, display, email, keywords, mail, notice, location, phone, url, header, name), `*services` (com.twitter, com.github, com.discord, org.telegram, com.reddit, com.linkedin, com.youtube, io.keybase, com.farcaster, xyz.lens…), `*all`. An unknown `*shortcut` fails the run with a suggestion. Empty = avatar, url, email, com.twitter, com.github, description.

## `coinTypes` (type: `array`):

Additional address records to read (ENSIP-9/11). Keys (any letter case): btc, ltc, doge, eth, atom, xrp, trx, sol, bnb, dot, optimism, bsc, gnosis, polygon, zksync, base, arbitrum, avalanche, linea, scroll — or a numeric SLIP-44 coin type. An unknown key fails the run with the list of valid keys. Empty = none (the ETH address is always returned in `address`).

## `includeRegistration` (type: `boolean`):

Owner, registrant, wrapped owner, registration date, expiry date, days to expiry, grace-period status, resolver, NFT token id (from the Blockscout ENS index).

## `includeContenthash` (type: `boolean`):

IPFS/IPNS/Arweave/Swarm content hash of the name (decentralised website), read from the name's resolver and returned as a URI (ipfs://…, ipns://…, bzz://…, ar://…).

## `verifyReverse` (type: `boolean`):

For name queries, also check that the resolved address has this name as its primary (reverse) name → `isPrimaryName`, flags `reverse_record_mismatch` / `no_reverse_record`. Important for identity checks: anyone can point a name at any address, only the address owner can set the reverse record.

## `includeEvents` (type: `boolean`):

Recent ENS events for the name (registration, renewals, transfers, record updates) with tx hashes.

## `eventsLimit` (type: `integer`):

Maximum events per name (mode=resolve with includeEvents).

## `expiresWithinDays` (type: `integer`):

Adds flag `expires_within_<N>d` when the name expires within this many days.

## `lookupOwnedBy` (type: `boolean`):

mode=ownedBy: include names whose owner (or wrapped owner) is the address.

## `lookupResolvedTo` (type: `boolean`):

mode=ownedBy: include names whose ETH address record points to the address.

## `onlyActive` (type: `boolean`):

mode=ownedBy / search: skip expired names.

## `maxNamesPerQuery` (type: `integer`):

Cap on names returned per address (ownedBy) or label (search); each name is one dataset item. The ENS index is read 100 names per page, page after page up to this cap.

## `fields` (type: `array`):

Keep only these top-level fields, in this order (query, name, address, found, fetchedAt are always kept and come first unless you list them). Letter case is forgiven; an unknown name fails the run with a suggestion; a field only the other mode's rows have is left out with a note.

## `rpcUrls` (type: `array`):

Your own mainnet JSON-RPC endpoints as a JSON array, e.g. \["https://mainnet.example/v2/<key>"], tried before the built-in public ones. Stored encrypted (secret input) because such URLs usually carry a provider key; never shown in logs or SUMMARY. Useful for large batches (public nodes rate-limit).

## Actor input object example

```json
{
  "mode": "resolve",
  "queries": [
    "vitalik.eth",
    "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"
  ],
  "textRecords": [
    "avatar",
    "url",
    "email",
    "com.twitter",
    "com.github",
    "description"
  ],
  "coinTypes": [],
  "includeRegistration": true,
  "includeContenthash": true,
  "verifyReverse": true,
  "includeEvents": false,
  "eventsLimit": 20,
  "expiresWithinDays": 30,
  "lookupOwnedBy": true,
  "lookupResolvedTo": true,
  "onlyActive": true,
  "maxNamesPerQuery": 50,
  "fields": []
}
```

# Actor output Schema

## `results` (type: `string`):

No description

## `summary` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "queries": [
        "vitalik.eth",
        "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"
    ],
    "textRecords": [
        "avatar",
        "url",
        "email",
        "com.twitter",
        "com.github",
        "description"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("yadroo/ens-resolver").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "queries": [
        "vitalik.eth",
        "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045",
    ],
    "textRecords": [
        "avatar",
        "url",
        "email",
        "com.twitter",
        "com.github",
        "description",
    ],
}

# Run the Actor and wait for it to finish
run = client.actor("yadroo/ens-resolver").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "queries": [
    "vitalik.eth",
    "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045"
  ],
  "textRecords": [
    "avatar",
    "url",
    "email",
    "com.twitter",
    "com.github",
    "description"
  ]
}' |
apify call yadroo/ens-resolver --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,yadroo/ens-resolver"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/fdBlJBTIgtiKc6R2J/builds/fo2OdLLR3UDJWVQdR/openapi.json
