Getting started
Authentication
API keys, what Free plan keys can do, rate limits, and OAuth sign-in for MCP clients.
API keys#
Every call to /v1 is made with an API key. Create one in Settings → Developer. Keys start with sd_, belong to your account, and are shown in full only once. The list in Settings shows each key's first characters and when it was last used, and you can revoke a key there at any time.
Send the key as a bearer token. An x-api-key header works too, for tools that can't set Authorization.
curl https://api.slingdrop.my/v1/me \
-H "Authorization: Bearer $SLINGDROP_API_KEY"import { Slingdrop } from "@slingdrop/sdk";
const sd = new Slingdrop({ apiKey: process.env.SLINGDROP_API_KEY });
const me = await sd.me(); // { id, email, name, plan, limits }# Either sign in once (saves a key in ~/.config/slingdrop/config.json)
slingdrop login
# or pass a key, e.g. in CI
SLINGDROP_API_KEY=sd_… slingdrop whoamiKeep keys on the server
A key can do anything your account can through the API. Don't ship it in a browser bundle or a mobile app. For uploads from your users' browsers, hand out signed upload URLs from your server instead.
Keys Slingdrop makes for you#
slingdrop logincreates a key named CLI on <your computer>.slingdrop logoutforgets it locally; revoke it in Settings to switch it off.- Signing in an MCP client with OAuth creates a key named MCP: <app name> (see below).
- The “try it” console on the API reference uses a temporary key that expires after an hour.
What each plan's keys can do#
Every signed-in plan, Free included, can use the whole API: create and manage drops, folders, file requests, reviews, webhooks and file hosting. Plans differ in how many calls a key can make per day and in the same limits the app enforces (drop size, storage, recipients and so on). Signed-out visitors can't create keys.
| Plan | Calls per key per day | Notes |
|---|---|---|
| Free | 1,000 | 1 GB per drop, 15 drops a day, 2 GB storage, up to 5 private recipients. Hosting: 1 GB, 25 MB per file. |
| Pro | 10,000 | 15 GB per drop, unlimited drops, 50 GB storage. |
| Team | 100,000 | 50 GB per drop, 250 GB pooled storage. |
The daily allowance is a rolling 24-hour window counted per key. Over it, calls answer 429 with "code": "rate_limited". The full list is on Limits.
Changed plan?
A key gets its daily allowance when it's created. After upgrading, create a new key (or sign in to the CLI again) to get the higher allowance.
Authentication errors#
| Status | code | Meaning |
|---|---|---|
| 401 | unauthorized | No key, a key that doesn't start with sd_, or a revoked or expired key. |
| 429 | rate_limited | This key has used its daily allowance. |
| 403 | plan_required | The request needs a higher plan (for example a burned-in watermark on Free). |
OAuth for MCP clients#
AI clients such as Claude, ChatGPT and Cursor connect to https://slingdrop.my/mcp and sign in with OAuth, so you never paste a key. Slingdrop runs a small OAuth 2.1 server for this:
- Discovery at
/.well-known/oauth-protected-resourceand/.well-known/oauth-authorization-server. - Dynamic client registration at
POST /api/oauth/register, so clients register themselves. - Authorization code with PKCE (
S256) only, scopeslingdrop, public clients (no client secret). You approve the app on a Slingdrop consent screen at/oauth/authorize. - The token endpoint,
POST /api/oauth/token, returns an ordinary Slingdrop API key as the access token, with your plan's daily allowance. It's listed in Settings as MCP: <app name>, and revoking it there signs the app out.
Clients that can't do OAuth can send an API key instead: Authorization: Bearer sd_… on the remote server, or SLINGDROP_API_KEY for the local npx -y @slingdrop/mcp server. Setup for each client is in AI agents (MCP).
curl https://slingdrop.my/.well-known/oauth-authorization-server
# → { "issuer": "https://slingdrop.my", "authorization_endpoint": "https://slingdrop.my/oauth/authorize",
# "token_endpoint": "https://slingdrop.my/api/oauth/token", "registration_endpoint": "https://slingdrop.my/api/oauth/register",
# "code_challenge_methods_supported": ["S256"], "scopes_supported": ["slingdrop"], … }