pixeldrive

Upload the files. Here are the URLs.

Pixeldrive is agent storage: a write API (HTTP, SDK, MCP), originals on a CDN, and a JSON listing. Share a public project to render on the web. Pro adds image transforms. No CMS schema, no bucket wiring.

Publish a listingUploadAllowed typesAPI referenceSDKMCP

Allowed types

Same allowlist on the dashboard, POST /v1/upload, the SDK, and MCP. kind is derived from MIME — callers never send it. HTML, SVG, and JavaScript are rejected, including on private projects.

kindWhatAccepts
imagePhotosimage/* except SVG
videoVideovideo/*
pdfPDFapplication/pdf
docWord.doc, .docx
textMarkdowntext/markdown

A project can tighten this list and the max file size in Settings → Uploads. It cannot raise the account plan cap. Keys inherit the project’s rules.

1. Share a project or folder

In the app, open a project and turn on Public API (project settings), or share a single folder from the folder view. Copy the link. It looks like:

GET
https://api.pixeldrive.dev/v1/projects/{publicId}

Private projects never publish a listing. Use a Bearer API key instead — see Sharing.

2. Fetch the listing

No API key for a shared public project. CORS is open. A 404 means the id is wrong, sharing is still off, or you need a Bearer key (unpublished public listing / private project).

fetch
const res = await fetch(
  "https://api.pixeldrive.dev/v1/projects/YOUR_PUBLIC_ID",
);
if (!res.ok) {
  throw new Error("Not found or listing unpublished");
}
const project = await res.json();

for (const file of project.files) {
  console.log(file.name, file.kind, file.url);
}

3. Upload with a write key

API keys live in project settings. Create a Write key in project settings. POST /v1/upload returns a presigned PUT (small files) or multipart URLs — never POST the file body to this API. Put-mode curl:

curl
curl -sS https://api.pixeldrive.dev/v1/upload \
  -H "Authorization: Bearer pd_live_…" \
  -H "Content-Type: application/json" \
  -d '{"name":"hero.jpg","contentType":"image/jpeg","size":4821933}'

# PUT the bytes to upload.url (mode: put), then:
curl -sS https://api.pixeldrive.dev/v1/upload/FILE_PUBLIC_ID/complete \
  -H "Authorization: Bearer pd_live_…" \
  -H "Content-Type: application/json" \
  -d '{}'

TypeScript: npm i @pixeldrive-dev/sdk. upload() hides put vs multipart. Full client: SDK.

sdk
import { readFile } from "node:fs/promises";
import { Pixeldrive } from "@pixeldrive-dev/sdk";

const pd = new Pixeldrive({ apiKey: process.env.PIXELDRIVE_API_KEY });

const file = await pd.upload({
  file: await readFile("./hero.jpg"),
  name: "selects/hero.jpg",
  contentType: "image/jpeg",
});

console.log(file.publicId, file.url);

Agents: npx @pixeldrive-dev/mcp with PIXELDRIVE_API_KEY. Setup and tools: MCP. Path-in-filename, tags, and rate limits live on the API page. The project’s Upload rules apply to keys the same as the dashboard.

mcp.json
{
  "mcpServers": {
    "pixeldrive": {
      "command": "npx",
      "args": ["-y", "@pixeldrive-dev/mcp"],
      "env": {
        "PIXELDRIVE_API_KEY": "pd_live_…"
      }
    }
  }
}

4. Render the files

Each file has url (this exact version, cached for a year) and stableUrl (https://cdn.pixeldrive.dev/f/{publicId}, follows replaces). Use url in <img> for photos unless you need the latest version after a replace. Other kinds are files — link them; don’t drop a PDF into an image tag.

Pro listings include src / srcset when optimizable is true. Or pass stableUrl to a width-based loader — see File URLs. ?w= only resizes photos.

JSX
{files.map((file) =>
  file.kind === "image" ? (
    <img
      key={file.publicId}
      src={file.url}
      alt={file.name}
      width={file.width}
      height={file.height}
    />
  ) : (
    <a key={file.publicId} href={file.stableUrl}>
      {file.name}
    </a>
  ),
)}

What you get

  • Nested folders as child listings, or flatten a small tree with ?recursive=true
  • Project-scoped tags as slugs on each file (tags). What you see in the app is what you pass to ?tag=la-jolla
  • kind, MIME, size, and for photos: width, height, optional blurhash
  • Page through large folders with nextCursor — up to 500 files per request; see the API