Get API key

Files

Upload a dataset once and reference it by id from batch, fine-tuning, and other endpoints.

The Files API is an org-scoped store for the datasets other endpoints consume. You upload a file once, get back an id, and hand that id to whatever needs it, rather than inlining the same bytes into every request. It is the input side of the Batch API and the same surface fine-tuning and other bulk endpoints read from.

The surface is OpenAI-compatible: point the official client at https://api.privatemind.com/v1 and client.files.* works unchanged (the one addition, /v1/files/usage, has no OpenAI equivalent). This is a REST API on the gateway and is separate from files you attach in a chat, which are per-conversation and never get a file id.

Purposes

Every file declares a purpose at upload, and the purpose is fixed for the life of the file. It tells the platform what the bytes are for, which validation to run, and how long to keep them.

Purpose For Validated as
batch Input for a batch JSONL, one request per line
fine-tune Fine-tuning datasets JSONL
vision Images referenced by requests Passed through (not validated)
assistants General-purpose reference files Passed through

Upload a file

POST /v1/files is a multipart upload. Send the purpose field first, then the file.

curl -s "https://api.privatemind.com/v1/files" \
  -H "Authorization: Bearer $PMIND_KEY" \
  -F purpose=batch \
  -F file=@requests.jsonl
from openai import OpenAI

client = OpenAI(base_url="https://api.privatemind.com/v1", api_key=PMIND_KEY)
f = client.files.create(file=open("requests.jsonl", "rb"), purpose="batch")
print(f.id)  # file-...

The upload is streamed and validated as it goes, so a file that fails validation (malformed JSONL for a line-oriented purpose, or a body over the size limit) is rejected without being stored. The response is a file object.

The file object

JSON
{
  "id": "file-abc123",
  "object": "file",
  "bytes": 148923,
  "created_at": 1730928000,
  "filename": "requests.jsonl",
  "purpose": "batch",
  "status": "processed"
}
  • id: the handle you pass to other endpoints. Keep it.
  • bytes: size of the stored content.
  • purpose: what you declared at upload.

Retrieve metadata

GET /v1/files/{id} returns the file object above. It does not return the content.

curl -s "https://api.privatemind.com/v1/files/file-abc123" \
  -H "Authorization: Bearer $PMIND_KEY"
f = client.files.retrieve("file-abc123")
print(f.filename, f.bytes)

List files

GET /v1/files lists your org's files, newest first. Filter to one kind with ?purpose=.

curl -s "https://api.privatemind.com/v1/files?purpose=batch" \
  -H "Authorization: Bearer $PMIND_KEY"
for f in client.files.list(purpose="batch"):
    print(f.id, f.filename)

Download content

GET /v1/files/{id}/content streams the raw bytes. This is how you pull a batch's output and error files.

curl -s "https://api.privatemind.com/v1/files/file-out-abc123/content" \
  -H "Authorization: Bearer $PMIND_KEY" -o output.jsonl
content = client.files.content("file-out-abc123")
content.write_to_file("output.jsonl")

Delete a file

DELETE /v1/files/{id} removes a general file and its content immediately.

curl -s -X DELETE "https://api.privatemind.com/v1/files/file-abc123" \
  -H "Authorization: Bearer $PMIND_KEY"
client.files.delete("file-abc123")

Storage usage

GET /v1/files/usage summarises how much of your org's file storage is in use, so you can see where you stand against a quota before an upload is refused.

cURL
curl -s "https://api.privatemind.com/v1/files/usage" \
  -H "Authorization: Bearer $PMIND_KEY"

If your org has a storage quota, an upload that would cross it is rejected; without a quota, storage is unbounded. Uploaded files, including batch inputs, count toward usage until they age out. (A batch's generated output and error files are served from the run itself and do not add to the total.)

Limits and retention

  • Maximum file size: 64 MB per file. A larger upload is rejected (413).
  • Retention depends on purpose. Files tied to a batch (its input, output, and error files) are retained for a fixed window after the batch reaches a terminal state, then deleted. General files (assistants, and other non-batch purposes) belong to you and stay until you delete them.
  • Content is stored server-side. See the Batch API for the batch-specific request cap and completion window.

Where next

  • Batch API: the primary consumer of purpose: batch files.
  • Errors: status codes and error shapes, including quota and validation rejections.
  • Files and sources: the separate, per-conversation attachments in the chat app.