API

プログラムやサーバーから呼ぶ API です。原稿によるデザインの依頼(サービス画面と同じこと)と、CANVAS の検査ができます。サービス画面の AI との相談は、API にはありません。すべて /api/v1 の下にあり、リクエストごとに Authorization: Bearer <トークン> で認証します。セッションやクッキーは使いません。応答はエラーも含めてすべて JSON で、Cache-Control: private, no-store と Vary: Authorization が付きます。

トークン

  • ログインして「アカウント」→「API クライアントとトークン」で発行します。トークンは発行したときに一度だけ表示されます。サーバーに残るのはトークンの SHA-256 だけです。画面で発行したトークンはそのアカウントのもので、API で依頼したデザインは、そのアカウントの「デザイン一覧」に入ります。
  • 事務局はサーバーのコマンドでも登録できます。この場合、トークンはサーバーに一度も送られません:php artisan api-clients:register neofactory-director <トークンの SHA-256> --days=365。コマンドで登録したクライアントはどのアカウントにも属さず、自分で依頼したデザインだけが見えます。
  • トークンがない、形が違う(Bearer <トークン> 以外)、知らない、期限切れ、失効済みのときは 401 {"message": "Unauthenticated."} と WWW-Authenticate: Bearer を返します。
  • 入れ替えるときは、新しいトークンを別の名前で発行し、呼ぶ側を切り替えてから古いほうを失効させます。
  • 1 クライアントあたり 1 分に 60 回まで呼べます。超えると 429 と Retry-After を返します。応答には X-RateLimit-Limit と X-RateLimit-Remaining が付きます。

デザインを依頼する

