API examples

Copy-and-paste examples for the REST API, in curl and JavaScript. Each sends an API key (Studio and above, under Settings, API keys) or an OAuth access token (every plan) as a bearer token. Getting started lists the scopes and the errors.

The JavaScript examples share one small helper (Node 18 or newer, or any browser-like runtime with fetch):

const API = 'https://share.deltabreen.eu/api/v1'
const share = (path, init = {}) =>
  fetch(API + path, {
    ...init,
    headers: { Authorization: `Bearer ${process.env.SHARE_API_KEY}`, 'Content-Type': 'application/json' },
  }).then((r) => r.json())

Send a file from code

A file is encrypted on your machine before it is uploaded, so making one takes a client that encrypts. The command-line tool does it in one line and prints JSON for your script:

SHARE_API_KEY=sbk_… npx -y @deltabreen/share send ./report.pdf --to client@example.com --json
import { execFile } from 'node:child_process'
import { promisify } from 'node:util'

const { stdout } = await promisify(execFile)('npx', ['-y', '@deltabreen/share', 'send', './report.pdf', '--to', 'client@example.com', '--json'])
const sent = JSON.parse(stdout) // who it was emailed to, and when it expires

Check the key

The workspace, its plan, your role and the scopes the key has.

curl https://share.deltabreen.eu/api/v1/whoami \
  -H "Authorization: Bearer $SHARE_API_KEY"
const me = await share('/whoami')
{
  "email": "you@firm.example",
  "tier": "studio",
  "role": "owner",
  "scopes": ["shares:read", "shares:write", "inbox:read"],
  "via": "key:sbk_AbCd1234"
}

Your latest shares

Newest first, up to limit; pass the last one's created_at as before for the page after. File names are encrypted, so a share shows the label you gave it, if any.

curl "https://share.deltabreen.eu/api/v1/shares?limit=5" \
  -H "Authorization: Bearer $SHARE_API_KEY"
const { shares } = await share('/shares?limit=5')
{
  "shares": [
    {
      "id": "01a148ca-24e8-7280-9a46-0d8e85aec755",
      "status": "active",
      "label": "Q3 accounts",
      "downloads_finished": 2,
      "expires_at": "2026-10-24T07:36:09Z",
      "created_at": "2026-10-17T07:36:09Z"
    }
  ]
}

Who downloaded it

One share's activity, newest first: each opening and each download started and finished, with the browser it came from.

curl https://share.deltabreen.eu/api/v1/shares/SHARE_ID/receipts \
  -H "Authorization: Bearer $SHARE_API_KEY"
const { events } = await share(`/shares/${id}/receipts`)
{
  "events": [
    { "kind": "download_finished", "at": "2026-10-17T09:12:41Z", "ua_family": "Safari on iOS" },
    { "kind": "download_started", "at": "2026-10-17T09:12:30Z", "ua_family": "Safari on iOS" },
    { "kind": "download_clicked", "at": "2026-10-17T09:12:29Z", "ua_family": "Safari on iOS" }
  ]
}

Give it more time

A new expiry for an active share, up to your plan's longest. The answer says the latest it can be.

curl -X PATCH https://share.deltabreen.eu/api/v1/shares/SHARE_ID \
  -H "Authorization: Bearer $SHARE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"expires_at": "2026-11-30T17:00:00Z"}'
await share(`/shares/${id}`, { method: 'PATCH', body: JSON.stringify({ expires_at: '2026-11-30T17:00:00Z' }) })
{
  "share": {
    "id": "01a148ca-24e8-7280-9a46-0d8e85aec755",
    "status": "active",
    "expires_at": "2026-11-30T17:00:00Z",
    "expires_max": "2027-10-17T07:36:09Z"
  }
}

An upload link to send to someone: their browser encrypts what they choose, and the share is yours. Ask for the upload link again to see whether it has arrived.

curl -X POST https://share.deltabreen.eu/api/v1/handoffs \
  -H "Authorization: Bearer $SHARE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"label": "Signed contract", "note": "Please upload the signed contract."}'
const { handoff, url } = await share('/handoffs', {
  method: 'POST',
  body: JSON.stringify({ label: 'Signed contract', note: 'Please upload the signed contract.' }),
})
// Later: (await share(`/handoffs/${handoff.id}`)).handoff.status is "uploaded"
{
  "handoff": { "id": "134ced81-a1f9-4ad7-b491-4fdc4697a754", "status": "pending", "share_id": null },
  "url": "https://share.deltabreen.eu/u/sbh_Eg3Ln-8RHzzeX…#juwdD3Oz7O86X…"
}

What arrived

Files people sent to your file requests, newest first. They are encrypted for your workspace, so the command-line tool's receive is what saves one to disk.

curl "https://share.deltabreen.eu/api/v1/inbox?limit=5" \
  -H "Authorization: Bearer $SHARE_API_KEY"
const { items } = await share('/inbox?limit=5')
{
  "items": [
    {
      "id": "68cbf998-84c6-438d-8f0a-fe5687065657",
      "request_page_id": "4949d126-eaf7-4f7b-9619-578c97396248",
      "uploader_email": "client@example.com",
      "plaintext_size": 248113,
      "created_at": "2026-10-17T00:27:03Z",
      "opened_at": null
    }
  ]
}

Errors and rate limits

A refused call answers with its status and a stable code: 401 unauthorized without a key, 403 missing_scope when the key lacks the scope, 409 not_active for a share that has ended.