File Management

The file management APIs accept raw media files and return the file_id required by downstream processing APIs. For most image, audio, and video workflows, this is the first API you call.

Upload File

Basic Information

ItemValue
Request MethodPOST
Request Path/base/file/upload
Content-Typemultipart/form-data
AuthenticationRaw API key in the Authorization header

Request Headers

ParameterTypeRequiredDescription
AuthorizationstringYesPass the raw API key, for example YOUR_API_KEY

Form Data

ParameterTypeRequiredDescription
filefileYesAudio, image, video, or text file to upload

ℹ️ Note: The current backend limits a single upload to 20 GB and validates file extension and file size.

Supported Upload Extensions

The upload endpoint currently documents the following media extensions. If the extension does not match the backend validation rules, the API can return 6001.

CategorySupported extensionsNotes
Image.jpg, .jpeg, .png, .webp, .bmpUsed by image processing APIs
Audio.mp3, .wav, .m4a, .aac, .flac, .oggUsed by audio processing APIs
Video.mp4, .mov, .avi, .mkv, .flv, .webmUsed by video processing APIs
Other text-like materialsNot explicitly enumerated in the current public docsVerify against the downstream task API before production use

💡 Tip: Upload success does not guarantee every downstream task will accept the file. Task APIs still validate compatibility and may return 6014.

Request Example

curl -X POST https://api.ai-mcn.tv:10000/base/file/upload \
  -H "Authorization: YOUR_API_KEY" \
  -F "file=@/path/to/video.mp4"

Success Example

{
  "code": 200,
  "msg": "File uploaded successfully~",
  "data": {
    "file_id": "537489015178246",
    "original_name": "video.mp4",
    "size": 10485760,
    "blake3_id": "a1b2c3d4...",
    "base_ext": ".mp4",
    "download_url": "/download/a1/537489015178246.mp4",
    "created_at": "2026-04-05T08:00:00Z",
    "expire_at": "2026-06-04T00:00:00Z",
    "is_expired": false
  }
}

Important Fields

  • file_id: the identifier used in task creation
  • download_url: download location of the original file
  • expire_at: file expiration time
  • blake3_id: content fingerprint

💡 Tip: Uploading the exact same file can hit backend deduplication and reuse an existing record instead of storing a duplicate file.

Error Codes

Error CodeHTTP StatusDescriptionResolution
6001400Unsupported file typeUpload a file with a supported extension
6002413File exceeds 20 GBCompress the file or upload a smaller one
6011400Empty fileMake sure the uploaded file contains actual content
6502401Authentication failedPass the raw API key in the Authorization header

💡 Tip: Single-shot upload works best for small files. For multi-GB files, use Chunked Upload (Resumable) below — after a network interruption you only re-upload the missing chunks instead of the whole file.

Chunked Upload (Resumable)

Chunked upload splits a large file into fixed-size parts that are uploaded one by one. If any part fails, only that part is retried; after an interruption you can query the list of missing parts and resume. Use it for multi-GB files; keep using the single-shot POST /base/file/upload for small files.

The response of the final complete call is identical in shape to the single-shot upload response — deduplication, expiration renewal, and the 60-day retention all behave the same, so downstream APIs never need to know which upload path produced the file.

Endpoint Overview

EndpointMethodPathDescription
Create sessionPOST/base/file/upload/chunk/initDeclare filename and total size; returns the session and chunk contract; supports instant upload
Upload partPUT/base/file/upload/chunk/{upload_id}/{index}Upload the raw bytes of part index; idempotent and safely retryable
Query statusGET/base/file/upload/chunk/{upload_id}Returns the list of missing parts — the basis for resuming
Complete uploadPOST/base/file/upload/chunk/{upload_id}/completeValidates all parts and finalizes the file; response mirrors single-shot upload
Abort sessionDELETE/base/file/upload/chunk/{upload_id}Actively discard the upload; idempotent

All endpoints use the same authentication as single-shot upload: pass the raw API key in the Authorization header.

Resumable Upload Flow

  1. Call init with filename and size to obtain upload_id, part_size, and total_parts.
  2. Split the file by part_size and upload each part — out of order and in parallel are both fine, and re-uploading the same part is safe.
  3. If the network drops, call the status endpoint after reconnecting to get the missing part list, then re-upload only the missing parts.
  4. After all parts are uploaded, call complete to obtain the file_id.

