# ファイル

入力をアップロードし、出力をダウンロードします。

出典：https://scifig.ai/ja/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 | 最大 20 MB の PNG、JPEG、WebP（ファイル名ではなく内容を検証） | 編集、文字検出、高解像度化、変換、参照画像 |
| mask | 最大 8 MB の PNG。白い部分が再描画する領域 | `POST /images/edits` |
| flowchart_attachment | FlowChart ワークスペース対応形式、最大 32 MB | `POST /flowcharts/generations` |

アップロードしたファイルは 24 時間利用できます。その後は `file_id` が見つからなくなります（`400 INVALID_REQUEST`、`FILE_NOT_FOUND`）。入力専用のため、ジョブのレスポンスには表示されず、他の人に共有されることもありません。

アップロードにはウェブサイトと同じ制限が適用されます。超過すると、`Retry-After` と `details.reason` を伴う `429 RATE_LIMITED` を返します。理由は、分ごとの制限では `UPLOAD_RATE_LIMITED`、日ごとのフローチャート添付制限では `UPLOAD_DAILY_LIMIT_REACHED` です。

アップロードには任意で `Idempotency-Key` ヘッダーを指定できます（表示可能な ASCII 文字 1～255 文字）。同じアカウント、キー、`purpose` は常に 1 つの `file_id` に対応します。再送すると、再アップロードや制限枠の消費なしに最初のファイルを `201` で返します。同じキーと `purpose` でバイト列が異なると `409 IDEMPOTENCY_CONFLICT` を返します。ヘッダーを省略すると、毎回新しいファイルを作成します。元のアップロードの期限が切れている場合、再送は `details.reason = FILE_EXPIRED` 付きの `400 INVALID_REQUEST` を返します。新しいキーで再アップロードしてください。

## ダウンロード

各ジョブの出力には、認証情報なしで 1 時間利用できる `download_url` が付いています。新しいリンクを取得するにはジョブを再度読み取ってください。認証情報付きの `GET /files/{file_id}` で自分のファイルをダウンロードできます。ファイルは常に添付ファイルとして配信されます。

署名付き `download_url` は、期限切れや改変があると `404 NOT_FOUND` を返します。利用停止中または削除処理中のアカウントのリンクも、すべて同じように利用できなくなります。

| 出力 | 入力として渡せる先 |
| --- | --- |
| PNG または JPEG | すべての画像エンドポイント（編集、文字検出、高解像度化、変換、参照画像） |
| WebP | 編集、文字検出、高解像度化、SVG ベクター化、参照画像。PNG・PDF・TIFF・PPTX 変換には使用不可 |
| フローチャートの SVG | PNG・PDF・TIFF・PPTX への `POST /images/conversions` |
| 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())
```
