---
title: "Request files from a person"
method: POST
path: "/file/upload-request"
tags: ["Files"]
---

# Request files from a person

`POST /file/upload-request`

## Request

- Base URL: `https://api.elaichi.ai`
- URL: `https://api.elaichi.ai/file/upload-request`
- Auth: HTTP bearer

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 Elaichi app, 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.

## Headers

- `X-Organization-Id` string

## Request body

- object
  - `purpose` string, required: A short sentence the person reads on the page.
  - `max_files` integer
  - `accept` string[]
  - `max_file_bytes` integer

## Response `201`

Created

- object
  - `request_id` string: Request id (`fupr_…`).
  - `status` 'open' | 'confirmed' | 'expired': `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.
  - `purpose` string: What the files are for, as the asker said it.
  - `requester` string: Who is asking: the connected app’s name, or “Elaichi assistant”.
  - `limits` object
    - `max_files` integer: Files at most. 10.
    - `max_file_bytes` integer: The most one file may be. 95 MiB, or the request’s lower setting.
    - `max_total_bytes` integer: The most the whole request may hold. 250 MiB.
    - `accept` string[], nullable: Allowed media types (`image/*`, `application/pdf`) and extensions (`.csv`); null means anything.
  - `created_at` string, date-time
  - `add_files_until` string, date-time: Ten minutes after creation, fixed. No new file can be reserved after it; the person can still send the files they added.
  - `expires_at` string, 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.
  - `upload_page_url` string: The Elaichi app page where the person confirms. Carries no secret: only the signed-in person who made the request can use it.
  - `files` object[]: At most `limits.max_files`.
    - `file_id` string
    - `filename` string
    - `size_bytes` integer, nullable
    - `mime` string, nullable
    - `state` 'uploading' | 'staged' | 'ready' | 'stalled'

## Other responses

- `400`: Bad request
- `401`: Unauthorized
- `403`: Forbidden
- `404`: Not found
- `429`: Rate limited

---

[API](https://skmtc.dev/elaichi/apis/elaichi-api.md) · [All operations](https://skmtc.dev/elaichi/apis/elaichi-api/llms.txt) · [OpenAPI document](https://skmtc.dev/elaichi/apis/elaichi-api/revisions/b22cfb7b6d15?raw)
