パブリックAPIが利用可能です。MarkdownをAPIで画像に変換、毎月50回まで透かし付きで利用できます。
ブログに戻る
2026年8月2日日曜日

Markdown to Image API 入門:cURL・Node.js・Python・n8n で PNG を生成

Markdown to Image API 入門:cURL・Node.js・Python・n8n で PNG を生成

Markdown to Image API 入門:cURL・Node.js・Python・n8n で PNG を生成

画像を一枚だけ書き出すなら手作業でも十分です。しかし、AI レポート、更新履歴、サポート回答、SNS 投稿を毎回同じ品質のビジュアルに変換する製品では、手動操作がすぐにボトルネックになります。Markdown to Image API を使えば、レンダリングをコードに組み込めます。Markdown を送り、形式とテーマを選び、URL またはバイナリを受け取り、必要な保存先へ送る流れです。

この記事では、MarkdownToImage API を実際に動かします。まず cURL で確認し、同じ処理を Node.js と Python で実装し、n8n を設定します。さらに、短いクイックスタートでは省かれがちな本番運用の対策も追加します。

エンドポイントと制限は、2026 年 8 月 2 日に公式 API ドキュメントで確認しました。クォータやプランは変更される可能性があるため、本番費用を見積もる前に最新の料金ページを確認してください。

1. Markdown to Image API を使うべき場面

画像生成が単発のデザイン作業ではなく、繰り返し実行するワークフローの一部なら API が向いています。代表的な用途は次のとおりです。

  • LLM の回答をダウンロード可能なレポート画像にする;
  • デプロイ後にリリースノートのカードを自動生成する;
  • CMS のフィールドから Open Graph 画像や SNS カードを作る;
  • コード、表、Mermaid 図、KaTeX 数式を一定の見た目で描画する;
  • n8n、Dify、Make、CI、社内ツールの中で画像成果物を作る。

一度きりならブラウザの変換ツールの方が速い場合があります。入力がすでに別のシステムにあり、同じスタイルを繰り返し使う場合や、出力を保存・公開・通知へ自動的に渡す場合に API の価値が高まります。

2. 事前準備:トークンと環境

MarkdownToImage にサインインし、API Tokens 画面からトークンを作成します。これはパスワードと同様に扱ってください。ソースコード、Markdown、スクリーンショット、ブラウザ側 JavaScript、エクスポートしたワークフローに書いてはいけません。

ローカルテストでは環境変数として設定します。

export MARKDOWN_TO_IMAGE_API_TOKEN="mti_your_token_here"

本番環境ではホスティング基盤の暗号化されたシークレット保管機能を利用します。公開リポジトリやログにトークンが出た場合は、古いコミットを隠すだけではなく、トークンを失効して作り直してください。

現在の API には、透かし付き出力の月間無料枠があります。透かしなしや大きな利用量は、クレジットまたは最新プランに依存します。実装時に公式ページを確認し、現在の枠を永続的な仕様としてハードコードしないでください。

3. cURL で最初のリクエストを送る

生成エンドポイントは JSON を受け取り、Bearer 認証を使います。次のリクエストは、幅 1200 ピクセル、GitHub のダークテーマを使った PNG を作成します。

curl -X POST https://markdowntoimage.com/api/v1/images/generate \
  -H "Authorization: Bearer $MARKDOWN_TO_IMAGE_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "markdown": "# Weekly release\n\n- Faster exports\n- Clearer reports\n- One automated workflow",
    "format": "png",
    "width": 1200,
    "quality": 2,
    "theme": "github-dark",
    "mode": "url"
  }'

URL モードが成功すると、レスポンスの data.imageUrl に結果が入ります。この URL は一時的です。ブラウザで開けば生成成功は確認できますが、永続保存にはなりません。早めにファイルをダウンロードし、自分のオブジェクトストレージ、CMS、メディアライブラリへ保存します。

4. パラメーターと出力形式の選び方

必須なのは markdown だけですが、自動化では設定を明示して出力を予測可能にすることが重要です。

パラメーター制御する内容実用的な選択
markdown元のコンテンツ送信前に長さと必須セクションを検証
formatpngjpegwebppdfコードと UI は PNG、軽い Web 素材は WebP、文書は PDF
width200〜2560 ピクセルの幅SNS やレポートは 1200 から始め、実データで確認
quality1〜3 のデバイススケールまず 2。大きい値はファイルサイズと処理量を増やす
theme全体のテーマ名前付きテーマを固定し、更新による見た目の変化を防ぐ
codeStyleシンタックスハイライトページテーマとのコントラストを確認
fontFamilyフォントプリセット製品で使う全言語をテスト
modeurl または binaryURL は連携向け、binary は直接ファイル処理向け

写真中心で非可逆圧縮を許容できる場合は JPEG、コードや図、シャープな UI には PNG が適しています。すべての利用先が対応するなら WebP は転送量を減らせます。PDF は同じ生成エンドポイントを使いますが、通常の SNS 画像ではなく文書出力です。

5. Node.js:画像を生成して保存する

次の Node.js スクリプトは API を呼び出し、HTTP レスポンスを確認し、一時 URL から画像をダウンロードして実ファイルに保存します。現在の Node.js にあるグローバル fetch を使います。

import { writeFile } from "node:fs/promises";

const token = process.env.MARKDOWN_TO_IMAGE_API_TOKEN;
if (!token) throw new Error("MARKDOWN_TO_IMAGE_API_TOKEN is required");

const response = await fetch("https://markdowntoimage.com/api/v1/images/generate", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${token}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    markdown: "# Build report\n\n- Tests: **passed**\n- Deploy: **ready**",
    format: "png",
    width: 1200,
    quality: 2,
    theme: "github-dark",
    mode: "url",
  }),
  signal: AbortSignal.timeout(30_000),
});

if (!response.ok) {
  throw new Error(`Generation failed: ${response.status} ${await response.text()}`);
}

const result = await response.json();
const imageResponse = await fetch(result.data.imageUrl, {
  signal: AbortSignal.timeout(30_000),
});
if (!imageResponse.ok) {
  throw new Error(`Download failed: ${imageResponse.status}`);
}

await writeFile("build-report.png", Buffer.from(await imageResponse.arrayBuffer()));
console.log("Saved build-report.png");

Web サービスでは、永続ストレージへのアップロードが完了してからジョブを成功にしてください。API の一時 URL だけを記録して実ファイルをコピーしないと、URL の期限切れ後に遅延障害が発生します。

6. Python:画像を生成して保存する

Python の URL モードも、生成とダウンロードの二段階です。タイムアウトを明示することで、Worker が無期限に待機するのを防ぎます。

import os
from pathlib import Path

import requests

token = os.environ["MARKDOWN_TO_IMAGE_API_TOKEN"]
payload = {
    "markdown": "# Build report\n\n- Tests: **passed**\n- Deploy: **ready**",
    "format": "png",
    "width": 1200,
    "quality": 2,
    "theme": "github-dark",
    "mode": "url",
}

response = requests.post(
    "https://markdowntoimage.com/api/v1/images/generate",
    headers={"Authorization": f"Bearer {token}"},
    json=payload,
    timeout=30,
)
response.raise_for_status()

image_url = response.json()["data"]["imageUrl"]
image_response = requests.get(image_url, timeout=30)
image_response.raise_for_status()
Path("build-report.png").write_bytes(image_response.content)
print("Saved build-report.png")

利用量が増えたら、この処理をユーザー向けの長い HTTP リクエスト内ではなくジョブキューで実行します。キューなら同時実行数とリトライを制御し、最終保存 URL も記録できます。

7. n8n で同じワークフローを作る

n8n では、Markdown を作成または取得するノードの後に HTTP Request ノードを置きます。トークンを Workflow JSON に貼らず、n8n Credentials に保存してください。

Method: POST
URL: https://markdowntoimage.com/api/v1/images/generate
Authentication: Header Auth
Header name: Authorization
Header value: Bearer {{$credentials.markdownToImageToken}}
Send Body: JSON
Body:
{
  "markdown": "{{$json.content}}",
  "format": "png",
  "width": 1200,
  "quality": 2,
  "theme": "github-dark",
  "mode": "url"
}

二つ目の HTTP Request ノードで {{$json.data.imageUrl}} をダウンロードし、ファイル出力を有効にします。そのバイナリを S3、Google Drive、Directus、WordPress、Slack などへ送ります。認証やクォータの失敗時に空のレコードを公開しないよう、エラー分岐も明示してください。

8. URL モードと binary モードの選択

