Upload a file

June 3, 2026

Table of contents

  1. Request Headers
  2. Query Parameters
  3. Responses
  4. Model
  5. Examples
  6. Try It

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

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

  • email is optional, which configured account to use.
  • stripMetadata is optional, default true β€” strips AI-provenance / EXIF metadata from images before upload (Flow Music’s edge rejects images that declare AI-generated provenance). Set false to keep the original bytes.

Responses

  • 200 OK

    {
      "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, and duration_s when 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=false was 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. The upstream block preserves the evidence β€” quote cf_ray to 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 email is in an error state and can’t be used β€” re-add it via POST /accounts. The error field 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())
    

Try It