· Nacho Coll · Tutorials  · 9 min čítania

IPFS Upload API — Kompletný tutoriál pre vývojárov

Naučte sa nahrávať súbory na IPFS cez REST API. Kompletné príklady kódu v JavaScripte, Node.js a curl. Nahrávajte JSON, obrázky, používajte podpísané tokeny pre nahrávanie z klienta.

Naučte sa nahrávať súbory na IPFS cez REST API. Kompletné príklady kódu v JavaScripte, Node.js a curl. Nahrávajte JSON, obrázky, používajte podpísané tokeny pre nahrávanie z klienta.

IPFS Upload API — Kompletný tutoriál pre vývojárov

Nahrávanie súborov na IPFS by malo byť také jednoduché ako odoslanie POST požiadavky. V tomto tutoriáli to presne urobíte — nahráte JSON dokumenty, obrázky a PDF súbory na IPFS s ničím viac než fetch() a API kľúčom. Na konci budete mať kompletný Node.js skript, ktorý nahráva obsah, vypisuje súbory, získava metadáta a generuje podpísané tokeny pre bezpečné nahrávanie zo strany klienta. Nový v IPFS? Začnite s Čo je IPFS Pinning?, aby ste pochopili základy pred ponorením sa do kódu.

IPFS Ninja API keys management page

Čo budete stavať

  • Nahráte JSON objekt na IPFS a získate späť identifikátor obsahu (CID).
  • Nahráte binárny obrázok z disku.
  • Pripojíte popisy a vlastné metadáta k nahrávaniam.
  • Dopytujete sa na históriu nahrávania podľa rozsahu dátumu.
  • Získate detaily konkrétneho súboru.
  • Vytvoríte časovo obmedzené podpísané tokeny, aby prehliadač mohol nahrávať priamo bez odhalenia vášho API kľúča.
  • Spracujete chyby a implementujete logiku opakovania.

Všetko beží proti jednej základnej URL: https://api.ipfs.ninja

1. Nastavenie — Registrácia a získanie API kľúča

  1. Zaregistrujte sa pre bezplatný účet (kreditná karta nie je potrebná).
  2. Prejdite na API Keys v bočnom paneli dashboardu.
  3. Kliknite na Create key, dajte mu meno a okamžite skopírujte kľúč — už sa znova nezobrazí.
API Keys page — create and manage your keys

Váš kľúč vyzerá takto: bws_a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6. Každý nasledujúci príklad ho posiela v hlavičke X-Api-Key.

2. Nahranie JSON na IPFS

Najjednoduchšie nahrávanie: odovzdajte obyčajný JavaScript objekt ako content a API ho serializuje, pripne na IPFS a vráti 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);

Spustite pomocou node upload-json.mjs. Úspešná odpoveď vyzerá takto:

{
  "cid": "bafkreigx7gq...",
  "sizeMB": 0.0004,
  "uris": {
    "ipfs": "ipfs://bafkreigx7gq...",
    "url": "https://ipfs.ninja/ipfs/bafkreigx7gq..."
  }
}

Pole url ukazuje na verejnú HTTP bránu, takže obsah je okamžite prístupný v akomkoľvek prehliadači.

3. Nahranie obrázka

Binárne súbory (obrázky, PDF, audio) sa posielajú ako base64-kódované reťazce v poli 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 automaticky deteguje MIME typ — PNG, JPEG, WebP, GIF a PDF sú všetky podporované. Žiadne ďalšie hlavičky ani prepísania content-type nie sú potrebné.

S curl vyzerá rovnaká operácia takto:

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. Nahrávanie s metadátami

Každé nahrávanie prijíma dve voliteľné polia: description (voľný textový popisok) a metadata (ľubovoľné páry kľúč-hodnota). Obe sú uložené spolu s CID a vrátené pri neskoršom výpise alebo načítaní súboru.

// 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);

Metadáta uľahčujú filtrovanie a organizáciu súborov na vašej strane bez parsovania samotného IPFS obsahu.

5. Pripnutie existujúceho CID

Ak už máte obsah na IPFS a chcete zabezpečiť jeho dostupnosť, pripnite ho podľa 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. Výpis vašich súborov

Načítajte každý súbor, ktorý ste nahrali v rámci časového okna. Parametre dotazu from a toUnix timestampy v milisekundách.

// 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)"}`);
}

S 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. Získanie detailov súboru

Načítajte kompletný záznam pre jeden CID, vrátane metadát, veľkosti a časových značiek:

// 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. Nahrávanie z klienta s podpísanými tokenmi

Vloženie API kľúča do balíčka prehliadača je bezpečnostné riziko. Namiesto toho vygenerujte na serveri krátkodobý podpísaný token a odovzdajte ho klientovi.

Server (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"));

Klient v prehliadači

<!-- 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>

Prehliadač nikdy nevidí váš API kľúč. Podpísaný token automaticky vyprší. Tokeny sú viacúčelové — môžu byť použité viackrát, kým nevypršia alebo nie sú zrušené. Hodnota useCount je sledovaná, ale nie je presadzovaná ako limit.

9. Spracovanie chýb

API používa konvenčné HTTP stavové kódy. Tu sú tie, ktoré by ste mali výslovne spracovať:

StavVýznamČo robiť
400Bad request — chýbajúce alebo neplatné poliaSkontrolujte, či je content prítomný a platný
401Unauthorized — zlý alebo chýbajúci API kľúčOverte hlavičku X-Api-Key
413Payload too largeZmenšite veľkosť súboru alebo rozdeľte obsah
429Rate limitedPozastavte a skúste znova s exponenciálnym oneskorením
500Server errorSkúste znova po krátkom oneskorení

Odolná funkcia pre nahrávanie s exponenciálnym 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. Kompletný pracovný príklad

Jeden skript, ktorý využíva každý endpoint zahrnutý v tomto tutoriáli. Uložte ho ako ipfs-demo.mjs a spustite pomocou 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.");

Nahraďte bws_your_key_here skutočným kľúčom a spustite skript. Každý krok vypíše svoj výsledok, takže môžete sledovať priebeh.

11. Ďalšie kroky

Teraz viete, ako nahrávať, pripínať, vypisovať a získavať súbory cez IPFS Upload API a ako udržať nahrávanie z prehliadača v bezpečí pomocou podpísaných tokenov. Pre širší prehľad vrátane UI dashboardu a Python príkladov si pozrite Ako nahrať súbory na IPFS. Tu je, kam pokračovať odtiaľto:

  • API Reference — Kompletná dokumentácia endpointov na ipfs.ninja/docs.
  • Vlastné brány — Doručujte IPFS obsah z vlastnej domény. Pozrite si sprievodcu nastavením brány.
  • Analytika — Sledujte objem nahrávania, šírku pásma a počty pripnutí v dashboarde.
  • HTTP klient — Žiadne SDK nie je potrebné. Môžete použiť štandardný fetch() alebo akéhokoľvek HTTP klienta na interakciu s API.

Ak narazíte na problémy, otvorte tiket na support.ipfs.ninja alebo sa pripojte ku komunite na Discorde.

Späť na Blog