File handling

Bring your own files to the model and build with your own data. Include bytes inline in a single Responses API or chat completion request, or upload once with the Files API and reuse the ID across calls. Both paths work for images, video, and PDFs.

How it works

Pick the path that fits your call:

  • Send it inline: include the file directly in a Responses or chat completion request, as base64 bytes (file_data) or a public URL (file_url). No storage to manage and nothing to clean up. Best for one-off calls. Limited to the 50 MB inline limit.
  • Upload it once: POST the file to the Files API, get a file- ID back, and reference that ID in as many requests as you need. Best for reuse and for large files up to 1 GiB.

See the Files API reference for full endpoint details.

Supported file types

The API accepts the following MIME types whether you send the file inline or upload it:

Media typeMIME typesNotes
Imageimage/png, image/jpeg (or image/jpg), image/gif, image/webp, image/x-iconimage/jpg is an alias for image/jpeg
Videovideo/mp4Visual frames plus embedded-audio transcription. See video and audio understanding.
Audioaudio/mpeg, audio/wavMP3 and WAV audio input. See video and audio understanding.
Documentapplication/pdfConverted to text plus per-page images. See PDF handling.
Texttext/plain, application/json, application/jsonlapplication/jsonl is used for batch uploads (purpose=batch)

Images, MP4 video, audio, and PDFs can be referenced in inference requests for image understanding, video and audio understanding, and document understanding. Audio files can be uploaded via /v1/files or sent inline using input_audio; see video and audio understanding. Text, JSON, and JSONL files are accepted for other purposes, such as batch datasets uploaded with purpose=batch.

PDF handling

PDFs are converted in parallel to text and per-page raster images, then sent together to the inference layer:

  • Text is extracted from the first 100 pages; pages beyond 100 contribute no text. The extracted text is then bounded by the model's context window.
  • Only the first 50 page-images are retained for visual understanding. These page-images count toward the per-request image budget (up to 50 images per request; see Image understanding).

A PDF with up to 50 pages is fully covered for both text and images. For a longer PDF, the model receives text from the first 100 pages and images from the first 50. It cannot see text beyond 100 pages or visual content beyond 50 pages.

Size limits

Send methodMaximum file size
Inline (file_data base64 or file_url in the request body)50 MB (50,000,000 bytes)
Files API upload (POST /v1/files)1 GiB (1,073,741,824 bytes)

Files larger than these limits are rejected.

Team storage limit

Uploaded files also count toward a per-team total storage limit of 100 GiB (107,374,182,400 bytes), shared across all API keys in your team. Only files stored through the Files API count toward this limit; inline files (file_data / file_url) do not.

Uploaded files don't expire, so stored data only grows until you remove it. When your team reaches the limit, further uploads to POST /v1/files are rejected with HTTP 400. Delete files you no longer need with DELETE /v1/files/{file_id} to free space.

Send a file inline

Send a file directly in the request body with no upload step. Chat Completions and the Responses API each carry an inline file in a content block:

  • Chat Completions: a file content block whose nested file object carries file_data (base64 bytes, optionally as a data: URL) and a filename.
  • Responses API: an input_file content block carrying file_data (with an optional filename), or a file_url the server fetches for you. Send inline video with an input_video block carrying video_url as a public URL or base64 data URL.

Inline files are bounded by the 50 MB inline limit. For anything larger, or for a file you will reuse, upload it instead.

First, read the file and base64-encode it into a data: URL. The request examples below reference this file_data variable:

python
import base64
with open("document.pdf", "rb") as f:
raw = f.read()
encoded = base64.b64encode(raw).decode()
file_data = f"data:application/pdf;base64,{encoded}"

In a chat completion

Pass the data URL in a file content block alongside your text.

python
import os
from openai import OpenAI
client = OpenAI(
base_url="https://api.meta.ai/v1",
api_key=os.environ["MODEL_API_KEY"],
)
response = client.chat.completions.create(
model="muse-spark-1.3",
messages=[
{
"role": "user",
"content": [
{
"type": "text",
"text": "Summarize this document.",
},
{
"type": "file",
"file": {
"filename": "document.pdf",
"file_data": file_data,
},
},
],
},
],
)
print(response.model_dump_json(indent=2))

In a Responses request

On the Responses API, carry the data URL in an input_file block's file_data field.

python
import os
from openai import OpenAI
client = OpenAI(
base_url="https://api.meta.ai/v1",
api_key=os.environ["MODEL_API_KEY"],
)
response = client.responses.create(
model="muse-spark-1.3",
input=[
{
"type": "message",
"role": "user",
"content": [
{
"type": "input_text",
"text": "Summarize this document.",
},
{
"type": "input_file",
"filename": "document.pdf",
"file_data": file_data,
},
],
},
],
)
print(response.model_dump_json(indent=2))

