Claude Media
Claudeでファイルをダウンロードできない原因 — Files APIの400エラー

Claudeでファイルをダウンロードできない原因 — Files APIの400エラー

Files APIにアップロードしたファイルはdownloadableがfalseのままで、ダウンロードを試みると400エラーになります。ダウンロードできるのはSkillsとコード実行ツールが生成したファイルだけです。

Files APIへ自分でアップロードしたファイルは、あとから同じAPIでダウンロードできません。アップロード直後のレスポンスに含まれるdownloadableフィールドは常にfalseで、GET /v1/files/{file_id}/contentを叩くと400エラーが返ります。ダウンロードできるのは、Skillsやコード実行ツールがコンテナ内で作ったファイルだけです。

「ダウンロードできない」が出る場面を切り分ける

Claudeでファイルが落とせないとき、原因は使っている画面で分かれます。このページが扱うのは、APIキーでGET /v1/files/{file_id}/contentを呼んだときの400と404です。

出ている症状場面見る先
400(Not downloadable)場面Files APIでアップロードしたファイルの取得見る先このページの次節以降
404(File not found)場面file_idの誤り、権限なし、または期限切れ見る先400と404の使い分け
チャットで生成されたファイルの保存場面Claudeアプリでの会話見る先Claudeのファイル作成と編集のガイド

「ファイルのダウンロードに失敗しました」という文言をAPIの応答で探しても、該当するエラー名はありません。API側のエラー名は、400なら「Not downloadable」、404なら「File not found」です。

downloadableフィールドが何を表すか

Files APIへのアップロードが成功すると、レスポンスにfile_idと一緒にdownloadableという真偽値が返ります。

{
  "id": "file_011CNha8iCJcU1wXNR6q4V8w",
  "type": "file",
  "filename": "budget.xlsx",
  "mime_type": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
  "size_bytes": 1024000,
  "created_at": "2026-09-01T12:00:00Z",
  "downloadable": false,
  "expires_at": null
}

downloadableがtrueになるのは、Skillやコード実行ツールがコンテナの中で生成したファイルだけです。自分でアップロードしたファイルはfalseのままです。一覧取得(list)やメタデータ取得(retrieve_metadata)でも同じ値が返るので、ダウンロードを試す前にこの1フィールドで判定できます。

くらべる

アップロードしたファイルと生成ファイル

入力側

アップロードしたファイル

contentエンドポイントは400を返します。file_idはMessagesリクエストの入力として参照します。

出力側

Skill・コード実行ツールの生成ファイル

GET /v1/files/{file_id}/contentで取得できます。file_idは応答のbash_code_execution_tool_resultに載ります。

ダウンロードしようとすると何が起きるか

downloadable: falseのファイルに対してGET /v1/files/{file_id}/contentを呼ぶと、レスポンスは400エラーになります。

curl "https://api.anthropic.com/v1/files/$FILE_ID/content" \
  -H "x-api-key: $ANTHROPIC_API_KEY" \
  -H "anthropic-version: 2023-06-01"

$FILE_IDが自分でアップロードしたファイルを指していると、このリクエストは400を返します。エラー一覧では「Not downloadable(400)」として、ファイルが存在しない、またはアクセス権がない場合の「File not found(404)」とは別の項目に載っています。Files APIのエラー一覧のうち、ダウンロード周りで当たりやすいのは次の3つです。

エラー発生条件
Not downloadable(400)発生条件アップロードしたファイル(downloadable: false)に対してcontentエンドポイントを呼んだ
Invalid file type(400)発生条件ファイルの種類とコンテンツブロックの型が一致しない(画像ファイルをdocumentブロックに使う等)
Storage limit exceeded(400)発生条件組織のストレージ上限(1TB)に達している

入力用と出力用でfile_idの出どころが違う

同じ形式のfile_idでも、渡す側と受け取る側で使い分けます。

監査ログにも非対称性が表れる

