API

Send files from a script.

Upload a file, send it to somebody and find out whether they opened it, over plain HTTP. Included on every plan, the free one as well.

Authentication

Create a token at API tokens, then send it as a bearer token. A token is shown once, when you create it.

curl https://campsend.app/api/v1/deliveries \
  -H "Authorization: Bearer csnd_your_token"

A token either reads, or reads and sends. On the tokens page those are labelled "Read deliveries" and "Read and send deliveries". Using a read token to send answers 403, because the caller is known and not allowed.

You can hold 10 active tokens. Revoke one and anything using it stops working immediately.

Sending a file

Three steps: reserve the upload, put the bytes where Campsend tells you, then send the delivery.

1. Reserve the upload

Tell Campsend the file's name, size, content type and base64 MD5. It answers with a file id and a URL to upload to.

curl -X POST https://campsend.app/api/v1/direct_uploads \
  -H "Authorization: Bearer csnd_your_token" \
  -H "Content-Type: application/json" \
  -d '{"blob":{
        "filename":"cut.mov",
        "byte_size":184838014,
        "checksum":"qDIkB3r1BIBPveaZqQ7rNw==",
        "content_type":"video/quicktime"
      }}'

The response carries an id, which you need for step three, and a direct_upload object holding the url and the headers to send with it.

2. Put the bytes

Upload straight to the URL from step one. The bytes never pass through Campsend's servers.

curl -X PUT "$UPLOAD_URL" \
  -H "Content-Type: video/quicktime" \
  -H "Content-MD5: qDIkB3r1BIBPveaZqQ7rNw==" \
  --data-binary @cut.mov

Send the headers the reservation gave you, unchanged. A successful upload answers 204 with no body.

3. Send the delivery

curl -X POST https://campsend.app/api/v1/deliveries \
  -H "Authorization: Bearer csnd_your_token" \
  -H "Content-Type: application/json" \
  -d '{
        "recipient_email":"[email protected]",
        "file_ids":[148],
        "message":"The final cut."
      }'

Campsend emails the recipient a link that works for 30 days. The response is the delivery, including its delivery_identifier, which you use to read it later.

Optional fields: message up to 500 characters, slug for a readable link, and scheduled_at as an ISO 8601 time in the future to send it later instead of now. One delivery takes up to 20 files.

Listing deliveries

curl "https://campsend.app/api/v1/deliveries?limit=10&status=opened" \
  -H "Authorization: Bearer csnd_your_token"

Newest first. limit defaults to 25 and stops at 100. status narrows to one of sent, opened, downloaded, scheduled, canceled, revoked or expired.

Reading one delivery

curl https://campsend.app/api/v1/deliveries/DELIVERY_IDENTIFIER \
  -H "Authorization: Bearer csnd_your_token"

This is how you find out whether somebody opened your file. The response carries the files and an events list with the times it was sent, first opened and first downloaded.

A delivery that isn't yours answers 404 rather than 403, so nobody can work out which identifiers exist.

Errors

Every failure answers with a JSON object holding one error string, and a status that says what to do about it.

StatusWhat it means
401The token is missing, revoked or expired.
403The token can read but not send, and this call sends.
404No delivery of yours has that identifier.
413The file is larger than your plan sends in one delivery.
422Something in the request was wrong. The message says what.
429Too many requests. Wait and try again.

Nothing in any response contains an access token or a signed storage URL. Downloading a delivered file happens through the link the recipient gets, not through this API.

Limits

120 delivery requests an hour per token, and 60 upload reservations an hour. Your plan's own limits apply as well: how many deliveries a month, how much one delivery holds and how much storage you have.

See pricing for what each plan includes.

AI assistants

Campsend also speaks MCP, so an assistant such as Claude can send files and check whether they were opened, using the same tokens. Point your client at https://campsend.app/mcp with the token as a bearer token.

Give it a read token if you want it to look without being able to send.