· Nacho Coll · Tutorials · 9 min lasīšanas
IPFS Upload API — Pilna izstrādātāju pamācība
Iemācieties augšupielādēt failus IPFS, izmantojot REST API. Pilni koda piemēri JavaScript, Node.js un curl. Augšupielādējiet JSON, attēlus, izmantojiet parakstītus tokenus klienta puses augšupielādēm.

IPFS Upload API — Pilna izstrādātāju pamācība
Failu augšupielādei IPFS vajadzētu būt tikpat vienkāršai kā POST pieprasījuma nosūtīšanai. Šajā pamācībā jūs darīsiet tieši to — augšupielādēsiet JSON dokumentus, attēlus un PDF uz IPFS ar neko vairāk kā fetch() un API atslēgu. Beigās jums būs pilna Node.js skripts, kas augšupielādē saturu, uzskaita failus, iegūst metadatus un ģenerē parakstītus tokenus drošām klienta puses augšupielādēm. Jauns IPFS? Sāciet ar Kas ir IPFS Pinning?, lai izprastu pamatus pirms iegremdēšanās kodā.

Ko jūs izveidosiet
- Augšupielādēsiet JSON objektu IPFS un saņemsiet atpakaļ satura identifikatoru (CID).
- Augšupielādēsiet binārā attēla no diska.
- Pievienosiet aprakstus un pielāgotus metadatus augšupielādēm.
- Vaicāsiet savu augšupielādes vēsturi pēc datuma diapazona.
- Iegūsiet detaļas par konkrētu failu.
- Izveidosiet laikā ierobežotus parakstītus tokenus, lai pārlūkprogramma varētu augšupielādēt tieši, neatklājot jūsu API atslēgu.
- Apstrādāsiet kļūdas un implementēsiet atkārtotas mēģināšanas loģiku.
Viss tiek darbināts pret vienu pamata URL: https://api.ipfs.ninja
1. Iestatīšana — Reģistrējieties un iegūstiet API atslēgu
- Reģistrējieties bezmaksas kontam (kredītkarte nav nepieciešama).
- Dodieties uz API Keys vadības paneļa sānjoslā.
- Noklikšķiniet uz Create key, piešķiriet tam nosaukumu un nekavējoties nokopējiet atslēgu — tā vairs netiks rādīta.

