Skip to main content

Contenthash Resolution

Resolve ENS names to decentralized content on IPFS, Arweave, Swarm, and other protocols.

Try it Live

Open in Swagger UI → to test these endpoints interactively.

Endpoints

EndpointDescriptionPrice
GET /api/ens/:name/contenthashGet contenthash$0.005
GET /api/ens/:name/contentResolve to URL$0.005
GET /api/contenthash/decode/:hashDecode contenthashFREE
GET /api/contenthash/encodeEncode contenthashFREE

GET /api/ens/:name/contenthash

Get the raw contenthash for an ENS name.

Request

curl https://api.web3identity.com/api/ens/vitalik.eth/contenthash

Response

{
"name": "vitalik.eth",
"contenthash": "0xe3010170122029f2d17be6139079dc48696d1f582a8530eb9805b561eda517e22a892c7e3f1f",
"protocol": "ipfs",
"decoded": "ipfs://QmRAQB6YaCyidP37UdDnjFY5vQuiBrcqdyoW1CuDgwxkD4",
"gateway": "https://vitalik.eth.limo"
}

Supported Protocols

ProtocolPrefixExample
IPFSipfs://ipfs://Qm...
IPNSipns://ipns://k51...
Arweavear://ar://abc123...
Swarmbzz://bzz://abc123...
Oniononion://onion://abc123.onion
Onion3onion3://onion3://abc123.onion

GET /api/ens/:name/content

Get the resolved content URL for an ENS name.

Request

curl https://api.web3identity.com/api/ens/vitalik.eth/content

Response

{
"name": "vitalik.eth",
"protocol": "ipfs",
"hash": "QmRAQB6YaCyidP37UdDnjFY5vQuiBrcqdyoW1CuDgwxkD4",
"url": "https://vitalik.eth.limo",
"gateways": [
"https://vitalik.eth.limo",
"https://ipfs.io/ipfs/QmRAQB6YaCyidP37UdDnjFY5vQuiBrcqdyoW1CuDgwxkD4",
"https://cloudflare-ipfs.com/ipfs/QmRAQB6YaCyidP37UdDnjFY5vQuiBrcqdyoW1CuDgwxkD4"
]
}

Query Parameters

ParamTypeDefaultDescription
gatewaystringeth.limoPreferred gateway
formatstringurlurl, raw, or decoded

GET /api/contenthash/decode/:hash

Decode a contenthash bytes string.

Request

curl "https://api.web3identity.com/api/contenthash/decode/0xe3010170122029f2d17be6139079dc48696d1f582a8530eb9805b561eda517e22a892c7e3f1f"

Response

{
"contentHash": "0xe3010170122029f2d17be6139079dc48696d1f582a8530eb9805b561eda517e22a892c7e3f1f",
"protocol": "ipfs",
"protocolType": "ipfs-ns",
"decoded": "ipfs://QmRAQB6YaCyidP37UdDnjFY5vQuiBrcqdyoW1CuDgwxkD4",
"hash": "QmRAQB6YaCyidP37UdDnjFY5vQuiBrcqdyoW1CuDgwxkD4"
}

GET /api/contenthash/encode

Encode a content URL to contenthash format.

Query Parameters

ParamTypeRequiredDescription
urlstringYesContent URL to encode

Request

curl "https://api.web3identity.com/api/contenthash/encode?url=ipfs://QmRAQB6YaCyidP37UdDnjFY5vQuiBrcqdyoW1CuDgwxkD4"

Response

{
"url": "ipfs://QmRAQB6YaCyidP37UdDnjFY5vQuiBrcqdyoW1CuDgwxkD4",
"protocol": "ipfs",
"contenthash": "0xe3010170122029f2d17be6139079dc48696d1f582a8530eb9805b561eda517e22a892c7e3f1f",
"length": 38
}

SDK Examples

JavaScript

import { Web3IdentityClient } from '@web3identity/sdk';

const client = new Web3IdentityClient();

// Get contenthash
const content = await client.getContenthash('vitalik.eth');
console.log(content.decoded); // ipfs://Qm...

// Resolve to gateway URL
const url = await client.resolveContent('vitalik.eth');
console.log(url); // https://vitalik.eth.limo

// Decode contenthash
const decoded = await client.decodeContenthash(
'0xe3010170122029f2d17be6139079dc48696d1f582a8530eb9805b561eda517e22a892c7e3f1f'
);
console.log(decoded.protocol); // "ipfs"

// Encode to contenthash
const encoded = await client.encodeContenthash('ipfs://QmRAQB6...');
console.log(encoded.contenthash); // 0xe301...

React Hook

import { useState, useEffect } from 'react';

function useENSContent(ensName: string) {
const [content, setContent] = useState<string | null>(null);
const [loading, setLoading] = useState(true);

useEffect(() => {
const fetchContent = async () => {
const res = await fetch(
`https://api.web3identity.com/api/ens/${ensName}/content`
);
const data = await res.json();
setContent(data.url);
setLoading(false);
};

fetchContent();
}, [ensName]);

return { content, loading };
}