Compliance APIを有効にしている組織では、Files APIの操作がActivity Feedに記録されます。アップロード(POST /v1/files)はplatform_file_uploaded、ダウンロード(GET /v1/files/{file_id}/content)はplatform_file_content_downloaded、削除はplatform_file_deletedというイベント種別で残ります。

アップロードしたファイルはdownloadable: falseのため、そのファイルのplatform_file_content_downloadedが記録されることはありません。このイベントが残るのは、Skillやコード実行ツールが生成したファイルを取得したときだけです。ダウンロード操作の内訳を追うときは、アップロードしたファイルのダウンロード履歴がないことを異常として調べずに済みます。

一覧取得やメタデータ取得(list / retrieve_metadata)はActivity Feedに記録されません。Compliance APIがオフの間の操作は記録されず、あとから復元することもできません。

生成ファイルだけに付くContent Credentials

ダウンロードできるファイルの側にも、アップロードファイルには無い挙動があります。コード実行ツールが生成した画像・動画・音声ファイルは、Claude APIでダウンロードするとC2PA(Coalition for Content Provenance and Authenticity)規格のContent Credentialsが付きます。対応形式には、PNG・JPEG・GIF・WebP・TIFF・HEIC・AVIF・SVG・MP4・MOV・MP3・WAV・FLAC・M4Aがあります。

署名はAnthropicを発行者として記録するもので、ファイルの見た目は変わりません。メタデータが数キロバイト分増えるため、ダウンロードしたファイルのサイズとチェックサムは、コンテナ内にあるファイルとは一致しなくなります。テキストファイル・PDF・Officeドキュメントは署名の対象外です。

アップロードしたファイルは、すでにContent Credentialsを持っていてもそのまま保存されます。ダウンロード対象外なので、この署名処理にも関わりません。署名が付くのは、ダウンロードできる生成ファイルのうち、対応する画像・動画・音声に限られます。

ワークスペーススコープにも注意する

downloadableとは別の軸として、アップロードしたファイルはワークスペース全体からアクセス可能で、特定のエンドユーザーや会話に紐づいていません。そのワークスペースにアクセスできるAPIキーであれば、誰がアップロードしたファイルでも参照できます。

エンドユーザーから受け取ったfile_idをそのまま信頼してはいけないのはこのためです。ファイルとユーザーの対応関係はアプリケーション側で管理します。マルチテナントのアプリケーションでは、テナントごとにワークスペースを分けるのが、ファイルの分離境界になります。

400と404の使い分け — 「ダウンロード不可」と「期限切れ」は別のエラー

Files APIのダウンロードでは、似たエラーが2種類の別条件で返るので区別が必要です。

ステータス発生条件
400(Not downloadable)発生条件ファイルは存在するが、アップロードしたファイルでdownloadable: false
404(File not found)発生条件file_idが存在しない、またはアクセス権がない。期限切れ(expires_atを過ぎた)ファイルのcontent取得も404

アップロード時にexpires_in_seconds(3,600秒の1時間から7,776,000秒の90日までの整数)を指定すると、そのファイルには有効期限が付きます。期限が来た後は、ダウンロード可能だったファイルでもcontentエンドポイントは404を返します。400は「このファイルでは、ダウンロードという操作が成立しない」、404は「そのfile_idは今アクセスできない」という別の意味です。エラーハンドリングでは、この2つを同じ「取得失敗」として握りつぶさず、原因ごとに分岐させます。

メタデータ(GET /v1/files/{file_id})は、期限切れから最長30日間、expires_atが過去日時のまま読み取れます。この期間は一覧にも載り続けます。つまりdownloadable: trueでも、expires_atが過去ならダウンロードは404です。ダウンロード前の判定では、downloadableだけでなくexpires_atも見ます。ベータヘッダーfiles-api-2025-04-14を付けたままのリクエストではexpires_atが返らず、ids[]も使えません(before_id・after_idで一覧を引きます)。

