Developers
Put large-file delivery in the workflow.
Automate yasync with the API, MCP, or CLI. These tools require Pro; the browser and desktop app remain available on every tier.
Authentication
- Create keys under Dashboard → API keys. Pro accounts can create keys; keys look like
ysk_+ 40 characters and act as the account that created them. - Send the key on every request as
Authorization: Bearer ysk_…. Bearer keys are the only auth on/api/v1and/api/mcp— no cookies, no sessions. - The full key is shown once at creation; we store only a keyed hash. Lost it? Revoke and mint a new one — revocation applies immediately.
Every request
curl -s https://yasync.com/api/v1/transfers \
-H "Authorization: Bearer ysk_a1b2c3d4…"Remote MCP: the transfer workflow as tools
Connect a Streamable HTTP MCP client to https://yasync.com/api/mcp and send the same Bearer key. The endpoint is stateless and returns JSON. It never accepts file bodies: upload planning tools return presigned URLs, and the client PUTs each part directly to object storage.
Available tools
yasync_create_transfer,yasync_list_transfers,yasync_get_transferyasync_register_file,yasync_plan_upload,yasync_get_upload_statusyasync_sign_upload_parts,yasync_complete_upload,yasync_abort_uploadyasync_finalize_transfer,yasync_delete_transfer
The tools call the same transfer and upload core as REST, so plan limits, ownership checks, resume state, and API-key rate limits stay consistent.
List the MCP tools
curl -s -X POST https://yasync.com/api/mcp \
-H "Authorization: Bearer $YASYNC_KEY" \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}'Quickstart: send a file in six curls
The whole send pipeline, by hand. Export YASYNC_KEY first, then carry transferId, fileId, and uploadId forward from each response.
1 — Create a transfer
Persist one UUID and reuse it on retries. Everything after this hangs off the returned transferId.
curl -s -X POST https://yasync.com/api/v1/transfers \ -H "Authorization: Bearer $YASYNC_KEY" \ -H "Content-Type: application/json" \ -d "{"creationRequestId":"$TRANSFER_REQUEST_UUID"}" # → {"transferId":"cme3k…","slug":"k4q0z7f2m9d1ab","url":"https://yasync.com/t/k4q0z7f2m9d1ab"}2 — Register the file
Name + exact byte size. Persist a key-safe fileId and reuse it on retries. Folder structure travels in the name ("renders/shot_010.mov").
curl -s -X POST https://yasync.com/api/v1/transfers/$TRANSFER_ID/files \ -H "Authorization: Bearer $YASYNC_KEY" \ -H "Content-Type: application/json" \ -d "{"fileId":"$CLIENT_FILE_ID","name":"big.mov","size":83886080}" # → {"fileId":"x7f3…","name":"big.mov","size":"83886080","contentType":"video/quicktime"}3 — Plan the upload
Compute the whole-file CRC32 locally first. Under 100 MiB it is required in the plan because the returned single-PUT URL is checksum-pinned; bigger files switch to per-part CRC32 — see below.
curl -s -X POST https://yasync.com/api/v1/transfers/$TRANSFER_ID/uploads \ -H "Authorization: Bearer $YASYNC_KEY" \ -H "Content-Type: application/json" \ -d "{"fileId":"x7f3…","fileSize":83886080,"crc32":"$CRC32_HEX"}" # → {"uploadId":"u01b…","mode":"s3_single_put","uploadUrl":"https://…","checksumCrc32":"…","requiredHeaders":{"x-amz-checksum-crc32":"…"}, …}4 — PUT the bytes
Straight to object storage — yasync never proxies your file bytes. Send the plan’s Content-Type and every returned requiredHeaders entry.
curl -s -X PUT "$UPLOAD_URL" \ -H "Content-Type: video/quicktime" \ -H "x-amz-checksum-crc32: $CHECKSUM_CRC32_BASE64" \ --data-binary @big.mov5 — Complete the upload
CRC32 is required again at completion. The server verifies stored size; for multipart it also folds the ordered, R2-validated part checksums and matches the whole-file CRC32.
curl -s -X POST https://yasync.com/api/v1/transfers/$TRANSFER_ID/uploads/$UPLOAD_ID/complete \ -H "Authorization: Bearer $YASYNC_KEY" \ -H "Content-Type: application/json" \ -d "{"crc32":"$CRC32_HEX"}"6 — Finalize → link
Add an optional title, message, password, and recipient emails. You can also share the returned link yourself.
curl -s -X POST https://yasync.com/api/v1/transfers/$TRANSFER_ID/finalize \ -H "Authorization: Bearer $YASYNC_KEY" \ -H "Content-Type: application/json" \ -d '{"title":"Rough cut v4","password":"review-secret"}' # → {"url":"https://yasync.com/t/k4q0z7f2m9d1ab"}
Big files: multipart
Files of 100 MiB and up plan as mode: "s3_multipart" with a fixed partSize and partCount. Request presigned part URLs in batches, PUT the parts in parallel with each URL’s requiredHeaders (keep each response’s ETag header), then send them all to /complete. Interrupted? Ask /status which parts already landed and resume from there.
# CRC32 each part locally; base64-encode its four big-endian bytes.
# Sign URLs for parts 1-2 (batch up to 100 per call).
curl -s -X POST https://yasync.com/api/v1/transfers/$TRANSFER_ID/uploads/$UPLOAD_ID/parts \
-H "Authorization: Bearer $YASYNC_KEY" \
-H "Content-Type: application/json" \
-d '{"parts":[{"partNumber":1,"checksumCrc32":"y/Q5Jg=="},{"partNumber":2,"checksumCrc32":"QixqFQ=="}]}'
# PUT each part with its returned x-amz-checksum-crc32 header. Then complete
# with every ETag, the same part checksums, and the required whole-file CRC32.
curl -s -X POST https://yasync.com/api/v1/transfers/$TRANSFER_ID/uploads/$UPLOAD_ID/complete \
-H "Authorization: Bearer $YASYNC_KEY" \
-H "Content-Type: application/json" \
-d '{"parts":[{"partNumber":1,"etag":"\"9b2cf5…\"","checksumCrc32":"y/Q5Jg=="},{"partNumber":2,"etag":"\"41ac00…\"","checksumCrc32":"QixqFQ=="}],"crc32":"3f8d2a1c"}'Endpoint reference
All byte counts are JSON strings (they can exceed 2⁵³). Timestamps are ISO 8601. Base URL: https://yasync.com.
Errors
Every non-2xx response has one stable shape. code is machine-matchable and never changes meaning within v1; message is for humans; some errors add a details object (e.g. the exact byte caps).
{
"error": {
"code": "FILE_TOO_LARGE",
"message": "Files on this tier are limited to 50 GB",
"details": { "maxFileBytes": "53687091200" }
}
}Rate limits
- 120 requests / minute per key across all v1 endpoints.
- 60 transfer creations / 10 minutes per key — batch files into one transfer instead of one transfer per file.
- 120 part-signing calls / minute per upload, each signing up to 100 part URLs — that comfortably feeds thousands of parallel parts.
- Hitting a limit returns
429withcode: "RATE_LIMITED"— back off and retry. Presigned PUTs to storage are not rate-limited by us.
Upload links and live receiving
Pro accounts can receive files from anyone through a reusable upload link. Create it with a title and optional password. Senders open the returned URL, or POST to /api/u/{token} with a stable creationRequestId UUID, optional package title, and the password. The response contains only a transfer ID and an upload-only sender token. Use that token as a Bearer credential on /api/transfers/{id}/files and the corresponding upload, parts, status, complete, abort and finalize routes. Their bodies match the v1 upload flow above. File bytes go directly to R2. Finalization returns a delivery confirmation; senders receive no download link.
Receivers poll incoming packages and their live file lists. As each verified file appears, select its file ID, create a download, fetch its manifest, then download and verify the CRC32. Save acknowledged file IDs to avoid duplicates. Do this while the package is still DRAFT; wait for closed: true only to know that no more files will arrive. Download IDs last 24 hours. Renew URLs within that window; after it expires, create a new download for the remaining file IDs.
Watch sessions use the same upload flow. Send a heartbeat every ten seconds, including during large uploads, and close the session when finished. Upload-link senders opt in with watchSession: true and use /api/transfers/{id}/session with their sender token. Save the refreshed sender token returned by each heartbeat. After five minutes without a heartbeat (configurable from one to fifteen minutes), new uploads are refused and completed files are retained. Closing aborts unfinished files. The desktop app and CLI handle polling, recovery, checksums and folders.
Command line
The yasync CLI sends and receives files from scripts and servers. It requires Pro. Use --json for machine-readable output.
yasync login # link this machine to your account (browser approval)
yasync send big.mov --json # create → upload → finalize; prints the link
yasync send renders/ --title "Night renders" --password s3cret
yasync receive https://yasync.com/t/k4q0z7f2m9d1ab -o ~/Downloads
yasync upload-links --title "AI renders" # create an upload-only link
yasync incoming # discover pending and ready packages
yasync get PACKAGE_ID --when-ready -o ~/Downloads
yasync incoming -o ~/Incoming # mirror all incoming into package folders
yasync watch ~/Renders --title "AI renders" --disconnect-grace 300
# Watch into someone else’s upload link (no account required):
yasync watch ~/Renders --upload-link https://yasync.com/u/UPLOAD_TOKEN
# Ctrl+C closes a watch session or stops receiving.
yasync ls # your transfers
yasync rm cme3k… # delete oneThe Apps page lists verified macOS Apple Silicon, Windows x86_64, and Linux x86_64 downloads with installer instructions.
Versioning & stability
/api/v1is stable: fields are only ever added. Anything breaking ships as/api/v2— v1 keeps working./api/mcpis a thin adapter over the same v1 transfer core. Tool schemas may gain optional fields, but existing tool names and required inputs remain compatible.- Write clients that tolerate unknown JSON fields and match errors by
error.code, not message text. - An OpenAPI spec is on the roadmap for a later release; this page is the v1 reference for now.