v1

latestOpenAPI 3.1.02026-07-223261135.0 KB
uploads

Register Upload

Finalize a signed-URL upload into a Moda file row.

Streams the staged blob through download_with_hash (writes to a temp file on disk, hashes in 8 KiB chunks) so a 250 MB upload never fully materializes in process memory — loading even a couple of those concurrently on Cloud Run would risk OOM and defeat the point of the direct-to-storage flow.

Deduplicates against existing team files by content hash. On a dedup miss the staged blob is server-side-copied to the canonical teams/<team>/files/<id> key via storage.copy (zero data transfer on GCS) and registered via create_file_from_storage. The pending blob is best-effort deleted either way.

post/uploads/register

Headers

Moda-Version'2026-04-12' | '2026-05-01'
Example:2026-05-01

Calendar-dated API version pin. New integrations should pin 2026-05-01 to opt into the newest response shapes. For back-compat the server also accepts requests with no header and resolves them to the current default (today: 2026-04-12); that default advances on each sunset date. Any unsupported value returns 400 unsupported_version.

Request body

storage_keystring required

storage_key returned by a prior POST /v1/uploads/url after the PUT completed.

filenamestring nullable

Filename to record on the File row. Defaults to the basename embedded in storage_key.

mime_typestring nullable

MIME type to record on the File row. Defaults to the type the signed URL was originally bound to (inferred from the filename when not supplied).

Response

Successful Response

idstring required

Unique file identifier (prefixed file_...).

urlstring required

Stable proxy URL for the uploaded file. Use this in attachment URLs.

filenamestring required

Filename of the uploaded file.

mime_typestring required

MIME type of the file.

size_bytesinteger nullable

File size in bytes.

was_duplicateboolean

True if an identical file already existed (deduplicated).

Example response

{
  "id": "file_01HT9WK8N3M2J4A5Z6P7Q8R9TV"
}