↓
Rivya AI Docs

Files API

Upload image, video, or audio reference files for Rivya API generation requests, with MIME checks, size limits, and duration tokens.

Last reviewed on August 26, 2026

Use POST /api/v1/files to upload reference media for models that need image, video, or audio inputs.

Files API is for reference inputs only. It does not create generation tasks by itself. After upload, pass the returned url and metadata into model params, usually through params.referenceMediaItems.

Endpoint

POST https://rivya.ai/api/v1/files
GET https://rivya.ai/api/v1/files/{fileId}

Required headers:

Authorization: Bearer rvya_sk_...
Content-Type: multipart/form-data

The API key must include the files:create scope to upload and files:read to retrieve metadata. Newly created Rivya API keys include both scopes by default.

Multipart Fields

FieldTypeRequiredNotes
filebinaryyesThe image, video, or audio file to upload.
kindstringyesOne of image, video, or audio.
modelstringnoPublic model ID. When present, Rivya validates that the model accepts this file kind.
client_request_idstringnoYour trace ID, up to 128 characters.

Use model when the file is intended for a specific model. This gives you model-specific MIME and size validation before the file is accepted.

Upload Limits

Files API uses the same upload policy as Rivya reference uploads.

Default limits:

KindDefault max sizeCommon MIME types
image10 MBimage/jpeg, image/png, image/webp
video50 MBvideo/mp4, video/quicktime, video/webm
audio10 MBaudio/mpeg, audio/mp4, audio/wav, audio/x-wav, audio/aac, audio/ogg

Some models have different limits. For example, selected reference-image models allow larger images, and selected video-reference models allow files up to the product's edge-safe upload ceiling. Always pass model when you know the target model, and read Model API Reference before accepting user uploads.

Signed image-reference limits include:

ModelMaximum imagesPer-image limitAccepted image MIME types
seedream-5-pro1010 MBJPEG, PNG, WebP
seedream-5-pro-layer-decompositionexactly 130 MBJPEG, PNG, WebP, BMP, GIF, TIFF
nano-banana-2-lite1030 MBJPEG, PNG, WebP
qwen-image-3 / qwen-image-3-pro310 MBJPEG, PNG, WebP, BMP, GIF, TIFF
grok-imagine-image-2-0510 MBJPEG, PNG, WebP
wan-3-0-video10 in reference mode; 1–2 in frames mode20 MBJPEG, non-transparent PNG, WebP, BMP

Every Image5, Grok Imagine Image 2.0, or Wan 3.0 reference image must be uploaded with its target model. Keep the original response's width, height, size_bytes, and image_dimensions_token; the generation request must send them as width, height, sizeBytes, and imageDimensionsToken. Arbitrary external image URLs do not satisfy this model-bound validation.

Layer decomposition additionally validates the detected image dimensions before upload: 262,144–36,000,000 pixels total and an aspect ratio from 1:16 through 16:1.

Video-reference model-specific upload limits include:

ModelImage inputsVideo inputsAudio inputs
kling-3-turbo1 × 10 MB; JPEG or PNGnot acceptednot accepted
seedance-2-miniup to 9 × 30 MB; JPEG, PNG, WebP, BMP, GIF, or TIFFup to 3 × 50 MB; MP4 or MOVup to 3 × 15 MB; MP3 or WAV
seedance-2-5up to 30 × 30 MB; JPEG, PNG, WebP, BMP, GIF, or TIFFup to 10 × 95 MB; MP4 or MOVup to 10 × 15 MB; MP3 or WAV
minimax-h3up to 9 × 30 MB; JPEG, PNG, or WebPup to 3 × 50 MB; MP4 or MOVup to 3 × 15 MB; MP3 or WAV
happyhorse-1-1up to 9 × 20 MB; JPEG, PNG, or WebPnot acceptednot accepted
omnihuman-1-51 × 10 MB; JPEG, PNG, or WebPnot accepted1 × 10 MB; MP3, M4A, WAV, AAC, or OGG
volcengine-video-lip-syncnot accepted1 × 95 MB; MP4 or MOV1 × 10 MB; MP3, M4A, WAV, AAC, or OGG
wan-3-0-videoframes: 1 required and 1 optional; reference: up to 10 × 20 MB; JPEG, non-transparent PNG, WebP, or BMPreference: up to 5 × 95 MB; MP4 or MOV; 1–15 seconds each and 15 seconds totalreference: up to 5 × 15 MB; MP3 or WAV; 1–15 seconds each and 15 seconds total; not accepted alone

