API の使い方
画面でできることは、すべて API でもできます。API は JSON で読み書きし、登録と更新のたびに判定と検査をして、その結果を応答に入れて返します。
認証
- 「APIトークン」でトークンを発行します。トークンの文字列は、発行したときに一度だけ表示されます。
- リクエストのたびに、
Authorizationヘッダーにトークンを付けます。
curl https://assets.magichtml.dev/api/v2/assets \
-H "Authorization: Bearer $TOKEN" -H "Accept: application/json"
- トークンは発行したアカウントのもので、そのアカウントのアセット(持ち主
user:<アカウントの番号>)だけを読み書きできます。 - 事務局が用意するフォント(持ち主
system:magic)は、誰でも読めます。書き込むことはできません。 - 有効期間は 90 日です。失効したトークンや期限の切れたトークンは
401になります。 - 1 分あたりの回数に上限があり、超えると
429になります。 - 応答はキャッシュされません(
Cache-Control: private, no-store)。
書き込みの約束
request_key:書き込みには、毎回新しい UUID を付けます。同じrequest_keyで送り直すと、最初の結果をそのまま返し、二重に登録されません。同じキーで中身を変えると409です。base_revision:ファイルを変える書き込みには、元にしたリビジョンの番号を付けます。その間にほかの書き込みが入っていると409になり、応答に今の番号が入ります。- ファイル:
{"path", "json"}・{"path", "text"}・{"path", "blob"}のどれかで指定します。画像などのバイナリは、先にPOST /api/v2/blobsに本文として送り、返ってきたsha256をblobに入れます。blob は 1 日で消えます。 - スキーマ:
{"path", "json", "schema": "magic://schemas/..."}のようにスキーマを付けると、そのスキーマで検査します。
エンドポイント
パスはすべて /api/v2 の下です。
| メソッドとパス | 内容 |
|---|---|
GET /assets |
一覧。q(名前の部分一致)、kind(カンマ区切り)、medium、state(active・archived・deleted。既定は active)、verdict(passed・failed・unchecked)、sort(updated・title)、page・per_page |
POST /assets |
登録。{request_key, kind, title, files}。1 ファイルの種類は、multipart の file でも送れる |
POST /assets(制作物) |
{request_key, kind: "production", title, medium: {id, version}, media_contract} |
GET /assets/{id} |
今のリビジョンを、ファイルの一覧と検査の結果つきで返す。?revision=<n> で番号を指定 |
PATCH /assets/{id} |
{request_key, title}。名前だけを変える。リビジョンは増えない |
GET /assets/{id}/revisions |
リビジョンの一覧。それぞれの検査の結果つき |
POST /assets/{id}/revisions |
ファイルを変える。{request_key, base_revision, put: [ファイル…], remove: [パス…]}。新しいリビジョンを作って検査する |
GET /assets/{id}/files/{path} |
ファイルの中身。?revision=<n>、Range ヘッダー、?download=1 |
POST /assets/{id}/duplicates |
丸ごと複製する。{request_key, title, revision?} |
POST /assets/{id}/copies |
ほかのアセットを制作物の references/ にコピーする。{request_key, base_revision, source: {asset, revision?}, to} |
PUT /assets/{id}/state |
{request_key, state}。archived(アーカイブ)・deleted(ゴミ箱。30 日後に完全に削除)・active(戻す) |
DELETE /assets/{id} |
{request_key}。ゴミ箱のアセットを、すべてのリビジョンとともに完全に削除する |
DELETE /assets/{id}/revisions/{n}/content |
{request_key, reason?}。そのリビジョンの中身だけを消す。以後、そのリビジョンのファイルは 410 になる |
POST /blobs |
本文にファイルのバイト列を送る。{sha256, size} を返す |
GET /schemas・GET /schemas/{kind}/{version} |
スキーマの一覧と本文 |
例:画像を登録する
curl https://assets.magichtml.dev/api/v2/assets \
-H "Authorization: Bearer $TOKEN" -H "Accept: application/json" \
-F request_key=$(uuidgen | tr A-Z a-z) -F kind=image -F title="春の OGP" -F file=@ogp.png
応答(抜粋):
{
"asset": {
"id": "0b6f…",
"kind": "image",
"title": "春の OGP",
"revision": {
"number": 1,
"ref": "0b6f…@1",
"files": [{"path": "image.png", "media_type": "image/png", "size": 48213, "sha256": "…"}],
"inspection": {
"verdict": "passed",
"media": [{"id": "ogp", "version": 1, "label": "OGP画像", "type": "banner", "basis": "1200×630 px が形式「1200 × 630 px」の寸法"}],
"checks": [
{"standard": "names", "contract": "media-contract", "version": "0.2.0", "target": null, "verdict": "passed", "violations": [], "details": {"files": 1}},
{"standard": "formats", "contract": "asset-manager", "version": null, "target": null, "verdict": "passed", "violations": [], "details": {"files": […]}}
],
"contracts": {"media-contract": "0.2.0", "magic-contract": "0.4.0"},
"inspected_at": "2026-10-10T09:00:00.000000Z"
}
}
}
}
例:制作物にファイルを足す
# 1. 画像を blob として送る
SHA=$(curl -s https://assets.magichtml.dev/api/v2/blobs -H "Authorization: Bearer $TOKEN" \
--data-binary @front.png -H "Content-Type: application/octet-stream" | jq -r .sha256)
# 2. リビジョン 1 を元に、canvas/front.png を足す
curl https://assets.magichtml.dev/api/v2/assets/$ID/revisions \
-H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" -H "Accept: application/json" \
-d '{"request_key": "'$(uuidgen | tr A-Z a-z)'", "base_revision": 1, "put": [{"path": "canvas/front.png", "blob": "'$SHA'"}]}'
画像の寸法が媒体の CANVAS と違うと、応答の inspection.verdict は failed になります。checks の canvas に canvas.size の違反が入り、expected と actual で寸法の違いがわかります。
検査の結果(inspection)
| フィールド | 内容 |
|---|---|
verdict |
passed(合格)・failed(不合格)・unchecked(実行できなかった検査がある) |
media |
判定した媒体。id・version・label・type・basis(根拠) |
checks |
規格ごとの結果。standard・contract・version・target(対象のパスやフォルダ、全体は null)・verdict・violations(code・path・message・expected・actual)・details(根拠) |
contracts |
検査に使った規格の版 |
inspected_at |
検査した日時 |
一覧(GET /assets)とリビジョンの一覧では、verdict と media だけを返します。規格の中身は判定と検査を見てください。
エラー
| コード | 場面 |
|---|---|
401 |
トークンがない、または無効 |
403 |
system: のアセットへの書き込み |
404 |
ほかのアカウントのアセット、または存在しないアセット |
409 |
base_revision の競合、許されていない状態の移り変わり、ゴミ箱にないアセットの完全な削除、request_key の使い回し |
410 |
中身を消したリビジョンのファイル |
422 |
入力の誤り(名前の規則・ファイル形式・スキーマ・媒体など)。errors にフィールドごとの理由が入る |
429 |
回数の上限を超えた |