Upload a file
June 3, 2026
Table of contents
Upload a reference image or audio file. The file is sent as the raw request body, with its MIME type in the Content-Type header (no multipart, no form fields). Returns an encoded asset ID you can pass to POST /music (refImage1β¦/refAudio1β¦).
https://api.useapi.net/v1/flowmusic/files
Request Headers
Authorization: Bearer {API token}
Content-Type: {file MIME type} # see supported types below
API tokenis required, see Setup useapi.net for details.
The request body is the fileβs raw bytes.
| Content-Type | File Extension | Max size |
|---|---|---|
| image/jpeg | jpg | 20 MB |
| image/png | png | 20 MB |
| image/webp | webp | 20 MB |
| audio/mpeg | mp3 | 40 MB |
| audio/wav | wav | 40 MB |
| audio/mp4 | m4a | 40 MB |
| audio/x-m4a | m4a | 40 MB |
| audio/aac | m4a | 40 MB |
Query Parameters
emailis optional, which configured account to use.stripMetadatais optional, defaulttrueβ strips AI-provenance / EXIF metadata from images before upload (Flow Musicβs edge rejects images that declare AI-generated provenance). Setfalseto keep the original bytes.
Responses
-
{ "id": "user:[email protected]:34cd56ef-...", "url": "https://storage.googleapis.com/...", "kind": "image", "assetType": "image", "email": "[email protected]", "metadata_stripped": true }Audio uploads also include
clip_id,operation_id,is_flagged, andduration_swhen available. -
400 β unsupported Content-Type, empty body, or magic-byte mismatch (declared type β actual bytes).
{ "error": "Content-Type (application/octet-stream) not supported. Valid values: image/jpeg, image/png, ...", "code": 400 } -
401 Unauthorized β invalid API token.
-
413 β file exceeds the size cap.
-
422 β image declares AI-generated provenance metadata and
stripMetadata=falsewas set. Remove the flag (default strips it) or re-save the image without metadata. -
500 β FlowMusic rejected the upload or hit an internal error. Image moderation (e.g. NSFW) surfaces here as a
flowmusic_error. Theupstreamblock preserves the evidence β quotecf_rayto support.{ "error": "Upload failed (HTTP 500): FlowMusic: \"Internal Server Error\"", "code": 500, "upstream": { "status": 500, "cause": "flowmusic_error", "cf_ray": "a05b815ef02cf9cc-SJC", "server": "cloudflare", "content_type": "application/json" } } -
596 Account Error
The account targeted by
emailis in an error state and canβt be used β re-add it via POST /accounts. Theerrorfield returns whatever reason was recorded for the account.{ "error": "Account [email protected] in error state: refresh token rejected", "code": 596 }
Model
{
id: string // encoded asset id β user:<id>-<email>-<image|audio>:<uuid>
url: string // Flow Music storage URL
kind: 'image' | 'audio'
assetType: 'image' | 'audio'
email: string
metadata_stripped?: boolean // images only β whether AI-provenance metadata was stripped
clip_id?: string | null // audio only
operation_id?: string | null // audio only
is_flagged?: boolean | null // audio only
duration_s?: number | null // audio only
}
Examples
-
curl -H "Authorization: Bearer YOUR_API_TOKEN" \ -H "Content-Type: image/png" \ -X POST "https://api.useapi.net/v1/flowmusic/files" \ --data-binary "@image.png" -
const bytes = await (await fetch('image.png')).arrayBuffer(); const response = await fetch('https://api.useapi.net/v1/flowmusic/files', { method: 'POST', headers: { 'Authorization': 'Bearer YOUR_API_TOKEN', 'Content-Type': 'image/png' }, body: bytes }); console.log(await response.json()); -
import requests data = open('image.png', 'rb').read() response = requests.post( 'https://api.useapi.net/v1/flowmusic/files', headers={'Authorization': 'Bearer YOUR_API_TOKEN', 'Content-Type': 'image/png'}, data=data ) print(response.status_code, response.json())