API
Magic Form Cloud には、ブラウザから使う公開API(フォーム定義の取得、JSONでの送信、添付ファイルのアップロード)と、APIトークンで使う管理API・デプロイAPIがあります。公開APIはAPIトークン不要で、サイトに登録した接続元から呼び出せます。管理APIはサイトやフォームの作成・更新・公開、受付の取得に、デプロイAPIはツールからのフォームの一括配置に使います。このページでは、各APIのURL、リクエストとレスポンスの形、エラー、制限を説明します。
一覧
| 種類 | 認証 | 主な用途 |
|---|---|---|
公開API /api/public/v1/... |
不要(接続元の確認あり) | フォーム定義の取得、JSON送信、添付ファイルのアップロード |
管理API /api/v1/... |
APIトークン | サイト・フォームの管理、受付の取得、書き出し |
デプロイAPI /api/v1/form-deployments/... |
APIトークン | ツールからのフォームの作成・更新・公開 |
公開フォーム定義
GET https://form.magichtml.dev/api/public/v1/sites/SITE_ID/resources/contact
公開中のフォームの定義を返します。サイトのHTMLで入力欄を作ったり、送信前にチェックしたりするのに使えます。
{
"version": "公開版のID(UUID)",
"name": "お問い合わせ",
"kind": "form",
"fields": [
{ "key": "name", "label": "お名前", "type": "text", "required": true, "public": false },
{ "key": "email", "label": "メールアドレス", "type": "email", "required": true, "public": false },
{ "key": "message", "label": "お問い合わせ内容", "type": "textarea", "required": true, "public": false }
],
"completion": { "redirect": null, "message": null }
}
| キー | 内容 |
|---|---|
version |
公開版のID。JSON送信とアップロードで version として送ります |
name |
フォーム名 |
kind |
常に "form" |
fields |
項目の定義。プロパティは 項目と入力ルール を参照 |
completion.redirect |
送信完了後の移動先。未設定なら null |
completion.message |
完了メッセージ。未設定なら null |
- 返すのは公開版の内容です。保存しただけの下書きは含みません。
- 通知先などのメール設定と、受付データは含みません。
- フォームが存在しないか公開されていない場合は
404です。
JSONでの送信
POST https://form.magichtml.dev/api/public/v1/sites/SITE_ID/forms/contact/submissions
Content-Type: application/json
Accept: application/json
{
"version": "公開版のID",
"request_id": "6f1c2a4e-8d3b-4c71-9e5a-2b7d0f3a9c18",
"values": {
"name": "山田 太郎",
"email": "taro@example.com",
"message": "見積もりをお願いします。"
},
"_hp": ""
}
| キー | 内容 |
|---|---|
version |
必須。フォーム定義APIの version |
request_id |
必須。送信ごとのUUID。再試行では同じ値を使います |
values |
必須。識別キーをキーにした値のオブジェクト |
_hp |
任意。ハニーポット。値があると受け付けたように応答し、何も保存しません |
values の値は型に合わせます。
| 型 | 値 |
|---|---|
| 文字列の型、選択、単一選択 | 文字列 |
| 数値 | 数値(数値として読める文字列も可) |
| 同意、はい/いいえ | true / false |
| 複数選択 | 選択肢の値の配列 |
| ファイル | アップロードで受け取ったトークンの配列 |
レスポンス
| 状態 | 本文 | 意味 |
|---|---|---|
201 |
{"accepted": true, "receipt": "受付ID", "duplicate": false} |
新しく受け付けた |
200 |
{"accepted": true, "receipt": "受付ID", "duplicate": true} |
同じ送信の再送。新しい受付もメールも作りません |
200 |
{"accepted": true} |
ハニーポットに値があった(保存しません) |
422 |
message、errors、violations |
入力内容のエラー |
409 |
message |
公開版が変わった、または同じ request_id で内容が変わった |
403 |
message |
接続元が許可されていない |
404 |
フォームが存在しないか公開されていない | |
429 |
送信回数の制限を超えた |
入力内容のエラーは、項目ごとのメッセージ(errors)と、コード付きの一覧(violations)で返します。
{
"message": "入力内容をご確認ください。",
"errors": {
"email": ["メールアドレスのメール形式が不正です。"]
},
"violations": [
{ "field": "email", "code": "email", "params": {}, "message": "メールアドレスのメール形式が不正です。" }
]
}
violationsの各要素はfield、code、params(常にオブジェクト)、messageを持ちます。コードの一覧は 項目と入力ルール を参照してください。version・request_id・valuesが欠けている、形式が違うといったリクエスト自体の誤りでは、violationsのない422を返します。
冪等性(同じ送信の再試行)
- 通信が途切れて結果が分からない場合は、同じ
request_idと同じ内容で再送してください。すでに受け付けていれば200と"duplicate": trueが返り、二重に保存されることはありません。 - 同じ
request_idで内容を変えると409(「同じ送信IDで内容を変更することはできません。」)になります。入力を変えたら新しいrequest_idを使います。 - 新しい送信の
versionが現在の公開版と違うと409(「フォームが更新されています。再読み込みしてください。」)になります。定義を取得し直してください。すでに受け付けた送信の再送は、その後に公開版が変わっても重複として成功します。
添付ファイルのアップロード
ファイル項目がある場合、JSON送信の前にファイルを1件ずつアップロードし、受け取ったトークンを送信の値に使います。
POST https://form.magichtml.dev/api/public/v1/sites/SITE_ID/forms/contact/uploads
Content-Type: multipart/form-data
Accept: application/json
| フィールド | 内容 |
|---|---|
version |
必須。公開版のID |
request_id |
必須。このあと送信で使う request_id と同じUUID |
field |
必須。ファイル項目の識別キー |
file |
必須。ファイル1件 |
_hp |
任意。ハニーポット |
成功すると次の形で返ります。新しく保存したときは 201、同じ request_id・項目・内容のファイルをもう一度送ったときは同じトークンを 200 で返します。
{ "token": "トークン(UUID)", "name": "portfolio.pdf", "mime": "application/pdf", "size": 48213 }
- トークンの有効期限は60分です。送信に使われなかったファイルは期限後に削除されます。
- トークンは、アップロード時と同じ
request_id・項目・公開版の送信でだけ使え、使えるのは1回の受付だけです。期限切れや無効なトークンでは「(項目名)のファイルの有効期限が切れたか、無効です。ファイルを選び直してください。」(422)になります。 - 形式・サイズ・保存容量の誤りは
422、versionが現在の公開版と違うと409です。 - 同じ
request_idと項目でアップロードできるのは20回までです。超えると429になります。
const body = new FormData();
body.append('version', schema.version);
body.append('request_id', requestId);
body.append('field', 'files');
body.append('file', fileInput.files[0]);
const upload = await fetch(`https://form.magichtml.dev/api/public/v1/sites/SITE_ID/forms/contact/uploads`, {
method: 'POST', body, headers: { Accept: 'application/json' },
}).then(r => r.json());
// 送信時: values.files = [upload.token]
フォームSDKの fetch モードは、このアップロードと送信を自動で行います(フォームSDK)。
リリース固定の公開API
デプロイAPIで作成したリリースには、そのリリースの公開版に固定されたURLがあります。
GET https://form.magichtml.dev/api/public/v1/sites/SITE_ID/releases/RELEASE_ID/resources/contact
POST https://form.magichtml.dev/api/public/v1/sites/SITE_ID/releases/RELEASE_ID/forms/contact/submissions
POST https://form.magichtml.dev/api/public/v1/sites/SITE_ID/releases/RELEASE_ID/forms/contact/uploads
使い方は通常のURLと同じです。ブラウザからの呼び出しでは、リリース作成時に指定したオリジンだけを受け付けます。
CORS
公開APIは、サイト設定の「許可する接続元」に登録したオリジンからブラウザで呼び出せます。
- 許可したオリジンからのリクエストには
Access-Control-Allow-Originにそのオリジンを返します。 - 使えるメソッドは
GET、POST、OPTIONS、リクエストヘッダーはContent-TypeとAcceptです。プリフライト(OPTIONS)には204を返します。 - 登録していないオリジンからのリクエストは
403(「この接続元は許可されていません。」)になります。 - Cookie や認証情報は使いません。
fetchではcredentialsを指定する必要はありません。 - レスポンスには
Cache-Control: no-storeが付きます。 - 接続元の確認はブラウザが送る
Originヘッダーに対して行います。
管理API
APIトークン
管理APIとデプロイAPIには、個人用のAPIトークンを使います。
- 管理画面右上の「アカウント・API」(
https://form.magichtml.dev/app/account)を開きます。 - 「管理APIトークン」に名前を入力し、「トークンを発行」を押します。
- 表示されたトークンを控えます。トークンはこの画面で一度だけ表示されます。
- 有効期間は発行から90日です。期限が過ぎたトークンは使えなくなるので、新しく発行してください。
- 不要になったトークンは「失効」で無効にできます。
- トークンは自分のサイトすべてを管理できます。公開サイトのHTMLやJavaScriptには絶対に入れないでください。
リクエストには Authorization ヘッダーで付けます。
curl -H "Authorization: Bearer YOUR_TOKEN" -H "Accept: application/json" \
https://form.magichtml.dev/api/v1/sites
トークンがない・誤っている・期限切れの場合は 401 です。他のアカウントのサイトやフォームを指定すると 404 になります。
ルート一覧
| メソッドとパス | 内容 |
|---|---|
GET /api/v1/sites |
サイトの一覧 |
POST /api/v1/sites |
サイトの作成(name) |
GET /api/v1/sites/{site} |
サイトとフォームの一覧 |
PUT /api/v1/sites/{site} |
サイトの更新(name、origins、retention_days) |
DELETE /api/v1/sites/{site} |
サイトの削除(フォーム・受付・添付ファイルも削除) |
POST /api/v1/sites/{site}/resources |
フォームの作成(name、key) |
GET /api/v1/resources/{resource} |
フォームの下書きの取得 |
PUT /api/v1/resources/{resource} |
フォームの下書きの更新(name、version、fields、settings) |
DELETE /api/v1/resources/{resource} |
フォームの削除(受付・公開履歴・添付ファイルも削除) |
POST /api/v1/resources/{resource}/publish |
保存済みの下書きを公開。{"version": "公開版のID"} を返します |
POST /api/v1/resources/{resource}/unpublish |
公開を停止 |
GET /api/v1/resources/{resource}/submissions |
受付の一覧(新しい順、30件ずつ。?page=2 で次のページ) |
GET /api/v1/submissions/{submission} |
受付の詳細(メールの配信状況を含む) |
DELETE /api/v1/submissions/{submission} |
受付の削除(添付ファイルも削除) |
GET /api/v1/submissions/{submission}/files/{file} |
添付ファイルのダウンロード |
GET /api/v1/sites/{site}/interchange/export |
フォームのバックアップ(ZIP)の書き出し |
PUT /api/v1/form-deployments/{deployment}/releases/{release} |
デプロイAPI(下記) |
{site}・{resource}・{submission}・{file} はそれぞれのID(UUID)です。レスポンスは、多くの場合 data の中に対象のデータを入れて返します。
リクエストの注意
- サイトの更新:
name(100文字まで)、retention_days(1〜3650)が必須です。originsはオリジンの配列(最大20件、https://example.comの形式でパスを含めない)です。 - フォームの作成:
keyは英小文字で始まり、英小文字・数字・_・-で80文字まで、サイト内で重複できません。作成直後の項目は お名前・メールアドレス・お問い合わせ内容 の3つです。 - フォームの更新:
versionには、取得したフォームのversion(下書きの更新番号。公開版のIDとは別です)を送ります。その間に別の操作で更新されていると409(「別の操作で更新されています。再読み込みしてください。」)になるので、取得し直してから更新します。fieldsの形式は 項目と入力ルール、settingsのキーは次の表のとおりです。既存の項目(同じキーで同じ型)で省略したプロパティは、以前の値が保持されます。 - 更新は下書きへの保存です。反映するには
publishを呼びます。
settings のキー |
内容 |
|---|---|
notify_enabled、reply_enabled |
通知・自動返信を有効にするか(真偽値) |
notify_to |
通知先のメールアドレスの配列(最大5件) |
notify_cc |
CCのメールアドレスの配列(最大5件) |
reply_field |
自動返信先にするメール型項目の識別キー |
reply_to |
自動返信メールの返信先アドレス |
notify_subject、notify_body |
通知の件名・本文(必須) |
reply_subject、reply_body |
自動返信の件名・本文(必須) |
success_redirect |
送信完了後の移動先 |
success_message |
完了メッセージ |
管理APIは、ユーザーごとに1分あたり120リクエストまでです。
デプロイAPI
PUT https://form.magichtml.dev/api/v1/form-deployments/{deployment}/releases/{release}
Authorization: Bearer YOUR_TOKEN
Content-Type: application/json
サイト制作ツールなどが、フォーム一式をまとめて作成・更新・公開するためのAPIです。{deployment}(配置先ごと)と {release}(配置操作ごと)は、呼び出す側が生成するUUIDです。
{
"name": "サイト名",
"origin": "https://example.com",
"forms": [
{
"key": "contact",
"name": "お問い合わせ",
"fields": [
{ "key": "email", "label": "メールアドレス", "type": "email", "required": true, "public": false }
],
"settings": {
"notify_enabled": false,
"reply_enabled": false,
"notify_subject": "{{form_name}}へのお問い合わせ",
"notify_body": "{{all_fields}}",
"reply_subject": "お問い合わせを受け付けました",
"reply_body": "{{all_fields}}"
}
}
]
}
originはフォームを置くサイトのHTTPSのオリジンです(パスなし)。formsは1〜100件で、各settingsにはnotify_enabledとreply_enabledが必須です。- 初めての
{deployment}では、サイトを作成してoriginを接続元に登録します。以降は同じサイトを更新します。 - 呼び出しごとに、各フォームを作成または更新して公開し、その公開版を
{release}に記録します。
{
"site_id": "サイトID",
"release_id": "リリースID",
"endpoint": "https://form.magichtml.dev/api/public/v1/sites/SITE_ID/releases/RELEASE_ID",
"versions": { "contact": "公開版のID" }
}
endpointはリリース固定の公開APIのベースURLです。HTMLフォームではhttps://form.magichtml.dev/f/SITE_ID/releases/RELEASE_ID/contactに送信できます。古いリリースのURLは、その後に新しいリリースを作っても、それぞれ記録された公開版で受け付けます(フォームが公開停止された場合を除く)。- 冪等性: 同じ
{release}に同じ内容を送ると、同じ結果を返します。内容が違うと409です。 - 手動の変更を上書きしない: このAPIで作ったフォームが前回の呼び出しの後に管理画面などで変更されていた場合(下書きの保存、公開、公開停止、版の切り替えを含む)、またはこのAPIで作っていない同じ識別キーのフォームがある場合は
409で止まり、何も上書きしません。originがサイトの接続元に含まれていない場合も409です。 - 検証:
notify_enabledがtrueなのにnotify_toが空、reply_enabledがtrueなのにreply_fieldが空の場合は422です。メールを有効にしたのにサービス側のメール配信が設定されていない場合も422になります。
バックアップ(書き出し)
サイトのフォームを、バックアップ用のZIP(MagicHTML形式、site.magichtml.zip)として書き出せます。
- 管理画面: サイト画面の「書き出し」から「管理用ZIPをダウンロード」
- API:
GET https://form.magichtml.dev/api/v1/sites/SITE_ID/interchange/export
| 含まれるもの | 含まれないもの |
|---|---|
| 各フォームの下書きの項目定義、メール設定、送信完了後の設定 | アカウント、APIトークン、受付データ、添付ファイル |
- ZIPには通知先などのメールアドレスが含まれます。公開サイトのフォルダには置かないでください。
- ZIPの取り込み(インポート)には対応していません。
制限のまとめ
| 対象 | 制限 |
|---|---|
| 公開APIへのリクエスト | IPアドレスごとに1分あたり120回 |
| 送信(JSON送信とHTMLフォームの送信の合計) | IPアドレスごとに1分あたり10回 |
| 添付ファイルのアップロード | IPアドレスごとに1分あたり30回 |
| 管理API・デプロイAPI | ユーザーごとに1分あたり120回 |
| 1リクエストの大きさ | 22MB |
制限を超えると 429(大きさの場合は 413)が返ります。