# 文件

上传输入文件并下载输出结果。

来源：https://scifig.ai/zh/docs/api/files

## 上传

`POST /files` 接受 `multipart/form-data`，需要 `figures:generate` 权限范围。成功返回 `201`，包含 `file_id`、`purpose`、`content_type`、`size_bytes`、`expires_at` 和 `created_at`。

| 字段 | 类型 | 必填 | 默认值 | 规则 |
| --- | --- | --- | --- | --- |
| file | file | 是 | — | 参阅下方用途限制 |
| purpose | string | 否 | `image` | `image`、`mask` 或 `flowchart_attachment` |

| 用途 | 支持的输入 | 使用场景 |
| --- | --- | --- |
| image | PNG、JPEG 或 WebP，最大 20 MB（按内容校验，而非文件名） | 编辑、文字识别、放大、转换、参考图像 |
| mask | 最大 8 MB 的 PNG；白色标记需要重绘的区域 | `POST /images/edits` |
| flowchart_attachment | FlowChart 工作台支持的格式，最大 32 MB | `POST /flowcharts/generations` |

上传文件可使用 24 小时；之后 `file_id` 不再有效（`400 INVALID_REQUEST`、`FILE_NOT_FOUND`）。它们仅作为输入，不会出现在任务响应中，也不会与任何人共享。

上传与网站共享上传限制。超出限制时，返回 `429 RATE_LIMITED`，包含 `Retry-After` 和 `details.reason`：每分钟限制为 `UPLOAD_RATE_LIMITED`，每日限制为 `UPLOAD_DAILY_LIMIT_REACHED`（流程图附件）。

上传可选带 `Idempotency-Key` 请求头（1–255 个可见 ASCII 字符）。相同账号、密钥和 `purpose` 始终对应同一个 `file_id`：重复请求以 `201` 返回首个文件，不会再次上传或占用上传额度。相同密钥和 `purpose` 搭配不同字节会返回 `409 IDEMPOTENCY_CONFLICT`。未发送此请求头时，每次上传均创建新文件。若文件已到期，重放请求返回 `400 INVALID_REQUEST` 和 `details.reason = FILE_EXPIRED`；请换新密钥重新上传。

## 下载

每个任务输出都有一个无需凭据、有效期一小时的 `download_url`；重新读取任务即可获得新链接。携带凭据调用 `GET /files/{file_id}` 可下载你的任意文件。所有文件均以附件形式提供。

签名 `download_url` 到期或被篡改时返回 `404 NOT_FOUND`；账号被封禁或正在删除时，其所有下载链接也会以相同方式失效。

| 输出 | 可传给 |
| --- | --- |
| PNG 或 JPEG | 所有图像端点（编辑、文字识别、放大、转换、参考图像） |
| WebP | 编辑、文字识别、放大、SVG 矢量化和参考图像；不适用于 PNG、PDF、TIFF 或 PPTX 转换 |
| 流程图 SVG | 通过 `POST /images/conversions` 转换为 PNG、PDF、TIFF 或 PPTX |
| PDF、TIFF、EPS、PPTX、其他 SVG | 均不可：只能下载 |

转换源文件大于 20 MB 时（例如放大至 8K 的图像），返回 `400 INVALID_REQUEST`（`FILE_TOO_LARGE`）。

## cURL

```bash
curl -X POST https://scifig.ai/api/v1/files \
  -H "Authorization: Bearer $SCIFIG_API_KEY" \
  -F "file=@figure.png" \
  -F "purpose=image"
```

## JavaScript

```javascript
import { readFile } from 'node:fs/promises';

const form = new FormData();
form.set('file', new Blob([await readFile('figure.png')]), 'figure.png');
form.set('purpose', 'image');

const response = await fetch('https://scifig.ai/api/v1/files', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.SCIFIG_API_KEY}`,
  },
  body: form,
});
const result = await response.json();
console.log(response.status, result);
```

## Python

```python
import os

import requests

headers = {
    "Authorization": f"Bearer {os.environ['SCIFIG_API_KEY']}",
}
response = requests.post(
    "https://scifig.ai/api/v1/files",
    headers=headers,
    files={"file": open("figure.png", "rb")},
    data={"purpose": "image"},
    timeout=60,
)
print(response.status_code, response.json())
```
