· Nacho Coll · Tutorials  · 9 min čtení

IPFS Upload API — Kompletní tutoriál pro vývojáře

Naučte se nahrávat soubory na IPFS přes REST API. Kompletní příklady v JavaScriptu, Node.js a curl. Nahrávejte JSON, obrázky, používejte podepsané tokeny pro nahrávání z klienta.

Naučte se nahrávat soubory na IPFS přes REST API. Kompletní příklady v JavaScriptu, Node.js a curl. Nahrávejte JSON, obrázky, používejte podepsané tokeny pro nahrávání z klienta.

IPFS Upload API — Kompletní tutoriál pro vývojáře

Nahrávání souborů na IPFS by mělo být tak jednoduché jako odeslání POST požadavku. V tomto tutoriálu to přesně uděláte — nahrajete JSON dokumenty, obrázky a PDF soubory na IPFS s ničím víc než fetch() a API klíčem. Na konci budete mít kompletní Node.js skript, který nahrává obsah, vypisuje soubory, získává metadata a generuje podepsané tokeny pro bezpečné nahrávání ze strany klienta. Nováček v IPFS? Začněte u Co je IPFS Pinning?, abyste pochopili základy, než se ponoříte do kódu.

IPFS Ninja API keys management page

Co si postavíte

  • Nahrajete JSON objekt na IPFS a získáte zpět identifikátor obsahu (CID).
  • Nahrajete binární obrázek z disku.
  • Připojíte popisy a vlastní metadata k nahráním.
  • Dotážete se na svou historii nahrávání podle rozsahu data.
  • Získáte detaily konkrétního souboru.
  • Vytvoříte časově omezené podepsané tokeny, aby prohlížeč mohl nahrávat přímo, aniž by odhalil váš API klíč.
  • Ošetříte chyby a implementujete logiku opakování.

Vše běží proti jedné základní URL: https://api.ipfs.ninja

1. Nastavení — Registrace a získání API klíče

  1. Zaregistrujte se pro bezplatný účet (není potřeba kreditní karta).
  2. Přejděte na API Keys v postranním panelu dashboardu.
  3. Klikněte na Create key, pojmenujte jej a okamžitě klíč zkopírujte — již se znovu nezobrazí.
API Keys page — create and manage your keys

Váš klíč vypadá takto: bws_a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6. Každý níže uvedený příklad jej posílá v hlavičce X-Api-Key.

2. Nahrání JSON na IPFS

Nejjednodušší nahrání: předáte obyčejný JavaScript objekt jako content a API jej serializuje, připne na IPFS a vrátí 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);

Spusťte pomocí node upload-json.mjs. Úspěšná odpověď vypadá takto:

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

Pole url ukazuje na veřejnou HTTP bránu, takže obsah je okamžitě přístupný v libovolném prohlížeči.

3. Nahrání obrázku

Binární soubory (obrázky, PDF, audio) se posílají jako base64-kódované řetězce 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 detekuje MIME typ — PNG, JPEG, WebP, GIF a PDF jsou všechny podporovány. Žádné další hlavičky nebo přepsání content-type nejsou potřeba.

S curl vypadá stejná operace 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ávání s metadaty

Každé nahrání přijímá dvě volitelná pole: description (volný textový popisek) a metadata (libovolné páry klíč-hodnota). Obě jsou uložena společně s CID a vrácena při pozdějším výpisu nebo načtení souboru.

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

Metadata usnadňují filtrování a organizaci souborů na vaší straně bez parsování samotného obsahu IPFS.

5. Připnutí existujícího CID

Pokud již máte obsah na IPFS a chcete zajistit jeho dostupnost, připněte jej pomocí 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 souborů

Načtěte všechny soubory, které jste nahráli v určitém časovém okně. Parametry dotazu from a to jsou Unix 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ískání detailů souboru

Načtěte kompletní záznam pro jeden CID, včetně metadat, velikosti a časových razítek:

// 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ávání z klienta pomocí podepsaných tokenů

Vložení API klíče do balíčku prohlížeče je bezpečnostní riziko. Místo toho vygenerujte na serveru krátkodobý podepsaný token a předejte jej 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 prohlížeč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>

Prohlížeč nikdy nevidí váš API klíč. Podepsaný token automaticky vyprší. Tokeny jsou víceúčelové — lze je použít vícekrát, dokud nevyprší nebo nejsou odvolány. Hodnota useCount je sledována, ale není vynucována jako limit.

9. Ošetření chyb

API používá konvenční HTTP stavové kódy. Zde jsou ty, které byste měli explicitně ošetřit:

StatusVýznamCo dělat
400Bad request — chybějící nebo neplatná poleZkontrolujte, zda je content přítomen a platný
401Unauthorized — špatný nebo chybějící API klíčOvěřte hlavičku X-Api-Key
413Payload too largeZmenšete velikost souboru nebo rozdělte obsah
429Rate limitedPočkejte a zkuste znovu s exponenciálním zpožděním
500Server errorZkuste znovu po krátké prodlevě

Odolná funkce pro nahrávání s exponenciálním 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í příklad

Jeden skript, který využívá každý endpoint zmíněný v tomto tutoriálu. Uložte jej jako ipfs-demo.mjs a spusťte pomocí 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 skutečným klíčem a skript spusťte. Každý krok vypíše svůj výsledek, takže můžete sledovat průběh.

11. Další kroky

Nyní víte, jak nahrávat, připínat, vypisovat a získávat soubory prostřednictvím IPFS Upload API a jak udržet nahrávání z prohlížeče v bezpečí pomocí podepsaných tokenů. Pro širší přehled včetně UI dashboardu a příkladů v Pythonu si přečtěte Jak nahrát soubory na IPFS. Kam pokračovat odsud:

  • API Reference — Kompletní dokumentace endpointů na ipfs.ninja/docs.
  • Vlastní brány — Doručujte obsah IPFS z vaší vlastní domény. Viz průvodce nastavením brány.
  • Analytika — Sledujte objem nahrávání, šířku pásma a počty připnutí v dashboardu.
  • HTTP klient — Žádné SDK není potřeba. Můžete použít standardní fetch() nebo libovolného HTTP klienta pro interakci s API.

Pokud narazíte na problémy, otevřete tiket na support.ipfs.ninja nebo se připojte ke komunitě na Discordu.

Zpět na Blog

Související články

Zobrazit všechny články »