file-... ID in requests. Reusing a file ID avoids uploading the same bytes again. Each occurrence still has its own position in the request’s asset ordering; file IDs and asset_idx serve different purposes.
Upload and use a local image
Installperceptron>=0.4.0 and set PERCEPTRON_API_KEY as shown in the quickstart. Replace ./image.png with a local PNG image. The SDK’s files.upload() sends the bytes to the Files API and returns a File; pass that object to image() to reference its ID in a completion.
image(file_id="file-...") instead. Calling image("./image.png") directly embeds the local image in the completion request; it does not upload to the Files API. The same distinction applies to video() and audio().
The curl example also needs Bash and jq. The upload uses multipart form data; let curl set its content type and boundary. The completion response has the same shape as any chat completion: read choices[0].message.content and check choices[0].finish_reason before treating the answer as complete.
Upload and use a local video
Usevideo(uploaded) to send a video_file_id content part. Replace ./video.mp4 with a local video:
vision_config={"enable_audio_in_video": True} to the completion request. See Video Q&A for soundtrack behavior.
Upload and use local audio
Audio uploads support these canonical content types:
Use the content type matching the file’s actual bytes. Renaming a file does not convert its format. Replace
./recording.wav with a local WAV recording:
purpose=vision is the accepted Files API purpose for media uploads, including audio. An audio_file_id input is analyzed without enabling video soundtracks. For an uploaded video’s soundtrack, use video_file_id and set vision_config.enable_audio_in_video: true on the completion request.
A successful upload does not guarantee that the recording fits the model’s audio or context limits. Each audio item is limited to 16,384 encoder tokens, approximately 21.8 minutes at 750 tokens per minute; timestamp tokens and other request content also consume context. See Audio and tokenization before submitting a long recording.
Manage uploaded files
The SDK also providesclient.files.list() for one page of files, client.files.iter() to iterate across pages, client.files.retrieve(file_id) for metadata, and client.files.download(file_id, path) to save the bytes locally. Call client.files.delete(file_id) when you no longer need a file; subsequent requests cannot use the deleted ID.
See Upload a file for accepted formats and Delete a file for the deletion endpoint.
Use presigned media uploads
POST /v1/media/upload-urls also accepts WAV, MP3, and FLAC with the content types above. This is a separate upload flow from the Files API:
- Send
filesentries containingfile_name,content_type, and the exact bytecontent_lengthto/v1/media/upload-urls, using your Perceptron API key. - Upload the bytes with
PUTto the returnedupload_url, using the sameContent-Typeyou declared. Do not send your Perceptron API key to the presigned URL. - Send the returned
object_keyin anobject_keysarray toPOST /v1/media/download-urls, using your Perceptron API key. Use the returneddownload_urlin anaudio_urlcontent part while it remains valid.
object_key is not a Files API file-... ID. Use /v1/files when you want to reference the recording with audio_file_id.
Referencing a file in a request
Reference an uploaded file in a chat completion by id with animage_file_id / video_file_id content part, or by passing its /v1/files/{file_id}/content URL as a standard image_url / video_url. All four forms are equivalent.