⚠️ Warning: part_size is decided by the server (currently 32 MiB). Clients must split the file using the value returned by init — never hard-code it. Every part must be exactly part_size bytes, except the last part, which is the remainder.

Create Session (init)

Basic Information

ItemValue
Request MethodPOST
Request Path/base/file/upload/chunk/init
Content-Typeapplication/json
AuthenticationRaw API key in the Authorization header

Request Body

ParameterTypeRequiredDefaultDescription
filenamestringYesOriginal filename with extension, used for type validation and record keeping
sizenumberYesTotal file size in bytes, up to 20 GB
blake3_idstringNoContent fingerprint (same convention as single-shot deduplication); may trigger instant upload

Request Example

curl -X POST https://api.ai-mcn.tv:10000/base/file/upload/chunk/init \
  -H "Authorization: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "filename": "video.mp4",
    "size": 4370031878
  }'

Success Example

{
  "code": 200,
  "msg": "success",
  "data": {
    "upload_id": "537489015178300",
    "part_size": 33554432,
    "total_parts": 131,
    "expires_at": "2026-07-05 12:00:00"
  }
}
  • upload_id: unique identifier for this upload session, used by the other four endpoints
  • part_size: bytes per part (server-decided; split your file accordingly)
  • total_parts: total part count, i.e. ceil(size / part_size)
  • expires_at: session expiration time; every part upload or status query extends it

ℹ️ Note: Sessions are kept for 72 hours by default and are automatically extended by upload activity. Sessions that never complete are cleaned up; you would then need a fresh init.

Instant Upload

When init carries a blake3_id and a non-expired file with identical content already exists in the system, the API returns that file's full information directly (same shape as the single-shot upload response, plus instant: true) — zero bytes uploaded, no session is created, and no upload_id is returned:

{
  "code": 200,
  "msg": "File already exists, expiration time renewed~",
  "data": {
    "file_id": "537489015178246",
    "original_name": "video.mp4",
    "size": 4370031878,
    "blake3_id": "a1b2c3d4...",
    "base_ext": ".mp4",
    "download_url": "/download/a1/537489015178246.mp4",
    "created_at": "2026-04-05T08:00:00Z",
    "expire_at": "2026-09-01T00:00:00Z",
    "is_expired": false,
    "instant": true
  }
}

💡 Tip: Clients should check for instant: true in the response — if present, use the returned file_id directly; otherwise continue with the chunked flow. A fingerprint that only matches an expired file does not trigger instant upload; the session is created normally, and after complete the system renews and reuses the original record.

Upload Part (part)

Basic Information

ItemValue
Request MethodPUT
Request Path/base/file/upload/chunk/{upload_id}/{index}
Content-Typeapplication/octet-stream
AuthenticationRaw API key in the Authorization header

Path Parameters

ParameterTypeRequiredDescription
upload_idstringYesSession ID returned by init
indexnumberYesPart index, starting from 0, less than total_parts

Query Parameters

ParameterTypeRequiredDescription
blake3stringNoBlake3 checksum of this part's content; if provided, the server verifies it and returns 6026 on mismatch, treating the part as not uploaded

The request body is the raw bytes of the part (not form data). Every part must be exactly part_size bytes, except the last part, which is the remainder.

Request Example

# Split the file by the part_size returned from init (example: 32 MiB)
split -b 33554432 -d -a 4 video.mp4 part_

# Upload part 0 (part_0000 maps to index=0, and so on)
curl -X PUT "https://api.ai-mcn.tv:10000/base/file/upload/chunk/537489015178300/0" \
  -H "Authorization: YOUR_API_KEY" \
  -H "Content-Type: application/octet-stream" \
  --data-binary @part_0000

Success Example

{
  "code": 200,
  "msg": "success",
  "data": {
    "upload_id": "537489015178300",
    "index": 0,
    "received": 1,
    "total_parts": 131
  }
}

💡 Tip: The part endpoint is idempotent — uploading the same part twice due to a timeout retry never corrupts the file. Different parts can be uploaded out of order and in parallel for higher throughput.

Query Status (status)

Basic Information

ItemValue
Request MethodGET
Request Path/base/file/upload/chunk/{upload_id}
AuthenticationRaw API key in the Authorization header