expires_atは、期限を付けずにアップロードしたファイルではnullです。判定コードではnullを期限なしとして扱います。期限切れのファイルを参照するMessagesリクエストは、推論が始まる前に失敗します。

downloadableを見てから叩く実装

400エラーを個別にキャッチするより、ダウンロード前にdownloadableを確認しておくほうが、意図が読み取りやすいコードになります。

def try_download(client, file_id: str):
    metadata = client.files.retrieve_metadata(file_id=file_id)
    if not metadata.downloadable:
        print(f"{file_id} はアップロードされたファイルのためダウンロードできません")
        return None
    content = client.files.download(file_id=file_id)
    content.write_to_file(metadata.filename)
    return metadata.filename

retrieve_metadataはダウンロードの成否に関わらず呼べます。Skillsの出力とユーザーがアップロードしたファイルのfile_idが混在するパイプラインでは、この分岐を挟むと400エラーの発生自体を避けられます。

既知のfile_idをまとめて調べたいときは、ids[]クエリパラメータで最大100件を1回のリクエストに渡せます。存在しないfile_idは結果から黙って省かれるので、返ってきたIDを依頼したIDと突き合わせて、欠けたものを検出します。ids[]はpageやlimitとは併用できません。

手元に原本がないとき、何が選べるか

「アップロードしたファイルをAPI経由でダウンロードする」という操作自体が存在しません。選べる道は、原本を手元に残してあるかどうかで分かれます。

  • 原本が手元にある場合: そのファイルを使います。Files APIは再アップロードを省くための参照であって、バックアップストレージではありません
  • 原本がなく、加工した結果でよい場合: コード実行ツールに読み込ませて、出力ファイルを受け取ります
  • 原本がなく、アップロードしたファイルそのものが必要な場合: ダウンロードの手段は用意されていません

2つ目の経路は、入力と出力のフォーマットが変わるケース(CSVをExcelに変換するなど)で使えます。コード実行ツールが新しく書き出した出力ファイルは、downloadable: trueになるためです。

手順

アップロードしたファイルを加工して取り出す流れ

  1. 1

    Files APIへアップロードする

    file_idを取得します。コード実行ツールが読める形式は、CSV・Excel・JSON・XML・画像(JPEG・PNG・GIF・WebP)・テキストファイルです。

  2. 2

    container_uploadで参照させる

    Messagesリクエストにcontainer_uploadブロックでそのfile_idを入れ、コード実行ツールもリクエストに含めます。

  3. 3

    生成ファイルのfile_idを取り出す

    応答のbash_code_execution_tool_resultから、コンテナが書き出したファイルのfile_idを拾います。

  4. 4

    Files APIでダウンロードする

    contentエンドポイントに渡して、ファイルを保存します。

組織内に大量のアップロードファイルと生成ファイルが混在している場合、listの結果をdownloadableの値で振り分けると、回収できるファイルと原本を別に持つしかないファイルを機械的に仕分けられます。ストレージ上限に近づいたときの棚卸しでは、この仕分けが削除の判断材料になります。

容量とセキュリティの注意点

ストレージ上限(組織で1TB、1ファイル500MB)や有効期限の扱いは、Claude Files APIの容量上限とファイルライフサイクルにまとめています。file_idを外部から受け取って使う場合のセキュリティ上の注意点は、Claude Files APIのfile_idセキュリティリスクと対策で扱っています。

まとめ

400は仕様どおりの応答なので、再試行しても結果は変わりません。404は期限切れかfile_id・権限の問題で、同じ呼び出しを繰り返しても戻りません。原本を残す責任はアップロードした側にあり、Files APIに預けたまま取り戻す前提では組めません。期限切れの404だけは、downloadableとexpires_atを見てからcontentを呼ぶと、呼び出す前に避けられます。

この記事を共有:XはてブLinkedIn