Developers
TypeScript SDK
A tiny, dependency-free TypeScript helper that wraps the presigned upload flow, downloads, and provenance verification — paste it into your project and go.
Overview
There is no package to install — the API is plain HTTP/JSON, so the “SDK” is a small client you can drop into any TypeScript project. It uses only the built-in fetch and crypto.subtle, so it runs in modern browsers, Node 18+, Deno, and edge runtimes.
Note
The client mirrors the three-step upload flow and the REST endpoints. Response shapes match the DTOs at the bottom of this page.
The client
udrive.tsTypeScript
export interface UdriveOptions {
/** Base URL, e.g. https://udrive.one */
baseUrl?: string;
/** Forwarded as the Cookie header for authenticated calls (server-side). */
cookie?: string;
}
export interface UploadInit {
name: string;
contentType?: string;
visibility?: "public" | "unlisted" | "private";
allowTraining?: boolean;
trainingPrice?: number;
expiresAt?: string | null;
}
export interface UploadResult {
shortId: string;
shareUrl: string;
}
async function sha256Hex(data: ArrayBuffer): Promise<string> {
const digest = await crypto.subtle.digest("SHA-256", data);
return [...new Uint8Array(digest)]
.map((b) => b.toString(16).padStart(2, "0"))
.join("");
}
export function createUdrive(opts: UdriveOptions = {}) {
const base = (opts.baseUrl ?? "https://udrive.one").replace(/\/+$/, "");
async function api<T>(path: string, init?: RequestInit): Promise<T> {
const res = await fetch(base + path, {
...init,
headers: {
"content-type": "application/json",
...(opts.cookie ? { cookie: opts.cookie } : {}),
...init?.headers,
},
});
if (!res.ok) {
const body = await res.json().catch(() => ({}));
throw new Error(body?.error?.message ?? `udrive: ${res.status}`);
}
return res.json() as Promise<T>;
}
return { base, api, sha256Hex };
}Uploading
One call presigns, PUTs the bytes, and finalizes — returning the share URL. It hashes the file so integrity is recorded.
upload.tsTypeScript
export async function upload(
client: ReturnType<typeof createUdrive>,
data: Blob | ArrayBuffer,
init: UploadInit,
): Promise<UploadResult> {
const bytes = data instanceof Blob ? await data.arrayBuffer() : data;
const contentType =
init.contentType ??
(data instanceof Blob ? data.type : "application/octet-stream");
// 1. Presign.
const presign = await client.api<{
fileId: string;
uploadUrl: string;
headers: Record<string, string>;
}>("/api/upload/presign", {
method: "POST",
body: JSON.stringify({
name: init.name,
size: bytes.byteLength,
contentType,
visibility: init.visibility ?? "unlisted",
allowTraining: init.allowTraining,
trainingPrice: init.trainingPrice,
expiresAt: init.expiresAt,
}),
});
// 2. Upload bytes straight to storage.
const put = await fetch(presign.uploadUrl, {
method: "PUT",
headers: presign.headers,
body: bytes,
});
if (!put.ok) throw new Error(`upload failed: ${put.status}`);
// 3. Finalize with an integrity digest.
return client.api<UploadResult>("/api/upload/complete", {
method: "POST",
body: JSON.stringify({
fileId: presign.fileId,
sha256: await client.sha256Hex(bytes),
}),
});
}TypeScript
const udrive = createUdrive();
const file = new Blob(["id,score\n1,42\n"], { type: "text/csv" });
const { shareUrl } = await upload(udrive, file, {
name: "scores.csv",
visibility: "public",
});
console.log(shareUrl); // https://udrive.one/f/a1B2c3D4e5F6Downloads & verification
TypeScript
// Public-safe metadata for a file view.
const meta = await udrive.api(`/api/f/${shortId}/meta`);
// Re-verify a provenance signature.
const proof = await udrive.api<{
signed: boolean;
verified: boolean;
signerPubkey: string | null;
}>(`/api/verify/${shortId}`);
// The download URL mints a fresh presigned link on each hit.
const downloadUrl = `${udrive.base}/api/f/${shortId}/download`;Shared types
The API responds with the same DTOs the udrive UI is typed against. These are the most useful ones to copy into your project:
dto.tsTypeScript
export type Visibility = "public" | "unlisted" | "private";
export type Encryption = "none" | "server" | "e2e";
export interface FileDTO {
id: string;
shortId: string;
name: string;
size: number;
contentType: string;
visibility: Visibility;
encryption: Encryption;
signed: boolean;
signerPubkey: string | null;
downloadCount: number;
allowTraining: boolean;
trainingPrice: string;
shareUrl: string;
downloadUrl: string;
createdAt: string;
expiresAt: string | null;
}
export interface ProvenanceResult {
signed: boolean;
verified: boolean;
signerPubkey: string | null;
statement: string | null;
}Tip
Authenticated calls (your drive, earnings, account) need the
udrive_sessioncookie. In the browser it's sent automatically; server-side, pass it via the cookie option.