Skip to content
Using the API

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.

You will need:

  • A valid API key
  • The files:create scope to create, complete, or cancel uploads
  • The files:read scope 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_KEY
Lightfield-Version: 2026-03-01
Content-Type: application/json

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.

PurposeUse for
meeting_transcriptA transcript file to attach to a meeting. See Uploading meeting transcripts.
knowledge_userA file staged in the authenticated user’s personal uploads area, accessible to the chat agent. See Uploading knowledge files.
knowledge_workspaceA 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.

Terminal window
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.

Upload the file contents directly to the returned uploadUrl.

Terminal window
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.txt

Use 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.

Knowledge uploads never overwrite an existing object. Two safeguards enforce this:

  • Timestamped filenames. POST /v1/files stamps each filename with an epoch-millisecond suffix before the extension (playbook.mdplaybook_1713045600000.md, archive.tar.gzarchive.tar_1713045600000.gz). The response’s filename field returns the stored name.
  • Conditional PUT. The presigned URL for knowledge uploads is signed with IfNoneMatch: *, and the required if-none-match: * header is included in uploadHeaders. If an object already exists at the target key, S3 rejects the PUT with 412 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.

After the raw bytes have been uploaded successfully, finalize the file in Lightfield by calling POST /v1/files/{id}/complete.

Terminal window
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.

You can verify the upload in two common ways.

Terminal window
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.

Terminal window
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.

If you created an upload session but do not want to complete it, you can cancel it while the file is still PENDING.

Terminal window
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.

The minimal file upload lifecycle is:

  1. POST /v1/files
  2. PUT <uploadUrl>
  3. POST /v1/files/{id}/complete

Common follow-up calls:

  1. GET /v1/files/{id}
  2. GET /v1/files/{id}/url