Skip to content
Slingdrop

Sharing & feedback

Drops

Create and update drops, upload files, publish versions, and control expiry, visibility, purpose and folders.

A drop is a link to one or more files. It has a current version, an optional history of earlier versions, an access setting (public, passcode or named people), an expiry, and a purpose that decides whether people are asked for feedback.

Endpoints#

POST/dropsCreate a drop and get upload targets
GET/dropsList your drops
GET/drops/{id}A drop with its files and versions
PATCH/drops/{id}Change access, purpose, expiry or folder
POST/drops/{id}/versionsPublish a new version behind the same link
POST/drops/{id}/revokeTurn off the link
DELETE/drops/{id}Move to Trash, or delete with ?forever=1
GET/drops/{id}/analyticsViews, viewers, dwell time and devices
GET/drops/{id}/commentsEvery comment, with where it's pinned

Paths are relative to https://api.slingdrop.my/v1. Try them in the API reference.

Create a drop#

Creating a drop is two steps: describe the files and get back the link plus one upload target per file, then send each file's bytes. The link exists immediately; viewers see the drop once every file is in. The SDK and CLI do both steps for you.

curl
curl https://api.slingdrop.my/v1/drops \
  -H "Authorization: Bearer $SLINGDROP_API_KEY" \
  -H "content-type: application/json" \
  -d '{
    "title": "Launch assets",
    "purpose": "share",
    "visibility": "private",
    "recipients": [{ "email": "ana@studio.com", "role": "commenter" }],
    "expiry": "30d",
    "files": [
      { "name": "logo.svg", "size": 18211, "type": "image/svg+xml", "relativePath": "brand/logo.svg" },
      { "name": "hero.mp4", "size": 48211990, "type": "video/mp4" }
    ]
  }'

Request body#

filesarrayrequired
1–2,000 entries of { name, size, type?, relativePath? }. size is in bytes and must match what you upload. relativePath keeps folder structure.
titlestring
Shown on the drop page. Defaults to the first file name (“logo + 1 more”).
purpose"share" | "feedback"
Default "feedback" on the REST API (the SDK and CLI default to "share"). See Purpose.
visibility"public" | "passcode" | "private"
Default "public". See Who can open it.
passcodestring
4–12 characters. Required when visibility is passcode.
recipientsarray
{ email, role } with role viewer, commenter or editor. Required (at least one) when visibility is private. They're emailed once the files are in.
expirystring
1h, 24h, 7d, 30d, 90d, forever or burn. See Expiry.
folderIdstring | null
File it in one of your folders. Left out, your filing rules may file it.
source"cli" | "mcp"
Which client made it. See Source.
notestring
A message shown with the first version (up to 2,000 characters).
allowDownloadboolean
Default true. false makes it view-only.
allowCommentboolean
Defaults to on for feedback drops and off for share drops.
requireApprovalboolean
Ask recipients to approve. Default false. See Reviews.
allowEditboolean
Let editors change docs and notes. Default false.
notifyOnViewboolean
Email you when it's opened. Default true.
watermark"off" | "overlay" | "burned"
Viewer watermark. burned needs Pro or Team.
encryption"none" | "vault"
Vault drops are encrypted on your machine; use the SDK's vault: true or the CLI's --vault rather than doing it by hand.
organizationIdstring
Send as a team you belong to. Team policies (allowed visibility, expiry, domains) apply.
replyTostring
Link id of a drop this one answers. Its owner is notified.
boostboolean
Spend a Boost bought in the app: one drop up to 10 GB, live for 14 days.

Response#

201 Created
{
  "drop": { "id": "k7Qm2xPa", "linkId": "k7Qm2xPa", "url": "https://slingdrop.my/d/k7Qm2xPa", "expiresAt": "2026-11-20T09:12:00.000Z", "folderId": null },
  "ownerKey": "…",
  "files": [
    { "id": "F1", "mode": "single", "partSize": 8388608, "token": "T1" },
    { "id": "F2", "mode": "multipart", "partSize": 8388608, "token": "T2" }
  ]
}

