Appearance
IPNS — Mutable Names for IPFS
IPNS (InterPlanetary Name System) gives you stable, shareable addresses that can be updated to point to different content over time. While IPFS CIDs change every time content changes, an IPNS name stays the same — you just update where it points.
Available on Bodhi (3 names, 100 publishes/mo) and Nirvana (10 names, 1,000 publishes/mo) plans.
Learn more about IPNS
For a deep dive into how IPNS works at the protocol level, see the official IPFS documentation on IPNS.

Why use IPNS?
The problem: Every time you upload a new version of a file to IPFS, you get a different CID. If you shared the old CID with users, they still see the old content. You'd have to share a new link every time.
The solution: Create an IPNS name once, share it, and update what it points to whenever your content changes. Anyone with the IPNS address always gets the latest version.
Common use cases
- Websites on IPFS — Deploy your site, get a CID, publish it to your IPNS name. Redeploy → new CID → update the IPNS name. The URL never changes.
- NFT metadata that evolves — Point your NFT's
tokenURIto an IPNS address. Update the metadata (e.g., game item levels up) without changing the smart contract. - Configuration files — Your app reads config from an IPNS address. Update the config without redeploying the app.
- Data feeds — Publish daily datasets or price feeds under a stable IPNS address.
- DNSLink — Connect your domain to IPNS so
https://yourdomain.comalways serves the latest IPFS content.
Using the Dashboard
1. Create an IPNS name
- Go to IPNS in the sidebar under Hosting.
- Click Create name.
- Enter a label (e.g., "my-website") and click Create.
- Copy the IPNS address (starts with
k51...) — this is your permanent, shareable address.

2. Publish a CID to your IPNS name
- Find the IPNS name in the list and click Publish.
- Enter the CID you want it to point to (e.g.,
QmXk7VRz...orbafybei...). - Click Publish. This propagates to the IPFS network and may take up to 60 seconds.
- Once published, the content is accessible at:
- IPFS gateway:
https://ipfs.ninja/ipns/{your-ipns-name} - Any public gateway:
https://dweb.link/ipns/{your-ipns-name} - IPFS native:
ipns://{your-ipns-name}
- IPFS gateway:

