Are you an LLM? Read llms.txt for a summary of the docs, or llms-full.txt for the full context.
Skip to content

Upload Files

Upload various content types to Pinner.

Basic File Upload

Basic Upload Pattern

import { Pinner } from "@lumeweb/pinner"; const pinner = new Pinner({ jwt: "YOUR_API_TOKEN" }); const file = new File(["Hello, Pinner!"], "hello.txt", { type: "text/plain" }); const result = await pinner.uploadAndWait(file); console.log("CID:", result.cid); console.log("Name:", result.name); console.log("Size:", result.size, "bytes");

Upload with Options

const result = await pinner.upload(file, { name: "my-file", keyvalues: { customKey: "customValue" } });

Directory Upload

import { Pinner } from "@lumeweb/pinner"; const pinner = new Pinner({ jwt: "YOUR_API_TOKEN" }); const files = [ new File(["Hello, Pinner!"], "hello.txt"), new File([JSON.stringify({ name: "config" })], "config.json"), ]; const operation = await pinner.uploadDirectory(files); const result = await operation.result; console.log("CID:", result.cid);

CAR Upload

import { Pinner } from "@lumeweb/pinner"; const pinner = new Pinner({ jwt: "YOUR_API_TOKEN" }); const response = await fetch("/path/to/data.car"); const carData = response.body; const operation = await pinner.uploadCar(carData); const result = await operation.result; console.log("CID:", result.cid);

Encoders

Choose how content is encoded before upload.

import { Pinner } from "@lumeweb/pinner"; const pinner = new Pinner({ jwt: "YOUR_API_TOKEN" }); // JSON encoder const jsonResult = await pinner.upload.json({ name: "test" }); const result = await jsonResult.result; // Base64 encoder const base64Result = await pinner.upload.base64("SGVsbG8sIFBpbm5lciE="); const base64Upload = await base64Result.result; // Text encoder const textResult = await pinner.upload.text("Hello, Pinner!"); const textUpload = await textResult.result; // CSV encoder const csvResult = await pinner.upload.csv("name,age\nJohn,30\nJane,25"); const csvUpload = await csvResult.result; // URL encoder (fetches and uploads) const urlResult = await pinner.upload.url("https://example.com/data.json"); const urlUpload = await urlResult.result;

Upload Options

Control upload behavior with options:

const operation = await pinner.upload(file, { name: "my-file", keyvalues: { project: "demo", version: "1.0" }, onProgress: (progress) => { console.log(`${progress.percentage.toFixed(2)}% complete`); }, onComplete: (result) => { console.log("Upload complete:", result.cid); }, onError: (error) => { console.error("Upload failed:", error); }, signal: abortController.signal, waitForOperation: true, operationPollingOptions: { interval: 1000, timeout: 60000 } });

Option Details

OptionTypeDescription
namestringCustom name for the content
keyvaluesRecord<string, string>Custom metadata
onProgress(progress) => voidProgress callback
onComplete(result) => voidSuccess callback
onError(error) => voidError callback
signalAbortSignalCancel upload with AbortController
sizenumberSize override for ReadableStream inputs
isDirectorybooleanWhether upload is a directory
isCarFilebooleanWhether input is already a valid CAR file
waitForOperationbooleanWait for pinning to complete
operationPollingOptionsOperationPollingOptionsPolling configuration

Type Guard

Check if a value is an UploadResult:

import { isUploadResult } from "@lumeweb/pinner";
 
const result = await operation.result;
 
if (isUploadResult(result)) {
  console.log("Upload ID:", result.id);
  console.log("CID:", result.cid);
}

Builder Pattern

Use the builder pattern for fluent, chainable uploads:

import { Pinner } from "@lumeweb/pinner"; const pinner = new Pinner({ jwt: "YOUR_API_TOKEN" }); // File upload with builder const operation = await pinner.upload.file(file) .name("my-file.txt") .keyvalues({ project: "demo", version: "1.0" }) .waitForOperation(true) .operationPollingOptions({ interval: 1000, timeout: 60000 }) .pin(); const result = await operation.result; // JSON upload with builder const jsonOp = await pinner.upload.json({ data: "test" }) .name("config.json") .keyvalues({ type: "config" }) .pin(); // Text upload with builder const textOp = await pinner.upload.text("Hello, world!") .name("greeting.txt") .pin(); // CSV upload with builder const csvOp = await pinner.upload.csv("name,age\nJohn,30") .name("users.csv") .pin(); // Raw CAR upload with builder const carOp = await pinner.upload.raw(carFile) .name("data.car") .pin(); // Text upload using content alias const contentOp = await pinner.upload.content("Hello, world!") .name("greeting.txt") .pin();

Builder Methods

All builder methods support chaining:

MethodDescription
.name(string)Set the content name
.keyvalues(object)Set custom metadata
.waitForOperation(boolean)Wait for pinning completion
.operationPollingOptions(object)Configure polling behavior
.pin()Start the upload and return operation

Builder Namespace Methods

The upload interface also works as a namespace with these methods:

MethodInput TypeDescription
.file(file)FileUpload a File object
.json(data)objectUpload JSON as a file
.text(text)stringUpload text content
.content(text)stringAlias for .text()
.base64(data)stringUpload Base64 decoded content
.csv(data)string | object[] | any[][]Upload CSV data
.url(url)stringUpload from URL
.raw(car)File | ReadableStreamUpload raw CAR file