yungle-cli, yungle-mcp, yungle-client, yungle, yungle-e2e and the browser extension). Newest first.
Versioning
/api/v1 is additive-only. New fields and endpoints may appear here; nothing existing will change meaning, disappear, or become required. Anything that would break a client ships as /api/v2, and v1 keeps working.
What counts as additive
- A new endpoint, or a new method on an existing one.
- A new optional request field.
- A new field in a response — so parse leniently and ignore what you do not recognise.
- A new error code, within an existing status. Branch on codes you know and treat the rest by status.
- A new scope. Existing keys keep exactly the scopes they were issued.
Deprecation and sunset
No v1 operation is deprecated today. If one ever is, it keeps working for at least six months from the day it is announced, and you will see it in three places before it stops:- An entry on this page naming the operation, what replaces it, and its last day.
deprecated: trueon the operation in the OpenAPI document.- On every response from it, a
Deprecationheader (RFC 9745) with the date it was deprecated, and aSunsetheader (RFC 8594) with the date it will stop answering. Log either header when you see it and you will hear about it from your own monitoring rather than from a failure.
/api/v2 exists, /api/v1 keeps working until its own Sunset date.
Changes
UploadsAPIExtension
- A zero-byte file now completes as soon as its tus upload is created. Before, it stayed
uploadingforever, and its transfer’s “ready” email never went out. - A webhook delivery now gives up after 10 seconds in total. Before, only an idle timeout applied, so a receiver that sent a byte every few seconds held up deliveries.
- Browser extension 0.1.4: plain (not end-to-end encrypted) uploads send one server part per tus
PATCH. A large file on a slow connection is no longer cut off by the 30-minute limit on a single request. Submitted to the Chrome Web Store and Firefox Add-ons for review.
Uploads
- A single tus
PATCHis no longer cut after five minutes. From 2026-09-30 to 2026-10-05, any upload request that took longer was cut and had to resume from the last committed part. - An upload that runs for more than 24 hours is no longer aborted by the storage cleanup sweep while it is still active.
- A file whose upload was recovered after a server crash no longer carries a wrong
crc32. Collection zips containing such a file declared a bad checksum for it. - Collection zips order files with the same creation time the same way on every request, so a ranged resume always gets the same layout. The
ETagof affected zips changed once.
OAuth
- Every authorization response, error responses included, carries the
issparameter (RFC 9207). The metadata at/.well-known/oauth-authorization-serveradvertisesauthorization_response_iss_parameter_supported.
APIUploadsMCPCLIJS SDKE2EExtension
- Uploads longer than two hours. Upload targets carry
uploadTokenExpiresAt, andPOST /api/uploads/tokentrades a still-valid token for a fresh one. See uploading large files. - Downloads.
GET /transfers/{id}/download-links,GET /collections/{id}/download-linksandPOST /links/resolvereturn signed, resumable URLs for your own files and for links shared with you. New error codespassword_required,wrong_password,guests_only(403),link_unavailable(410) ande2ee_unsupported(409). See downloading files. - Imports from URLs.
importsonPOST /transfers,POST /transfers/{id}/filesandPOST /collections/{id}/files;filesmay now be empty whenimportsis not. Responses gain animportsarray; follow one withGET /imports/{fileId}. crc32on transfer files, collection files and download links.- Upload requests.
GET/POST /requests,GET/PATCH /requests/{id}, and the paid webhook eventrequest.submitted.collection.file_uploadedreportssource: "import"for a file fetched from a URL. - End-to-end encrypted transfers.
e2ee: trueonPOST /transfers,POST /transfers/{id}/files/{fileId}/sealedfor each file’s sealed name and thumbnail, ande2eeMetaonPOST /transfers/{id}/finalize. Transfers reporte2ee, so a client knows not to offer a link without its key. Such a transfer takes no title, imports, recipients or password. - yungle-cli 0.3.0:
yungle gettakes collection links and keeps folder structure.yungle pull --collection <id>downloads your own collection, and on a second run fetches only what is new.yungle putruns the keyless upload commands that the MCPcreate_transfertool returns.yungle requestslists upload requests;requests new --collection <id> --title …creates one;pause,resume,closeandshowmanage them.yungle sendandyungle pushtake--from-url <url>(repeatable).send,pushandwatchrenew the upload token, so a run longer than two hours completes, and a killed run still resumes.- Downloads are checked against the server’s CRC-32, and a damaged copy is deleted.
- Fixed: a repeated
--tokept only the last address. JSON errors fromyungle getcarry the server’s error code, and a cancelled prompt exits 130.
- yungle-mcp 0.3.0, and the hosted server at
/mcp:- New tools:
share_from_urls,get_import_status,get_download_links,list_upload_requestsandget_upload_request. The server can read upload requests but not create them. create_transferreturns one upload command per file, andfinalize_transferturns the draft into a link.- Local server only:
download_files.share_local_filesresumes after a dropped connection, takes folders and reports progress.
- New tools:
- yungle-client 0.3.0:
uploadFile(andclient.uploadFile): a resumable tus upload from anyBlob, with no dependencies, that retries after drops and renews its token.createTokenKeeper,renewUploadTokenandclient.renewUploadToken().transferDownloadLinks,collectionDownloadLinksandresolveLink.importsoncreateTransfer,addTransferFilesandaddCollectionFiles, followed withgetImportandwaitForImports.listRequests,createRequest,getRequest,setRequestStatus, and therequest.submittedwebhook type.createTransfer({ e2ee: true }),sealTransferFile(), ande2eeMetaonfinalizeTransfer.- Errors carry
docs.retryAfterSecondsreads theRetry-Afterheader when the body gives no wait, so the monthly-allowance429is retried after an hour instead of half a second. - Timestamps the API always sends (
createdAt,updatedAt, a transfer’sexpiresAt) are no longer typed as nullable. Pulled webhook events have a named type,PulledWebhookEvent.
- yungle-client 0.3.1:
getReferral(). - yungle-e2e 0.2.0, first release: the end-to-end encryption core (ciphertext format, key derivation, sealed metadata), published so the code that runs in your browser is public.
- Browser extension 0.1.1, first release, for Chrome, Edge, Brave and Firefox: send files from the toolbar, and add a Yungle link while writing in Gmail or Outlook on the web. Uploads through the extension count against your plan, not against API usage. Version 0.1.3 set Firefox 140 as the minimum.
API
GET /me/referralreturns your invite code and link, and the free months it has earned. Any scope can read it, on every plan.
API
- Every response past authentication carries
RateLimitandRateLimit-Policyheaders (the IETF draft fields), one entry per bucket you were charged against. See limits. - Error bodies gain
error.docs, a link to the row on the errors page that explains the code. - A path under
/apithat is not an endpoint now answers404 not_foundin JSON instead of an HTML page. - Repeated requests with no valid key from one address are limited to 60 a minute, then answered
429 rate_limited. A valid key never counts against this. - The OpenAPI document gives every operation an
operationId, and every 4xx and 5xx one shared, typedErrorschema. - Every success response is now typed in the OpenAPI document, with the resources named under
components/schemas, and the reference lists response fields. Nothing on the wire changed. The document now also gives the real status forPOST /webhooks/{id}/testandPOST /webhooks/{id}/deliveries/{deliveryId}/retry: both have always answered202, and it used to say200. - The OpenAPI document no longer marks five fields as nullable that never are:
expiresAtonTransferandTransferSummary,sessionIdonDownload, andmimeTypeonTransferFileandCollectionFile.
APIOAuthMCPCLIJS SDKPython SDK
openedon a recipient is now alwaysfalse. Whether someone loaded a transfer page is no longer recorded — a sender learns whether the files were downloaded, and nothing about the visit before that. The field stays in the response because removing one needs a version bump.- Webhooks: signed pushes for
transfer.ready,transfer.downloaded,transfer.expiring,transfer.expiredandcollection.file_uploaded, or pull endpoints read from/webhooks/{id}/events. New scopeswebhooks:readandwebhooks:write. See webhooks. - OAuth 2.1 sign-in for apps (
/.well-known/oauth-authorization-server): authorization code with PKCE (S256), open client registration, refresh-token rotation, revocation, and a device flow for first-party clients. An access token works on/api/v1like a key; an app may email recipients only if the user allowedtransfers:send, and otherwise gets403 insufficient_scope. - The hosted MCP server at
https://yungle.co/mcp(Streamable HTTP), signed in with OAuth. See MCP. GET /mereportskey.via(keyoroauth) andkey.canEmail.- yungle-cli 0.2.0:
yungle loginsigns you in from the browser, also over SSH;yungle logoutrevokes the session.yungle login --keysaves an API key. A browser sign-in makes links but never emails anyone:yungle send --tochecks this before uploading.- New commands:
get <link>(downloads a transfer someone sent you, no key needed),status,open,watch <dir> --collection <id>,completion,whoami,transfers,collections,contacts,revoke,webhooks lsandwebhooks listen(with--forward-tofor a local server), and--version. - Run
yungleon its own for a guided menu. It never prompts in scripts, in CI, or with--json/--yes. - Commands accept the short ID from
yungle transfersor a transfer’s link. The old spellings (auth login,ls transfers,rm transfer) still work. yungle mcp install --allow-writeaccepts a key withtransfers:write.- Also installable with Homebrew (
brew install heindewilde/yungle/yungle), and from CI with theheindewilde/yungle-send-actionGitHub Action.
- yungle-cli 0.2.1:
yungle statusno longer shows opens. - yungle-mcp 0.2.0:
- New tools:
create_share_link(shares content you pass it as a link, emails nobody) and, local server only,share_local_files(refuses hidden files). send_transferexists only when the credential may send email, and asks you to confirm every send. A client that cannot ask gets the link instead.- The package exports
createServerfor running it over HTTP, and reports its real version in the handshake.
- New tools:
- yungle-mcp 0.2.1–0.2.4: every tool repeats its title in
annotations.title; withoutYUNGLE_API_KEYthe server starts and lists its read tools, and every call says the key is missing; tool descriptions only describe what each tool does. - yungle-client 0.2.0:
listTransfersandlistCollectionFilestake{ limit, cursor }and returnnextCursor;allTransfers()andallCollectionFiles()walk every page.- Every
POSTsends anIdempotency-Keyand reuses it when retrying. - Every webhook endpoint, and
verifyWebhook()to check aYungle-Signatureheader on Node, Bun, Deno and edge runtimes. me().keyreportsviaandcanEmail. AuserAgentoption, and each client sendsyungle-client/<version>(oryungle-cli,yungle-mcp) inUser-Agent.
- yungle-client 0.2.1:
RecipientStatus.openedis deprecated. - Python SDK
yungle0.1.0, first release: a method for every endpoint, a one-callsend(),upload_file()for resumable tus uploads,all_transfers()andall_collection_files(), automaticIdempotency-Keyon retries,YungleError, andverify_webhook().
API
GET /transfersandGET /collections/{id}/filestakelimitandcursor, and returnnextCursor. With neither parameter, both answer exactly as before: the latest 100 transfers, and every file.- Every
POSTaccepts anIdempotency-Keyheader. A retry with the same key replays the original success instead of creating a second one. - Free accounts can create keys with transfers:write and contacts:write, which the API already accepted. Settings used to offer them read-only keys only.
- Fixed: files registered with
POST /transfersandPOST /collections/{id}/filesnow count toward API upload usage, and are checked against it before the upload starts, like every other API upload. Past the included usage with no credit, they answer402 out_of_credit. - Fixed:
/api/v1only reaches transfers and collections in the key’s own workspace. - File names are cleaned of control characters and bidirectional overrides when a file is created, and a MIME type must be a plain
type/subtype.
API
ipTruncatedon a download receipt is now alwaysnull. The truncated IP address is no longer recorded at all — telling a sender where their recipient downloaded from is profiling we would rather not do. The field stays in the response, and stays nullable, because removing one needs a version bump.- Download receipts, per-recipient delivery status and the transfer detail view are free on every account. They used to need a plan.
- Recipients now report three states rather than two: emailed, opened, and downloaded.
- Transfers can be given any expiry up to your plan’s maximum at creation, rather than only afterwards.
Uploads
- A whole-collection zip download sends
Content-Length, so a client can show progress and tell a finished archive from one that was cut off. - A collection zip can be resumed with a
Rangerequest, checked withIf-Rangeagainst itsETag. If the collection changed in the meantime you get a fresh200instead of a corrupt splice. A collection holding files from before this change answersaccept-ranges: noneuntil their checksums are filled in. - The upload service finishes in-flight requests during a deploy instead of cutting them. While it restarts, upload requests can get
502,503or504: retry those.
API
- Breaking:
workspace.handleonGET /mebecameworkspace.customDomain. Handles were removed; no account had claimed one. - Breaking:
GET /transfers/{id}/downloadsneeded a paid plan, and answered402on a free account. This was reversed on 2026-09-20. - Free accounts can create transfers and contacts through the API (
transfers:write,contacts:write). Collections still need a plan. - A monthly call allowance: 50,000 calls a month on a free account, and a higher one on a paid plan. Past it, the API answers
429withRetry-After. - API uploads are metered apart from the plans: 10 GB a month free, then €0.02/GB from prepaid credit, on every plan. The check runs before the upload starts.
APICLIMCPJS SDK
- Reads are free on every account. Writes answered
402 upgrade_requiredon a free account until 2026-07-31. GET /meaccepts a key with any scope. It used to refuse a key withoutcontacts:read.- yungle-cli 0.1.0, first release:
auth login,auth status,send,push --collection,ls,rm transfer, and--jsonon every command. An interruptedsendresumes from the last committed part when you run it again. - yungle-cli 0.1.2:
yungle mcp installadds the MCP server to Claude Desktop, Claude Code, Cursor or Windsurf. - yungle-mcp 0.1.0, first release: ten read tools and
create_transfer, which prepares a draft to finish in the browser and emails nobody. Version 0.1.2 is listed in the official MCP registry asco.yungle/yungle. - yungle-client 0.1.0, first release: the typed SDK the CLI and MCP server are built on. Version 0.1.1 ships type declarations that resolve under
moduleResolution: node16andnodenext.
First release.
- API keys, created in Settings → API keys. Six scopes across transfers, collections and contacts.
- Transfers: create as draft, add and remove files, finalize, amend expiry and download limits, revoke, and read download receipts.
- Collections: create, rename, delete, register and delete files, create and list folders, invite and remove guests.
- Contacts: full CRUD.
- Uploads via tus, resumable at part granularity, on the same endpoint the web app uses.
- An OpenAPI 3.1 document at
/api/v1/openapi.json, generated from the same definitions the server validates with.
