# 檔案

上傳輸入檔案並下載輸出結果。

來源：https://scifig.ai/zh-Hant/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())
```
