curl --request POST \
--url https://yungle.co/api/v1/transfers \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"files": [],
"imports": [
{
"url": "<string>",
"name": "<string>",
"path": "<string>"
}
],
"title": "<string>",
"expiresInDays": 123,
"e2ee": true
}
'import requests
url = "https://yungle.co/api/v1/transfers"
payload = {
"files": [],
"imports": [
{
"url": "<string>",
"name": "<string>",
"path": "<string>"
}
],
"title": "<string>",
"expiresInDays": 123,
"e2ee": True
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
files: [],
imports: [{url: '<string>', name: '<string>', path: '<string>'}],
title: '<string>',
expiresInDays: 123,
e2ee: true
})
};
fetch('https://yungle.co/api/v1/transfers', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://yungle.co/api/v1/transfers",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'files' => [
],
'imports' => [
[
'url' => '<string>',
'name' => '<string>',
'path' => '<string>'
]
],
'title' => '<string>',
'expiresInDays' => 123,
'e2ee' => true
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://yungle.co/api/v1/transfers"
payload := strings.NewReader("{\n \"files\": [],\n \"imports\": [\n {\n \"url\": \"<string>\",\n \"name\": \"<string>\",\n \"path\": \"<string>\"\n }\n ],\n \"title\": \"<string>\",\n \"expiresInDays\": 123,\n \"e2ee\": true\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://yungle.co/api/v1/transfers")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"files\": [],\n \"imports\": [\n {\n \"url\": \"<string>\",\n \"name\": \"<string>\",\n \"path\": \"<string>\"\n }\n ],\n \"title\": \"<string>\",\n \"expiresInDays\": 123,\n \"e2ee\": true\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://yungle.co/api/v1/transfers")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"files\": [],\n \"imports\": [\n {\n \"url\": \"<string>\",\n \"name\": \"<string>\",\n \"path\": \"<string>\"\n }\n ],\n \"title\": \"<string>\",\n \"expiresInDays\": 123,\n \"e2ee\": true\n}"
response = http.request(request)
puts response.read_body{
"tusEndpoint": "<string>",
"files": [
{
"id": "<string>",
"name": "<string>",
"size": 1,
"uploadToken": "<string>",
"uploadTokenExpiresAt": "2023-11-07T05:31:56Z"
}
],
"imports": [
{
"fileId": "<string>",
"name": "<string>",
"size": 1,
"source": "<string>",
"status": "<string>"
}
],
"transfer": {
"id": "<string>",
"slug": "<string>",
"expiresAt": "2023-11-07T05:31:56Z",
"maxBytes": 1
}
}{
"error": {
"code": "unauthorized",
"message": "<string>",
"details": {},
"docs": "<string>"
}
}{
"error": {
"code": "unauthorized",
"message": "<string>",
"details": {},
"docs": "<string>"
}
}{
"error": {
"code": "unauthorized",
"message": "<string>",
"details": {},
"docs": "<string>"
}
}{
"error": {
"code": "unauthorized",
"message": "<string>",
"details": {},
"docs": "<string>"
}
}{
"error": {
"code": "unauthorized",
"message": "<string>",
"details": {},
"docs": "<string>"
}
}{
"error": {
"code": "unauthorized",
"message": "<string>",
"details": {},
"docs": "<string>"
}
}{
"error": {
"code": "unauthorized",
"message": "<string>",
"details": {},
"docs": "<string>"
}
}{
"error": {
"code": "unauthorized",
"message": "<string>",
"details": {},
"docs": "<string>"
}
}{
"error": {
"code": "unauthorized",
"message": "<string>",
"details": {},
"docs": "<string>"
}
}Create a transfer
Always creates a draft: the link is not live and nobody is emailed until you call finalize. Returns a tus endpoint and one upload token per file. An unfinalized draft is swept after 24 hours.
curl --request POST \
--url https://yungle.co/api/v1/transfers \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"files": [],
"imports": [
{
"url": "<string>",
"name": "<string>",
"path": "<string>"
}
],
"title": "<string>",
"expiresInDays": 123,
"e2ee": true
}
'import requests
url = "https://yungle.co/api/v1/transfers"
payload = {
"files": [],
"imports": [
{
"url": "<string>",
"name": "<string>",
"path": "<string>"
}
],
"title": "<string>",
"expiresInDays": 123,
"e2ee": True
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
files: [],
imports: [{url: '<string>', name: '<string>', path: '<string>'}],
title: '<string>',
expiresInDays: 123,
e2ee: true
})
};
fetch('https://yungle.co/api/v1/transfers', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://yungle.co/api/v1/transfers",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'files' => [
],
'imports' => [
[
'url' => '<string>',
'name' => '<string>',
'path' => '<string>'
]
],
'title' => '<string>',
'expiresInDays' => 123,
'e2ee' => true
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://yungle.co/api/v1/transfers"
payload := strings.NewReader("{\n \"files\": [],\n \"imports\": [\n {\n \"url\": \"<string>\",\n \"name\": \"<string>\",\n \"path\": \"<string>\"\n }\n ],\n \"title\": \"<string>\",\n \"expiresInDays\": 123,\n \"e2ee\": true\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://yungle.co/api/v1/transfers")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"files\": [],\n \"imports\": [\n {\n \"url\": \"<string>\",\n \"name\": \"<string>\",\n \"path\": \"<string>\"\n }\n ],\n \"title\": \"<string>\",\n \"expiresInDays\": 123,\n \"e2ee\": true\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://yungle.co/api/v1/transfers")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"files\": [],\n \"imports\": [\n {\n \"url\": \"<string>\",\n \"name\": \"<string>\",\n \"path\": \"<string>\"\n }\n ],\n \"title\": \"<string>\",\n \"expiresInDays\": 123,\n \"e2ee\": true\n}"
response = http.request(request)
puts response.read_body{
"tusEndpoint": "<string>",
"files": [
{
"id": "<string>",
"name": "<string>",
"size": 1,
"uploadToken": "<string>",
"uploadTokenExpiresAt": "2023-11-07T05:31:56Z"
}
],
"imports": [
{
"fileId": "<string>",
"name": "<string>",
"size": 1,
"source": "<string>",
"status": "<string>"
}
],
"transfer": {
"id": "<string>",
"slug": "<string>",
"expiresAt": "2023-11-07T05:31:56Z",
"maxBytes": 1
}
}{
"error": {
"code": "unauthorized",
"message": "<string>",
"details": {},
"docs": "<string>"
}
}{
"error": {
"code": "unauthorized",
"message": "<string>",
"details": {},
"docs": "<string>"
}
}{
"error": {
"code": "unauthorized",
"message": "<string>",
"details": {},
"docs": "<string>"
}
}{
"error": {
"code": "unauthorized",
"message": "<string>",
"details": {},
"docs": "<string>"
}
}{
"error": {
"code": "unauthorized",
"message": "<string>",
"details": {},
"docs": "<string>"
}
}{
"error": {
"code": "unauthorized",
"message": "<string>",
"details": {},
"docs": "<string>"
}
}{
"error": {
"code": "unauthorized",
"message": "<string>",
"details": {},
"docs": "<string>"
}
}{
"error": {
"code": "unauthorized",
"message": "<string>",
"details": {},
"docs": "<string>"
}
}{
"error": {
"code": "unauthorized",
"message": "<string>",
"details": {},
"docs": "<string>"
}
}Authorizations
An API key from Settings → API keys, sent as Authorization: Bearer yk_live_…. Scopes: transfers:read, transfers:write, collections:read, collections:write, contacts:read, contacts:write, webhooks:read, webhooks:write. A write scope implies read of the same resource.
Body
Files you will upload yourself.
500Show child attributes
Show child attributes
Files Yungle fetches from URLs itself, so the bytes never pass through you. Up to 20 per call. Each is created like an upload (quota, size ceilings, API metering) and imported in the background; follow it with GET /imports/{fileId}.
20Show child attributes
Show child attributes
Shown in your dashboard; never to recipients.
200Defaults to 7. Clamped to your plan’s maximum (7 free, 365 paid) rather than rejected.
x <= 3650The files are encrypted by the client before upload and Yungle never holds the key, which travels in the link’s fragment. Such a transfer takes no title, no imports, and cannot be emailed or password-protected.
Response
Draft created, with upload targets.
Stream each file here with tus.
One per entry in files, in the same order.
Show child attributes
Show child attributes
One per entry in imports, in the same order. Empty when none were sent.
Show child attributes
Show child attributes
Show child attributes
Show child attributes
