Skip to content
GET /file/{id}/content

Streams the file — never JSON on success — with `Content-Disposition: attachment` and `X-Content-Type-Options: nosniff`. Supports `Range` (standard partial-content semantics; answers `206` with `Content-Range` when the request carries one). **Three tiers decide who may open a file, evaluated live on every request:** (1) the **owner** — the member who ran the tool, always; deliberately NOT the owner of the connection behind it, because delegation is disclosed, not gated and the person a file was made for routinely has no access to that connection; (2) anyone the owner **shared it with** (`POST /file/{id}/share`) — a user, a team they are in, or the whole organization, at `view`; (3) anyone with **`use` or better on the connection or the toolbox** the file came from, because they could have produced the same output. Tier 3 follows those grants as they move — revoke someone’s toolbox share and the file goes with it — and is **vetoed by the caller’s own organization restrictions** on that connector: a member a restriction blocks from the connector cannot open its files through the side door either. A file reached through tier 3 is listed by `GET /file` (flagged `restricted_by` / `can_open: false` when a restriction blocks it), but this route stays the authority. No permission verb gates any of it; an org permission plays no part in a file’s reach, and org owners and admins get no oversight read. Reached with **no** `X-Organization-Id` header — both a session cookie and an org API token work here, and an API token’s own pinned organization is cross-checked against the file’s organization by hand: a token minted in one org can never read a file in another, even when the same person is a member of both. The caller must also be a LIVE member of the file’s org right now, not merely its creator back when the tool ran. Every refusal answers the identical `404`, never `403`: a malformed or unknown id, a caller no tier reaches, a tier-3 reach vetoed by a restriction (or whose source connection has since been deleted, so there is nothing to check the restriction against), an API token pinned to another organization, a member who has left the org, an expired file, a staff member impersonating the owner in an org that turned staff access off, a blocked (suspended) org, and an org with no active plan. Existence is not disclosed to anyone but someone the file reaches, and the response never names which gate answered. The one other refusal is `416` for a `Range` that starts at or past the end of the file.

Path Parameters

idstring
required·

File id (file_…).

curl -X GET 'https://api.elaichi.ai/file/<id>/content' \
  -H 'Authorization: Bearer $ELAICHI_API_TOKEN' \
  -H 'Content-Type: application/json'
const response = await fetch('https://api.elaichi.ai/file/<id>/content', {
  method: 'GET',
  headers: {
    'Authorization': 'Bearer ' + process.env.ELAICHI_API_TOKEN,
    'Content-Type': 'application/json',
  },
});

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

url = "https://api.elaichi.ai/file/<id>/content"
headers = {
    "Authorization": f"Bearer {os.environ['ELAICHI_API_TOKEN']}",
    "Content-Type": "application/json",
}

response = requests.get(url, headers=headers)
print(response.json())