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.
What we promise, and what we don't
Yungle is small and self-hosted in the EU. There is no SLA and no uptime guarantee: it runs on a single server with no failover, so a hardware fault or a bad deploy means downtime rather than a graceful failover. It has happened, and it will happen again.
What you do get: your files are encrypted at rest, nothing is sent to a US cloud, and every byte is served from the EU under a real DPA. If your integration needs a contractual uptime guarantee, Yungle is not the right choice today — and we would rather you found that out here than during an incident.
Free usage is genuinely free: 10 GB of uploads through the API each month,50,000 calls, and 10 GB per transfer — no card, no trial clock. Beyond that it is €0.02 per GB uploaded, paid from credit you top up in advance. It is priced apart from the plans, so it works the same on Free, Leaf and Tree.
Prepaid on purpose. Nothing is ever served that has not been paid for, which means no invoice can arrive for traffic you did not expect and a runaway script cannot spend money you have not already given us. When the balance runs out your next upload is refused rather than your recipient's download failing — the refusal lands on you, where you can see and fix it, never on someone waiting for a file. What your recipients download is never metered at all. The call limit is an abuse guard rather than a price: it sits far above what a working integration uses, because a limit that trips in normal use is a support ticket, not a safeguard.