Skip to content
POST /file/upload-request

Makes an upload request: up to 10 files (`max_files`), 95 MiB each (`max_file_bytes`), 250 MiB in all, optionally restricted to `accept` types. It lapses 10 minutes after it is made unless the person confirms. There is no link to hand around and no secret: the person opens `upload_page_url` in the console, must be signed in as the account that made the request, chooses the files (each uploads in the background and can be removed again) and presses **Confirm**, which is their approval to hand the files over. Only confirmed files exist as files; until then a tool naming one is refused `file_pending`. Bounded per person: at most 20 requests open at once (`429` `too_many_open_uploads`) and 100 made per hour (`429` `too_many_upload_requests`, counted on requests made, so deleting files does not reset it). Audited as `file.upload_requested`. A backend that needs a file of its own, with no person involved, uses `POST /file` instead.

Request Body

acceptstring[]
max_file_bytesinteger
max_filesinteger
purposestring

A short sentence the person reads on the page.

Response Body

add_files_untilstring · date-time

Ten minutes after creation, fixed. No new file can be reserved after it; the person can still send the files they added.

created_atstring · date-time
expires_atstring · date-time

The last moment the person can confirm (Send). Starts at add_files_until; it moves out when an upload finishes or an upload that was running ends without landing, never past 35 minutes after creation.

filesobject[]

At most limits.max_files.

file_idstring
filenamestring
mimestring,null
size_bytesinteger,null
statestring
Possible values:
uploadingstagedreadystalled
limitsobject
acceptarray,null

Allowed media types (image/*, application/pdf) and extensions (.csv); null means anything.

max_file_bytesinteger

The most one file may be. 95 MiB, or the request’s lower setting.

max_filesinteger

Files at most. 10.

max_total_bytesinteger

The most the whole request may hold. 250 MiB.

purposestring

What the files are for, as the asker said it.

request_idstring

Request id (fupr_…).

requesterstring

Who is asking: the connected app’s name, or “Elaichi assistant”.

statusstring

open: waiting for the person (files may be added, removed, confirmed). confirmed: they approved; the staged files are now theirs. expired: the deadline passed unconfirmed with nothing still uploading. A request whose upload STARTED before the deadline stays open until that upload finishes, and each finished file keeps it open for at least five more minutes, so someone mid-upload is never told it expired.

Possible values:
openconfirmedexpired
upload_page_urlstring

The console page. Carries no secret: only the signed-in person who made the request can use it.

curl -X POST 'https://api.elaichi.ai/file/upload-request' \
  -H 'Authorization: Bearer $ELAICHI_API_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{"purpose":"your_purpose","max_files":0,"accept":[],"max_file_bytes":0}'
const body = {
  "purpose": "your_purpose",
  "max_files": 0,
  "accept": [],
  "max_file_bytes": 0
};

const response = await fetch('https://api.elaichi.ai/file/upload-request', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer ' + process.env.ELAICHI_API_TOKEN,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify(body),
});

const data = await response.json();
console.log(data);
import os
import requests

url = "https://api.elaichi.ai/file/upload-request"
headers = {
    "Authorization": f"Bearer {os.environ['ELAICHI_API_TOKEN']}",
    "Content-Type": "application/json",
}
payload = {
    "purpose": "your_purpose",
    "max_files": 0,
    "accept": [],
    "max_file_bytes": 0
}

response = requests.post(url, headers=headers, json=payload)
print(response.json())