Reference a file by URL

Skip uploading and encoding; pass a public URL in an input_file block's file_url field on the Responses API. The server fetches the URL, detects the file type, and processes it. PDFs are parsed as described in PDF handling. Use this when the document is already hosted somewhere the API can reach over http or https. Other URL schemes return HTTP 400.

python
import os
from openai import OpenAI
client = OpenAI(
base_url="https://api.meta.ai/v1",
api_key=os.environ["MODEL_API_KEY"],
)
response = client.responses.create(
model="muse-spark-1.3",
input=[
{
"type": "message",
"role": "user",
"content": [
{
"type": "input_text",
"text": "Summarize this document.",
},
{
"type": "input_file",
"file_url": "https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf",
},
],
},
],
)
print(response.model_dump_json(indent=2))

Upload and reference a file

Upload a file once, then reference its ID across requests. Upload with POST /v1/files and set purpose to user_data for files you plan to reference in inference calls. To make a file expire automatically, include an optional expires_after object (see File expiration).

For lower upload latency, send purpose and all expires_after fields before the file part, and make file the final multipart part. Other field orders remain supported, but the server may finish receiving the request to disk before forwarding it.

python
import os
from openai import OpenAI
client = OpenAI(
base_url="https://api.meta.ai/v1",
api_key=os.environ["MODEL_API_KEY"],
)
with open("/path/to/image.png", "rb") as f:
file = client.files.create(
purpose="user_data",
file=f,
)
print(file.model_dump_json(indent=2))

Example response

json
{
"id": "file-842549258569145",
"object": "file",
"bytes": 245832,
"created_at": 1714502400,
"filename": "document.pdf",
"purpose": "user_data",
"status": "uploaded"
}

The response includes an id: a file- prefix followed by a numeric identifier, such as file-842549258569145. Use that ID to reference the file in later requests.

Reference an uploaded file

Pass the file ID in an input_file block's file_id field on a Responses API request. This works for images, videos, and PDFs. You can also reference uploaded images and videos with the typed input_image and input_video blocks.

python
import os
from openai import OpenAI
client = OpenAI(
base_url="https://api.meta.ai/v1",
api_key=os.environ["MODEL_API_KEY"],
)
response = client.responses.create(
model="muse-spark-1.3",
input=[
{
"type": "message",
"role": "user",
"content": [
{
"type": "input_text",
"text": "Summarize this document.",
},
{
"type": "input_file",
"file_id": "file-abc123",
},
],
},
],
)
print(response.model_dump_json(indent=2))

File expiration

By default, uploaded files do not expire. If you do not set expires_after, the response omits expires_at. To set an expiration, include an expires_after object in the upload request with two fields:

  • anchor: the reference point the lifetime is measured from. The only supported value is created_at.
  • seconds: the lifetime in seconds, from 3600 (1 hour) to 2592000 (30 days).

Both fields are required when expires_after is present. Omitting either, or using any anchor other than created_at, returns HTTP 400. When set, expires_at is created_at + seconds in Unix seconds.

python
import os
from openai import OpenAI
client = OpenAI(
base_url="https://api.meta.ai/v1",
api_key=os.environ["MODEL_API_KEY"],
)
with open("/path/to/document.pdf", "rb") as f:
file = client.files.create(
purpose="user_data",
expires_after={
"anchor": "created_at",
"seconds": 2592000,
},
file=f,
)
print(file.model_dump_json(indent=2))

List files

Retrieve a list of your uploaded files with GET /v1/files. Filter by purpose with the purpose query parameter, such as ?purpose=user_data.

python
import os
from openai import OpenAI
client = OpenAI(
base_url="https://api.meta.ai/v1",
api_key=os.environ["MODEL_API_KEY"],
)
response = client.files.list()
print(response.model_dump_json(indent=2))

Retrieve a file

Get metadata for a specific file with GET /v1/files/{file_id}.

python
import os
from openai import OpenAI
client = OpenAI(
base_url="https://api.meta.ai/v1",
api_key=os.environ["MODEL_API_KEY"],
)
response = client.files.retrieve("file_abc123")
print(response.model_dump_json(indent=2))

Delete a file

Remove a file with DELETE /v1/files/{file_id}.

python
import os
from openai import OpenAI
client = OpenAI(
base_url="https://api.meta.ai/v1",
api_key=os.environ["MODEL_API_KEY"],
)
response = client.files.delete("file_abc123")
print(response.model_dump_json(indent=2))

Next steps

Now that you can get files to the model, put them to work: