WordPress から Qiita へ予約投稿するプラグインを書いています。テキストだけの記事はすんなり通るのに、画像を1枚はさんだ瞬間に手が止まりました。その画像を、どうやって Qiita 側へ渡せばいいのか。
結論を先に言うと、渡せませんでした。正確には、渡すための入り口が用意されていなかった。半日ほど API リファレンスを行ったり来たりして、ようやくそこに気づきます。同じところで止まる人がいそうなので、たどった道を残しておきます。

画像アップロードの口は、どこにあるのか?
Qiita の編集画面では、画像をドラッグして放り込むだけでアップロードできます。だから当然、それを叩く API があるものと思っていました。記事を投稿する POST /api/v2/items があるのだから、画像にも対応する口があるはずだ、と。
無いんです。これが今回の答えでした。
Qiita の公式 API(v2、個人用アクセストークンで叩けるもの)が用意しているのは、記事の投稿・編集・取得、タグ、ユーザー情報あたりまでです。画像をアップロードするエンドポイントは、この一覧に含まれていません。公式ヘルプでも、API でできることとして挙げられているのはデータの取得と記事・コメントの投稿で、画像アップロードはそこに入っていない。探しても見つからないわけです。無いものは見つからない。
編集画面のドラッグ&ドロップが使っているのは、ログインセッション(Cookie)前提の内部的な仕組みで、個人用アクセストークンの権限(read_qiita / write_qiita)には画像アップロードが含まれていません。トークンでそこを叩こうとしても、認証が通らないか、そもそも口が見当たらない。私が最初に踏んだのは、まさにこの「見当たらない」でした。
ここで少し脱線します。「ブラウザでできることは、だいたい API でもできるはず」という思い込みは、わりと裏切られます。ブラウザはログイン状態という強い文脈を持っていて、その文脈に依存した機能は、トークン認証の外側にあることが多い。今回はその典型でした。内部エンドポイントを Cookie ごと再現すれば技術的には叩けるのかもしれませんが、それは公開された手段ではないので、仕様変更ひとつで壊れます。配布するプラグインの土台に、壊れやすい裏口を据えるわけにはいきません。ここで方針を切り替えました。
では、画像はどこに置けばいいのか?
Qiita に置けないなら、自分の管理下に置いて、その URL を本文に書けばいい。Markdown なら  の一行です。Qiita の記事投稿 API には、この Markdown を body として渡すだけ。画像そのものを転送する処理は、まるごと要らなくなります。
置き場所は、3つ用意しました。
- WordPress のメディア(そのまま自サイトのURL)
- Cloudflare R2
- AWS S3
デフォルトは WordPress のメディアにしています。理由は単純で、追加の契約も設定も要らず、すでに記事に使っている画像がそのまま公開 URL を持っているからです。プラグインを入れてすぐ動く状態を、まず優先しました。R2 や S3 を選べるようにしたのは、画像の配信を自サイトの負荷から切り離したい人や、すでにオブジェクトストレージを運用している人のためです。最初から全員にバケットを用意させるのは、入り口として重すぎます。
この方式には、地味な副産物もあります。画像が自分の手元に残り続けること。Qiita 側にホストさせると、画像の管理は Qiita のものになり、こちらからは触れません。URL 埋め込みなら、差し替えも削除も自分の都合でできます。当初は「Qiita に置けないから仕方なく」と思っていた切り替えが、振り返るとむしろ素直な設計でした。
表示されない、をどう避けるか?
URL を埋め込めば終わり、とはいきませんでした。埋め込んだ画像が、相手から見えるかどうかは別の話です。
確認したのは、WordPress メディアの URL と、Cloudflare R2 の URL の両方。今回の環境ではどちらも Qiita 上で問題なく表示できました。ここで一点だけ、Cloudflare を使っている人は気に留めておくと安全な設定があります。Hotlink Protection です。
これは、別ドメインからの画像直リンクを Referrer で判定してブロックする機能です。オンにすると、Qiita の記事ページから読み込まれた画像は「別サイト(Qiita)からのリクエスト」と見なされ、表示されなくなります。今回やりたいことは、まさに別サイトからの直リンク表示なので、この機能とは相性が悪い。私の環境は Cloudflare デフォルト設定(Hotlink Protection はオフ)だったので素通りでしたが、もし過去にオンにしていたら、ここで詰まっていたはずです。Cloudflare 配下の画像が Qiita で表示されないときは、まずここを疑うといいと思います。
公開後の見え方も、念のため確認しておくと安心です。自分がログインしている画面では見えても、第三者(ログアウト状態)からは見えない、という取り違えがたまにあるためです。私はプライベートウィンドウで開いて、画像が出ることを確かめました。
次にやるなら、こうしたい
今回ぶつかったのは、機能の作り込み以前の、前提の確認でした。Qiita に画像アップロードの公開 API があるかどうか。最初にここを15分調べていれば、半日は浮いていた気がします。「ブラウザでできるから API でもできる」を疑うこと。次に外部サービスへ何かを送る実装を始めるときは、まず公式 API の範囲をひと通り眺めてから手を動かそう、と自分に言い聞かせています。
残っている問いもあります。R2 や S3 を選んだ人向けに、Hotlink Protection 相当の設定をプラグイン側でどこまで案内すべきか。表示されない原因が利用者の CDN 設定にある場合、プラグインのログだけでは切り分けが難しい。ここはまだ答えが出ていません。動くものはできたけれど、人に渡したときに迷わせない形になっているかは、これから確かめていくところです。
検証環境:2026年6月16日 / WordPress 7.0 / PHP 8.3.30 / Rapls Relay 0.9.0(開発版)/ Cloudflare デフォルト設定。Qiita の API 仕様は変わることがあるので、画像アップロードの口がいつか公式に増える可能性はあります。試すときは、そのときのリファレンスを一度確認してみてください。





コメント