3. Update your content
When your content changes:
- Upload the new version to IPFS (via dashboard or API) → get a new CID.
- Go back to IPNS, click Publish on the same name, enter the new CID.
- The IPNS address stays the same — anyone using it automatically gets the new content.
4. Resolve an IPNS name
Use the Resolve section at the bottom of the page to look up the current CID for any IPNS name — yours or anyone else's.
5. Delete an IPNS name
Click the delete button next to any name. The IPNS record will expire from the network within 48 hours.
Connecting a Domain with DNSLink
You can point your own domain name to an IPNS address using DNSLink. This lets users access your IPFS content through a regular URL like https://yourdomain.com.
How to set up DNSLink
Create an IPNS name and publish your content CID to it (steps above).
Add a DNS TXT record at your domain's DNS provider:
_dnslink.yourdomain.com TXT "dnslink=/ipns/{your-ipns-name}"Example: If your IPNS name is
k51qzi5uqu5djcpbukxs...:_dnslink.myapp.com TXT "dnslink=/ipns/k51qzi5uqu5djcpbukxs..."Verify the record using dig or nslookup:
bashdig +short TXT _dnslink.myapp.com # Should return: "dnslink=/ipns/k51qzi5uqu5djcpbukxs..."Access via any IPFS gateway that supports DNSLink:
https://ipfs.ninja/ipns/myapp.comOr via a browser with IPFS support (like Brave):
ipns://myapp.com
DNS propagation
DNS changes can take up to 24 hours to propagate globally. After adding the TXT record, wait a few hours before testing.
TIP
You only need to set up DNSLink once. When you publish a new CID to your IPNS name, the domain automatically resolves to the new content — no DNS changes needed.
DNSLink with Cloudflare
If you use Cloudflare:
- Go to DNS → Records.
- Add a new record: Type: TXT, Name:
_dnslink, Content:dnslink=/ipns/k51... - Set proxy status to DNS only (gray cloud).
DNSLink with Route 53
- Go to your hosted zone in Route 53.
- Create a record: Name:
_dnslink.yourdomain.com, Type: TXT, Value:"dnslink=/ipns/k51..."
Usage Examples
Example 1: Static website deployment
bash
# 1. Build your site
npm run build
# 2. Upload the build output to IPFS
CID=$(curl -s -X POST https://api.ipfs.ninja/upload/new \
-H "X-Api-Key: bws_your_api_key" \
-H "Content-Type: application/json" \
-d "{\"content\": $(cat dist/index.html | base64 -w0 | jq -Rs .), \"description\": \"Website v2.1\"}" \
| jq -r '.cid')
echo "Uploaded: $CID"
# 3. Update your IPNS name to point to the new build
curl -X POST https://api.ipfs.ninja/ipns/publish \
-H "X-Api-Key: bws_your_api_key" \
-H "Content-Type: application/json" \
-d "{\"ipnsName\": \"k51qzi5uqu5dlvj2bv6...\", \"cid\": \"$CID\"}"
# Your site at ipns://k51... now serves the new versionExample 2: Mutable NFT metadata
javascript
// Smart contract points tokenURI to IPNS address:
// tokenURI = "ipns://k51qzi5uqu5dlvj2bv6..."
// When the NFT evolves (e.g., game item levels up):
const newMetadata = {
name: "Dragon Sword",
description: "A legendary weapon — Level 5",
image: "ipfs://QmNewImageCID...",
attributes: [
{ trait_type: "Level", value: 5 },
{ trait_type: "Damage", value: 150 }
]
};
// Upload new metadata
const uploadRes = await fetch("https://api.ipfs.ninja/upload/new", {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-Api-Key": "bws_your_api_key"
},
body: JSON.stringify({ content: newMetadata, description: "Dragon Sword v5" })
});
const { cid } = await uploadRes.json();
// Update the IPNS pointer — tokenURI stays the same!
await fetch("https://api.ipfs.ninja/ipns/publish", {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-Api-Key": "bws_your_api_key"
},
body: JSON.stringify({ ipnsName: "k51qzi5uqu5dlvj2bv6...", cid })
});Example 3: CI/CD integration
yaml
# GitHub Actions: auto-publish to IPNS on every push
- name: Upload to IPFS and publish IPNS
run: |
CID=$(curl -s -X POST https://api.ipfs.ninja/upload/new \
-H "X-Api-Key: ${{ secrets.IPFS_NINJA_API_KEY }}" \
-H "Content-Type: application/json" \
-d '{"content": '"$(cat build/output.json)"', "description": "Deploy ${{ github.sha }}"}' \
| jq -r '.cid')
curl -X POST https://api.ipfs.ninja/ipns/publish \
-H "X-Api-Key: ${{ secrets.IPFS_NINJA_API_KEY }}" \
-H "Content-Type: application/json" \
-d '{"ipnsName": "${{ vars.IPNS_NAME }}", "cid": "'"$CID"'"}'API Reference
All API examples use the X-Api-Key header. Get your API key from the API Keys page.
List IPNS Keys
bash
curl https://api.ipfs.ninja/ipns/keys \
-H "X-Api-Key: bws_your_api_key_here"Response:
json
[
{
"ipnsName": "k51qzi5uqu5dlvj2bv6...",
"keyName": "my-website",
"currentCid": "bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdi",
"lastPublishedAt": 1711123200000,
"publishCountMonth": 12,
"status": "active",
"createdAt": 1711036800000
}
]Create IPNS Key
bash
curl -X POST https://api.ipfs.ninja/ipns/keys \
-H "X-Api-Key: bws_your_api_key_here" \
-H "Content-Type: application/json" \
-d '{"name": "my-website"}'Response 201:
json
{
"ipnsName": "k51qzi5uqu5dlvj2bv6...",
"keyName": "my-website",
"createdAt": 1711036800000
}Publish to IPNS
Publishing updates the IPNS name to point to a new CID. This propagates to the IPFS DHT and may take up to 60 seconds.
bash
curl -X POST https://api.ipfs.ninja/ipns/publish \
-H "X-Api-Key: bws_your_api_key_here" \
-H "Content-Type: application/json" \
-d '{"ipnsName": "k51qzi5uqu5dlvj2bv6...", "cid": "bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdi"}'Response:
json
{
"ipnsName": "k51qzi5uqu5dlvj2bv6...",
"cid": "bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdi",
"published": true
}Resolve IPNS Name
Look up the current CID for any IPNS name.
bash
curl https://api.ipfs.ninja/ipns/resolve/k51qzi5uqu5dlvj2bv6... \
-H "X-Api-Key: bws_your_api_key_here"Response:
json
{
"ipnsName": "k51qzi5uqu5dlvj2bv6...",
"cid": "bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdi"
}Delete IPNS Key
bash
curl -X DELETE https://api.ipfs.ninja/ipns/keys/k51qzi5uqu5dlvj2bv6... \
-H "X-Api-Key: bws_your_api_key_here"Response:
json
{ "success": true }How IPNS Works
- Key generation: When you create an IPNS name, a cryptographic keypair (Ed25519) is generated. The public key hash becomes your IPNS address (
k51...). - Publishing: When you publish, you sign a record saying "this name points to CID X" and broadcast it to the IPFS DHT (Distributed Hash Table).
- Resolution: When someone looks up your IPNS name, IPFS nodes query the DHT for the latest signed record and follow it to the CID.
- Republishing: IPNS records expire after 48 hours. IPFS Ninja automatically republishes your records every 12 hours to keep them alive.
- Security: Only the private key holder (you) can update what an IPNS name points to. No one else can hijack your name.
Plan Limits
| Plan | IPNS Names | Publishes / Month |
|---|---|---|
| Dharma (Free) | Not available | — |
| Bodhi ($5/mo) | 3 | 100 |
| Nirvana ($29/mo) | 10 | 1,000 |
- Records are automatically republished every 12 hours to keep them alive on the IPFS network.
- Names not published to for 90 days are marked as inactive and stop being republished.
- Inactive names can be reactivated by publishing a new CID to them.
Further Reading
- IPNS Concepts — IPFS Docs — Official documentation on how IPNS works at the protocol level
- DNSLink — IPFS Docs — Connecting domain names to IPFS/IPNS content
- Content Addressing — Understanding CIDs and why IPNS solves the mutability problem
