Pin any CID with a single API call. Free tier, no credit card. Connect your wallet and start building.
curl -X POST https://9522f1f0cb3e394a.dyndns.dappnode.io/pins \
-H "Authorization: Bearer YOUR_API_KEY" \
-d '{"cid": "QmYourContentHash"}'
Three steps. No KYC. No credit card. Just pin.
Enter your email, get an API key instantly.
curl -X POST https://api.netrix.ai/v1/keys \
-H "Content-Type: application/json" \
-d '{"email": "you@example.com"}'
Grab the client library (or use raw curl).
npm install @netrix/ipfs-client
or skip the SDK entirely — curl works fine.
Push any CID to IPFS in one call.
curl -X POST https://api.netrix.ai/pin \
-d '{"cid":"QmYourCid"}' \
-H "X-API-Key: YOUR_KEY"
That's it. Your content is pinned and served from our IPFS gateway. Get your free key →
Three commands. That's it. Go from zero to pinned in under a minute.
Generate a free API key with one command. No signup needed.
curl -X POST https://9522f1f0cb3e394a.dyndns.dappnode.io/v1/keys \
-H "Content-Type: application/json"
Response:
{
"key": "ipfs_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6",
"tier": "free",
"storage": "100 MB"
}
Upload any file directly to IPFS and pin it in one call.
curl -X POST https://9522f1f0cb3e394a.dyndns.dappnode.io/upload \
-H "Authorization: Bearer YOUR_API_KEY" \
-F "file=@./my-image.png"
Response:
{
"cid": "QmYwAPJzv5CZsnA625s3Xf2nemtYgPpHdWEz79ojWnPbdG",
"size": 24576,
"pinned": true
}
List all your pinned content and verify everything is stored.
curl https://9522f1f0cb3e394a.dyndns.dappnode.io/pins \
-H "Authorization: Bearer YOUR_API_KEY"
Response:
{
"count": 1,
"results": [{
"requestid": "req_abc123",
"status": "pinned",
"pin": {
"cid": "QmYwAPJzv5CZsnA625s3Xf2nemtYgPpHdWEz79ojWnPbdG",
"name": "my-image.png",
"size": 24576
}
}]
}
No gatekeepers. No paperwork. Just pin.
No email, no identity verification, no corporate onboarding. Wallet-based auth only. Your data, your rules.
Pay with ETH on Base. No credit cards, no invoices, no fiat rails. Direct on-chain payments, instant provisioning.
Clean, predictable REST API. Pin by CID, list your pins, manage lifecycle. Works with any HTTP client.
Auto-scaling infrastructure with edge caching worldwide. Your content is fast, everywhere. No config needed.
Pay in USDC (or ETH equivalent). No subscriptions, no surprises.
Connect wallet → choose tier → pay → get key. Zero KYC.
Your wallet address is your identity. No email. No forms. No KYC.
0x1234...abcd
Tier: Basic
From your wallet: 0x1234...abcd
Sends transaction directly from your connected wallet on Base network.
0x742d35Cc6634C0532925a3b844Bc9e7595f2bD68
⚠️ Send only ETH on Base network. Other chains/tokens will be lost.
Tier: Pro
Linked to: 0x1234...abcd
ipfs_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
⚠️ Save this key now. It cannot be recovered if lost.
From zero to pinned content in 3 steps.
Connect your wallet, choose a tier, and pay with ETH on Base. Free tier available — no payment needed.
Connect Wallet →Send a CID to the pinning API. Works with any content addressable hash.
curl -X POST https://9522f1f0cb3e394a.dyndns.dappnode.io/pins \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"cid": "QmYourContentHash", "name": "my-first-pin"}'
Verify your content is pinned and available.
curl https://9522f1f0cb3e394a.dyndns.dappnode.io/pins \
-H "Authorization: Bearer YOUR_API_KEY"
Ready to go deeper?
Full API Reference →Drop-in snippets for the complete API workflow. Pick your language.
Create a new API key linked to your wallet address.
const BASE_URL = 'https://pin.netrix.dev';
async function generateKey(walletAddress) {
const res = await fetch(`${BASE_URL}/api/keys`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ wallet: walletAddress })
});
if (!res.ok) throw new Error(`HTTP ${res.status}`);
const data = await res.json();
console.log('API Key:', data.key);
return data.key;
}
// Usage
generateKey('0xYourWalletAddress');
Pin content by its Content Identifier (CID).
const BASE_URL = 'https://pin.netrix.dev';
const API_KEY = 'YOUR_API_KEY';
async function pinContent(cid, name) {
const res = await fetch(`${BASE_URL}/api/pins`, {
method: 'POST',
headers: {
'Authorization': `Bearer ${API_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({ cid, name })
});
if (!res.ok) throw new Error(`HTTP ${res.status}`);
const data = await res.json();
console.log('Pinned:', data);
return data;
}
// Usage
pinContent('QmYwAPJzv5CZsnA625s3Xf2nemtYgPpHdWEz79ojWnPbdG', 'my-file');
Retrieve all pins in your account with pagination.
const BASE_URL = 'https://pin.netrix.dev';
const API_KEY = 'YOUR_API_KEY';
async function listPins() {
const res = await fetch(`${BASE_URL}/api/pins`, {
headers: { 'Authorization': `Bearer ${API_KEY}` }
});
if (!res.ok) throw new Error(`HTTP ${res.status}`);
const data = await res.json();
console.log(`Found ${data.count} pins:`);
data.results.forEach(pin => {
console.log(` ${pin.pin.cid} — ${pin.status}`);
});
return data;
}
// Usage
listPins();
View your storage usage and remaining quota.
const BASE_URL = 'https://pin.netrix.dev';
const API_KEY = 'YOUR_API_KEY';
async function checkQuota() {
const res = await fetch(`${BASE_URL}/api/quota`, {
headers: { 'Authorization': `Bearer ${API_KEY}` }
});
if (!res.ok) throw new Error(`HTTP ${res.status}`);
const data = await res.json();
console.log('Storage:', data.used, '/', data.total);
console.log('Requests:', data.requestsUsed, '/', data.requestsLimit);
return data;
}
// Usage
checkQuota();
Create a new API key linked to your wallet address.
import requests
BASE_URL = "https://pin.netrix.dev"
def generate_key(wallet_address):
"""Generate a new API key for the given wallet."""
res = requests.post(
f"{BASE_URL}/api/keys",
json={"wallet": wallet_address}
)
res.raise_for_status()
data = res.json()
print(f"API Key: {data['key']}")
return data["key"]
# Usage
api_key = generate_key("0xYourWalletAddress")
Pin content by its Content Identifier (CID).
import requests
BASE_URL = "https://pin.netrix.dev"
API_KEY = "YOUR_API_KEY"
def pin_content(cid, name="my-file"):
"""Pin a CID to IPFS via the Netrix API."""
res = requests.post(
f"{BASE_URL}/api/pins",
headers={
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json"
},
json={"cid": cid, "name": name}
)
res.raise_for_status()
data = res.json()
print(f"Pinned: {data}")
return data
# Usage
pin_content("QmYwAPJzv5CZsnA625s3Xf2nemtYgPpHdWEz79ojWnPbdG")
Retrieve all pins in your account with pagination.
import requests
BASE_URL = "https://pin.netrix.dev"
API_KEY = "YOUR_API_KEY"
def list_pins():
"""List all pins in the account."""
res = requests.get(
f"{BASE_URL}/api/pins",
headers={"Authorization": f"Bearer {API_KEY}"}
)
res.raise_for_status()
data = res.json()
print(f"Found {data['count']} pins:")
for pin in data["results"]:
print(f" {pin['pin']['cid']} — {pin['status']}")
return data
# Usage
list_pins()
View your storage usage and remaining quota.
import requests
BASE_URL = "https://pin.netrix.dev"
API_KEY = "YOUR_API_KEY"
def check_quota():
"""Check storage usage and remaining quota."""
res = requests.get(
f"{BASE_URL}/api/quota",
headers={"Authorization": f"Bearer {API_KEY}"}
)
res.raise_for_status()
data = res.json()
print(f"Storage: {data['used']} / {data['total']}")
print(f"Requests: {data['requestsUsed']} / {data['requestsLimit']}")
return data
# Usage
check_quota()
Create a new API key linked to your wallet address.
package main
import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
)
const baseURL = "https://pin.netrix.dev"
type KeyResponse struct {
Key string `json:"key"`
}
func generateKey(wallet string) (string, error) {
body, _ := json.Marshal(map[string]string{"wallet": wallet})
res, err := http.Post(
baseURL+"/api/keys",
"application/json",
bytes.NewReader(body),
)
if err != nil {
return "", err
}
defer res.Body.Close()
var data KeyResponse
if err := json.NewDecoder(res.Body).Decode(&data); err != nil {
return "", err
}
fmt.Println("API Key:", data.Key)
return data.Key, nil
}
Pin content by its Content Identifier (CID).
package main
import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
)
const baseURL = "https://pin.netrix.dev"
type PinRequest struct {
CID string `json:"cid"`
Name string `json:"name"`
}
func pinContent(apiKey, cid, name string) error {
body, _ := json.Marshal(PinRequest{CID: cid, Name: name})
req, err := http.NewRequest("POST", baseURL+"/api/pins", bytes.NewReader(body))
if err != nil {
return err
}
req.Header.Set("Authorization", "Bearer "+apiKey)
req.Header.Set("Content-Type", "application/json")
res, err := http.DefaultClient.Do(req)
if err != nil {
return err
}
defer res.Body.Close()
data, _ := io.ReadAll(res.Body)
fmt.Println("Response:", string(data))
return nil
}
Retrieve all pins in your account with pagination.
package main
import (
"fmt"
"io"
"net/http"
)
const baseURL = "https://pin.netrix.dev"
func listPins(apiKey string) error {
req, err := http.NewRequest("GET", baseURL+"/api/pins", nil)
if err != nil {
return err
}
req.Header.Set("Authorization", "Bearer "+apiKey)
res, err := http.DefaultClient.Do(req)
if err != nil {
return err
}
defer res.Body.Close()
data, _ := io.ReadAll(res.Body)
fmt.Println("Pins:", string(data))
return nil
}
View your storage usage and remaining quota.
package main
import (
"fmt"
"io"
"net/http"
)
const baseURL = "https://pin.netrix.dev"
func checkQuota(apiKey string) error {
req, err := http.NewRequest("GET", baseURL+"/api/quota", nil)
if err != nil {
return err
}
req.Header.Set("Authorization", "Bearer "+apiKey)
res, err := http.DefaultClient.Do(req)
if err != nil {
return err
}
defer res.Body.Close()
data, _ := io.ReadAll(res.Body)
fmt.Println("Quota:", string(data))
return nil
}
Four endpoints. That's it. You're building in minutes.
/health
No auth required
curl https://9522f1f0cb3e394a.dyndns.dappnode.io/health
const res = await fetch('https://9522f1f0cb3e394a.dyndns.dappnode.io/health');
const data = await res.json();
console.log(data);
import requests
r = requests.get('https://9522f1f0cb3e394a.dyndns.dappnode.io/health')
print(r.json())
{
"status": "ok",
"uptime": 86400,
"version": "1.0.0"
}
/pins
Auth: Bearer <api_key>
curl https://9522f1f0cb3e394a.dyndns.dappnode.io/pins \
-H "Authorization: Bearer YOUR_API_KEY"
const res = await fetch('https://9522f1f0cb3e394a.dyndns.dappnode.io/pins', {
headers: { 'Authorization': 'Bearer YOUR_API_KEY' }
});
const data = await res.json();
console.log(data);
import requests
r = requests.get(
'https://9522f1f0cb3e394a.dyndns.dappnode.io/pins',
headers={'Authorization': 'Bearer YOUR_API_KEY'}
)
print(r.json())
{
"count": 42,
"results": [
{
"requestid": "req_abc123",
"status": "pinned",
"created": "2026-03-14T20:00:00Z",
"pin": {
"cid": "QmYourContentHash",
"name": "my-file",
"size": 1024
}
}
]
}
/pins
Auth: Bearer <api_key>
curl -X POST https://9522f1f0cb3e394a.dyndns.dappnode.io/pins \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"cid": "QmYourContentHash", "name": "my-file"}'
const res = await fetch('https://9522f1f0cb3e394a.dyndns.dappnode.io/pins', {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({ cid: 'QmYourContentHash', name: 'my-file' })
});
const data = await res.json();
console.log(data);
import requests
r = requests.post(
'https://9522f1f0cb3e394a.dyndns.dappnode.io/pins',
headers={
'Authorization': 'Bearer YOUR_API_KEY',
'Content-Type': 'application/json'
},
json={'cid': 'QmYourContentHash', 'name': 'my-file'}
)
print(r.json())
{
"requestid": "req_abc123",
"status": "pinned",
"created": "2026-03-14T20:00:00Z",
"pin": {
"cid": "QmYourContentHash",
"name": "my-file",
"size": 1024
}
}
// 401 Unauthorized — missing or invalid key
{ "error": "Unauthorized", "message": "Invalid or expired API key" }
// 400 Bad Request — invalid CID format
{ "error": "BadRequest", "message": "Invalid CID: must be a valid v0 or v1 CID" }
// 402 Payment Required — insufficient balance
{ "error": "PaymentRequired", "message": "Top up your balance to continue pinning" }
// 429 Too Many Requests — rate limit exceeded
{ "error": "RateLimited", "message": "Rate limit exceeded. Retry after 30s", "retryAfter": 30 }
/pins/:cid
Auth: Bearer <api_key>
curl -X DELETE https://9522f1f0cb3e394a.dyndns.dappnode.io/pins/QmYourContentHash \
-H "Authorization: Bearer YOUR_API_KEY"
const res = await fetch('https://9522f1f0cb3e394a.dyndns.dappnode.io/pins/QmYourContentHash', {
method: 'DELETE',
headers: { 'Authorization': 'Bearer YOUR_API_KEY' }
});
console.log(res.status);
import requests
r = requests.delete(
'https://9522f1f0cb3e394a.dyndns.dappnode.io/pins/QmYourContentHash',
headers={'Authorization': 'Bearer YOUR_API_KEY'}
)
print(r.status_code)
{
"requestid": "req_abc123",
"status": "deleted",
"cid": "QmYourContentHash"
}
// 404 Not Found — CID not pinned
{ "error": "NotFound", "message": "No pin found for CID: QmYourContentHash" }
Got your key? Start pinning now.
Get API Key →See how Netrix stacks up against other IPFS pinning services.
| Feature | Netrix | Pinata | Web3.Storage | Infura IPFS |
|---|---|---|---|---|
| Zero KYC | ✅ Yes | ❌ Email required | ❌ Email required | ❌ Email required |
| Free Tier | ✅ 100 MB | ✅ 1 GB | ✅ 5 GB | ✅ 1 GB |
| Crypto Payments | ✅ ETH on Base | ❌ Fiat only | ❌ Fiat only | ❌ Fiat only |
| REST API | ✅ OpenAPI 3.0 | ✅ Yes | ✅ Yes | ✅ Yes |
| Self-Hosted Option | ✅ Open source | ❌ No | ✅ W3S CLI | ❌ No |
| Rate Limits | Generous | Varies | Varies | Varies |
| Data Selling | ✅ Never | ? | ? | ? |
No email, no KYC, no identity verification. Connect your wallet and go. We never sell your data — because we never collect it.
Pay with ETH on Base. No credit cards, no invoices, no fiat rails. Direct on-chain payments with full transparency and instant provisioning.
Fully open source. Run your own instance on your own infrastructure. No vendor lock-in, no black boxes. Fork it, host it, own it.
From DeFi to research — IPFS pinning for every use case.
Pin contract metadata, ABIs, and frontend assets for trustless, verifiable distribution.
Store artwork and metadata on IPFS, pin with API — permanent, decentralized hosting.
Pin proposals, voting results, and documentation for transparent, immutable records.
Integrate IPFS pinning into CI/CD pipelines — automate builds, releases, and artifacts.
Store posts, images, and user data on IPFS with API-driven pinning and retrieval.
Share datasets and research papers permanently — censorship-resistant, globally accessible.
Built by devs, for devs. Here's what the community thinks.
Switched from Pinata in 5 minutes. Same API shape, but I pay with ETH and don't hand over my email. Exactly what I've been waiting for.
Finally, an IPFS pinning service that takes crypto. No credit card, no invoices, no accounting headaches. Just connect wallet and pin.
Zero KYC means I can integrate into our dApp without a legal review. That alone saved us weeks. The API is clean and rate limits are generous.
We moved 200 NFT collections off Web3.Storage onto Netrix. Self-hostable, open source, and our users don't need to create accounts anywhere. Game changer.