Figmaのフレームやコンポーネントを画像として書き出すREST APIは、GET /v1/images/:keyです。複数のnode IDをidsへまとめて指定し、返ってきた画像URLから別途ダウンロードします。APIの応答自体は画像ファイルではありません。
この記事は2026年10月3日に確認した公式仕様に基づき、PNGを保存するPython例を掲載します。保存処理は模擬HTTP応答で確認していますが、実際のFigma APIでのレンダリング・画像寸法の検証は未実施です。Figma公式の画像API
レンダリング画像と画像塗りの取得を区別する
| API | 取得するもの | URLの有効期間 |
|---|---|---|
| GET /v1/images/:key | 指定したノードをPNG・JPG・SVG・PDFへレンダリングしたURL | 30日 |
| GET /v1/files/:key/images | ファイル内の画像塗りに使うimageRefとダウンロードURL | 最大14日 |
画面全体やボタンをそのまま書き出したい場合は前者です。画像塗りの取得は、ノードのレイアウトや文字まで含む画面の書き出しではありません。得られた一時URLは公開サイトの恒久画像URLに使わず、必要なファイルを保存します。
PAT・ファイルキー・node IDを用意する
画像の書き出しにはfile_content:readスコープと、対象ファイルへのアクセス権が必要です。個人アクセストークンの取得を参照し、環境変数FIGMA_TOKENへ設定します。
ファイルキーはFigmaのURLの/design/や/file/の直後にある文字列です。node IDは対象フレーム・レイヤーへのリンクで確認します。URLのnode-id=1-2は、APIでは1:2として指定します。ファイル名やフレーム名だけではIDの代わりになりません。
書き出しパラメーター
| 項目 | 役割 |
|---|---|
| ids | node IDをカンマ区切りで指定 |
| format | png・jpg・svg・pdf |
| scale | 0.01〜4の倍率 |
| version | 指定バージョンを使う。省略時は現行版 |
| svg_outline_text | SVGの文字をアウトラインにするか |
| svg_include_id | SVGへレイヤー名に基づくidを含めるか |
| svg_include_node_id | SVGへdata-node-idを含めるか |
| svg_simplify_stroke | 内側・外側の線をマスクではなくstrokeへ簡略化するか |
| contents_only | ノードに重なる外側の内容を含めるか |
| use_absolute_bounds | 切り抜きや空白によらずノード全体の寸法を使うか |
画像は最大32メガピクセルまでで、それを超える場合は縮小されます。scale=2を指定しても、常に寸法がちょうど2倍になるとは限りません。通常のエディター書き出しは倍率と固定幅の使い方、SVGの文字はSVG設定を参照してください。
応答のimagesとnullを確認する
成功時のimagesはnode IDとURLの対応表です。statusは成功時に省略されると公式に説明されているため、常に200というフィールドがあると仮定しないでください。
{
"images": {
"1:2": "https://example.com/temporary-image.png",
"3:4": null
}
}これは形を説明する例です。nullは、そのノードのレンダリング失敗を示します。IDが存在しない、表示可能な内容がない、不可視・透明などの条件を確認します。1件がnullでも、ほかのノードのURLを保存できる場合があります。
PythonでPNGを保存する
次をexport_images.pyとして保存します。環境変数FIGMA_FILE_KEYへファイルキー、FIGMA_NODE_IDSへ1:2,3:4のようにIDを設定します。出力先はfigma-imagesです。同じIDのPNGがある場合は成功時に置き換えます。
import os
import re
import tempfile
from pathlib import Path
from urllib.parse import urlparse
import requests
def save_png(url, destination):
if urlparse(url).scheme != "https":
raise ValueError("画像URLはHTTPSである必要があります")
# ダウンロード先にFigmaトークンを渡さない。
response = requests.get(url, timeout=60)
if response.status_code != 200:
raise RuntimeError(f"画像取得失敗: HTTP {response.status_code}")
data = response.content
if not data.startswith(b"\x89PNG\r\n\x1a\n"):
raise ValueError("取得結果がPNGではありません")
destination = Path(destination)
temporary = None
try:
with tempfile.NamedTemporaryFile(dir=destination.parent, delete=False) as handle:
temporary = Path(handle.name)
handle.write(data)
temporary.replace(destination)
finally:
if temporary is not None:
temporary.unlink(missing_ok=True)
def main():
key = os.environ["FIGMA_FILE_KEY"]
ids = list(dict.fromkeys(x.strip().replace("-", ":")
for x in os.environ["FIGMA_NODE_IDS"].split(",")))
if not re.fullmatch(r"[A-Za-z0-9_-]+", key):
raise SystemExit("ファイルキーを確認してください")
if not ids or any(not re.fullmatch(r"\d+:\d+", x) for x in ids):
raise SystemExit("node IDを1:2,3:4の形式で設定してください")
response = requests.get(
f"https://api.figma.com/v1/images/{key}",
headers={"X-Figma-Token": os.environ["FIGMA_TOKEN"]},
params={"ids": ",".join(ids), "format": "png", "scale": 2}, timeout=60
)
if response.status_code == 429:
raise SystemExit("API制限に達しました。Retry-Afterを確認してください")
if response.status_code != 200:
raise SystemExit(f"レンダリング要求失敗: HTTP {response.status_code}")
result = response.json()
if result.get("err"):
raise SystemExit("APIがレンダリングエラーを返しました")
images = result["images"]
directory = Path("figma-images")
directory.mkdir(exist_ok=True)
for node_id in ids:
url = images.get(node_id)
if not url:
print(node_id, "レンダリング結果なし")
continue
try:
save_png(url, directory / (node_id.replace(":", "-") + ".png"))
except (requests.RequestException, OSError, ValueError, RuntimeError):
print(node_id, "保存失敗。HTTP結果・接続・出力先を確認してください")
else:
print(node_id, "保存しました")
if __name__ == "__main__":
main()python -m pip install requests
python export_images.pyAPIへの認証ヘッダーと、画像URLからの取得を分けています。PNGのシグネチャを確認するので、エラーページをPNG名で保存することを避けられます。ただし、この確認だけでは画像が最後まで正常か、期待するピクセル寸法かは判定できません。保存後に実ファイルを開いて確認してください。
403・404・429と保存失敗を切り分ける
| 状況 | 確認すること |
|---|---|
| API要求が403 | PATの期限・スコープ、対象ファイルへの権限 |
| API要求が404 | ファイルキーとアクセス対象 |
| API要求が429 | Retry-After、席と対象リソースのプラン、連続呼び出し |
| imagesの値がnull | node ID、不可視・透明・描画対象なし |
| 画像URLから取得できない | URLの期限、通信、HTTP結果 |
| 保存できない | 出力先の権限、同名ファイルを別アプリが使用していないか |
画像レンダリングはTier 1です。idsをまとめることでAPI要求数を減らせますが、画像のダウンロードまで含めて1要求になるわけではありません。REST APIの制限
大きなファイルでは対象を絞り、成功分・null・保存失敗を記録して再取得範囲を決めます。API全体の役割はREST APIとPlugin APIの比較で説明しています。