files is in the same order as your request. folderId tells you if a filing rule filed it.

Uploads#

Each upload target carries a token, valid for seven days. Send it as x-upload-token. Uploads go to https://slingdrop.my/api/uploads/{fileId} and don't need your API key.

  • single (10 MB or less): PUT /api/uploads/{fileId} with the raw bytes. The Content-Length must equal the declared size, or you get 400 size_mismatch.
  • multipart (over 10 MB): PUT /api/uploads/{fileId}/parts/{n} for each partSize slice, numbered from 1, then POST /api/uploads/{fileId}/complete with the parts. Parts can go up in parallel. DELETE /api/uploads/{fileId} abandons the upload.
Multipart upload
# A file over 10 MB comes back as { "id": "F2", "mode": "multipart", "partSize": 8388608, "token": "T2" }.
# Upload each 8 MB slice (the last may be smaller), numbered from 1:
curl -X PUT https://slingdrop.my/api/uploads/F2/parts/1 -H "x-upload-token: T2" --data-binary @part1
# → { "partNumber": 1, "etag": "…" }
curl -X PUT https://slingdrop.my/api/uploads/F2/parts/2 -H "x-upload-token: T2" --data-binary @part2
# …

# Then finish with every part's etag:
curl -X POST https://slingdrop.my/api/uploads/F2/complete \
  -H "x-upload-token: T2" -H "content-type: application/json" \
  -d '{ "parts": [{ "partNumber": 1, "etag": "…" }, { "partNumber": 2, "etag": "…" }] }'

Repeating a finished upload is harmless: it answers { "ok": true }. When the last file of a drop is in, the drop becomes active, private recipients are emailed and a drop.ready webhook fires.

Purpose: share or feedback#

sharefeedback
ForSending and keeping filesAsking for comments and approval
CommentsOff unless allowComment is trueOn unless allowComment is false
Default expiry (REST, signed in)Kept until you delete it24 hours
Default expiry (SDK / CLI, signed in)Kept until you delete it7 days

Switch later with PATCH { "purpose": "share" }, which also turns comments and approval off unless the same update sets them. Switching to feedback turns comments on.

Who can open it#

  • public: anyone with the link.
  • passcode: anyone with the link and the passcode (4–12 characters).
  • private: only the listed recipients, who sign in with that email. Free allows 5 recipients per drop; Pro and Team are effectively unlimited.

Vault drops (encryption: "vault") are end-to-end encrypted: the key lives only in the #k= part of the share URL the SDK returns, so Slingdrop can't read them, preview them or search them, and can't email the link for you.

Expiry#

ValueMeaning
1hOne hour from now (also: 24h, 7d, 30d, 90d).
foreverKept until you delete it, within your storage. Signed-in plans only.
burnBurn after reading: the first person to open it gets 30 minutes, then the link is gone. Create only.

Without an account, drops last at most 24 hours. PATCH with a new expiry resets the clock from now. An expired drop stops opening; drops you delete go to Trash and can be restored in the app for 30 days.

Update a drop#

curl
curl -X PATCH https://api.slingdrop.my/v1/drops/$DROP_ID \
  -H "Authorization: Bearer $SLINGDROP_API_KEY" -H "content-type: application/json" \
  -d '{ "visibility": "passcode", "passcode": "tiger42", "expiry": "7d", "allowDownload": false }'

You can change title, purpose, visibility, passcode, recipients (replaces the list; new people are emailed), allowDownload, allowComment, allowEdit, requireApproval, notifyOnView, watermark, expiry (not burn), pinnedToProfile and folderId. Access changes are written to the audit log. The response is the updated drop in data.

Versions#

A new version replaces the files behind the same link. Open comments move to the file with the same path in the new version, people who have the drop are told, and a version.created webhook fires.

