Skip to main content
The Uploads API allows you to upload large files in parts, which is useful for files larger than the standard file upload limit. An upload can accept up to 8 GB in total and expires after an hour.

Create Upload

Create an intermediate upload object to which you can add parts.
upload = client.uploads.create(
  bytes: 1024 * 1024 * 100,  # 100 MB
  filename: "training_data.jsonl",
  mime_type: "application/jsonl",
  purpose: "fine-tune"
)

puts upload.id
# => "upload_abc123"
bytes
integer
required
The total number of bytes in the file you are uploading.
filename
string
required
The name of the file to upload.
mime_type
string
required
The MIME type of the file. Must match the purpose requirements.
purpose
string
required
The intended purpose of the uploaded file. Options: assistants, batch, fine-tune, vision.
expires_after
integer
Number of seconds after which the upload expires (default: 1 hour).

Add Parts

Upload file data in chunks using the parts subresource:
# Upload first part
part1 = client.uploads.parts.create(
  upload.id,
  data: File.read("chunk1.dat")
)

# Upload second part
part2 = client.uploads.parts.create(
  upload.id,
  data: File.read("chunk2.dat")
)

Complete Upload

Finalize the upload by providing the ordered list of part IDs:
completed = client.uploads.complete(
  upload.id,
  part_ids: [part1.id, part2.id]
)

# The upload now includes a usable File object
file = completed.file
puts file.id
# => "file-xyz789"
upload_id
string
required
The ID of the upload to complete.
part_ids
array<string>
required
Ordered list of part IDs to assemble into the final file.
md5
string
Optional MD5 checksum for verification.

Cancel Upload

Cancel an upload before completion:
cancelled = client.uploads.cancel(upload.id)

puts cancelled.status
# => "cancelled"
upload_id
string
required
The ID of the upload to cancel.

Complete Example

require "openai"

client = OpenAI::Client.new

# Create the upload
upload = client.uploads.create(
  bytes: File.size("large_file.jsonl"),
  filename: "large_file.jsonl",
  mime_type: "application/jsonl",
  purpose: "fine-tune"
)

# Upload in 10MB chunks
chunk_size = 10 * 1024 * 1024
part_ids = []

File.open("large_file.jsonl", "rb") do |file|
  while chunk = file.read(chunk_size)
    part = client.uploads.parts.create(upload.id, data: chunk)
    part_ids << part.id
  end
end

# Complete the upload
completed = client.uploads.complete(upload.id, part_ids: part_ids)

puts "File uploaded: #{completed.file.id}"

Best Practices

Use the Uploads API for files larger than 50 MB or when you need to:
  • Upload files from multiple sources
  • Resume interrupted uploads
  • Verify data integrity with MD5 checksums
Use chunk sizes between 5 MB and 100 MB for optimal performance. Smaller chunks increase overhead; larger chunks may fail on slow connections.
Uploads expire after 1 hour by default. For long uploads:
  • Monitor upload progress
  • Implement retry logic
  • Consider increasing expires_after if needed

Response Fields

id
string
The upload identifier.
status
string
Current status: pending, completed, or cancelled.
bytes
integer
Total number of bytes for the upload.
file
object
The created File object (only present after completion).

Files API

Manage uploaded files

Fine-tuning

Use uploaded files for fine-tuning

File Uploads Guide

File upload patterns and examples

Batch API

Process batch requests

Build docs developers (and LLMs) love