Uploading files
Upload a file to Lightfield using the file upload lifecycle.
This guide shows how to upload a file to Lightfield: create an upload session, upload the raw bytes to storage, and complete the file in Lightfield.
Before you begin
Section titled “Before you begin”You will need:
- A valid API key
- The
files:createscope to create, complete, or cancel uploads - The
files:readscope if you want to verify the uploaded file or fetch a signed download URL
All Lightfield API calls in this flow use these headers:
Authorization: Bearer YOUR_API_KEYLightfield-Version: 2026-03-01Content-Type: application/jsonStep 1: Create an upload session
Section titled “Step 1: Create an upload session”Create a pending file upload by calling POST /v1/files.
The purpose field determines what the uploaded file will be used for. Each purpose has its own MIME type and size limits, and routes the file to the appropriate storage location.
| Purpose | Use for |
|---|---|
meeting_transcript | A transcript file to attach to a meeting. See Uploading meeting transcripts. |
knowledge_user | A file staged in the authenticated user’s personal uploads area, accessible to the chat agent. See Uploading knowledge files. |
knowledge_workspace | A file staged in the organization’s shared uploads area, accessible to the chat agent. Requires the caller to be an org admin. See Uploading knowledge files. |
The example below uses purpose: "meeting_transcript" because the meeting transcript flow in the next guide builds directly on this upload lifecycle.
curl https://api.lightfield.app/v1/files \ -X POST \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Lightfield-Version: 2026-03-01" \ -H "Content-Type: application/json" \ -d '{ "purpose": "meeting_transcript", "filename": "manual-upload-check.txt", "mimeType": "text/plain", "sizeBytes": 29 }'A successful response looks like:
{ "id": "fil_abc123", "filename": "manual-upload-check.txt", "status": "PENDING", "uploadUrl": "https://...", "uploadHeaders": { "content-type": "text/plain" }, "expiresAt": "2026-04-08T12:00:00.000Z"}Save the returned id, filename, uploadUrl, and uploadHeaders. You will use them in the next two steps.
Step 2: Upload the raw bytes
Section titled “Step 2: Upload the raw bytes”Upload the file contents directly to the returned uploadUrl.
printf 'hello from Lightfield upload\n' > /tmp/manual-upload-check.txt
curl -i -X PUT "$UPLOAD_URL" \ -H "content-type: text/plain" \ --data-binary @/tmp/manual-upload-check.txtUse the exact headers returned in uploadHeaders. The example only shows content-type, but your upload session may include additional required headers as well — for knowledge uploads, uploadHeaders will also contain if-none-match: *, and you must pass it on the PUT. Depending on the storage backend, the upload typically returns 200, 201, or 204.
Collision handling
Section titled “Collision handling”Knowledge uploads never overwrite an existing object. Two safeguards enforce this:
- Timestamped filenames.
POST /v1/filesstamps each filename with an epoch-millisecond suffix before the extension (playbook.md→playbook_1713045600000.md,archive.tar.gz→archive.tar_1713045600000.gz). The response’sfilenamefield returns the stored name. - Conditional PUT. The presigned URL for knowledge uploads is signed with
IfNoneMatch: *, and the requiredif-none-match: *header is included inuploadHeaders. If an object already exists at the target key, S3 rejects the PUT with412 Precondition Failed. The signed-headers policy means clients cannot strip the header without invalidating the signature.
There is no overwrite field on the create request. To replace an uploaded file, upload it again — the new timestamped name will land alongside the previous one.
Step 3: Complete the upload
Section titled “Step 3: Complete the upload”After the raw bytes have been uploaded successfully, finalize the file in Lightfield by calling POST /v1/files/{id}/complete.
curl https://api.lightfield.app/v1/files/$FILE_ID/complete \ -X POST \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Lightfield-Version: 2026-03-01" \ -H "Content-Type: application/json" \ -d '{}'If you computed an MD5 checksum while uploading, you can include it here:
{ "md5": "5d41402abc4b2a76b9719d911017c592"}After this call, the file status should transition from PENDING to COMPLETED.
Optional verification
Section titled “Optional verification”You can verify the upload in two common ways.
Read the file metadata
Section titled “Read the file metadata”curl https://api.lightfield.app/v1/files/$FILE_ID \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Lightfield-Version: 2026-03-01"This is useful for checking file status and stored metadata.
Get a temporary download URL
Section titled “Get a temporary download URL”curl https://api.lightfield.app/v1/files/$FILE_ID/url \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Lightfield-Version: 2026-03-01"This returns a signed URL you can use to download the uploaded file.
Cancel a pending upload
Section titled “Cancel a pending upload”If you created an upload session but do not want to complete it, you can cancel it while the file is still PENDING.
curl https://api.lightfield.app/v1/files/$FILE_ID/cancel \ -X POST \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Lightfield-Version: 2026-03-01"Only pending uploads can be cancelled.
End-to-end flow
Section titled “End-to-end flow”The minimal file upload lifecycle is:
POST /v1/filesPUT <uploadUrl>POST /v1/files/{id}/complete
Common follow-up calls:
GET /v1/files/{id}GET /v1/files/{id}/url
Next steps
Section titled “Next steps”- Uploading meeting transcripts — Upload a transcript file and attach it to a meeting.
- Uploading knowledge files — Stage files for the chat agent to promote into your knowledge base.
- API Reference — Full endpoint reference for files, meetings, and other resources.
- Errors — Learn how to handle 4xx and 5xx responses.