自動化基盤が JSON を扱いやすく、二回目のダウンロードを実行できるなら URL モードが便利です。キュー、Webhook、ノーコードフローに適していますが、返される URL は一時的です。公式ドキュメントでは現在 24 時間保持とされています。

一回のレスポンスをそのままストレージへ流したい場合は binary を選びます。二回目の HTTP リクエストは不要ですが、クライアント側でバイナリ、Content-Type、拡張子、メモリ上限、不完全なアップロードの削除を正しく扱う必要があります。

どちらでも最終ファイルは自分が管理するストレージに保存します。形式、幅、テーマ、元コンテンツ ID、生成日時、Markdown のハッシュも記録すると、重複防止と障害調査が容易になります。

9. 重複レンダリングを防ぐエラー処理

API では次の主な結果が文書化されています。

HTTP ステータス意味推奨対応
400Markdown がない、またはパラメーターが不正同じ入力を再試行せず、Payload を修正
401トークンがない、無効、または失効済み停止して通知し、Secret を修正または更新
429無料枠またはクレジットを利用できないジョブを遅延し、担当者へ通知または容量を追加
500生成失敗または内部エラーBackoff を使い、回数を制限して再試行

自動リトライは、一時的な障害に限定します。すべての非 200 応答を再試行してはいけません。500 とネットワークタイムアウトには、ジッター付き指数バックオフを使います。接続結果が不明な場合は、同じコンテンツハッシュの出力がすでに保存されていないか確認してから再試行し、一つのジョブで複数回課金されるのを防ぎます。

ログにはステータス、サービス側エラーコード、ジョブ ID、試行回数、遅延を残します。ただし Authorization ヘッダー全体は記録しません。

10. 本番運用チェックリスト

実トラフィックを送る前に確認してください。

  • API トークンはサーバー側の暗号化シークレットに保存;
  • 接続と全体のタイムアウトを設定;
  • リトライ回数を制限し、ジッター付き指数バックオフを使用;
  • Worker の同時実行数をクォータと保存先に合わせる;
  • API 呼び出し前に Markdown のサイズと必須項目を検証;
  • 形式、幅、テーマ、コードスタイル、フォントを固定;
  • URL モードの結果をすぐに永続保存;
  • ユーザー入力をそのまま使わず、安全で決定的なファイル名を作る;
  • 公開画像に代替テキストと適切な文脈を付ける;
  • 使用量を記録し、クォータ枯渇前に通知;
  • 多言語フォント、長いコード、表、Mermaid、KaTeX を実データで確認;
  • 重要な公開フローに手動の代替手段を用意。

まず少数の代表的な入力で試してください。現実的な Markdown を十件試す方が、数百回の “Hello World” より多くのレイアウト問題を見つけられます。

11. よくある質問

Markdown を直接 PNG に変換できますか?

はい。生成エンドポイントへ format: "png" を送ります。JPEG、WebP、PDF も選べます。コード、本文、図、UI のキャプチャには PNG が最も安全な選択です。

ブラウザから API を直接呼べますか?

クライアントコードにシークレットトークンを公開してはいけません。サーバー、Serverless Function、保護された自動化フローから呼び出し、保存済みの結果だけをブラウザへ返します。

AI や LLM の出力を画像にする方法は?

長さ、内容、安全性を自分の側で確認してから、モデルの Markdown を markdown フィールドへ渡します。安定したプロンプトテンプレートと固定レンダリング設定を使う方が、回答ごとにレイアウトを変えるより一貫したカードになります。

n8n だけで十分ですか?

単純な生成、ダウンロード、アップロードなら n8n で十分です。高い同時実行数、独自の冪等性、詳細な可観測性、権限や課金との密接な統合が必要なら Node.js や Python のアプリケーションコードを使います。

12. 次の一歩:実際の Payload を試す

製品がすでに生成している Markdown を一つ選び、cURL の例で実行してください。ワークフローを広げる前に、コードの折り返し、表、フォント、画像サイズを確認します。

最初の結果が良ければ、MarkdownToImage API ガイドを開き、サーバー専用トークンを作成し、Node.js、Python、n8n のいずれかを小規模な本番テストへ移します。一種類の実コンテンツ、固定した表示プリセット、永続ストレージ、観測可能なエラー処理から始め、結果を確認してから拡張するのが安全です。

Markdown to Image API:Node.js・Python・n8n 入門 | MarkdownToImage