Request Example

curl -X GET https://api.ai-mcn.tv:10000/base/file/upload/chunk/537489015178300 \
  -H "Authorization: YOUR_API_KEY"

Success Example

{
  "code": 200,
  "msg": "success",
  "data": {
    "upload_id": "537489015178300",
    "size": 4370031878,
    "part_size": 33554432,
    "total_parts": 131,
    "received": 100,
    "missing": [100, 101, 102, 130],
    "expires_at": "2026-07-05 12:00:00"
  }
}
  • missing: list of missing part indexes — after reconnecting, re-upload only these parts

Complete Upload (complete)

Basic Information

ItemValue
Request MethodPOST
Request Path/base/file/upload/chunk/{upload_id}/complete
AuthenticationRaw API key in the Authorization header

Request Example

curl -X POST https://api.ai-mcn.tv:10000/base/file/upload/chunk/537489015178300/complete \
  -H "Authorization: YOUR_API_KEY"

Success Example

The response shape is identical to POST /base/file/upload:

{
  "code": 200,
  "msg": "File uploaded successfully~",
  "data": {
    "file_id": "537489015178246",
    "original_name": "video.mp4",
    "size": 4370031878,
    "blake3_id": "a1b2c3d4...",
    "base_ext": ".mp4",
    "download_url": "/download/a1/537489015178246.mp4",
    "created_at": "2026-07-02T08:00:00Z",
    "expire_at": "2026-08-31T00:00:00Z",
    "is_expired": false
  }
}

💡 Tip: Just like single-shot upload, if the assembled content matches an existing file, deduplication kicks in and the existing (renewed) record is returned instead of storing a duplicate.

Error Example

When parts are still missing:

{
  "code": 6027,
  "msg": "Parts still missing, cannot complete: missing indexes (up to 20 listed) [100, 101, 102]",
  "data": null
}

Abort Session (abort)

Basic Information

ItemValue
Request MethodDELETE
Request Path/base/file/upload/chunk/{upload_id}
AuthenticationRaw API key in the Authorization header

Request Example

curl -X DELETE https://api.ai-mcn.tv:10000/base/file/upload/chunk/537489015178300 \
  -H "Authorization: YOUR_API_KEY"

Success Example

{
  "code": 200,
  "msg": "success",
  "data": {
    "upload_id": "537489015178300",
    "aborted": true
  }
}

ℹ️ Note: Abort is idempotent — calling it again, or on an expired session, still returns success.

Chunked Upload Error Codes

Error CodeHTTP StatusDescriptionResolution
6024404Session not found or expiredCall init again and re-upload from scratch
6025400Invalid part (index out of range / wrong part size)Check the index range and part byte count against the contract returned by init
6026400Part checksum mismatchRe-upload the part
6027400Parts still missing at completeUpload the missing indexes from the response, then call complete again
6028400Assembled file size does not match the declared sizeVerify the size declared at init against how the file was actually split
6001400Unsupported file typeUpload a file with a supported extension
6002413Declared size exceeds 20 GBCompress the file or upload a smaller one
6011400Declared size is 0Make sure the file contains actual content
6502401Authentication failedPass the raw API key in the Authorization header

Get File Details

Basic Information

ItemValue
Request MethodGET
Request Path/base/file/{file_id}
AuthenticationRaw API key in the Authorization header

Path Parameters

ParameterTypeRequiredDescription
file_idstringYesFile ID returned by the upload API

Request Example

curl -X GET https://api.ai-mcn.tv:10000/base/file/537489015178246 \
  -H "Authorization: YOUR_API_KEY"

Success Example

{
  "code": 200,
  "msg": "success",
  "data": {
    "file_id": "537489015178246",
    "original_name": "video.mp4",
    "size": 10485760,
    "blake3_id": "a1b2c3d4...",
    "base_ext": ".mp4",
    "upload_user_id": 1001,
    "download_url": "/download/a1/537489015178246.mp4",
    "created_at": "2026-04-05T08:00:00Z",
    "expire_at": "2026-06-04T00:00:00Z",
    "is_expired": false
  }
}

Notes

  • Uploaded files are retained for 60 days by default
  • Processing APIs validate both file existence and file type compatibility before task creation
  • Missing or expired files return 6004

Next Steps