These are Rivya's accepted upload ceilings, which may be lower than an upstream service limit. Upload each Video8 or Wan 3.0 reference with its target model. Reference videos require both the signed duration proof and the signed video metadata from the original model-bound upload response. Wan 3.0 audio duration tokens also bind the detected MIME type and upload byte size.

Wan 3.0 images must be 240–8,000 pixels per side, and videos must be 240–4,096 pixels per side; both stay within a 1:8–8:1 aspect-ratio boundary. In reference mode, video and audio have separate 15-second aggregate limits, and audio cannot be the only reference kind.

Rivya validates the detected file signature, not only the filename extension.

curl Example

curl https://rivya.ai/api/v1/files \
  -H "Authorization: Bearer rvya_sk_..." \
  -F "file=@./reference.png" \
  -F "kind=image" \
  -F "model=nano-banana-2-lite" \
  -F "client_request_id=asset-123"

JavaScript Example

import { readFile } from "node:fs/promises";

const form = new FormData();
const file = new Blob([await readFile("./reference.png")], {
  type: "image/png"
});

form.set("file", file, "reference.png");
form.set("kind", "image");
form.set("model", "nano-banana-2-lite");
form.set("client_request_id", "asset-123");

const response = await fetch("https://rivya.ai/api/v1/files", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.RIVYA_API_KEY}`
  },
  body: form
});

const uploadedFile = await response.json();
console.log(uploadedFile.id, uploadedFile.url);

Python Example

import os
import requests

with open("./reference.png", "rb") as file_handle:
    response = requests.post(
        "https://rivya.ai/api/v1/files",
        headers={
            "Authorization": f"Bearer {os.environ['RIVYA_API_KEY']}",
        },
        files={"file": ("reference.png", file_handle, "image/png")},
        data={
            "kind": "image",
            "model": "nano-banana-2-lite",
            "client_request_id": "asset-123",
        },
        timeout=60,
    )

uploaded_file = response.json()
print(uploaded_file["id"], uploaded_file["url"])

Response

{
  "id": "file_...",
  "object": "file",
  "kind": "image",
  "file_name": "reference.png",
  "mime_type": "image/png",
  "size_bytes": 482314,
  "url": "https://...",
  "duration_seconds": null,
  "duration_token": null,
  "width": 1024,
  "height": 1024,
  "image_dimensions_token": "signed_image_metadata_token",
  "video_width": null,
  "video_height": null,
  "frames_per_second": null,
  "video_bitrate_mbps": null,
  "video_file_size_bytes": null,
  "video_metadata_token": null,
  "created_at": "2026-05-11T00:00:00.000Z",
  "expires_at": null
}

For video and audio uploads, duration_seconds may be populated. When a model requires duration verification, copy duration_token into the related generation parameter as durationToken.

For supported image uploads, width and height are detected from the file bytes. All five Image5 models, Grok Imagine Image 2.0, and Wan 3.0 require the signed image_dimensions_token from the original model-bound upload response; copy it into the reference item as imageDimensionsToken, and copy size_bytes as sizeBytes. A later file-metadata retrieval may return that token as null, so re-upload the source image if the original token is unavailable or expired.

For supported Video8 and Wan 3.0 video uploads, Rivya inspects the MP4 or MOV bytes and returns video_width, video_height, frames_per_second, video_bitrate_mbps, video_file_size_bytes, and video_metadata_token. Copy them into the reference item as width, height, framesPerSecond, videoBitrateMbps, sizeBytes, and videoMetadataToken. The token is bound to the account, target model, URL, MIME type, dimensions, frame rate, bitrate, and upload size. Duration is verified separately with durationToken. A later file-metadata retrieval may return video_metadata_token as null; re-upload the source video instead of inventing metadata.

Retrieve File Metadata

Use GET /api/v1/files/{fileId} to read metadata for a file owned by the same Rivya account:

curl https://rivya.ai/api/v1/files/file_... \
  -H "Authorization: Bearer rvya_sk_..."

The response uses the same PublicApiFile shape as upload. If the file belongs to another account or is no longer available, the API returns not_found.

Use The Upload In Generation Params

Do not send a top-level files field to POST /api/v1/generations.

For new integrations, pass the upload result through params.referenceMediaItems:

{
  "model": "nano-banana-2-lite",
  "prompt": "Restyle this product photo for a clean editorial catalog page",
  "params": {
    "referenceMediaItems": [
      {
        "url": "https://...",
        "kind": "image",
        "name": "reference.png",
        "mimeType": "image/png",
        "width": 1024,
        "height": 1024,
        "sizeBytes": 482314,
        "imageDimensionsToken": "image_dimensions_token_from_files_api"
      }
    ]
  },
  "client_request_id": "order-123-preview"
}

For video or audio:

{
  "url": "https://...",
  "kind": "video",
  "name": "source.mov",
  "mimeType": "video/quicktime",
  "durationSeconds": 12.4,
  "durationToken": "duration_token_from_files_api",
  "width": 1920,
  "height": 1080,
  "framesPerSecond": 30,
  "videoBitrateMbps": 8.5,
  "sizeBytes": 26214400,
  "videoMetadataToken": "video_metadata_token_from_files_api"
}

The complete signed video fields above are required for Video8 and Wan 3.0 video references. Wan 3.0 audio references use mimeType, sizeBytes, durationSeconds, and durationToken; image references use the model-specific image metadata contract described above.

For Seedream 5.0 Pro Layer Decomposition, send exactly one image and the signed metadata returned by its model-bound upload:

{
  "model": "seedream-5-pro-layer-decomposition",
  "prompt": "Separate the product, shadow, typography, and background into clean layers",
  "params": {
    "size": "auto",
    "output_format": "png",
    "referenceMediaItems": [
      {
        "url": "https://...",
        "kind": "image",
        "name": "campaign.tiff",
        "mimeType": "image/tiff",
        "width": 2048,
        "height": 2048,
        "sizeBytes": 6291456,
        "imageDimensionsToken": "image_dimensions_token_from_files_api"
      }
    ]
  }
}

Some older model parameters still use model-specific URL fields. If the Model API Reference documents a specific parameter, follow that model page instead of inventing a new field.

Errors

Files API uses the same public error envelope as the rest of Rivya API:

{
  "error": {
    "code": "validation_failed",
    "message": "The request is invalid.",
    "requestId": "req_..."
  }
}

Common cases:

HTTPCodeCause
400validation_failedMissing file, unsupported kind, unsupported MIME type, file too large, or model does not accept the selected kind.
401api_key_missing / api_key_invalidMissing or invalid Bearer API key.
403api_scope_deniedThe key does not include files:create or files:read for the requested action.
429rate_limitedToo many file uploads in the current minute.
503public_api_disabledPublic API is disabled in the current environment.

Security Notes

Do not store full API keys in browsers, mobile clients, logs, analytics events, or screenshots.

Treat uploaded file URLs, duration_token, image_dimensions_token, and video_metadata_token values as temporary integration material. Use them only to build the follow-up generation request, and do not expose them in public pages.