Skip to main content

Node.js Examples

All examples use the built-in fetch API (Node.js 18+) and fs module. No additional packages required. Set your API key as an environment variable:
export AGENTDROP_API_KEY="agd_live_xxxxxxxxxxxxxxxxxxxx"

Helper Setup

import fs from "fs";
import path from "path";

const BASE_URL = "https://agentdrop-production.up.railway.app";
const API_KEY = process.env.AGENTDROP_API_KEY;
const HEADERS = { Authorization: `Bearer ${API_KEY}` };

Upload a Single File

async function uploadFile(filepath, sender, recipient, expiresIn = "24h") {
  const form = new FormData();
  form.append("sender", sender);
  form.append("recipient", recipient);
  form.append("expires_in", expiresIn);
  form.append(
    "files",
    new Blob([fs.readFileSync(filepath)]),
    path.basename(filepath)
  );

  const response = await fetch(`${BASE_URL}/v1/transfers`, {
    method: "POST",
    headers: HEADERS,
    body: form,
  });

  if (!response.ok) throw new Error(`Upload failed: ${response.status}`);
  return response.json();
}

const transfer = await uploadFile(
  "report.pdf",
  "research-agent",
  "analysis-agent"
);
console.log(`Transfer ID: ${transfer.id}`);

Upload Multiple Files

async function uploadFiles(filepaths, sender, recipient, options = {}) {
  const form = new FormData();
  form.append("sender", sender);
  form.append("recipient", recipient);

  if (options.encrypted) form.append("encrypted", "true");
  if (options.maxDownloads)
    form.append("max_downloads", String(options.maxDownloads));
  if (options.expiresIn) form.append("expires_in", options.expiresIn);

  for (const filepath of filepaths) {
    form.append(
      "files",
      new Blob([fs.readFileSync(filepath)]),
      path.basename(filepath)
    );
  }

  const response = await fetch(`${BASE_URL}/v1/transfers`, {
    method: "POST",
    headers: HEADERS,
    body: form,
  });

  if (!response.ok) throw new Error(`Upload failed: ${response.status}`);
  return response.json();
}

const transfer = await uploadFiles(
  ["data.csv", "metadata.json"],
  "etl-pipeline",
  "dashboard-agent",
  { encrypted: true, maxDownloads: 5 }
);

Download a Transfer

async function downloadTransfer(transferId, outputPath) {
  const response = await fetch(
    `${BASE_URL}/v1/transfers/${transferId}/download`,
    { headers: HEADERS }
  );

  if (!response.ok) throw new Error(`Download failed: ${response.status}`);

  const buffer = Buffer.from(await response.arrayBuffer());
  fs.writeFileSync(outputPath, buffer);

  const remaining = response.headers.get("X-Downloads-Remaining");
  console.log(`Saved to ${outputPath} (${remaining} downloads remaining)`);
}

await downloadTransfer("txfr_abc123", "report.pdf");

Check Transfer Status

async function getTransfer(transferId) {
  const response = await fetch(`${BASE_URL}/v1/transfers/${transferId}`, {
    headers: HEADERS,
  });

  if (!response.ok) throw new Error(`Fetch failed: ${response.status}`);
  return response.json();
}

const transfer = await getTransfer("txfr_abc123");
console.log(`Status: ${transfer.status}`);
console.log(`Downloads: ${transfer.download_count}/${transfer.max_downloads}`);

List All Transfers

async function listTransfers(page = 1, limit = 20) {
  const response = await fetch(
    `${BASE_URL}/v1/transfers?page=${page}&limit=${limit}`,
    { headers: HEADERS }
  );

  if (!response.ok) throw new Error(`List failed: ${response.status}`);
  return response.json();
}

const result = await listTransfers();
result.data.forEach((t) => {
  console.log(`${t.id} | ${t.status} | ${t.sender} -> ${t.recipient}`);
});

Delete a Transfer

async function deleteTransfer(transferId) {
  const response = await fetch(`${BASE_URL}/v1/transfers/${transferId}`, {
    method: "DELETE",
    headers: HEADERS,
  });

  if (!response.ok) throw new Error(`Delete failed: ${response.status}`);
  return response.json();
}

const result = await deleteTransfer("txfr_abc123");
console.log(`Deleted: ${result.status}`);

Full Send-and-Receive Flow

import fs from "fs";
import path from "path";

const BASE_URL = "https://agentdrop-production.up.railway.app";
const API_KEY = process.env.AGENTDROP_API_KEY;
const HEADERS = { Authorization: `Bearer ${API_KEY}` };

// --- Sender Agent ---
async function senderWorkflow() {
  const form = new FormData();
  form.append("sender", "finance-agent");
  form.append("recipient", "exec-summary-agent");
  form.append("expires_in", "12h");
  form.append("max_downloads", "3");
  form.append(
    "files",
    new Blob([fs.readFileSync("quarterly-report.pdf")]),
    "quarterly-report.pdf"
  );

  const response = await fetch(`${BASE_URL}/v1/transfers`, {
    method: "POST",
    headers: HEADERS,
    body: form,
  });

  const transfer = await response.json();
  console.log(`Uploaded. Transfer ID: ${transfer.id}`);
  return transfer.id;
}

// --- Receiver Agent ---
async function receiverWorkflow(transferId) {
  // Check status
  const statusResp = await fetch(`${BASE_URL}/v1/transfers/${transferId}`, {
    headers: HEADERS,
  });
  const transfer = await statusResp.json();

  if (transfer.status !== "active") {
    console.log(`Transfer not available: ${transfer.status}`);
    return;
  }

  // Download
  const dlResp = await fetch(
    `${BASE_URL}/v1/transfers/${transferId}/download`,
    { headers: HEADERS }
  );
  const buffer = Buffer.from(await dlResp.arrayBuffer());
  fs.writeFileSync("received-report.pdf", buffer);
  console.log("File received and saved.");
}

// Run
const transferId = await senderWorkflow();
await receiverWorkflow(transferId);

Error Handling

async function safeUpload(filepath, sender, recipient) {
  try {
    const form = new FormData();
    form.append("sender", sender);
    form.append("recipient", recipient);
    form.append(
      "files",
      new Blob([fs.readFileSync(filepath)]),
      path.basename(filepath)
    );

    const response = await fetch(`${BASE_URL}/v1/transfers`, {
      method: "POST",
      headers: HEADERS,
      body: form,
    });

    if (response.status === 413) {
      console.error(
        "File too large for your plan. Upgrade at https://agent-drop.com/pricing"
      );
      return null;
    }

    if (response.status === 429) {
      console.log("Rate limited. Waiting 60 seconds...");
      await new Promise((r) => setTimeout(r, 60000));
      return safeUpload(filepath, sender, recipient);
    }

    if (!response.ok) {
      console.error(`HTTP ${response.status}: ${await response.text()}`);
      return null;
    }

    return response.json();
  } catch (err) {
    console.error(`Network error: ${err.message}`);
    return null;
  }
}