// Usage
function ENSWebsite({ name }: { name: string }) {
const { content, loading } = useENSContent(name);

if (loading) return <div>Loading...</div>;
if (!content) return <div>No website set</div>;

return (
<iframe
src={content}
title={`${name} website`}
width="100%"
height="600"
/>
);
}

Python

from web3identity import Client

client = Client()

# Get contenthash
content = client.get_contenthash('vitalik.eth')
print(f"Protocol: {content['protocol']}")
print(f"URL: {content['decoded']}")

# Resolve to gateway
url = client.resolve_content('vitalik.eth', gateway='ipfs.io')
print(f"Gateway URL: {url}")

# Decode contenthash
decoded = client.decode_contenthash('0xe301017012...')
print(f"Decoded: {decoded['decoded']}")

cURL Examples

# Get contenthash
curl https://api.web3identity.com/api/ens/vitalik.eth/contenthash

# Get resolved URL
curl https://api.web3identity.com/api/ens/vitalik.eth/content

# Decode contenthash
curl "https://api.web3identity.com/api/contenthash/decode/0xe301..."

# Encode URL
curl "https://api.web3identity.com/api/contenthash/encode?url=ipfs://Qm..."

# Use custom gateway
curl "https://api.web3identity.com/api/ens/vitalik.eth/content?gateway=ipfs.io"

Gateway Options

Public IPFS Gateways

GatewayURL FormatSpeedReliability
eth.limoname.eth.limoFastHigh
ipfs.ioipfs.io/ipfs/hashMediumHigh
Cloudflarecloudflare-ipfs.com/ipfs/hashFastVery High
Pinatagateway.pinata.cloud/ipfs/hashFastHigh

Custom Gateway Usage

// Prefer specific gateway
const content = await fetch(
'https://api.web3identity.com/api/ens/vitalik.eth/content?gateway=pinata'
);

// Or construct gateway URL manually
const decoded = await client.getContenthash('vitalik.eth');
const hash = decoded.hash;
const customUrl = `https://my-gateway.com/ipfs/${hash}`;

Setting Contenthash

To set a contenthash for your ENS name, use the ENS Manager or Web3 library:

Via ENS Manager

  1. Go to app.ens.domains
  2. Select your name
  3. Click "Add/Edit Record"
  4. Select "Content" tab
  5. Enter your IPFS hash or URL

Via ethers.js

import { ethers } from 'ethers';
import contentHash from '@ensdomains/content-hash';

const provider = new ethers.providers.Web3Provider(window.ethereum);
const signer = provider.getSigner();

// Encode IPFS hash to contenthash
const encoded = contentHash.encode('ipfs-ns', 'QmRAQB6...');

// Get resolver
const resolver = await provider.getResolver('yourname.eth');

// Set contenthash
const tx = await resolver.setContenthash(encoded);
await tx.wait();

console.log('Contenthash updated!');

Via Web3 Identity API (Coming Soon)

# Future endpoint
POST /api/ens/yourname.eth/contenthash
Authorization: Bearer YOUR_API_KEY
Content-Type: application/json

{
"contenthash": "ipfs://QmRAQB6..."
}

Use Cases

Decentralized Website Hosting

Host your website on IPFS and link via ENS:

# 1. Upload to IPFS
ipfs add -r ./dist
# Added QmRAQB6...

# 2. Set contenthash
# Via ENS Manager: ipfs://QmRAQB6...

# 3. Access via ENS
# https://yourname.eth.limo

NFT Metadata

Link ENS names to NFT collections:

// Get collection metadata
const metadata = await client.getContenthash('coolnfts.eth');
const metadataUrl = metadata.gateways[0];

const response = await fetch(metadataUrl);
const collectionData = await response.json();

Decentralized Apps

Point ENS to your dApp hosted on IPFS:

yourapp.eth → ipfs://QmHash → https://yourapp.eth.limo

Users can access via:

  • ENS-enabled browsers (Brave, Opera)
  • eth.limo gateway
  • IPFS gateway
  • Local IPFS node

Error Handling

Common Errors

ErrorCauseSolution
NO_CONTENTHASHName has no contenthash setSet contenthash via ENS Manager
INVALID_CONTENTHASHMalformed contenthash bytesCheck encoding
UNSUPPORTED_PROTOCOLProtocol not supportedUse ipfs, ipns, ar, bzz, or onion
GATEWAY_TIMEOUTGateway not respondingTry different gateway parameter

Error Response

{
"error": true,
"code": "NO_CONTENTHASH",
"message": "This ENS name does not have a contenthash set"
}

Performance Tips

Caching

Gateway URLs can be cached safely:

const cache = new Map();

async function getCachedContent(ensName) {
if (cache.has(ensName)) {
return cache.get(ensName);
}

const response = await fetch(
`https://api.web3identity.com/api/ens/${ensName}/content`
);
const data = await response.json();

// Cache for 1 hour
cache.set(ensName, data.url);
setTimeout(() => cache.delete(ensName), 3600000);

return data.url;
}

Prefer eth.limo

For best performance and ENS integration:

// ✅ Good - Uses optimized ENS gateway
const url = `https://${ensName}.eth.limo`;

// ⚠️ Slower - Generic IPFS gateway
const url = `https://ipfs.io/ipfs/${hash}`;


Resources