Official Node.js SDK for dropthis -- the publish layer between AI and the internet. One API call in, one URL out.
npm install @dropthis/nodeimport { Dropthis } from "@dropthis/node";
const dropthis = new Dropthis({ apiKey: "sk_..." });
const { data, error } = await dropthis.publish("<h1>Hello</h1>");
console.log(data.url); // https://abc123.dropthis.appconst { data } = await dropthis.publish("<h1>Launch page</h1>");const { data } = await dropthis.publish("./report.html");const { data } = await dropthis.publish("./dist");const { data } = await dropthis.publish("./dist", {
title: "Q4 Report",
visibility: "unlisted",
password: "s3cret",
expiresAt: "2026-12-31T00:00:00Z",
});const created = await dropthis.publish("./dist", { title: "v1" });
const updated = await dropthis.update(created.data.id, "./dist-v2", {
ifRevision: created.data.revision,
});await dropthis.update("drop_abc123", { title: "New title" });The publish() method accepts:
- HTML string --
"<h1>Hello</h1>" - File path --
"./report.html" - Directory --
"./dist" - Bytes --
new Uint8Array(...) - Explicit object --
{ content: "...", contentType: "text/html" }or{ files: [...] }
All inputs are uploaded through staged presigned URLs. The SDK handles this transparently.
All methods return { data, error, headers }. Check error before using data.
const result = await dropthis.drops.get("drop_abc123");
if (result.error) {
console.error(result.error.code, result.error.message);
// error.statusCode, error.requestId also available
} else {
console.log(result.data);
}const dropthis = new Dropthis({
apiKey: "sk_...", // Required. Defaults to DROPTHIS_API_KEY env var.
baseUrl: "https://...", // Override API base URL.
timeoutMs: 30_000, // Request timeout in milliseconds.
fetch: customFetch, // Custom fetch implementation.
});You can also pass just the API key as a string:
const dropthis = new Dropthis("sk_...");await dropthis.drops.list({ limit: 20 });
await dropthis.drops.get("drop_abc123");
await dropthis.drops.create({ uploadId: "upl_abc123", options: { title: "New" } });
await dropthis.drops.createRaw({ upload_id: "upl_abc123" }); // no snake_case conversion
await dropthis.drops.update("drop_abc123", { title: "Updated" });
await dropthis.drops.delete("drop_abc123");List results support auto-pagination:
const page = await dropthis.drops.list();
const allDrops = await page.data.autoPagingToArray({ limit: 100 });
// Or iterate
for await (const drop of page.data) {
console.log(drop.url);
}await dropthis.deployments.create("drop_abc123", { uploadId: "upl_xyz789" });
await dropthis.deployments.createRaw("drop_abc123", { upload_id: "upl_xyz789" });
await dropthis.deployments.list("drop_abc123");
await dropthis.deployments.get("drop_abc123", "dep_xyz789");Low-level upload session management. Most users should use publish() instead.
await dropthis.uploads.create({
schemaVersion: 1,
files: [{ path: "index.html", contentType: "text/html", sizeBytes: 1024 }],
});
await dropthis.uploads.get("upl_abc123");
await dropthis.uploads.createPartTargets("upl_abc123", {
fileId: "file_xyz",
partNumbers: [1, 2, 3],
});
await dropthis.uploads.complete("upl_abc123", { files: {} });
await dropthis.uploads.cancel("upl_abc123");await dropthis.auth.requestEmailOtp({ email: "you@example.com" });
await dropthis.auth.verifyEmailOtp({ email: "you@example.com", code: "123456" });
await dropthis.auth.logout();await dropthis.apiKeys.create({ label: "CI" });
await dropthis.apiKeys.list();
await dropthis.apiKeys.delete("key_abc123");await dropthis.account.get();
await dropthis.account.update({ displayName: "Jane Doe" });
await dropthis.account.delete();Key types exported from the package:
import type {
DropthisClientOptions,
DropthisResult,
DropthisErrorResponse,
DropResponse,
DropDeploymentResponse,
ListPage,
CreateUploadSessionRequest,
CreateUploadSessionResponse,
} from "@dropthis/node";For AI coding agents (Cursor, Claude Code, Windsurf, etc.), this SDK ships with a built-in agent skill at skills/dropthis-node/SKILL.md. For the CLI skill, see the CLI repo.