Jūsu atslēga izskatās šādi: bws_a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6. Katrs zemāk redzamais piemērs to nosūta X-Api-Key galvenē.
2. JSON augšupielāde uz IPFS
Vienkāršākā augšupielāde: nododiet vienkāršu JavaScript objektu kā content, un API to serializēs, piespraudīs IPFS un atgriezīs CID.
// upload-json.mjs
const API = "https://api.ipfs.ninja";
const API_KEY = "bws_your_key_here";
const payload = {
content: {
name: "Galactic Badge #42",
description: "Proof of attendance — Galactic Meetup 2026",
attributes: [
{ trait_type: "Event", value: "Galactic Meetup" },
{ trait_type: "Year", value: 2026 }
]
}
};
const res = await fetch(`${API}/upload/new`, {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-Api-Key": API_KEY
},
body: JSON.stringify(payload)
});
const data = await res.json();
console.log("CID :", data.cid);
console.log("Size:", data.sizeMB, "MB");
console.log("IPFS:", data.uris.ipfs);
console.log("URL :", data.uris.url);Palaidiet ar node upload-json.mjs. Veiksmīga atbilde izskatās šādi:
{
"cid": "bafkreigx7gq...",
"sizeMB": 0.0004,
"uris": {
"ipfs": "ipfs://bafkreigx7gq...",
"url": "https://ipfs.ninja/ipfs/bafkreigx7gq..."
}
}Lauks url norāda uz publisku HTTP vārteju, tāpēc saturs ir nekavējoties pieejams jebkurā pārlūkprogrammā.
3. Attēla augšupielāde
Binārie faili (attēli, PDF, audio) tiek nosūtīti kā base64-kodētas virknes laukā content.
// upload-image.mjs
import { readFileSync } from "node:fs";
const API = "https://api.ipfs.ninja";
const API_KEY = "bws_your_key_here";
const imageBuffer = readFileSync("./photo.png");
const base64 = imageBuffer.toString("base64");
const res = await fetch(`${API}/upload/new`, {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-Api-Key": API_KEY
},
body: JSON.stringify({ content: base64 })
});
const data = await res.json();
console.log("Image CID:", data.cid);
console.log("Gateway :", data.uris.url);API automātiski nosaka MIME tipu — PNG, JPEG, WebP, GIF un PDF visi tiek atbalstīti. Nav nepieciešamas papildu galvenes vai content-type aizstājumi.
Ar curl tā pati operācija izskatās šādi:
BASE64=$(base64 -w 0 photo.png)
curl -X POST https://api.ipfs.ninja/upload/new \
-H "Content-Type: application/json" \
-H "X-Api-Key: bws_your_key_here" \
-d "{\"content\": \"$BASE64\"}"4. Augšupielāde ar metadatiem
Katra augšupielāde pieņem divus neobligātus laukus: description (brīva teksta etiķete) un metadata (patvaļīgi atslēgas-vērtības pāri). Abi tiek saglabāti blakus CID un atgriezti, kad vēlāk uzskaitāt vai iegūstat failu.
// upload-with-metadata.mjs
const API = "https://api.ipfs.ninja";
const API_KEY = "bws_your_key_here";
const res = await fetch(`${API}/upload/new`, {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-Api-Key": API_KEY
},
body: JSON.stringify({
content: { title: "Meeting Notes", body: "Q1 roadmap recap..." },
description: "Q1 2026 planning meeting notes",
metadata: {
project: "acme-app",
author: "dana",
version: "1"
}
})
});
const data = await res.json();
console.log("CID:", data.cid);Metadati atvieglo failu filtrēšanu un organizēšanu jūsu pusē bez nepieciešamības analizēt pašu IPFS saturu.
5. Esoša CID piespraušana
Ja jums jau ir saturs IPFS un vēlaties pārliecināties, ka tas paliek pieejams, piespraudiet to pēc CID:
// pin-cid.mjs
const API = "https://api.ipfs.ninja";
const API_KEY = "bws_your_key_here";
const res = await fetch(`${API}/pin`, {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-Api-Key": API_KEY
},
body: JSON.stringify({
cid: "bafkreigx7gq...",
description: "Pinned from external source"
})
});
const data = await res.json();
console.log("Pinned:", data.cid);6. Jūsu failu uzskaite
Iegūstiet katru failu, ko esat augšupielādējis noteiktā laika logā. Vaicājuma parametri from un to ir Unix laika zīmogi milisekundēs.
// list-files.mjs
const API = "https://api.ipfs.ninja";
const API_KEY = "bws_your_key_here";
const now = Date.now();
const oneWeekAgo = now - 7 * 24 * 60 * 60 * 1000;
const url = `${API}/upload/list?from=${oneWeekAgo}&to=${now}`;
const res = await fetch(url, {
headers: { "X-Api-Key": API_KEY }
});
const files = await res.json();
for (const file of files) {
console.log(`${file.cid} ${file.description ?? "(no description)"}`);
}Ar curl:
FROM=$(($(date +%s) * 1000 - 604800000))
TO=$(($(date +%s) * 1000))
curl -s "https://api.ipfs.ninja/upload/list?from=$FROM&to=$TO" \
-H "X-Api-Key: bws_your_key_here" | jq .7. Faila detaļas
Iegūstiet pilnu ierakstu par vienu CID, ieskaitot metadatus, izmēru un laika zīmogus:
// get-file.mjs
const API = "https://api.ipfs.ninja";
const API_KEY = "bws_your_key_here";
const CID = "bafkreigx7gq...";
const res = await fetch(`${API}/file/${CID}`, {
headers: { "X-Api-Key": API_KEY }
});
const details = await res.json();
console.log(JSON.stringify(details, null, 2));8. Klienta puses augšupielādes ar parakstītiem tokeniem
API atslēgas iegulšana pārlūkprogrammas paketē ir drošības risks. Tā vietā savā serverī ģenerējiet īslaicīgu parakstītu tokenu un nododiet to klientam.
Serveris (Express)
// server.mjs
import express from "express";
const app = express();
const API = "https://api.ipfs.ninja";
const API_KEY = process.env.IPFS_API_KEY;
app.post("/api/upload-token", async (req, res) => {
const response = await fetch(`${API}/upload/signed-url`, {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-Api-Key": API_KEY
},
body: JSON.stringify({
name: "browser-upload",
expiresIn: 600 // token valid for 10 minutes
})
});
const { token, tokenId, expiresAt } = await response.json();
res.json({ token, tokenId, expiresAt });
});
app.listen(3000, () => console.log("Server running on :3000"));Pārlūkprogrammas klients
<!-- upload.html -->
<input type="file" id="filePicker" />
<button id="uploadBtn">Upload to IPFS</button>
<pre id="result"></pre>
<script>
const API = "https://api.ipfs.ninja";
document.getElementById("uploadBtn").addEventListener("click", async () => {
// 1. Get a signed token from your own backend
const tokenRes = await fetch("/api/upload-token", { method: "POST" });
const { token } = await tokenRes.json();
// 2. Read the selected file as base64
const file = document.getElementById("filePicker").files[0];
if (!file) return alert("Pick a file first");
const base64 = await new Promise((resolve) => {
const reader = new FileReader();
reader.onload = () => resolve(reader.result.split(",")[1]);
reader.readAsDataURL(file);
});
// 3. Upload directly to IPFS using the signed token
const uploadRes = await fetch(`${API}/upload/new`, {
method: "POST",
headers: {
"Content-Type": "application/json",
"Authorization": `Signed ${token}`
},
body: JSON.stringify({
content: base64,
description: file.name
})
});
const data = await uploadRes.json();
document.getElementById("result").textContent = JSON.stringify(data, null, 2);
});
</script>Pārlūkprogramma nekad neredz jūsu API atslēgu. Parakstītais tokens beidzas automātiski. Tokeni ir vairākkārt lietojami — tos var izmantot vairākas reizes, līdz tie beidzas vai tiek atsaukti. useCount tiek izsekots, bet netiek piemērots kā limits.
9. Kļūdu apstrāde
API izmanto parastos HTTP statusa kodus. Šeit ir tie, kuriem vajadzētu apstrādāt nepārprotami:
| Statuss | Nozīme | Ko darīt |
|---|---|---|
| 400 | Bad request — trūkstoši vai nederīgi lauki | Pārbaudiet, vai content ir klāt un derīgs |
| 401 | Unauthorized — slikta vai trūkstoša API atslēga | Pārbaudiet galveni X-Api-Key |
| 413 | Payload too large | Samaziniet faila izmēru vai sadaliet saturu |
| 429 | Rate limited | Atkāpieties un mēģiniet vēlreiz ar eksponenciālu aizkavi |
| 500 | Server error | Mēģiniet vēlreiz pēc neilgas aizkaves |
Izturīga augšupielādes funkcija ar eksponenciālu backoff:
// resilient-upload.mjs
const API = "https://api.ipfs.ninja";
const API_KEY = "bws_your_key_here";
async function uploadWithRetry(content, retries = 3) {
for (let attempt = 1; attempt <= retries; attempt++) {
const res = await fetch(`${API}/upload/new`, {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-Api-Key": API_KEY
},
body: JSON.stringify({ content })
});
if (res.ok) return await res.json();
const body = await res.text();
if (res.status === 401) {
throw new Error(`Authentication failed: ${body}`);
}
if (res.status === 413) {
throw new Error(`Payload too large — reduce file size. ${body}`);
}
if (res.status === 429 || res.status >= 500) {
const delay = Math.pow(2, attempt) * 1000; // 2s, 4s, 8s
console.warn(`Attempt ${attempt} failed (${res.status}). Retrying in ${delay}ms...`);
await new Promise((r) => setTimeout(r, delay));
continue;
}
throw new Error(`Upload failed (${res.status}): ${body}`);
}
throw new Error("Upload failed after all retries");
}
// Usage
const data = await uploadWithRetry({ hello: "world" });
console.log("CID:", data.cid);10. Pilns darba piemērs
Viens skripts, kas izmanto katru šajā pamācībā aplūkoto endpoint. Saglabājiet to kā ipfs-demo.mjs un palaidiet ar node ipfs-demo.mjs.
// ipfs-demo.mjs
import { readFileSync } from "node:fs";
const API = "https://api.ipfs.ninja";
const API_KEY = "bws_your_key_here";
const headers = {
"Content-Type": "application/json",
"X-Api-Key": API_KEY
};
async function request(method, path, body) {
const opts = { method, headers };
if (body) opts.body = JSON.stringify(body);
const res = await fetch(`${API}${path}`, opts);
if (!res.ok) throw new Error(`${method} ${path} → ${res.status}: ${await res.text()}`);
return res.json();
}
// --- 1. Upload JSON ---
console.log("--- Upload JSON ---");
const jsonResult = await request("POST", "/upload/new", {
content: { name: "Demo Token", edition: 1 },
description: "Tutorial demo — JSON upload",
metadata: { tutorial: "true" }
});
console.log("CID:", jsonResult.cid);
console.log("URL:", jsonResult.uris.url);
// --- 2. Upload an image (if photo.png exists) ---
try {
const img = readFileSync("./photo.png");
console.log("\n--- Upload Image ---");
const imgResult = await request("POST", "/upload/new", {
content: img.toString("base64"),
description: "Tutorial demo — image upload"
});
console.log("CID:", imgResult.cid);
console.log("URL:", imgResult.uris.url);
} catch {
console.log("\n--- Skipping image upload (no photo.png found) ---");
}
// --- 3. Pin the JSON CID ---
console.log("\n--- Pin CID ---");
const pinResult = await request("POST", "/pin", {
cid: jsonResult.cid,
description: "Pinned from tutorial"
});
console.log("Pinned:", pinResult.cid);
// --- 4. Get file details ---
console.log("\n--- File Details ---");
const details = await request("GET", `/file/${jsonResult.cid}`);
console.log(JSON.stringify(details, null, 2));
// --- 5. List recent files ---
console.log("\n--- Recent Files ---");
const now = Date.now();
const oneHourAgo = now - 60 * 60 * 1000;
const files = await request("GET", `/upload/list?from=${oneHourAgo}&to=${now}`);
console.log(`Found ${files.length} file(s) in the last hour`);
for (const f of files) {
console.log(` - ${f.cid} ${f.description ?? ""}`);
}
// --- 6. Create a signed upload token ---
console.log("\n--- Signed Token ---");
const tokenResult = await request("POST", "/upload/signed-url", {
name: "demo-token",
expiresIn: 300
});
console.log("Token ID :", tokenResult.tokenId);
console.log("Expires :", new Date(tokenResult.expiresAt).toISOString());
// --- 7. Upload using the signed token ---
console.log("\n--- Upload with Signed Token ---");
const signedRes = await fetch(`${API}/upload/new`, {
method: "POST",
headers: {
"Content-Type": "application/json",
"Authorization": `Signed ${tokenResult.token}`
},
body: JSON.stringify({
content: { note: "Uploaded with a signed token" }
})
});
const signedData = await signedRes.json();
console.log("CID:", signedData.cid);
console.log("\nDone.");Aizvietojiet bws_your_key_here ar reālu atslēgu un palaidiet skriptu. Katrs solis izdrukā savu rezultātu, lai jūs varētu sekot līdzi.
11. Nākamie soļi
Tagad jūs zināt, kā augšupielādēt, piespraust, uzskaitīt un iegūt failus, izmantojot IPFS Upload API, un kā uzturēt drošas pārlūkprogrammas augšupielādes ar parakstītiem tokeniem. Plašākam pārskatam, kas ietver vadības paneļa UI un Python piemērus, skatiet Kā augšupielādēt failus IPFS. Lūk, kur iet no šejienes:
- API Reference — Pilna endpoint dokumentācija ipfs.ninja/docs.
- Pielāgotas vārtejas — Apkalpojiet IPFS saturu no savas domēna. Skatiet vārtejas iestatīšanas ceļvedi.
- Analītika — Sekojiet augšupielāžu apjomam, joslas platumam un piespraušanas skaitam vadības panelī.
- HTTP klients — SDK nav nepieciešams. Lai mijiedarbotos ar API, varat izmantot standarta
fetch()vai jebkuru HTTP klientu.
Ja jūs saskaraties ar problēmām, atveriet biļeti support.ipfs.ninja vai pievienojieties kopienai Discord.