curl
curl https://api.slingdrop.my/v1/drops/$DROP_ID/versions \
  -H "Authorization: Bearer $SLINGDROP_API_KEY" -H "content-type: application/json" \
  -d '{ "note": "Tighter kerning on the logo", "files": [{ "name": "logo.svg", "size": 18004, "type": "image/svg+xml" }] }'
# → { "version": { "id": "…", "number": 2 }, "files": [{ "id": "F3", "mode": "single", "token": "T3", … }] }
# Upload the bytes exactly as for a new drop. Version 2 goes live when its last file is in.

Free keeps the last 3 versions (older ones are deleted when a new one goes live); Pro and Team keep them all. GET /drops/{id} lists them. The drop must be active, or you get 409 inactive.

Folders#

Pass folderId when creating or updating a drop to file it; null on update unfiles it. List one folder with GET /drops?folderId={id}, or unfiled drops with ?folderId=none. When you create a drop without a folder, your filing rules run. Only the sender can file a drop.

Source#

Every drop records where it came from: web, mobile, email, request, api, cli or mcp. Over the API you may only claim cli or mcp; anything else is recorded as api. The library can filter by source, and filing rules can match on it (for example “everything from my agents goes in AI work”). It's returned as source on GET /drops/{id}.

List and read#

GET /drops returns up to 200 of your most recent live drops in data; add ?status=all to include expired, revoked and trashed ones. GET /drops/{id} adds files and versions.

SDK
const drops = await sd.drops.list();          // or sd.drops.list("all")
const drop = await sd.drops.get(drops[0]!.id);  // with files and versions
const report = await sd.drops.analytics(drop.id, 7);
const comments = await sd.drops.comments(drop.id);

Analytics take ?days= (1–365, default 30). Free gets the basic report; Pro and Team get the full one with per-viewer and per-page detail.

Revoke or delete#

curl
# Turn the link off (the drop stays in your library)
curl -X POST https://api.slingdrop.my/v1/drops/$DROP_ID/revoke -H "Authorization: Bearer $SLINGDROP_API_KEY"

# Move to Trash (restorable for 30 days) or delete right away
curl -X DELETE "https://api.slingdrop.my/v1/drops/$DROP_ID" -H "Authorization: Bearer $SLINGDROP_API_KEY"
curl -X DELETE "https://api.slingdrop.my/v1/drops/$DROP_ID?forever=1" -H "Authorization: Bearer $SLINGDROP_API_KEY"

File requests#

The other direction: a link people use to upload files to you. Each upload becomes a drop in your library (source request).

curl
curl https://api.slingdrop.my/v1/requests \
  -H "Authorization: Bearer $SLINGDROP_API_KEY" -H "content-type: application/json" \
  -d '{ "title": "Brand assets", "instructions": "Logo in SVG please", "deadlineAt": "2026-11-01T17:00:00Z",
        "items": [{ "label": "Logo", "required": true, "acceptedTypes": [".svg"] }] }'
# → { "id": "…", "url": "https://slingdrop.my/r/…" }

Fields: title (required), instructions, visibility and passcode, allowedEmails, maxSizeBytes, deadlineAt, remindersEnabled, items (a checklist, Pro and Team) and organizationId. publicNameMode (full, first, custom or hidden) with publicName for a custom name sets how you appear to uploaders on this request; leave it out to use your account setting. Your email is never shown. PATCH /requests/{id} closes or reopens one, POST /requests/{id}/nudge reminds invited people who haven't uploaded (at most every 6 hours), and DELETE removes it while keeping uploaded drops. Free allows one open request at a time.

Common errors#

StatuscodeWhen
400invalidA field failed validation; the message names it.
401login_requiredA feature that needs an account, e.g. forever without a signed-in owner.
403plan_requiredOver a plan limit: expiry, recipients, burned-in watermark.
404not_foundNot your drop, or no such drop.
413too_largeThe drop is bigger than your plan allows per drop.
413storage_fullYour storage is full.
429daily_limitYou've hit your plan's drops per 24 hours.

Errors always carry error (a sentence you can show) and code. The SDK throws them as SlingdropError with status and code.