依頼は、媒体(プリセット)の掲載原稿(magic://schemas/manuscript/v1、Magic の各プロダクトで共通の契約 magic-contract が定める形)で送ります。原稿の文言は、言い換えずにそのまま画像に入ります。

  1. GET /api/v1/templates/{preset} で、その媒体の原稿のスキーマ(schema。JSON Schema 2020-12、自己完結)と、サンプルの原稿(manuscript)を取り出します。
  2. 原稿を書きます。media はその媒体の {"id", "version"}(templates の media)です。どの掲載項目も、構成(structure)のどこかのブロックの content_refs から参照してください。サンプルの文言はそのまま送れますが、そのまま画像に入ります。
  3. POST /api/v1/designs で送ります。原稿は magic-contract の検査(ManuscriptCheck)を通ったものだけを受け付け、通らないときは 422 で、違反の場所(JSON Pointer)と理由を返します。
  4. 受け付けた時点で 202 を返し、AI が順番に描きます。status が completed か failed になるまで、GET /api/v1/designs/{id} を数十秒おきに確かめてください。

描く枚数は、原稿の構成で決まります。名刺・チラシは faces の数、スライドは slides、Instagram カルーセルは images、動画は scenes の数です(pages.max まで)。Web サイトとランディングページは PC と SP の 2 枚、ほかの媒体は 1 枚です。

メソッドとパス リクエスト 応答
GET /api/v1/templates なし 200 {"media_contract", "data": [プリセット…]}。依頼できるプリセットと、その寸法・面や枚数の上限(pages.max)・媒体(media)
GET /api/v1/templates/{preset} なし 200 {"data": プリセット}。上に加えて、原稿のスキーマ(schema)とサンプルの原稿(manuscript)、共通デザイン指示のスキーマ(design_direction_schema)。知らないプリセットは 404
POST /api/v1/designs {"preset", "manuscript", "title"(省略可), "design_direction"(省略可)} 202 {"data": デザイン} と Location
GET /api/v1/designs ?page= 200 {"data": [デザイン…], "meta": {"current_page", "last_page", "total"}}。新しい順に 20 件ずつ
GET /api/v1/designs/{id} なし 200 {"data": デザイン}
PATCH /api/v1/designs/{id} {"title"}、{"manuscript"}、{"design_direction"}、または {"generate": true} タイトルだけなら 200。原稿かデザイン指示を変えたとき、または "generate": true は、新しい版として描き直して 202。生成中は 409
DELETE /api/v1/designs/{id} なし 204。画像もすべて削除します
GET /api/v1/designs/{id}/canvases/{canvas}/image なし 200。PNG の画像(image_url に入っている URL)

原稿の文字列は、送ったとおりに保存します(前後の空白を削ったり、空の文字列を null にしたりしません)。原稿の JSON は 200 KB までです。

任意のデザイン指示

design_direction は magic-contract の共通契約です。目的、対象、雰囲気、ブランド、強調点、書体、配色、レイアウト、写真・イラスト、避けたい表現、自由記述を指定できます。すべて任意で、名刺・Web・チラシなどに同じ項目を使います。項目名と構造は design_direction_schema を参照してください。

掲載する文言は必ず manuscript に入れ、デザイン指示には伝え方を書いてください。依頼前に原稿を確定してください。指示を省略した PATCH は保存済みの指示を維持し、{"design_direction": {}} は指示を消して再生成します。null は受け付けません。指示の emphasis[].content_refs は、原稿の content.items に存在するキーだけを参照できます。指示の形式や参照に問題がある場合は 422 の errors.design_direction(原稿だけの変更で保存済み指示と不整合になる場合は errors.manuscript)に理由を返します。

422 の例:

{
  "message": "/content/items/holder/display_name:入力してください。 (and 1 more error)",
  "errors": {"manuscript": ["/content/items/holder/display_name:入力してください。", "/content/items/email/channel:「種類」を入れてください。"]}
}

デザインは次の形です。

{
  "id": "01jabcd…",
  "title": "山田さんの名刺",
  "preset": "business-card",
  "preset_label": "名刺",
  "pages": 2,
  "manuscript": {"schema_version": 1, "kind": "publication-manuscript", "media": {"id": "business-card", "version": 1}, "…": "…"},
  "design_direction": {"purpose": "初対面で信頼を伝える", "mood": ["落ち着いた", "読みやすい"]},
  "brief": null,
  "revision": 1,
  "status": "completed",
  "error": null,
  "media_contract": "0.3.0",
  "order": {"$schema": "magic://schemas/canvas-order/v1", "media_contract": "0.3.0", "preset": "business-card", "slots": [{"key": "front"}, {"key": "back"}]},
  "check": {"valid": true, "violations": []},
  "canvases": [
    {"key": "front", "viewport": null, "model": "gpt-image-2.5-flare", "width": 1456, "height": 880, "sha256": "…", "image_url": "https://designer.magichtml.dev/api/v1/designs/01jabcd…/canvases/1/image", "metadata": {"$schema": "magic://schemas/canvas/v2", "…": "…"}}
  ],
  "created_at": "2026-10-10T10:00:00+09:00",
  "updated_at": "2026-10-10T10:03:00+09:00",
  "completed_at": "2026-10-10T10:03:00+09:00"
}
  • status は queued(生成待ち)・generating(生成中)・completed(完了)・failed(失敗。理由は error)です。
  • 描き直しのあいだも、canvases は描き終わるまで前の版のままです。
  • metadata は、その画像の CANVAS のメタデータ(magic://schemas/canvas/v2)です。check は、order の納品としてそれらを検査した結果です。
  • brief は、原稿の前に依頼文で依頼したデザインだけが持ちます(manuscript は null)。描き直すには、PATCH で原稿を送ってください。原稿なしの "generate": true は 422 です。
  • 見えるのは、そのトークンのアカウントのデザインだけです。ほかのデザインの ID は 404 です。
curl -sS https://designer.magichtml.dev/api/v1/templates/business-card \
  -H "Authorization: Bearer $TOKEN" | jq '.data.manuscript' > manuscript.json

# manuscript.json の文言を書き換えてから
curl -sS https://designer.magichtml.dev/api/v1/designs \
  -H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
  -d "{\"preset\": \"business-card\", \"manuscript\": $(cat manuscript.json)}"

CANVAS を検査する

ほかで作った CANVAS が、発注書どおりに納品されたかを検査します(NeoFactory のディレクターが使います)。

メソッドとパス リクエスト 応答
GET /api/v1/catalog なし 200。媒体・形式・プリセット・ビューポートのカタログ
POST /api/v1/canvas/check JSON の本文 {"canvas": <メタデータ 1 つか配列>, "order": <発注書>}(order は省略可)。または multipart/form-data で canvas(JSON のファイルかフィールド)、order(省略可)、image(省略可。メタデータが 1 つのときだけ) 200 {"valid": …, "violations": […]}。合否にかかわらず 200
curl -sS https://designer.magichtml.dev/api/v1/catalog \
  -H "Authorization: Bearer $TOKEN"

curl -sS https://designer.magichtml.dev/api/v1/canvas/check \
  -H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
  -d "{\"canvas\": $(cat canvas.json), \"order\": $(cat order.json)}"

curl -sS https://designer.magichtml.dev/api/v1/canvas/check \
  -H "Authorization: Bearer $TOKEN" -H 'Accept: application/json' \
  -F canvas=@canvas.json -F order=@order.json -F image=@canvas.png

検査の結果

  • order があると、メタデータを発注書の納品として検査します("order": null は発注書なしと同じ)。なければ、配列は 1 つずつ検査します。
  • 違反は code・path(JSON ポインタ)・target(枠の key。Web では :desktop などが付く)・expected・actual・message を持ちます。コードの一覧は CANVAS と発注書 にあります。
  • canvas や order の中身が JSON でないときは違反 document.invalid_json・order.invalid_json です。配列に画像を付けると document.image_with_set、画像が読めないと image.unreadable(actual は送ったファイル名)です。
  • 422({"message", "errors": {"canvas"|"order"|"image": […]}})は、読めるメタデータや発注書がリクエストになかったときです。本文が JSON でない、canvas がない、ファイルが壊れて届いた、などです。
  • 画像は PHP のアップロードを通るので、大きさの上限は upload_max_filesize と post_max_size で決まります。超えると 422 か 413 です。