Qiita API v2 には公式の画像アップロードがありません。Web エディタが内部で何を叩いているかを bundle から読み解き、実際に叩いて仕様を測りました。非公式 API なので将来変わる可能性はあります。
Qiita の記事にプログラムから画像を貼りたい——でも POST /api/v2/items はテキストしか受け付けません。
エディタの JS bundle(v3-editor-bundle) を読んだら、画像アップロードは 「ポリシー発行 → S3 直接 POST」 の2段構成でした。Qiita のサーバは画像を一切中継しません。
検証: 2026-09-21 / Qiita Web エディタと同一エンドポイント / Chrome セッション Cookie + CSRF トークンで実行
全体シーケンス: Qiita は署名だけ発行する
-
POST /api/upload/policies— サイズ・MIME・ファイル名を宣言すると S3 の presigned POST 情報が返る - 返ってきた
formフィールド全部 +fileをupload_url(=qiita-image-store.s3.amazonaws.com) に multipart POST - 204 が返れば完了。
asset.hrefがそのまま記事に貼れる公開 URL
Qiita 側で画像を保存しているわけではなく、発行した署名を使ってクライアントが直接 S3 に置きに行く設計です。レスポンスの form は S3 presigned POST の定型フィールドでした。
{
"upload_url": "https://qiita-image-store.s3.ap-northeast-1.amazonaws.com",
"form": {
"key": "0/<user_id>/<uuid>.png",
"acl": "public-read",
"Content-Type": "image/png",
"policy": "eyJleHBpcmF0aW9uIjoi...",
"x-amz-credential": "...",
"x-amz-algorithm": "AWS4-HMAC-SHA256",
"x-amz-date": "...",
"x-amz-signature": "..."
},
"asset": {
"href": "https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/<user_id>/<uuid>.png",
"name": "a.png",
"id": 5011669,
"size": 100
}
}
バリデーションを叩いて測った
許可される content_type・サイズ上限・必須項目を実際に変えて投げてみました。
| 条件 | 結果 | レスポンス |
|---|---|---|
| png / jpeg / gif / avif | ✅ 200 | policy 発行 |
| webp / svg / mp4 / pdf | ❌ 422 | content_type は一覧にありません |
| size > 10MB | ❌ 413 | size must be less than 10 MB |
name 欠落 |
❌ 422 | name を入力してください |
content_type 欠落 |
❌ 422 | content_type を入力してください |
意外なのは webp が拒否で avif が通る点です。モダン形式の受け入れ順が一般的な印象と逆なので、webp を上げるスクリプトは素直に png に変換してからにした方が安全です。
実装: 30行で完結するアップローダ
セッション Cookie と CSRF トークンがあれば、ブラウザを介さず fetch だけで完結します。
async function uploadToQiita(imagePath: string, cookie: string, csrf: string) {
const buf = fs.readFileSync(imagePath);
// 1. ポリシー発行
const policy = await fetch('https://qiita.com/api/upload/policies', {
method: 'POST',
headers: { cookie, 'x-csrf-token': csrf, 'content-type': 'application/json' },
body: JSON.stringify({
image: { size: buf.length, content_type: 'image/png', name: 'image.png' },
}),
}).then((r) => r.json());
// 2. S3 へ直接 POST
const fd = new FormData();
for (const k in policy.form) fd.append(k, policy.form[k]);
fd.append('file', new Blob([buf], { type: 'image/png' }), 'image.png');
await fetch(policy.upload_url, { method: 'POST', body: fd }); // 204
return policy.asset.href; // →  で貼れる
}
返ってきた href をそのまま Markdown の  に入れれば、記事内に Qiita ホストの画像として表示されます。本記事の図もすべてこの方法で置いています。
まとめ
- Qiita の画像アップロードは
/api/upload/policies→ S3 presigned POST の2段構成。公式 API ではないが構造は単純 - 許可形式は png / jpeg / gif / avif。webp・svg は 422。上限は 10MB
- 画像は
qiita-image-storeバケットに0/<user_id>/<uuid>.<ext>で置かれ、acl: public-readで即公開される
非公式エンドポイントのため仕様変更リスクがあります。記事投稿本体は引き続き安定した Qiita API v2 を使い、画像だけこの経路に逃がす分業が現実的です。
Qiita への自動投稿・CLI クライアントを作るときの参考になれば幸いです。

