## Upload a file **post** `/files` Upload a file to your namespace, then reference it from a generation via ImageRef.file_id (as source, image_ref[], video.start_frame, keyframes, and so on). Two upload modes share this endpoint, selected by Content-Type: - multipart/form-data — send the bytes inline in the `file` part. Best for small files (subject to an inline size cap; larger files must use the presigned flow). The returned file is already `pending` ingest. - application/json — request a presigned upload. The response `upload` envelope tells you where to PUT the bytes; afterward call POST /files/{file_id}/complete to start ingest. Use this for larger files. ### Body Parameters - `mime_type: string` MIME type of the bytes you will upload. - `size_bytes: number` Exact size in bytes of the object you will PUT. Up to 5 GiB (the S3 single-PUT ceiling). - `expires_at: optional string` Optional TTL. After this time Luma may automatically delete the file and reclaim its bytes. - `filename: optional string` Optional original filename to record. - `purpose: optional FilePurpose` How the file is intended to be used in a generation. `input` is the primary subject (e.g. the source image for an edit); `reference` is style/content guidance. - `"input"` - `"reference"` - `user_id: optional string` Optional opaque end-user tag for abuse attribution. Mirrors the user_id field on POST /generations. ### Returns - `CreateFileResponse = object { id, file, state, upload }` Result of POST /files. In the multipart (inline) flow `upload` is null and the file is already `pending` ingest. In the presigned (JSON) flow `upload` carries the PUT envelope and the file stays `pending` until you call POST /files/{file_id}/complete. Top-level `id` and `state` are conveniences that mirror `file.id` and `file.state`; the full record is always under `file`. - `id: string` File identifier. - `file: File` A file in the caller's namespace. - `id: string` File identifier, referenced as ImageRef.file_id. - `created_at: string` Creation timestamp. - `mime_type: string` MIME type of the stored bytes (for example, image/jpeg). - `purpose: FilePurpose` How the file is intended to be used in a generation. `input` is the primary subject (e.g. the source image for an edit); `reference` is style/content guidance. - `"input"` - `"reference"` - `size_bytes: number` Size of the stored object in bytes. - `state: FileState` Lifecycle state of an uploaded file. `pending` until bytes are received and the ingest pipeline runs; `ready` once it can be referenced from a generation; `failed` if ingest/moderation rejected it; `deleted` after a soft-delete. - `"pending"` - `"ready"` - `"failed"` - `"deleted"` - `deleted_at: optional string` Soft-delete timestamp, if the file was deleted. - `expires_at: optional string` TTL set at upload, if any. After this time Luma may automatically delete the file and reclaim its bytes — you don't need to call DELETE yourself. - `failure_reason: optional string` Human-readable reason when state is failed. - `filename: optional string` Original filename supplied at upload, if any. - `user_id: optional string` The opaque end-user tag supplied at upload, echoed back unchanged. Abuse-attribution only; not an access-control primitive. - `state: FileState` Lifecycle state of an uploaded file. `pending` until bytes are received and the ingest pipeline runs; `ready` once it can be referenced from a generation; `failed` if ingest/moderation rejected it; `deleted` after a soft-delete. - `upload: optional PresignedUpload` Where to PUT the file bytes for a presigned (JSON) upload. Issue an HTTP PUT of the raw bytes to `url` with the given `headers`, then call POST /files/{file_id}/complete. - `expires_at: string` When the presigned URL expires. - `method: string` HTTP method to use for the upload — always PUT. - `url: string` Presigned S3 URL to PUT the bytes to. - `headers: optional map[string]` Headers that must be sent with the PUT request. ### Example ```http curl https://agents.lumalabs.ai/v1/files \ -H 'Content-Type: application/json' \ -H "Authorization: Bearer $LUMA_AGENTS_API_KEY" \ -d '{ "mime_type": "x", "size_bytes": 1 }' ``` #### Response ```json { "id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", "file": { "id": "182bd5e5-6e1a-4fe4-a799-aa6d9a6ab26e", "created_at": "2019-12-27T18:11:19.117Z", "mime_type": "mime_type", "purpose": "input", "size_bytes": 0, "state": "pending", "deleted_at": "2019-12-27T18:11:19.117Z", "expires_at": "2019-12-27T18:11:19.117Z", "failure_reason": "failure_reason", "filename": "filename", "user_id": "user_id" }, "state": "pending", "upload": { "expires_at": "2019-12-27T18:11:19.117Z", "method": "method", "url": "https://example.com", "headers": { "foo": "string" } } } ```