Framed! API · v1.6.0
開発者向けドキュメント
Framed! のスペースのサイトを、外部のプログラムやエージェントから作るための API です。扱えるのは 4 つです。
- フリーページ: サイトの 1 枚。URL を持ちます。本文は Liquid のテンプレートとして評価されます
- パーツ: ページから組み込む共通のテンプレート。単独では公開されません
- データストア: ページから読める共有の JSON。見た目と中身を分けるためのものです
- ストレージ: 画像などのファイル。URL を持ち、ページの HTML から参照します
見た目は HTML、繰り返す枠はパーツ、変わる中身はデータストアに置き、ページからはテンプレートで読むと、あとで中身だけを直せます。
テンプレートの書き方(引ける値・エスケープ・パーツの組み込み)は開発者向けドキュメントの「テンプレート」にあります。
- 認証はスペースごとに発行する API キーで行います(
Authorization: Bearer <API キー>)。 - 本文は JSON、エラーは RFC 9457(
application/problem+json)で返します。ファイルの中身も JSON の文字列(base64 か、文字のファイルならそのまま)で送ります。 - 呼び出しは API キーごとに 60 回/分までです。
- キーには触れる範囲が付きます。 まず
GET /spaces/{subdomain}を呼んで、そのキーで何ができるかを確かめてください。 - API キーは秘密情報です。 サーバからだけ呼び出してください。ブラウザからの呼び出し(CORS)には対応していません。
自分として投稿・コメント・いいねをしたい場合は、こちらではありません。この API はスペースのサイトを扱うもので、認証はスペースごとの API キーです。人として 投稿するには ユーザーAPI を使ってください(アカウントごとのトークンで認証します)。
はじめる
- Framed! にサインインし、スペースの「外部連携(API)」の画面(
/spaces/<subdomain>/integrations)でキーを発行します。キーは発行したときに一度だけ表示されます。 - キーを環境変数などの秘密の置き場所に保存します(例:
FRAMED_API_KEY)。 - サーバから次のように呼び出すと、フリーページがすぐに公開されます。その前に
GET /v1/spaces/<subdomain>を呼ぶと、そのキーで何ができるか(範囲)と入力の規則が分かります。
AI エージェントから使う場合は、MCP サーバをつなぐのが簡単です。
認証
スペースごとに発行する API キー。Framed! のスペースの管理画面(/spaces/<subdomain>)で参加者が発行します。
キーは発行したときに一度だけ表示されます。発行した人がスペースから外れると、そのキーは失効します。
キーには触れる範囲が付きます(発行時に選び、あとから変えられません)。
pages: スペースのサイトのフリーページとパーツ(共通のテンプレート)を読み書きします。サイトの見た目を作る範囲です。data: スペースのデータストアのレコードを読み書きします。files: スペースのストレージに上がっているファイルの一覧と URL を読みます。上げる・消すはできません。files_write: スペースのストレージにファイルを上げ、中身の差し替え・名前の変更・削除をします。一覧と URL の読み取り(files)も含みます。
範囲の足りない操作を呼ぶと 403 insufficient_scope を返します。
- キーは発行したスペースだけを操作できます。別のスペースを指すと
403になります。 - 範囲は発行するときに決まり、あとから変えられません。範囲の足りない操作は
403 insufficient_scopeです。範囲を変えたいときは発行し直し、古いキーを失効させてください。 - キーは秘密情報です。ブラウザのコードやリポジトリに含めないでください。ブラウザからの呼び出し(CORS)には対応していません。
- 漏れたときは、スペースの管理画面ですぐに失効させてください。失効したキーは直後から使えません。
エンドポイント
ベース URL は https://api.framed.dog/v1 です。
- GET/spaces/{subdomain}スペースと、このキーでできることを確かめる
- GET/spaces/{subdomain}/pagesフリーページの一覧
- POST/spaces/{subdomain}/pagesフリーページを作る
- GET/spaces/{subdomain}/pages/{page_id}フリーページを取得する
- PATCH/spaces/{subdomain}/pages/{page_id}フリーページを書き換える
- DELETE/spaces/{subdomain}/pages/{page_id}フリーページを削除する
- GET/spaces/{subdomain}/partsパーツの一覧
- POST/spaces/{subdomain}/partsパーツを作る
- GET/spaces/{subdomain}/parts/{part_id}パーツを取得する
- PATCH/spaces/{subdomain}/parts/{part_id}パーツを書き換える
- DELETE/spaces/{subdomain}/parts/{part_id}パーツを削除する
- GET/spaces/{subdomain}/dataデータストアのレコードの一覧
- GET/spaces/{subdomain}/data/{key}データストアのレコードを取得する
- PUT/spaces/{subdomain}/data/{key}データストアのレコードを保存する
- DELETE/spaces/{subdomain}/data/{key}データストアのレコードを削除する
- GET/spaces/{subdomain}/filesストレージのファイルの一覧
- POST/spaces/{subdomain}/filesストレージにファイルを上げる
- GET/spaces/{subdomain}/files/{file_id}ストレージのファイルを 1 つ取得する
- PATCH/spaces/{subdomain}/files/{file_id}ストレージのファイルを書き換える
- DELETE/spaces/{subdomain}/files/{file_id}ストレージのファイルを削除する
スペースと、このキーでできることを確かめる
GEThttps://api.framed.dog/v1/spaces/{subdomain}
スペースの名前・URL に加えて、この API キーに付いている範囲(`scopes`)と、
ページ・パーツ・データ・ファイルそれぞれの入力の規則、呼び出し回数の上限を返します。
最初にこれを呼んでください。 範囲の足りない操作は 403 insufficient_scope になるので、
何ができるキーなのかを先に知る必要があります。この操作だけは範囲を問わず答えます。
規則の値は実装と同じ定義から組み立てているので、上限を変えてもここがずれることはありません。
パスパラメータ
| 項目 | 型 | 説明 |
|---|---|---|
| subdomain必須string | string | スペースのサブドメイン(
|
応答(200)スペースと、このキーでできること。
| 項目 | 型 | 説明 |
|---|---|---|
| subdomain必須string | string | スペースのサブドメイン。 |
| name必須string | string | スペースの表示名。自由な文字列です。 |
| url必須string (uri) | string (uri) | スペースのサイトの URL。 |
| icon_url必須stringnull | stringnull | スペースの画像(256×256 の PNG)の URL。設定されていなければ |
| scopes必須string[] | string[] | この API キーに付いている範囲。 発行するときに決まり、あとから変わりません。 無い範囲の操作は |
| rules必須object | object | 入力の規則。実装と同じ定義から組み立てているので、上限を変えてもここがずれることはありません。 |
| rate_limit必須object | object |
ここに無い項目を送ると 422 になります。
返りうるステータス
- 200スペースと、このキーでできること。
- 401API キーが無いか、有効ではありません
- 403キーのスペースがパスと違う(`space_mismatch`)か、キーにその操作の範囲が付いていない(`insufficient_scope`)。`code` で見分けてください。
- 429呼び出しの回数が上限を超えました
- 500サーバの内部で問題が起きました
フリーページの一覧
GEThttps://api.framed.dog/v1/spaces/{subdomain}/pages
スペースのフリーページを、スラグの順にすべて返します。本文(HTML)は含みません。
パスパラメータ
| 項目 | 型 | 説明 |
|---|---|---|
| subdomain必須string | string | スペースのサブドメイン(
|
応答(200)スペースのページの一覧。
| 項目 | 型 | 説明 |
|---|---|---|
| data必須Page[] | Page[] | ページ。スラグの順。 |
ここに無い項目を送ると 422 になります。
返りうるステータス
- 200スペースのページの一覧。
- 401API キーが無いか、有効ではありません
- 403キーのスペースがパスと違う(`space_mismatch`)か、キーにその操作の範囲が付いていない(`insufficient_scope`)。`code` で見分けてください。
- 429呼び出しの回数が上限を超えました
- 500サーバの内部で問題が起きました
フリーページを作る
POSThttps://api.framed.dog/v1/spaces/{subdomain}/pages
スラグと HTML を指定して、スペースのサイトにフリーページを作ります。
作ったページはすぐに https://<subdomain>.framed.dog/<slug> で公開されます。
HTML はサーバで書き換えずにそのまま保存し、Framed! 本体とは別のドメイン(<id>.pages.frmd.spot)から配信します。
同じスラグのページがすでにあると 409 を返します(既存のページは変わりません)。
パスパラメータ
| 項目 | 型 | 説明 |
|---|---|---|
| subdomain必須string | string | スペースのサブドメイン(
|
リクエスト本文(application/json)
| 項目 | 型 | 説明 |
|---|---|---|
| slug必須string | string | ページの URL( 英小文字・数字・ハイフンの 1〜60 文字で、先頭と末尾はハイフンにできません。前後の空白は取り除きます。 サイトが自分で使うパスは指定できません( その名前のページは作れても開けなくなるためです。
|
| kind任意string | string | ページの種類。
省略すると
|
| html必須string | string | ページの中身。保存するときには書き換えません。 前後の空白を取り除いたうえで、空でなく 262144 文字以内であること。
|
ここに無い項目を送ると 422 になります。
応答(201)ページを作りました。
| 項目 | 型 | 説明 |
|---|---|---|
| id必須string | string | ページの ID。スラグを変えても変わりません。
|
| slug必須string | string | ページのスラグ。 |
| kind必須string | string | ページの種類。
|
| url必須string (uri) | string (uri) | ページが公開されている URL。 |
| created_at必須string (date-time) | string (date-time) | 作った日時(UTC、ISO 8601)。 |
| updated_at必須string (date-time) | string (date-time) | 最後に書き換えた日時(UTC、ISO 8601)。作っただけなら作った日時。 |
ここに無い項目を送ると 422 になります。
返りうるステータス
- 201ページを作りました。
- 400リクエスト本文を JSON として読めません
- 401API キーが無いか、有効ではありません
- 403キーのスペースがパスと違う(`space_mismatch`)か、キーにその操作の範囲が付いていない(`insufficient_scope`)。`code` で見分けてください。
- 409そのスラグのページはすでにあります
- 413リクエスト本文が大きすぎます
- 415Content-Type は application/json にしてください
- 422入力が規則を満たしていません
- 429呼び出しの回数が上限を超えました
- 500サーバの内部で問題が起きました
フリーページを取得する
GEThttps://api.framed.dog/v1/spaces/{subdomain}/pages/{page_id}
ページを本文(HTML)ごと返します。
パスパラメータ
| 項目 | 型 | 説明 |
|---|---|---|
| subdomain必須string | string | スペースのサブドメイン(
|
| page_id必須string | string | ページの ID(作成・一覧の応答の
|
応答(200)ページ。
| 項目 | 型 | 説明 |
|---|---|---|
| id必須string | string | ページの ID。スラグを変えても変わりません。
|
| slug必須string | string | ページのスラグ。 |
| kind必須string | string | ページの種類。
|
| url必須string (uri) | string (uri) | ページが公開されている URL。 |
| created_at必須string (date-time) | string (date-time) | 作った日時(UTC、ISO 8601)。 |
| updated_at必須string (date-time) | string (date-time) | 最後に書き換えた日時(UTC、ISO 8601)。作っただけなら作った日時。 |
| html必須string | string | ページの中身(保存したとおりの HTML)。 |
ここに無い項目を送ると 422 になります。
返りうるステータス
- 200ページ。
- 401API キーが無いか、有効ではありません
- 403キーのスペースがパスと違う(`space_mismatch`)か、キーにその操作の範囲が付いていない(`insufficient_scope`)。`code` で見分けてください。
- 404そのページはありません
- 429呼び出しの回数が上限を超えました
- 500サーバの内部で問題が起きました
フリーページを書き換える
PATCHhttps://api.framed.dog/v1/spaces/{subdomain}/pages/{page_id}
slug・kind・html のうち、送ったものだけを書き換えます。どれも無いと 422 です。
スラグを変えると公開 URL が変わり、古い URL は開けなくなります(転送はしません)。ページ ID は変わりません。
パスパラメータ
| 項目 | 型 | 説明 |
|---|---|---|
| subdomain必須string | string | スペースのサブドメイン(
|
| page_id必須string | string | ページの ID(作成・一覧の応答の
|
リクエスト本文(application/json)
| 項目 | 型 | 説明 |
|---|---|---|
| slug任意string | string | ページの URL( 英小文字・数字・ハイフンの 1〜60 文字で、先頭と末尾はハイフンにできません。前後の空白は取り除きます。 サイトが自分で使うパスは指定できません( その名前のページは作れても開けなくなるためです。
|
| kind任意string | string | ページの種類。
|
| html任意string | string | ページの中身。保存するときには書き換えません。 前後の空白を取り除いたうえで、空でなく 262144 文字以内であること。
|
ここに無い項目を送ると 422 になります。
応答(200)書き換えました。
| 項目 | 型 | 説明 |
|---|---|---|
| id必須string | string | ページの ID。スラグを変えても変わりません。
|
| slug必須string | string | ページのスラグ。 |
| kind必須string | string | ページの種類。
|
| url必須string (uri) | string (uri) | ページが公開されている URL。 |
| created_at必須string (date-time) | string (date-time) | 作った日時(UTC、ISO 8601)。 |
| updated_at必須string (date-time) | string (date-time) | 最後に書き換えた日時(UTC、ISO 8601)。作っただけなら作った日時。 |
ここに無い項目を送ると 422 になります。
返りうるステータス
- 200書き換えました。
- 400リクエスト本文を JSON として読めません
- 401API キーが無いか、有効ではありません
- 403キーのスペースがパスと違う(`space_mismatch`)か、キーにその操作の範囲が付いていない(`insufficient_scope`)。`code` で見分けてください。
- 404そのページはありません
- 409そのスラグのページはすでにあります
- 413リクエスト本文が大きすぎます
- 415Content-Type は application/json にしてください
- 422入力が規則を満たしていません
- 429呼び出しの回数が上限を超えました
- 500サーバの内部で問題が起きました
フリーページを削除する
DELETEhttps://api.framed.dog/v1/spaces/{subdomain}/pages/{page_id}
ページを削除します。公開中のページは開けなくなり、元に戻せません。
パスパラメータ
| 項目 | 型 | 説明 |
|---|---|---|
| subdomain必須string | string | スペースのサブドメイン(
|
| page_id必須string | string | ページの ID(作成・一覧の応答の
|
応答(204)削除しました(本文なし)。
返りうるステータス
- 204削除しました(本文なし)。
- 401API キーが無いか、有効ではありません
- 403キーのスペースがパスと違う(`space_mismatch`)か、キーにその操作の範囲が付いていない(`insufficient_scope`)。`code` で見分けてください。
- 404そのページはありません
- 429呼び出しの回数が上限を超えました
- 500サーバの内部で問題が起きました
パーツの一覧
GEThttps://api.framed.dog/v1/spaces/{subdomain}/parts
スペースのパーツを、識別名の順にすべて返します。中身(HTML)は含みません。
パスパラメータ
| 項目 | 型 | 説明 |
|---|---|---|
| subdomain必須string | string | スペースのサブドメイン(
|
応答(200)パーツの一覧。
| 項目 | 型 | 説明 |
|---|---|---|
| data必須Part[] | Part[] | パーツ。識別名の順。 |
ここに無い項目を送ると 422 になります。
返りうるステータス
- 200パーツの一覧。
- 401API キーが無いか、有効ではありません
- 403キーのスペースがパスと違う(`space_mismatch`)か、キーにその操作の範囲が付いていない(`insufficient_scope`)。`code` で見分けてください。
- 429呼び出しの回数が上限を超えました
- 500サーバの内部で問題が起きました
パーツを作る
POSThttps://api.framed.dog/v1/spaces/{subdomain}/parts
識別名とテンプレート HTML でパーツを作ります。パーツ単独では公開されません(URL を持ちません)。
ページやほかのパーツから、Liquid の標準のタグで組み込んで使います。
{% render 'site-header', title: 'お知らせ' %}— 値を明示して渡す(ページの変数は見えない){% include 'site-header' %}— ページの変数をそのまま使う{% layout 'base' %}{% block content %}…{% endblock %}— 共通の枠に本文をはめる
組み込みをたどって元に戻る形(循環)は 422 で断ります。評価が終わらなくなるためです。
パスパラメータ
| 項目 | 型 | 説明 |
|---|---|---|
| subdomain必須string | string | スペースのサブドメイン(
|
リクエスト本文(application/json)
| 項目 | 型 | 説明 |
|---|---|---|
| name必須string | string | パーツの識別名。テンプレートからは 英小文字・数字・ハイフン・アンダースコアの 1〜60 文字で、先頭と末尾は英小文字か数字です。スペースの中で一意です。
|
| html必須string | string | パーツの中身。Liquid のテンプレートです。 前後の空白を取り除いたうえで、空でなく 262144 文字以内であること。 1 スペースのパーツの中身の合計は 1048576 文字までです。 ほかのパーツを組み込めますが、たどって元に戻る形(循環)は保存できません。
|
ここに無い項目を送ると 422 になります。
応答(201)パーツを作りました。
| 項目 | 型 | 説明 |
|---|---|---|
| id必須string | string | パーツの ID。識別名を変えても変わりません。
|
| name必須string | string | パーツの識別名。 |
| created_at必須string (date-time) | string (date-time) | 作った日時。 |
| updated_at必須string (date-time) | string (date-time) | 最後に書き換えた日時。 |
ここに無い項目を送ると 422 になります。
返りうるステータス
- 201パーツを作りました。
- 400リクエスト本文を JSON として読めません
- 401API キーが無いか、有効ではありません
- 403キーのスペースがパスと違う(`space_mismatch`)か、キーにその操作の範囲が付いていない(`insufficient_scope`)。`code` で見分けてください。
- 409識別名が使われている(`part_name_taken`)か、パーツの合計の大きさが上限に達している(`parts_quota_exceeded`)。`code` で見分けてください。
- 413リクエスト本文が大きすぎます
- 415Content-Type は application/json にしてください
- 422入力が規則を満たしていません
- 429呼び出しの回数が上限を超えました
- 500サーバの内部で問題が起きました
パーツを取得する
GEThttps://api.framed.dog/v1/spaces/{subdomain}/parts/{part_id}
パーツを中身(HTML)ごと返します。
そのパーツを組み込んでいるページとパーツ(`used_by`)も返します。
識別名を変える前・消す前に、どこが壊れるかを確かめてください。
used_by に出るのは、識別名を引用符でそのまま書いた組み込みだけです。
変数で名前を渡した組み込み({% render part_name %})は探せません。
パスパラメータ
| 項目 | 型 | 説明 |
|---|---|---|
| subdomain必須string | string | スペースのサブドメイン(
|
| part_id必須string | string | パーツの ID(作成・一覧の応答の
|
応答(200)パーツ。
| 項目 | 型 | 説明 |
|---|---|---|
| id必須string | string |
|
| name必須string | string | |
| created_at必須string (date-time) | string (date-time) | |
| updated_at必須string (date-time) | string (date-time) | |
| html必須string | string | パーツの中身(保存したとおりのテンプレート)。 |
| used_by必須object | object | このパーツを組み込んでいるページとパーツ。 識別名を引用符でそのまま書いた組み込みだけが見つかります(変数で渡したものは探せません)。 |
ここに無い項目を送ると 422 になります。
返りうるステータス
- 200パーツ。
- 401API キーが無いか、有効ではありません
- 403キーのスペースがパスと違う(`space_mismatch`)か、キーにその操作の範囲が付いていない(`insufficient_scope`)。`code` で見分けてください。
- 404そのパーツはありません
- 429呼び出しの回数が上限を超えました
- 500サーバの内部で問題が起きました
パーツを書き換える
PATCHhttps://api.framed.dog/v1/spaces/{subdomain}/parts/{part_id}
name と html のうち、送ったものだけを書き換えます。どちらも無いと 422 です。
組み込んでいる公開中のページは、直ちに変わります。
識別名を変えると、古い名前で組み込んでいるページはエラーのページになります。
組み込み側の記述は書き換わらないので、先に GET の used_by を見て、
ページやほかのパーツの方も直してください。
パスパラメータ
| 項目 | 型 | 説明 |
|---|---|---|
| subdomain必須string | string | スペースのサブドメイン(
|
| part_id必須string | string | パーツの ID(作成・一覧の応答の
|
リクエスト本文(application/json)
| 項目 | 型 | 説明 |
|---|---|---|
| name任意string | string | パーツの識別名。テンプレートからは 英小文字・数字・ハイフン・アンダースコアの 1〜60 文字で、先頭と末尾は英小文字か数字です。スペースの中で一意です。
|
| html任意string | string | パーツの中身。Liquid のテンプレートです。 前後の空白を取り除いたうえで、空でなく 262144 文字以内であること。 1 スペースのパーツの中身の合計は 1048576 文字までです。 ほかのパーツを組み込めますが、たどって元に戻る形(循環)は保存できません。
|
ここに無い項目を送ると 422 になります。
応答(200)書き換えました。
| 項目 | 型 | 説明 |
|---|---|---|
| id必須string | string | パーツの ID。識別名を変えても変わりません。
|
| name必須string | string | パーツの識別名。 |
| created_at必須string (date-time) | string (date-time) | 作った日時。 |
| updated_at必須string (date-time) | string (date-time) | 最後に書き換えた日時。 |
ここに無い項目を送ると 422 になります。
返りうるステータス
- 200書き換えました。
- 400リクエスト本文を JSON として読めません
- 401API キーが無いか、有効ではありません
- 403キーのスペースがパスと違う(`space_mismatch`)か、キーにその操作の範囲が付いていない(`insufficient_scope`)。`code` で見分けてください。
- 404そのパーツはありません
- 409識別名が使われている(`part_name_taken`)か、パーツの合計の大きさが上限に達している(`parts_quota_exceeded`)。`code` で見分けてください。
- 413リクエスト本文が大きすぎます
- 415Content-Type は application/json にしてください
- 422入力が規則を満たしていません
- 429呼び出しの回数が上限を超えました
- 500サーバの内部で問題が起きました
パーツを削除する
DELETEhttps://api.framed.dog/v1/spaces/{subdomain}/parts/{part_id}
パーツを削除します。組み込んでいたページはエラーのページになります。元に戻せません。 先に GET の used_by で影響を確かめてください。
パスパラメータ
| 項目 | 型 | 説明 |
|---|---|---|
| subdomain必須string | string | スペースのサブドメイン(
|
| part_id必須string | string | パーツの ID(作成・一覧の応答の
|
応答(204)削除しました(本文なし)。
返りうるステータス
- 204削除しました(本文なし)。
- 401API キーが無いか、有効ではありません
- 403キーのスペースがパスと違う(`space_mismatch`)か、キーにその操作の範囲が付いていない(`insufficient_scope`)。`code` で見分けてください。
- 404そのパーツはありません
- 429呼び出しの回数が上限を超えました
- 500サーバの内部で問題が起きました
データストアのレコードの一覧
GEThttps://api.framed.dog/v1/spaces/{subdomain}/data
スペースのデータストアのレコードを、キーの順にすべて返します。値も含みます。
レコードは 100 件・合計 1048576 バイトまでなので、ページ分割はありません。
レコードを作るのは PUT /spaces/{subdomain}/data/{key} です。キーは呼び出し側が決めるので、ここに POST はありません。
パスパラメータ
| 項目 | 型 | 説明 |
|---|---|---|
| subdomain必須string | string | スペースのサブドメイン(
|
応答(200)データストアのレコードの一覧。
| 項目 | 型 | 説明 |
|---|---|---|
| data必須DataRecord[] | DataRecord[] | レコード。キーの順。 |
ここに無い項目を送ると 422 になります。
返りうるステータス
- 200データストアのレコードの一覧。
- 401API キーが無いか、有効ではありません
- 403キーのスペースがパスと違う(`space_mismatch`)か、キーにその操作の範囲が付いていない(`insufficient_scope`)。`code` で見分けてください。
- 429呼び出しの回数が上限を超えました
- 500サーバの内部で問題が起きました
データストアのレコードを取得する
GEThttps://api.framed.dog/v1/spaces/{subdomain}/data/{key}
キーを指定してレコードを 1 件返します。
書き換えるときは、返ってきた version をそのまま PUT に渡すと、他の人の更新を上書きしません。
パスパラメータ
| 項目 | 型 | 説明 |
|---|---|---|
| subdomain必須string | string | スペースのサブドメイン(
|
| key必須string | string | レコードのキー。呼び出し側が決めます。フリーページからは
|
応答(200)レコード。
| 項目 | 型 | 説明 |
|---|---|---|
| key必須string | string | レコードのキー。
|
| value必須any | any | レコードの中身。JSON として表せるものなら何でも入ります。 1 件 65536 バイト・入れ子 32 段までです。 |
| description必須stringnull | stringnull | このレコードが何かの短い説明。スペースの管理画面に出ます。
|
| version必須integer | integer | 書き換えるたびに 1 増えます。 |
| updated_at必須string (date-time) | string (date-time) | 最後に書き換えた日時(UTC、ISO 8601)。 |
| schema必須object | object |
型と、その値に在るキーだけの緩いものです( |
| warnings必須ShapeWarning[] | ShapeWarning[] | 形の食い違い。あっても保存は通っています。 同じ配列の要素どうしで、キーの集合・型が揃っているかだけを見ます。 |
ここに無い項目を送ると 422 になります。
返りうるステータス
- 200レコード。
- 401API キーが無いか、有効ではありません
- 403キーのスペースがパスと違う(`space_mismatch`)か、キーにその操作の範囲が付いていない(`insufficient_scope`)。`code` で見分けてください。
- 404そのレコードはありません
- 429呼び出しの回数が上限を超えました
- 500サーバの内部で問題が起きました
データストアのレコードを保存する
PUThttps://api.framed.dog/v1/spaces/{subdomain}/data/{key}
キーを指定してレコードを作る、または丸ごと置き換えます。一部だけの更新はできません。
既存のレコードを直すときは、GET で読んだ値を元に、変えたところだけ直した value 全体を送ってください。
version を送ると、その版のままのときだけ書き換えます(楽観ロック)。合わないときは 409 version_conflict です。
description を省くと、既存の説明はそのままです。
形の食い違いでは断りません。 配列の要素どうしでキーや型が揃っていないときは、
保存したうえで応答の warnings に載せます。スキーマはユーザーが書くのではなく、入れた値から推論します。
ここに置いたものは公開されます。 フリーページから読める=誰でも読めるということです。秘密は置かないでください。
パスパラメータ
| 項目 | 型 | 説明 |
|---|---|---|
| subdomain必須string | string | スペースのサブドメイン(
|
| key必須string | string | レコードのキー。呼び出し側が決めます。フリーページからは
|
リクエスト本文(application/json)
| 項目 | 型 | 説明 |
|---|---|---|
| value必須any | any | レコードの中身。丸ごと置き換わります。 1 件 65536 バイト・入れ子 32 段までです。 |
| description任意stringnull | stringnull | 短い説明。省くと、既存の説明はそのままです。
|
| version任意integer | integer | いま持っている版。送ると、その版のままのときだけ書き換えます(楽観ロック)。 省くと、あるかどうかに関わらず置き換えます。 |
ここに無い項目を送ると 422 になります。
応答(200)保存しました。`warnings` があっても保存は通っています。
| 項目 | 型 | 説明 |
|---|---|---|
| key必須string | string | レコードのキー。
|
| value必須any | any | レコードの中身。JSON として表せるものなら何でも入ります。 1 件 65536 バイト・入れ子 32 段までです。 |
| description必須stringnull | stringnull | このレコードが何かの短い説明。スペースの管理画面に出ます。
|
| version必須integer | integer | 書き換えるたびに 1 増えます。 |
| updated_at必須string (date-time) | string (date-time) | 最後に書き換えた日時(UTC、ISO 8601)。 |
| schema必須object | object |
型と、その値に在るキーだけの緩いものです( |
| warnings必須ShapeWarning[] | ShapeWarning[] | 形の食い違い。あっても保存は通っています。 同じ配列の要素どうしで、キーの集合・型が揃っているかだけを見ます。 |
ここに無い項目を送ると 422 になります。
返りうるステータス
- 200保存しました。`warnings` があっても保存は通っています。
- 400リクエスト本文を JSON として読めません
- 401API キーが無いか、有効ではありません
- 403キーのスペースがパスと違う(`space_mismatch`)か、キーにその操作の範囲が付いていない(`insufficient_scope`)。`code` で見分けてください。
- 404そのレコードはありません
- 409版が合わない(`version_conflict`)か、データストアの上限に達している(`data_quota_exceeded`)。`code` で見分けてください。
- 413リクエスト本文が大きすぎます
- 415Content-Type は application/json にしてください
- 422入力が規則を満たしていません
- 429呼び出しの回数が上限を超えました
- 500サーバの内部で問題が起きました
データストアのレコードを削除する
DELETEhttps://api.framed.dog/v1/spaces/{subdomain}/data/{key}
レコードを削除します。このレコードを読んでいるフリーページは、その部分が空になります。元に戻せません。
パスパラメータ
| 項目 | 型 | 説明 |
|---|---|---|
| subdomain必須string | string | スペースのサブドメイン(
|
| key必須string | string | レコードのキー。呼び出し側が決めます。フリーページからは
|
応答(204)削除しました(本文なし)。
返りうるステータス
- 204削除しました(本文なし)。
- 401API キーが無いか、有効ではありません
- 403キーのスペースがパスと違う(`space_mismatch`)か、キーにその操作の範囲が付いていない(`insufficient_scope`)。`code` で見分けてください。
- 404そのレコードはありません
- 429呼び出しの回数が上限を超えました
- 500サーバの内部で問題が起きました
ストレージのファイルの一覧
GEThttps://api.framed.dog/v1/spaces/{subdomain}/files
スペースのストレージに上がっているファイルを、新しい順にすべて返します。使っている容量も返します。
ページの HTML から画像やフォントを参照するための `url` を知る手段は、これだけです
(上げたときの応答を除く。ID は推測できません)。テンプレートの中からは {{ files }} でも引けます。
パスパラメータ
| 項目 | 型 | 説明 |
|---|---|---|
| subdomain必須string | string | スペースのサブドメイン(
|
応答(200)ファイルの一覧と、使っている容量。
| 項目 | 型 | 説明 |
|---|---|---|
| data必須File[] | File[] | ファイル。新しい順。 |
| storage必須object | object | スペースのストレージの状況。 |
ここに無い項目を送ると 422 になります。
返りうるステータス
- 200ファイルの一覧と、使っている容量。
- 401API キーが無いか、有効ではありません
- 403キーのスペースがパスと違う(`space_mismatch`)か、キーにその操作の範囲が付いていない(`insufficient_scope`)。`code` で見分けてください。
- 429呼び出しの回数が上限を超えました
- 500サーバの内部で問題が起きました
ストレージにファイルを上げる
POSThttps://api.framed.dog/v1/spaces/{subdomain}/files
ファイル名と中身でファイルを上げ、url を返します。範囲 `files_write` が要ります。
中身は JSON の文字列で送ります。
encoding: "base64": 画像など、どんなファイルでも。改行や空白は無視しますencoding: "text": SVG・CSS・JSON のような文字のファイルを、そのまま(UTF-8 で保存します)
1 ファイル 10485760 バイト(元の大きさ)・1 スペース合計 104857600 バイトまでです。
base64 にすると大きくなるので、このエンドポイントだけ本文の上限を 14680064 バイトにしています。
配信する種類はファイル名の拡張子で決まります(送った Content-Type や中身は見ません)。
画像・動画・音声・PDF・テキスト・CSS・JSON・フォントはブラウザでそのまま開き、
それ以外(.html・.js・知らない拡張子)はダウンロードとして返します。どれも配信元でスクリプトは動きません。
同じ名前のファイルがあっても、別のファイルとして増えます(URL は ID で決まります)。
パスパラメータ
| 項目 | 型 | 説明 |
|---|---|---|
| subdomain必須string | string | スペースのサブドメイン(
|
リクエスト本文(application/json)
| 項目 | 型 | 説明 |
|---|---|---|
| name必須string | string | ファイル名。255 文字までです。拡張子で配信する種類が決まります。 パスの部分(
|
| content必須string | string | ファイルの中身。 1 ファイル 10485760 バイトまで(元の大きさで数えます)。空のファイルは上げられません。
|
| encoding必須string | string |
|
ここに無い項目を送ると 422 になります。
応答(201)上げました。
| 項目 | 型 | 説明 |
|---|---|---|
| id必須string | string | ファイルの ID。名前や中身を変えても変わりません。
|
| name必須string | string | ファイル名。同じ名前のファイルを複数置けます。 |
| content_type必須string | string | 配信するときの種類。ファイル名の拡張子から決めます(送られてきた種類や中身は使いません)。 |
| size必須integer | integer | 大きさ(バイト)。 |
| url必須string (uri) | string (uri) | ファイルの URL。1 ファイル 1 オリジンで、パスは見ません。 URL を知っていれば誰でも取り出せます(スペースのサイトは公開のため)。 |
| uploaded_by必須stringnull | stringnull | 上げた人のハンドル。アカウントが消えていれば |
| created_at必須string (date-time) | string (date-time) | 上げた日時。 |
| updated_at必須string (date-time) | string (date-time) | 最後に名前か中身を変えた日時。上げただけなら上げた日時。 |
ここに無い項目を送ると 422 になります。
返りうるステータス
- 201上げました。
- 400リクエスト本文を JSON として読めません
- 401API キーが無いか、有効ではありません
- 403キーのスペースがパスと違う(`space_mismatch`)か、キーにその操作の範囲が付いていない(`insufficient_scope`)。`code` で見分けてください。
- 409ストレージの容量が足りません
- 413リクエスト本文が大きすぎます
- 415Content-Type は application/json にしてください
- 422入力が規則を満たしていません
- 429呼び出しの回数が上限を超えました
- 500サーバの内部で問題が起きました
ストレージのファイルを 1 つ取得する
GEThttps://api.framed.dog/v1/spaces/{subdomain}/files/{file_id}
ファイルの名前・種類・大きさ・URL を返します。中身は返しません(url をそのまま取りに行けば取り出せます)。
パスパラメータ
| 項目 | 型 | 説明 |
|---|---|---|
| subdomain必須string | string | スペースのサブドメイン(
|
| file_id必須string | string | ファイルの ID(一覧・上げたときの応答の
|
応答(200)ファイル。
| 項目 | 型 | 説明 |
|---|---|---|
| id必須string | string | ファイルの ID。名前や中身を変えても変わりません。
|
| name必須string | string | ファイル名。同じ名前のファイルを複数置けます。 |
| content_type必須string | string | 配信するときの種類。ファイル名の拡張子から決めます(送られてきた種類や中身は使いません)。 |
| size必須integer | integer | 大きさ(バイト)。 |
| url必須string (uri) | string (uri) | ファイルの URL。1 ファイル 1 オリジンで、パスは見ません。 URL を知っていれば誰でも取り出せます(スペースのサイトは公開のため)。 |
| uploaded_by必須stringnull | stringnull | 上げた人のハンドル。アカウントが消えていれば |
| created_at必須string (date-time) | string (date-time) | 上げた日時。 |
| updated_at必須string (date-time) | string (date-time) | 最後に名前か中身を変えた日時。上げただけなら上げた日時。 |
ここに無い項目を送ると 422 になります。
返りうるステータス
- 200ファイル。
- 401API キーが無いか、有効ではありません
- 403キーのスペースがパスと違う(`space_mismatch`)か、キーにその操作の範囲が付いていない(`insufficient_scope`)。`code` で見分けてください。
- 404そのファイルはありません
- 429呼び出しの回数が上限を超えました
- 500サーバの内部で問題が起きました
ストレージのファイルを書き換える
PATCHhttps://api.framed.dog/v1/spaces/{subdomain}/files/{file_id}
name と中身(content と encoding)のうち、送ったものだけを書き換えます。範囲 `files_write` が要ります。
ID と `url` は変わりません。 参照しているページの HTML を直さずに、画像や CSS を差し替えられます。
contentとencodingは一緒に送ります。中身の書き方はPOSTと同じです- 名前を変えると、配信する種類も新しい拡張子で決め直します
- 参照している公開中のページは、直ちに変わります。 前の中身には戻せません
- 配信はブラウザに 5 分キャッシュさせるので、見る人によっては古い中身がしばらく見えます
- 同時に書き換えられたときは、あとから届いた方が残ります
人が管理画面から上げたファイルも書き換えられます。
パスパラメータ
| 項目 | 型 | 説明 |
|---|---|---|
| subdomain必須string | string | スペースのサブドメイン(
|
| file_id必須string | string | ファイルの ID(一覧・上げたときの応答の
|
リクエスト本文(application/json)
| 項目 | 型 | 説明 |
|---|---|---|
| name任意string | string | ファイル名。255 文字までです。拡張子で配信する種類が決まります。 パスの部分(
|
| content任意string | string | ファイルの中身。 1 ファイル 10485760 バイトまで(元の大きさで数えます)。空のファイルは上げられません。
|
| encoding任意string | string |
|
ここに無い項目を送ると 422 になります。
応答(200)書き換えました。
| 項目 | 型 | 説明 |
|---|---|---|
| id必須string | string | ファイルの ID。名前や中身を変えても変わりません。
|
| name必須string | string | ファイル名。同じ名前のファイルを複数置けます。 |
| content_type必須string | string | 配信するときの種類。ファイル名の拡張子から決めます(送られてきた種類や中身は使いません)。 |
| size必須integer | integer | 大きさ(バイト)。 |
| url必須string (uri) | string (uri) | ファイルの URL。1 ファイル 1 オリジンで、パスは見ません。 URL を知っていれば誰でも取り出せます(スペースのサイトは公開のため)。 |
| uploaded_by必須stringnull | stringnull | 上げた人のハンドル。アカウントが消えていれば |
| created_at必須string (date-time) | string (date-time) | 上げた日時。 |
| updated_at必須string (date-time) | string (date-time) | 最後に名前か中身を変えた日時。上げただけなら上げた日時。 |
ここに無い項目を送ると 422 になります。
返りうるステータス
- 200書き換えました。
- 400リクエスト本文を JSON として読めません
- 401API キーが無いか、有効ではありません
- 403キーのスペースがパスと違う(`space_mismatch`)か、キーにその操作の範囲が付いていない(`insufficient_scope`)。`code` で見分けてください。
- 404そのファイルはありません
- 409ストレージの容量が足りません
- 413リクエスト本文が大きすぎます
- 415Content-Type は application/json にしてください
- 422入力が規則を満たしていません
- 429呼び出しの回数が上限を超えました
- 500サーバの内部で問題が起きました
ストレージのファイルを削除する
DELETEhttps://api.framed.dog/v1/spaces/{subdomain}/files/{file_id}
ファイルを削除します。範囲 `files_write` が要ります。
`url` はすぐ 404 になり、参照しているページでは画像などが表示されなくなります。元に戻せません。
人が管理画面から上げたファイルも消せます。
パスパラメータ
| 項目 | 型 | 説明 |
|---|---|---|
| subdomain必須string | string | スペースのサブドメイン(
|
| file_id必須string | string | ファイルの ID(一覧・上げたときの応答の
|
応答(204)削除しました(本文なし)。
返りうるステータス
- 204削除しました(本文なし)。
- 401API キーが無いか、有効ではありません
- 403キーのスペースがパスと違う(`space_mismatch`)か、キーにその操作の範囲が付いていない(`insufficient_scope`)。`code` で見分けてください。
- 404そのファイルはありません
- 429呼び出しの回数が上限を超えました
- 500サーバの内部で問題が起きました
テンプレート
ページとパーツの本文は、配信する前にサーバでテンプレートとして評価されます。記法は Liquid です。ページの種類(scripted / static)に関わらず、どちらも評価します。
評価はサーバの中だけで完結します。ブラウザに届くのは評価が終わった HTML だけなので、テンプレートから API キーやデータストアの書き込み権限が漏れることはありません。 逆に言うと、ここで引けた値はすべて公開されます。
引ける値
| 変数 | 型 | 中身 |
|---|---|---|
| space.name | 文字列 | スペースの表示名。 |
| space.subdomain | 文字列 | スペースのサブドメイン。 |
| space.url | 文字列 | スペースのサイトの URL。 |
| page.slug | 文字列 | いま表示しているページのスラグ。 |
| page.url | 文字列 | いま表示しているページの URL。 |
| pages | 配列 | そのスペースのページ。要素は slug と url。ナビゲーションを組み立てるのに使います。 |
| files | 配列 | ストレージのファイル。要素は name・contentType・size・url。画像を貼るための URL はここから取ります。 |
| data | オブジェクト | データストアのレコード。キーで引きます(data.events)。ハイフンを含むキーは data["weekly-todo"] と書きます。 |
出力は既定でエスケープされます
スペース名もファイル名もデータストアの中身も自由入力なので、生のまま埋めると、 ある参加者が別の参加者のページに HTML を注入できてしまいます。生の HTML として入れたいときだけ | raw を付けます。
パーツを組み込む
共通の見出しやレイアウトはパーツに切り出し、識別名で組み込みます。 パーツ自身も URL を持たず、ページやほかのパーツから組み込まれて初めて世に出ます。 組み込めるのは同じスペースのパーツだけです。
renderの中からは、ページの変数が見えません。spaceやdataも含めて、渡した値だけが見えます。{{ space.name }}と書いたパーツが空になるのはこれが理由です。値が要るなら{% render 'x', title: space.name %}のように明示して渡すか、includeを使ってください(includeはページの変数をそのまま使えます)。- 組み込みをたどって元に戻る形(循環)は保存できません。評価が終わらなくなるためです。
- パーツの識別名を変える・消すと、組み込んでいるページはエラーのページになります。組み込み側の記述は書き換わりません。先に
GET /parts/{part_id}のused_byで影響を確かめてください。
書き間違えたとき
- 知らない変数は空になります。
{{ space.nmae }}と書いてもページ全体は壊れず、 そこが空文字になるだけです。 - 構文エラーのときは、直し方が分かるページを返します。白紙にも 500 にもしません。閉じ忘れた
{% for %}などがこれに当たります。 - 保存するときは構文を検査していません。壊れたテンプレートも保存でき、開いて初めて分かります。作ったあとに URL を開いて確かめてください。
上限とできないこと
- 解析するのは 1 本あたり 262,144 文字まで。 1 スペースのパーツの中身の合計は 1,048,576 文字まで。
- 1 回の評価は 250ms まで。入れ子のループで重くすると、途中で打ち切られてエラーのページになります。
- ファイルを読むタグ(テーマのファイルなど)は使えません。
include/render/layoutが引けるのは、そのスペースのパーツだけです。 - 任意の JavaScript は動きません。オブジェクトのプロトタイプ経由で値を引くこともできません。
- 評価のたびに、そのスペースのページ・ファイル・データ・パーツを全部読みます。 表示のたびに評価するので(配信はキャッシュしません)、重いテンプレートはそのまま表示の遅さになります。
データストア
スペースには、キーで引ける JSON を置けるデータストアがあります。フリーページの HTML からは、テンプレートで {{ data.<キー> }} として読めます。見た目を直すのと、中身を更新するのを分けられます。
- 置いたものは公開されます。ページから読める=誰でも読めるということです。秘密は置かないでください。
PUTは丸ごとの置き換えです。一部だけ直すときはGETで読んだ値を元にしてください。- 同じキーを同時に書くときは、
GETのversionをPUTに渡すと、他の人の更新を上書きしません。 - 形(スキーマ)は書きません。入れた値から推論して
schemaとして返します。配列の要素どうしで形が 揃っていないときはwarningsに載りますが、保存そのものは通ります。 - レコードは 100 件・1 件 65536 バイト・ スペース合計 1048576 バイトまでです。
ストレージ
スペースには画像・フォント・CSS などを置けるストレージがあります。 上げたファイルは URL を持ち、ページの HTML から参照できます。一覧と取得には files、上げる・書き換える・消すには files_write の範囲が要ります。
中身は JSON の文字列で送ります。画像などは "encoding": "base64"、SVG・CSS・JSON のような文字のファイルは "encoding": "text" で中身をそのまま送れます。
- ページに画像を貼るための URL を知る手段は、一覧か上げたときの応答だけです。ID は推測できません。テンプレートの中からは
{{ files }}でも引けます。 PATCHで名前や中身を変えても ID と URL は変わりません。参照しているページは直ちに変わります (見る人のブラウザには、古い中身が最大 5 分残ることがあります)。- 消したファイルの URL はすぐ開けなくなり、元に戻せません。人が管理画面から上げたファイルも、API から書き換え・削除できます。
- ファイルは 1 つずつ別のオリジン(
<file_id>.files.frmd.spot)から配られます。URL を知っていれば誰でも取り出せます。 - 配信するときの種類はファイル名の拡張子から決めます。HTML や JavaScript はブラウザで開かれず、ダウンロードとして返ります。
- 1 ファイル 10 MB、1 スペース合計 100 MB までです。base64 にすると大きくなるので、ファイルを送るエンドポイントだけ本文の上限を 14 MB にしています。
エラー
エラー(RFC 9457 Problem Details)。機械的な分岐には code を使ってください。
失敗は application/problem+json(RFC 9457)で返します。code の一覧は api.framed.dog の 2 つの API(この API と ユーザーAPI)で共通なので、こちらでは起きないものも含みます。
| 項目 | 型 | 説明 |
|---|---|---|
| type必須string (uri) | string (uri) | エラーの種類を説明するドキュメントの URI。 |
| title必須string | string | エラーの種類ごとに固定の説明。 |
| status必須integer | integer | HTTP ステータスコード。 |
| detail任意string | string | このリクエストに固有の説明。 |
| code必須string | string | エラーの種類を表す機械向けのコード。
|
| errors任意ValidationError[] | ValidationError[] |
|
invalid_json400リクエスト本文を JSON として読めません本文が JSON として壊れているか、空です。
space_mismatch403この API キーでは、そのスペースを操作できませんAPI キーはスペースごとに発行されます。パスの
subdomainと、キーを発行したスペースが違います。insufficient_scope403この資格情報には、その操作の範囲が付いていませんAPI キーには触れる範囲(
pages/data/files/files_write)、ユーザーAPIトークンには範囲(posts/comments/likes/profile)が付いています。範囲は発行するときに決まり、あとから増やせません。必要な範囲を選んで発行し直してください。not_found404そのエンドポイントはありませんパスが間違っています。ベース URL に
/v1が含まれているか確かめてください。page_not_found404そのページはありませんパスの
page_idのページが、そのスペースにありません。削除されたか、ID が間違っています。part_not_found404そのパーツはありませんパスの
part_idのパーツが、そのスペースにありません。削除されたか、ID が間違っています。file_not_found404そのファイルはありませんパスの
file_idのファイルが、そのスペースのストレージにありません。削除されたか、ID が間違っています。data_not_found404そのレコードはありませんパスの
keyのレコードが、そのスペースのデータストアにありません。削除されたか、キーが間違っています。post_not_found404その投稿はありませんパスの
post_idの投稿がありません。削除されたか、ID が間違っています。書き換え・削除では、他人の投稿を指したときもこれになります(ID の存在を他人に教えないため)。ほかの人の下書きも同じです。comment_not_found404そのコメントはありませんパスの
comment_idのコメントがありません。削除されたか、ID が間違っています。他人のコメントを書き換え・削除しようとしたときもこれになります(ID の存在を他人に教えないため)。method_not_allowed405そのメソッドは使えませんエンドポイントが受け付けるメソッドは
Allowヘッダに入っています。slug_taken409そのスラグのページはすでにありますスラグはスペースの中で一意です。別のスラグを指定してください。
version_conflict409他の人が先に更新しましたversionを送ると、その版のままのときだけ書き換えます(楽観ロック)。合わないときは読み直してから、もう一度送ってください。handle_taken409そのハンドルはすでに使われていますハンドルは大文字・小文字を区別せずに一意です(
Appleがいればappleは使えません)。別のハンドルを指定してください。part_name_taken409その識別名のパーツはすでにあります識別名はスペースの中で一意です。別の識別名を指定してください。
parts_quota_exceeded409パーツの合計の大きさが上限に達しました1 スペースのパーツの中身の合計には上限があります。要らないパーツを消すか、中身を減らしてください。
data_quota_exceeded409データストアの上限に達しましたレコードの数か、スペースの合計サイズが上限に達しています。要らないレコードを消してください。
storage_quota_exceeded409ストレージの容量が足りません1 スペースのファイルの合計には上限があります。要らないファイルを消すか、小さくしてから送ってください。
payload_too_large413リクエスト本文が大きすぎます本文は 1MiB まで、ファイルを上げる・書き換えるときだけ 14MiB までです。HTML やファイルそのものの上限は別にあります(
validation_failed)。unsupported_media_type415Content-Type は application/json にしてください本文は JSON で送ってください。
validation_failed422入力が規則を満たしていませんerrorsに、どの項目がなぜ通らなかったかが並びます。rate_limited429呼び出しの回数が上限を超えましたRetry-Afterヘッダの秒数だけ待ってから、もう一度呼び出してください。上限は「制限」の節にあります。internal_error500サーバの内部で問題が起きました送った内容に問題はありません。少し待ってからもう一度呼び出し、続くようなら
detailの照合用の番号を添えて問い合わせてください。
制限
呼び出しの回数
- API キーごとに 60 回/分。REST と MCP の呼び出しを合わせて数えます。
- 送信元の IP アドレスごとに 120 回/分。認証の前に数えるので、キーの無いリクエストも含みます。
- 1 分ごとに数え直します。上限を超えると
429(rate_limited)を返し、Retry-Afterに待つ秒数を入れます。 - 成功した応答には
RateLimit-Limit・RateLimit-Remaining・RateLimit-Resetが付きます。
大きさと規則
- リクエスト本文は 1,048,576 バイトまで(ファイルを送るときだけ 14,680,064 バイトまで)。HTML は 262,144 文字まで。
- スラグはスペースの中で一意。スラグを変えると URL が変わり、古い URL は開けなくなります。
- 削除したページは元に戻せません。
- ページの HTML は Framed! 本体とは別のドメインのフレームの中で動き、閲覧者のサインイン状態には触れられません。
MCP サーバ
Claude などの AI エージェントから、同じ操作を MCP(Model Context Protocol)で使えます。 REST の API と同じ API キー・同じ規則・同じ回数の上限で動きます。
- URL:
https://api.framed.dog/mcp(Streamable HTTP) - 認証:
Authorization: Bearer <API キー>ヘッダ - ページ・パーツ・データ・ファイルの書き換えと削除は、公開中のページに直ちに効きます。エージェントには、実行前に内容を確かめるよう指示してあります。
- 自分として投稿する MCP サーバは別にあります(
https://api.framed.dog/user-mcp、ユーザーAPIトークンで認証)→ ユーザーAPIの MCP サーバ
ツール
get_spaceスペースを確かめる読み取りだけこの API キーで操作できるスペースの名前・URL、このキーで使える範囲(scopes)、ページ・パーツ・データ・ファイルの入力の規則、呼び出し回数の上限を返す。最初に必ず呼ぶこと。範囲の無いツールを呼ぶと insufficient_scope で失敗する。
list_pagesページの一覧読み取りだけスペースのフリーページを、スラグの順にすべて返す。本文(HTML)は含まない。
get_pageページを取得読み取りだけページを本文(HTML)ごと返す。
create_pageページを作って公開スラグと HTML(と種類 kind)でフリーページを作り、https://<subdomain>.framed.dog/<slug> に直ちに公開する。kind は scripted(スクリプトあり・既定)か static(スクリプトなし)。同じスラグがあると slug_taken で失敗する。実行前に利用者に内容を確かめること。
update_pageページを書き換え公開中の内容を変える公開中のページの slug・kind・html のうち、渡したものだけを書き換える。slug を変えると URL が変わり、古い URL は開けなくなる。実行前に利用者に確かめること。
delete_pageページを削除公開中の内容を変える公開中のページを削除する。URL は開けなくなり、元に戻せない。実行前に必ず利用者に確かめること。
list_partsパーツの一覧読み取りだけスペースのパーツ(ページから組み込む共通のテンプレート)を、識別名の順にすべて返す。中身は含まない。
get_partパーツを取得読み取りだけパーツを中身ごと返す。そのパーツを組み込んでいるページとパーツ(used_by)も返すので、識別名を変える前・消す前に影響を確かめられる。
create_partパーツを作る識別名とテンプレート HTML でパーツを作る。パーツ単独では公開されず、ページやほかのパーツから組み込んで使う。
組み込みは Liquid の標準のタグ: {% render 'name' %}(値を明示して渡す)、{% include 'name' %}(ページの変数をそのまま使う)、{% layout 'name' %}{% block content %}…{% endblock %}(共通の枠にはめる)。
同じ識別名があると part_name_taken、組み込みをたどって元に戻る形(循環)は 422 で失敗する。
update_partパーツを書き換え公開中の内容を変えるパーツの name と html のうち、渡したものだけを書き換える。組み込んでいる公開中のページが直ちに変わる。
識別名を変えると、古い名前で組み込んでいるページはエラーのページになる(組み込み側は書き換わらない)。先に get_part の used_by を見て、組み込み側も直すこと。
実行前に利用者に確かめること。
delete_partパーツを削除公開中の内容を変えるパーツを削除する。組み込んでいたページはエラーのページになる。元に戻せない。先に get_part の used_by で影響を確かめ、実行前に必ず利用者に確かめること。
list_filesストレージのファイルの一覧読み取りだけスペースのストレージに上がっているファイルを新しい順に返す。ページの HTML から画像やフォントを参照するための url を知る手段は、これか upload_file の結果だけ(ID は推測できない)。使っている容量も返す。
get_fileストレージのファイルを 1 つ取得読み取りだけファイルの名前・種類・大きさ・URL を返す。中身は返さない(url をそのまま取りに行けば取り出せる)。
upload_fileストレージにファイルを上げるファイル名と中身でファイルを上げ、url を返す。url は URL を知っている誰でも開けるので、ページの HTML から画像・フォント・CSS として参照できる。
encoding は、SVG・CSS・JSON・テキストのような文字のファイルなら text(content に中身をそのまま渡す)、画像などは base64。
配信する種類はファイル名の拡張子で決まる(.html や .js はダウンロードとして返り、ページの中では動かない)。同じ名前のファイルがあっても別のファイルとして増える。
1 ファイルと合計の上限は get_space の rules.file にある。容量が足りなければ storage_quota_exceeded。実行前に利用者に確かめること。
update_fileストレージのファイルを書き換え公開中の内容を変えるファイルの name と中身(content と encoding)のうち、渡したものだけを書き換える。ID と url は変わらないので、参照しているページの HTML は直さなくてよい。
そのファイルを参照している公開中のページが直ちに変わる(見る人のブラウザには、古い中身が最大 5 分残ることがある)。前の中身には戻せない。
名前を変えると、配信する種類も新しい拡張子で決め直す。人が管理画面から上げたファイルも書き換えられるので、実行前に必ず利用者に確かめること。
delete_fileストレージのファイルを削除公開中の内容を変えるファイルを削除する。url はすぐ開けなくなり、参照しているページでは画像などが表示されなくなる。元に戻せない。人が管理画面から上げたファイルも消せるので、実行前に必ず利用者に確かめること。
list_dataデータストアの一覧読み取りだけスペースのデータストアのレコードを、キーの順にすべて返す。値のほかに、値から推論した形(schema)と形の食い違い(warnings)も付く。
get_dataデータストアのレコードを取得読み取りだけキーを指定して 1 件返す。書き換えるときは、返ってきた version をそのまま put_data に渡すと、他の人の更新を上書きしない。
put_dataデータストアのレコードを保存公開中の内容を変えるキーを指定してレコードを作る、または丸ごと置き換える。一部だけの更新はできないので、先に get_data で読み、変えたところだけ直した value 全体を渡すこと。
version を渡すと、その版のままのときだけ書き換える(合わなければ version_conflict)。
データはフリーページから読まれて公開される。実行前に利用者に内容を確かめること。
応答の warnings は「形が他の要素と食い違う」という知らせで、保存そのものは通っている。
delete_dataデータストアのレコードを削除公開中の内容を変えるキーを指定してレコードを消す。そのレコードを読んでいるフリーページは、その部分が空になる。元に戻せない。実行前に必ず利用者に確かめること。
OpenAPI
この API は OpenAPI 3.1.0 で定義しています。クライアントの生成や API ツールへの取り込みには、次の文書を使ってください。