curl --request POST \
--url https://api.fanvue.com/v1/media/uploads \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--header 'X-Fanvue-API-Version: <x-fanvue-api-version>' \
--data '
{
"name": "<string>",
"filename": "<string>"
}
'import requests
url = "https://api.fanvue.com/v1/media/uploads"
payload = {
"name": "<string>",
"filename": "<string>"
}
headers = {
"X-Fanvue-API-Version": "<x-fanvue-api-version>",
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {
'X-Fanvue-API-Version': '<x-fanvue-api-version>',
Authorization: 'Bearer <token>',
'Content-Type': 'application/json'
},
body: JSON.stringify({name: '<string>', filename: '<string>'})
};
fetch('https://api.fanvue.com/v1/media/uploads', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));{
"mediaUuid": "d4e5f6a7-8b9c-0d1e-2f3a-4b5c6d7e8f9a",
"uploadId": "abc123XYZ789multipart",
"partSize": 6291456,
"maxParts": 256,
"totalParts": 4
}{
"error": "<string>",
"message": "<string>"
}{
"error": "<string>"
}{
"error": "<string>"
}{
"error": "<string>",
"message": "<string>",
"nextVersion": "<string>"
}{
"error": "<string>"
}Create multipart upload session
Create a media record and start an S3 multipart upload session.
Use mediaType: "audio" to upload a voice note. A voice note is ordinary audio media —
there is no separate voice-note type — so upload it here, then attach the resulting
mediaUuid to a chat message. Wait for the media to reach status: "ready" on
GET /media/{mediaUuid} before sending it: audio is transcoded asynchronously, and a
message sent earlier attaches media the recipient cannot play yet. Duration is measured
during transcoding and returned as lengthMs on the media’s main variant.
curl --request POST \
--url https://api.fanvue.com/v1/media/uploads \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--header 'X-Fanvue-API-Version: <x-fanvue-api-version>' \
--data '
{
"name": "<string>",
"filename": "<string>"
}
'import requests
url = "https://api.fanvue.com/v1/media/uploads"
payload = {
"name": "<string>",
"filename": "<string>"
}
headers = {
"X-Fanvue-API-Version": "<x-fanvue-api-version>",
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {
'X-Fanvue-API-Version': '<x-fanvue-api-version>',
Authorization: 'Bearer <token>',
'Content-Type': 'application/json'
},
body: JSON.stringify({name: '<string>', filename: '<string>'})
};
fetch('https://api.fanvue.com/v1/media/uploads', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));{
"mediaUuid": "d4e5f6a7-8b9c-0d1e-2f3a-4b5c6d7e8f9a",
"uploadId": "abc123XYZ789multipart",
"partSize": 6291456,
"maxParts": 256,
"totalParts": 4
}{
"error": "<string>",
"message": "<string>"
}{
"error": "<string>"
}{
"error": "<string>"
}{
"error": "<string>",
"message": "<string>",
"nextVersion": "<string>"
}{
"error": "<string>"
}write:media— Upload, modify, and manage media files and content assets. Also required for vault folder management.
Authorizations
OAuth 2.0 access token, presented as a JWT bearer token in the Authorization header. Obtain a token via the authorization-code flow; the scopes granted to the token determine which operations it may call.
Headers
API version to use for the request
"2025-06-26"
Body
1 - 2551 - 255Use "audio" for a voice note — it has no media type of its own.
image, video, audio, document Total size of the file in bytes. When provided, the response includes the exact totalParts to upload.
x <= 1610612736Response
Upload session created
Size in bytes of every part except the final one (which may be smaller).
Maximum number of parts allowed, derived from the maximum supported file size.
Exact number of parts to upload, computed from sizeBytes. Null when sizeBytes was not provided — compute it client-side as ceil(fileSize / partSize).
Was this page helpful?