← Yungle

Yungle API

Delivery is usually a step in a pipeline, not a website you visit. The API lets your own systems do it: create a transfer, stream the bytes, send it, and find out who collected it. Reading is free on any account; creating, sending and uploading come with a paid plan.

Quickstart

Create a key in Settings → API keys, then check it works:

curl https://yungle.co/api/v1/me \
  -H "Authorization: Bearer $YUNGLE_API_KEY"

Sending a file is three calls plus the upload itself:

# 1. Create the draft. Nothing is live and nobody is emailed yet.
curl -X POST https://yungle.co/api/v1/transfers \
  -H "Authorization: Bearer $YUNGLE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"files":[{"name":"final-cut.mov","size":8123456789}]}'

# → { "transfer": { "id": "01J…", "slug": "…" },
#     "tusEndpoint": "https://yungle.co/files",
#     "files": [ { "id": "01J…", "uploadToken": "…" } ] }

# 2. Stream the bytes to tusEndpoint (resumable — see Uploading files).

# 3. Send it.
curl -X POST https://yungle.co/api/v1/transfers/01J…/finalize \
  -H "Authorization: Bearer $YUNGLE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"recipients":["client@example.com"],"message":"Final cut attached."}'

How it is shaped

  • Base URL is https://yungle.co/api/v1. Everything is JSON in and JSON out.
  • File bytes never go through this API. Endpoints that accept files hand you a tus endpoint and a per-file token; you stream to that. It is resumable at part granularity, which is the point — a 100 GB upload should survive a dropped connection.
  • Creating and sending are separate calls. A transfer is created as a draft, so bytes land before anyone is emailed a link.
  • Resources are addressed by id, never by slug. A share slug is a capability — anyone holding it can download — so it is returned but never used as an address.

Versioning

/api/v1 is additive-only. New fields and new endpoints may appear; existing fields will not change meaning or disappear, and no new required request field will be added. A change that would break a client gets /api/v2 instead, and v1 keeps working.

The machine-readable contract lives at /api/v1/openapi.json — OpenAPI 3.1, generated from the same definitions the server validates with, so it cannot drift from the running code. It needs no key to read.

The vault and end-to-end encrypted transfers are not reachable from the API, and cannot be — their keys are derived in your browser and never sent to us. What the API cannot do explains where that boundary is.