Upload Assets
November 17, 2025 (May 25, 2026)
Table of contents
Upload assets to Google Flow. Supports image and video uploads:
| Content-Type | File Extension | Max size |
|---|---|---|
| image/png | png | 20 MB |
| image/jpeg | jpeg | 20 MB |
| image/webp | webp | 20 MB |
| video/mp4 | mp4 | 100 MB |
POST raw content using Make.com and similar nocode tools.
https://api.useapi.net/v1/google-flow/assets/
Request Headers
Authorization: Bearer {API token}
Content-Type: select from the table above
API tokenis required, see Setup useapi.net for details.Content-Typeis required, see table above.
Path Parameters
-
emailis optional. The email address of the Google Flow account to use (URL-encoded if necessary).When only one account is configured, the API will automatically use that account.
With multiple accounts configured, omitting the email parameter triggers automatic load balancing based on image generation job statistics to select the healthiest account.
Note: The endpoint can be called as either
POST /assets(no email) orPOST /assets/:email(explicit email).
Request Body
Binary file contents (raw bytes). Set Content-Type to match the file:
image/png,image/jpeg,image/webpfor image uploadsvideo/mp4for video uploads (used asreferenceVideo_1inomni-flashV2V edit)
The image and video paths return slightly different response shapes — see the 200 response below.
Responses
-
Upload successful. The response shape differs between image and video uploads — see both below.
Image upload response
Returned when
Content-Typeisimage/png,image/jpeg, orimage/webp.{ "media": { "name": "ff9aa5cc-...redacted...", "projectId": "5c37e988-...redacted...", "workflowId": "69603881-...redacted...", "workflowStepId": "CAE", "mediaMetadata": { "createTime": "2026-02-27T16:34:25.128454Z", "requestData": { "clientPlatform": "CLIENT_PLATFORM_WEB" }, "visibility": "PRIVATE" }, "image": { "userUploadedImage": { "aspectRatio": "IMAGE_ASPECT_RATIO_UNSPECIFIED" }, "dimensions": { "width": 1024, "height": 1024 } } }, "workflow": { "name": "69603881-...redacted...", "metadata": { "displayName": "upload.webp", "createTime": "2026-02-27T16:34:25.128454Z", "primaryMediaId": "ff9aa5cc-...redacted..." }, "projectId": "5c37e988-...redacted..." }, "mediaGenerationId": { "mediaGenerationId": "user:12345-email:6a6f...-image:ff9aa5cc-...redacted..." }, "width": 1024, "height": 1024, "email": "jo***@gmail.com" }Field Description mediaFull media object from Google Flow API with upload details and dimensions media.image.dimensionsImage dimensions as reported by Google ( widthandheight)workflowWorkflow metadata including display name and project ID mediaGenerationId.mediaGenerationIdReference ID for use in subsequent API calls. Format: user:{userid}-email:{hex_encoded_email}-image:{internal_media_id}widthImage width in pixels heightImage height in pixels emailAccount email that was used for the upload (useful when email was omitted and auto-selected via load balancing) Video upload response
Returned when
Content-Typeisvideo/mp4. Use the returnedmediaGenerationIdasreferenceVideo_1on POST /videos withmodel: "omni-flash"to drive V2V edit.{ "media": { "name": "07c542b0-...redacted...", "projectId": "5c37e988-...redacted...", "workflowId": "290a1f7a-...redacted...", "workflowStepId": "CAE", "mediaMetadata": { "createTime": "2026-05-20T23:04:23.089821Z", "requestData": { "clientPlatform": "CLIENT_PLATFORM_WEB" }, "mediaStatus": { "mediaGenerationStatus": "MEDIA_GENERATION_STATUS_PENDING" }, "visibility": "PRIVATE" }, "video": { "dimensions": { "width": 1280, "height": 720, "length": "11.940s" }, "videoOffset": { "startOffset": "0s", "endOffset": "11.940s" }, "userUploadedVideo": { "encodedVideo": "" } } }, "mediaGenerationId": { "mediaGenerationId": "user:12345-email:6a6f...-video:07c542b0-...redacted..." }, "durationSeconds": 11.94, "width": 1280, "height": 720, "email": "jo***@gmail.com" }Field Description mediaFull media object from Google Flow API with upload details and dimensions (mirrors the image response shape, with a video{}sub-object instead ofimage{})media.video.dimensionsVideo dimensions as reported by Google ( width,height,length)mediaGenerationId.mediaGenerationIdReference ID for use as referenceVideo_1on POST /videos. Format:user:{userid}-email:{hex_encoded_email}-video:{internal_media_id}durationSecondsVideo duration in seconds. Use this to pre-compute endFrameIndex_1for V2V edit:min(round(durationSeconds × 24), 240)widthVideo width in pixels heightVideo height in pixels emailAccount email that was used for the upload -
Invalid request (empty content, unsupported content type, file too large, or content policy violation).
General error:
{ "error": "File size (25165824) is over 20971520 bytes" }Content policy error:
{ "error": { "code": 400, "message": "Request contains an invalid argument.", "status": "INVALID_ARGUMENT", "details": [ { "@type": "type.googleapis.com/google.rpc.ErrorInfo", "reason": "PUBLIC_ERROR_TRUMP_FACE_DETECTED" } ] } } -
Invalid API token.
{ "error": "Unauthorized" } -
Account not found or not configured.
{ "error": "Google Flow account [email protected] not found" } -
Rate limit or quota exhausted (concurrency limit or account quota reached).
When the reason is
PUBLIC_ERROR_USER_REQUESTS_THROTTLEDthe response includes aRetry-After: 1800header (30 minutes — matches the internal quarantine TTL on the throttled account). During that window the account is removed from load-balanced selection, so callers that didn’t pinemailwill auto-route to a different account in their pool.{ "error": { "code": 429, "message": "Resource has been exhausted (e.g. check quota).", "status": "RESOURCE_EXHAUSTED", "details": [ { "@type": "type.googleapis.com/google.rpc.ErrorInfo", "reason": "PUBLIC_ERROR_USER_REQUESTS_THROTTLED" } ] } } -
596 Session Error
Google session refresh failed. The account needs to be reconfigured. Delete the account using DELETE /accounts/
emailand add it again by strictly following the procedure in Setup Google Flow.{ "error": "Failed to refresh session: 500 Internal Server Error" }
Model
Image upload response
{
media: { // Full media object from Google Flow API
name: string // Media UUID
projectId: string
workflowId: string
workflowStepId: string
mediaMetadata?: {
createTime?: string // ISO 8601 timestamp
requestData?: object
visibility?: string // "PRIVATE"
}
image?: {
userUploadedImage?: {
aspectRatio: string // "IMAGE_ASPECT_RATIO_UNSPECIFIED" | "LANDSCAPE" | "PORTRAIT"
}
dimensions?: {
width: number
height: number
}
}
}
workflow?: { // Workflow metadata
name: string // Workflow UUID
metadata?: {
displayName?: string // Original filename
createTime?: string
primaryMediaId?: string // Same as media.name
}
projectId?: string
}
mediaGenerationId: {
mediaGenerationId: string // Reference ID: user:{userid}-email:{hex_encoded_email}-image:{internal_media_id}
}
width: number // Image width in pixels
height: number // Image height in pixels
email: string // Account email used for upload
error?: string | { // Error: string (useapi.net) or object (Google API)
code: number
message: string
status: string
details: Array<{
'@type': string
reason: string
}>
}
}
Video upload response
Returned when Content-Type: video/mp4.
{
media?: { // Mirrors image response shape (with video{} instead of image{})
name: string
projectId: string
workflowId: string
workflowStepId: string
mediaMetadata: {
createTime: string
requestData: { clientPlatform: string }
mediaStatus: { mediaGenerationStatus: string }
visibility: string
}
video: {
dimensions: { width: number; height: number; length: string } // length is "11.940s"
videoOffset: { startOffset: string; endOffset: string }
userUploadedVideo: { encodedVideo: string }
}
}
mediaGenerationId: {
mediaGenerationId: string // Reference ID: user:{userid}-email:{hex_encoded_email}-video:{internal_media_id}
// — use as referenceVideo_1 on POST /videos with model='omni-flash'
}
durationSeconds?: number // Video duration in seconds
width?: number // Video width in pixels (from upload finalize response)
height?: number // Video height in pixels
email: string // Account email used for upload
error?: string | { // Error: string (useapi.net) or object (Google API)
code: number
message: string
status: string
details: Array<{
'@type': string
reason: string
}>
}
}
Examples
-
# Option 1: Without email (auto-selection/load balancing) curl -X POST \ -H "Authorization: Bearer YOUR_API_TOKEN" \ -H "Content-Type: image/jpeg" \ --data-binary @/path/to/your/image.jpeg \ "https://api.useapi.net/v1/google-flow/assets" # Option 2: With specific email curl -X POST \ -H "Authorization: Bearer YOUR_API_TOKEN" \ -H "Content-Type: image/jpeg" \ --data-binary @/path/to/your/image.jpeg \ "https://api.useapi.net/v1/google-flow/assets/john%40gmail.com" -
const token = 'YOUR_API_TOKEN'; // Option 1: Without email (auto-selection/load balancing) const apiUrl = 'https://api.useapi.net/v1/google-flow/assets'; // Option 2: With specific email // const email = '[email protected]'; // const apiUrl = `https://api.useapi.net/v1/google-flow/assets/${encodeURIComponent(email)}`; // Load image - Example 1: Fetch from URL const imageUrl = "https://upload.wikimedia.org/wikipedia/commons/7/7d/Mona_Lisa_color_restoration.jpg"; const responseImage = await fetch(imageUrl); const blob = await responseImage.blob(); // Load image - Example 2: From local file (Node.js) // const fsp = require('fs').promises; // const imageFileName = "./cat.png"; // const blob = new Blob([await fsp.readFile(imageFileName)]); // Load image - Example 3: From file input element // // <input id="image-file" type="file"> // const imageFile = document.getElementById('image-file'); // const blob = imageFile.files[0]; const response = await fetch(apiUrl, { method: 'POST', headers: { 'Authorization': `Bearer ${token}`, 'Content-Type': blob.type || 'image/jpeg' }, body: blob }); const result = await response.json(); console.log('Upload result:', result); console.log('Reference ID:', result.mediaGenerationId.mediaGenerationId); console.log('Account used:', result.email); -
import requests from urllib.parse import quote token = 'YOUR_API_TOKEN' # Option 1: Without email (auto-selection/load balancing) api_url = 'https://api.useapi.net/v1/google-flow/assets' # Option 2: With specific email # email = '[email protected]' # api_url = f'https://api.useapi.net/v1/google-flow/assets/{quote(email)}' # Load image - Example 1: Fetch from URL # image_url = "https://upload.wikimedia.org/wikipedia/commons/7/7d/Mona_Lisa_color_restoration.jpg" # response_image = requests.get(image_url) # file_content = response_image.content # Load image - Example 2: From local file # image_file_path = "./image.jpg" # with open(image_file_path, 'rb') as image_file: # file_content = image_file.read() headers = { 'Authorization': f'Bearer {token}', 'Content-Type': 'image/jpeg' } response = requests.post( api_url, headers=headers, data=file_content ) result = response.json() print('Upload result:', result) print('Reference ID:', result.get('mediaGenerationId', {}).get('mediaGenerationId')) print('Account used:', result.get('email'))