Framed! User API · v1.3.0
ユーザーAPI
Framed! に自分として投稿し、反応し、プロフィールを整えるための API です。扱えるのは 4 つです。
- 投稿: HTML・Markdown・リブログ(URL の共有)のどれかで書く。作る・本文を書き換える・消す(自分の投稿だけ)
- コメント: 投稿へのプレーンテキスト。書く・書き換える・消す(自分のコメントだけ)
- いいね: 投稿に付ける・外す。何度呼んでも同じ結果になります
- プロフィール: 表示名・ハンドル・自己紹介・画像を書き換える(自分のものだけ)
- 認証はアカウントごとに発行するユーザーAPIトークンで行います(
Authorization: Bearer <トークン>)。
トークンは Framed! の https://framed.dog/account/api-tokens で自分で発行します。
- トークンで出来ることは、あなたが画面から出来ることの部分集合です。 他人の投稿やコメントは書き換えられません。
- 本文は JSON、エラーは RFC 9457(
application/problem+json)で返します。 - 呼び出しはトークンごとに 60 回/分までです。
- トークンには触れる範囲が付きます。 まず
GET /meを呼んで、そのトークンで何ができるかを確かめてください。 - トークンは秘密情報で、あなたのアカウントそのものです。 サーバからだけ呼び出してください。ブラウザからの呼び出し(CORS)には対応していません。
スペースのサイト(フリーページ・データストア・ストレージ)は別の API です。そちらはスペースごとの API キーで認証します → Framed! API のドキュメント
はじめる
- Framed! にサインインし、アカウントのユーザーAPIトークンの画面(
/account/api-tokens)でトークンを発行します。トークンは発行したときに一度だけ表示されます。 - トークンを環境変数などの秘密の置き場所に保存します(例:
FRAMED_USER_TOKEN)。 - サーバから次のように呼び出すと、すぐタイムラインに出ます。その前に
GET /v1/meを呼ぶと、そのトークンで何ができるか(範囲)と入力の規則が分かります。
認証
アカウントごとに発行するユーザーAPIトークン。Framed! の /account/api-tokens で自分で発行します。
トークンは発行したときに一度だけ表示されます。あなたのアカウントそのものとして扱ってください。
トークンには触れる範囲が付きます(発行時に選び、あとから変えられません)。
posts: 自分の投稿を読み、投稿を作り、自分の投稿の本文を書き換え、削除します。ほかの人の投稿は読めますが書き換えられません。comments: 投稿へのコメントを読み、コメントを書き、自分のコメントを書き換え、削除します。ほかの人のコメントは書き換えられません。likes: 投稿にいいねを付け、外します。profile: 自分の表示名・ハンドル・自己紹介・画像を書き換えます。ハンドルを変えると、古いハンドルのプロフィールの URL は開けなくなります。
範囲の足りない操作を呼ぶと 403 insufficient_scope を返します。
スペースごとの API キー(framed_sk_…)とは別物で、こちらでは使えません(401 になります)。
- トークンはあなたのアカウントそのものです。渡した相手は、あなたとして投稿できます。ブラウザのコードやリポジトリに含めないでください (ブラウザからの呼び出し(CORS)には対応していません)。
- 出来ることは、あなたが画面から出来ることの範囲に収まります。ほかの人の投稿やコメントは書き換えられません。
- 範囲は発行するときに決まり、あとから変えられません。範囲の足りない操作は
403 insufficient_scopeです。変えたいときは発行し直し、古いトークンを失効させてください。 - 漏れたときは、トークンの画面ですぐに失効させてください。失効したトークンは直後から使えません。
- スペースごとの API キー(
framed_sk_…)はこの API では使えません(401)。逆も同じです。
触れる範囲
トークンには資源ごとの範囲が付きます。読み取りと書き込みは分けていません (投稿もコメントもタイムラインで公開されるので、意味のある境目は「何を書き換えられるか」の方です)。
posts投稿- 自分の投稿を読み、投稿を作り、自分の投稿の本文を書き換え、削除します。ほかの人の投稿は読めますが書き換えられません。
commentsコメント- 投稿へのコメントを読み、コメントを書き、自分のコメントを書き換え、削除します。ほかの人のコメントは書き換えられません。
likesいいね- 投稿にいいねを付け、外します。
profileプロフィール- 自分の表示名・ハンドル・自己紹介・画像を書き換えます。ハンドルを変えると、古いハンドルのプロフィールの URL は開けなくなります。
GET /v1/me だけは範囲を問わず答えます。何ができるトークンなのかを知る手段が無いと、範囲を分けた意味が薄れるためです。
エンドポイント
ベース URL は https://api.framed.dog/v1 です。
- GET/meトークンの持ち主と、このトークンで出来ることを確かめる
- PATCH/me表示名・ハンドル・自己紹介を書き換える
- PUT/me/icon画像を設定する
- DELETE/me/icon画像を外す
- GET/posts自分の投稿の一覧
- POST/posts投稿する
- GET/posts/{post_id}投稿を本文ごと取得する
- PATCH/posts/{post_id}投稿の本文を書き換える
- DELETE/posts/{post_id}投稿を消す
- GET/posts/{post_id}/comments投稿へのコメントの一覧
- POST/posts/{post_id}/commentsコメントする
- PUT/posts/{post_id}/likeいいねを付ける
- DELETE/posts/{post_id}/likeいいねを外す
- PATCH/comments/{comment_id}コメントを書き換える
- DELETE/comments/{comment_id}コメントを消す
トークンの持ち主と、このトークンで出来ることを確かめる
GEThttps://api.framed.dog/v1/me
ハンドル・表示名・画像・自己紹介に加えて、このトークンに付いている範囲(`scopes`)と、
投稿・コメント・プロフィールの入力の規則、呼び出し回数の上限を返します。
最初にこれを呼んでください。 範囲の足りない操作は 403 insufficient_scope になるので、
何ができるトークンなのかを先に知る必要があります。この操作だけは範囲を問わず答えます。
規則の値は実装と同じ定義から組み立てているので、上限を変えてもここがずれることはありません。
応答(200)トークンの持ち主と、このトークンで出来ること。
| 項目 | 型 | 説明 |
|---|---|---|
| handle必須string | string | あなたのハンドル( |
| display_name必須stringnull | stringnull | 表示名。設定していなければ |
| icon_url必須string,null (uri) | string,null (uri) | アカウントの画像の URL。設定していなければ |
| bio必須stringnull | stringnull | 自己紹介(プレーンテキスト。改行は |
| scopes必須string[] | string[] | このトークンに付いている範囲。 足りない操作は 403 になります。 |
| rules必須object | object | 入力の規則。画面と同じ定義から組み立てています。 |
| rate_limit必須object | object |
ここに無い項目を送ると 422 になります。
返りうるステータス
- 200トークンの持ち主と、このトークンで出来ること。
- 401API キーが無いか、有効ではありません
- 403トークンにその操作の範囲が付いていない(`insufficient_scope`)。範囲は発行するときに決まり、あとから増やせません。
- 429呼び出しの回数が上限を超えました
- 500サーバの内部で問題が起きました
表示名・ハンドル・自己紹介を書き換える
PATCHhttps://api.framed.dog/v1/me
送った項目だけを書き換えます。範囲 profile が要ります。応答は書き換えたあとの GET /me と同じです。
規則はアカウントの画面と同じで、上限は GET /me の rules.profile にあります。
display_name: 表示名。日本語・空白・絵文字も使え、ほかの人と同じでもかまいません。
`null` か空の文字列で外れ、画面にはハンドルが出ます。
bio: 自己紹介。プレーンテキストで、改行を使えます(HTML も Markdown も解釈しません)。nullか空の文字列で外れます。handle: ハンドル。英字・数字・.・_だけ。先頭の@は取り除きます。
大文字・小文字を区別せずに一意で、使われていれば 409 handle_taken です。
古いハンドルはすぐに空き、誰でも取れます。 古いハンドルのプロフィールの URL は開けなくなり、転送もしません。
規則を満たさない項目が 1 つでもあれば、どの項目も書き換えません(422 に全部の理由が並びます)。
ハンドルがぶつかったとき(409)も、表示名と自己紹介は書き換えません。
リクエスト本文(application/json)
| 項目 | 型 | 説明 |
|---|---|---|
| handle任意string | string | ハンドル。英字・数字・ 前後の空白と先頭の |
| display_name任意stringnull | stringnull | 表示名。前後の空白を落として 30 文字まで(コードポイントで数えます)。 改行・制御文字・文字の向きを変える制御は使えません。 |
| bio任意stringnull | stringnull | 自己紹介(プレーンテキスト)。前後の空白を落として 1000 文字まで(コードポイントで数え、改行も 1 文字)。 改行は使えますが、タブなどほかの制御文字と、文字の向きを変える制御は使えません。 |
ここに無い項目を送ると 422 になります。
応答(200)書き換えました。
| 項目 | 型 | 説明 |
|---|---|---|
| handle必須string | string | あなたのハンドル( |
| display_name必須stringnull | stringnull | 表示名。設定していなければ |
| icon_url必須string,null (uri) | string,null (uri) | アカウントの画像の URL。設定していなければ |
| bio必須stringnull | stringnull | 自己紹介(プレーンテキスト。改行は |
| scopes必須string[] | string[] | このトークンに付いている範囲。 足りない操作は 403 になります。 |
| rules必須object | object | 入力の規則。画面と同じ定義から組み立てています。 |
| rate_limit必須object | object |
ここに無い項目を送ると 422 になります。
返りうるステータス
- 200書き換えました。
- 400リクエスト本文を JSON として読めません
- 401API キーが無いか、有効ではありません
- 403トークンにその操作の範囲が付いていない(`insufficient_scope`)。範囲は発行するときに決まり、あとから増やせません。
- 409そのハンドルはすでに使われています
- 413リクエスト本文が大きすぎます
- 415Content-Type は application/json にしてください
- 422入力が規則を満たしていません
- 429呼び出しの回数が上限を超えました
- 500サーバの内部で問題が起きました
画像を設定する
PUThttps://api.framed.dog/v1/me/icon
アカウントの画像を設定します(あれば置き換えます)。範囲 profile が要ります。
- 256×256 の PNG だけを、base64 にして
pngに入れて送ります(1048576 バイトまで)。
切り抜きや縮小はしません。正方形に切り抜いて縮めてから送ってください。
- サーバは中身を信用せず、画素だけを使って PNG を作り直して保存します(メタデータは残りません)。
- 画像の URL は設定するたびに変わります。応答の
icon_urlを使ってください。 - 本文の上限は、このエンドポイントだけ 1399128 バイトです。
リクエスト本文(application/json)
| 項目 | 型 | 説明 |
|---|---|---|
| png必須string | string | 256×256 の PNG を base64 にしたもの(改行は無視します)。
|
ここに無い項目を送ると 422 になります。
応答(200)設定しました。
| 項目 | 型 | 説明 |
|---|---|---|
| handle必須string | string | あなたのハンドル( |
| display_name必須stringnull | stringnull | 表示名。設定していなければ |
| icon_url必須string,null (uri) | string,null (uri) | アカウントの画像の URL。設定していなければ |
| bio必須stringnull | stringnull | 自己紹介(プレーンテキスト。改行は |
| scopes必須string[] | string[] | このトークンに付いている範囲。 足りない操作は 403 になります。 |
| rules必須object | object | 入力の規則。画面と同じ定義から組み立てています。 |
| rate_limit必須object | object |
ここに無い項目を送ると 422 になります。
返りうるステータス
- 200設定しました。
- 400リクエスト本文を JSON として読めません
- 401API キーが無いか、有効ではありません
- 403トークンにその操作の範囲が付いていない(`insufficient_scope`)。範囲は発行するときに決まり、あとから増やせません。
- 413リクエスト本文が大きすぎます
- 415Content-Type は application/json にしてください
- 422入力が規則を満たしていません
- 429呼び出しの回数が上限を超えました
- 500サーバの内部で問題が起きました
画像を外す
DELETEhttps://api.framed.dog/v1/me/icon
アカウントの画像を外します。範囲 profile が要ります。
画面には名前の先頭の 1 文字が出ます。設定していなくても成功します。
応答(204)外しました(本文なし)。
返りうるステータス
- 204外しました(本文なし)。
- 401API キーが無いか、有効ではありません
- 403トークンにその操作の範囲が付いていない(`insufficient_scope`)。範囲は発行するときに決まり、あとから増やせません。
- 429呼び出しの回数が上限を超えました
- 500サーバの内部で問題が起きました
自分の投稿の一覧
GEThttps://api.framed.dog/v1/posts
自分の投稿を新しい順に返します。本文(HTML)は含みません。
画面で作りかけの下書きも含み、published で見分けられます。
ほかの人の投稿の一覧(タイムライン)は、この API では読めません。
応答(200)自分の投稿の一覧。
| 項目 | 型 | 説明 |
|---|---|---|
| data必須Post[] | Post[] | 自分の投稿。新しい順。 |
ここに無い項目を送ると 422 になります。
返りうるステータス
- 200自分の投稿の一覧。
- 401API キーが無いか、有効ではありません
- 403トークンにその操作の範囲が付いていない(`insufficient_scope`)。範囲は発行するときに決まり、あとから増やせません。
- 429呼び出しの回数が上限を超えました
- 500サーバの内部で問題が起きました
投稿する
POSThttps://api.framed.dog/v1/posts
本文を送ると投稿になり、すぐタイムラインに出ます。 書き方は format で選びます。
html(省略したときもこれ): HTML をそのまま。サーバは書き換えません(サニタイズしません)。
CSS と JavaScript も、配信オリジンのフレームの中で動きます。
markdown: Markdown。画面の「文章」と同じ形に移して保存します。スクリプトは動きません。reblog: 共有する URL と、添える短い文。画面にはリンクカードが出ます。
tagsでタグを付けられます(あとから付け外しはできません)。- 応答の
urlが配信オリジンです。 - 画面の下書きには触りません。 画面で書きかけのものは、この呼び出しで消えません。
- 宛先は本体のタイムラインだけです(スペース宛ての投稿はまだ API から作れません)。
リクエスト本文(application/json)
| 項目 | 型 | 説明 |
|---|
応答(201)投稿しました。
| 項目 | 型 | 説明 |
|---|---|---|
| id必須string | string | 投稿の ID。本文を書き換えても変わりません。
|
| url必須string (uri) | string (uri) | 投稿の HTML が配信される URL。投稿ごとに 1 つのオリジンです。 タイムラインはこの URL をフレームで読み込みます。 |
| author_handle必須string | string | 投稿した人のハンドル。 |
| format必須string | string | いまの本文の書き方。
|
| tags必須string[] | string[] | 付いているタグ(名前の順)。付いていなければ空の配列。 |
| published必須boolean | boolean | 公開されているか。 |
| published_at必須string,null (date-time) | string,null (date-time) | 公開した日時(UTC、ISO 8601)。下書きなら |
| created_at必須string (date-time) | string (date-time) | 作った日時(UTC、ISO 8601)。 |
| updated_at必須string (date-time) | string (date-time) | 最後に書き換えた日時(UTC、ISO 8601)。作っただけなら作った日時。 |
| like_count必須integer | integer | いいねの数。 |
| comment_count必須integer | integer | コメントの数。 |
ここに無い項目を送ると 422 になります。
返りうるステータス
- 201投稿しました。
- 400リクエスト本文を JSON として読めません
- 401API キーが無いか、有効ではありません
- 403トークンにその操作の範囲が付いていない(`insufficient_scope`)。範囲は発行するときに決まり、あとから増やせません。
- 413リクエスト本文が大きすぎます
- 415Content-Type は application/json にしてください
- 422入力が規則を満たしていません
- 429呼び出しの回数が上限を超えました
- 500サーバの内部で問題が起きました
投稿を本文ごと取得する
GEThttps://api.framed.dog/v1/posts/{post_id}
投稿を 1 件、本文(配信している HTML)といいね・コメントの数まで返します。
リブログなら reblog に URL と文が入ります。
ほかの人の公開済みの投稿も読めます(タイムラインに並ぶものなので)。
ただし下書きは本人だけです。ほかの人の下書きを指すと 404 になります。
パスパラメータ
| 項目 | 型 | 説明 |
|---|---|---|
| post_id必須string | string | 投稿の ID(作成・一覧の応答の
|
応答(200)投稿の本文と数。
| 項目 | 型 | 説明 |
|---|---|---|
| id必須string | string | 投稿の ID。本文を書き換えても変わりません。
|
| url必須string (uri) | string (uri) | 投稿の HTML が配信される URL。投稿ごとに 1 つのオリジンです。 タイムラインはこの URL をフレームで読み込みます。 |
| author_handle必須string | string | 投稿した人のハンドル。 |
| format必須string | string | いまの本文の書き方。
|
| tags必須string[] | string[] | 付いているタグ(名前の順)。付いていなければ空の配列。 |
| published必須boolean | boolean | 公開されているか。 |
| published_at必須string,null (date-time) | string,null (date-time) | 公開した日時(UTC、ISO 8601)。下書きなら |
| created_at必須string (date-time) | string (date-time) | 作った日時(UTC、ISO 8601)。 |
| updated_at必須string (date-time) | string (date-time) | 最後に書き換えた日時(UTC、ISO 8601)。作っただけなら作った日時。 |
| like_count必須integer | integer | いいねの数。 |
| comment_count必須integer | integer | コメントの数。 |
| html必須string | string | 配信している HTML 文書そのもの(
|
| reblog必須objectnull | objectnull | リブログの URL と文。 |
ここに無い項目を送ると 422 になります。
返りうるステータス
- 200投稿の本文と数。
- 401API キーが無いか、有効ではありません
- 403トークンにその操作の範囲が付いていない(`insufficient_scope`)。範囲は発行するときに決まり、あとから増やせません。
- 404その投稿がない、ほかの人の下書きである、または**書き換え・削除でほかの人の投稿を指した**(`post_not_found`)。ID の存在を他人に伝えないため、権限が無い場合も 404 です。
- 429呼び出しの回数が上限を超えました
- 500サーバの内部で問題が起きました
投稿の本文を書き換える
PATCHhttps://api.framed.dog/v1/posts/{post_id}
自分の投稿の本文だけを、丸ごと書き換えます。ほかの人の投稿を指すと 404 です。
本文の送り方は作成と同じ(format と、その書き方の項目)です。
- ID と配信オリジン(`url`)は変わりません。 書き換えは次に開いた人にすぐ届きます。
- 書き方は元と違ってもかまいません(Markdown で書いた投稿を HTML で書き換える、など)。
- タグと公開の状態は変わりません(下書きは下書きのまま)。
パスパラメータ
| 項目 | 型 | 説明 |
|---|---|---|
| post_id必須string | string | 投稿の ID(作成・一覧の応答の
|
リクエスト本文(application/json)
| 項目 | 型 | 説明 |
|---|
応答(200)書き換えました。
| 項目 | 型 | 説明 |
|---|---|---|
| id必須string | string | 投稿の ID。本文を書き換えても変わりません。
|
| url必須string (uri) | string (uri) | 投稿の HTML が配信される URL。投稿ごとに 1 つのオリジンです。 タイムラインはこの URL をフレームで読み込みます。 |
| author_handle必須string | string | 投稿した人のハンドル。 |
| format必須string | string | いまの本文の書き方。
|
| tags必須string[] | string[] | 付いているタグ(名前の順)。付いていなければ空の配列。 |
| published必須boolean | boolean | 公開されているか。 |
| published_at必須string,null (date-time) | string,null (date-time) | 公開した日時(UTC、ISO 8601)。下書きなら |
| created_at必須string (date-time) | string (date-time) | 作った日時(UTC、ISO 8601)。 |
| updated_at必須string (date-time) | string (date-time) | 最後に書き換えた日時(UTC、ISO 8601)。作っただけなら作った日時。 |
| like_count必須integer | integer | いいねの数。 |
| comment_count必須integer | integer | コメントの数。 |
ここに無い項目を送ると 422 になります。
返りうるステータス
- 200書き換えました。
- 400リクエスト本文を JSON として読めません
- 401API キーが無いか、有効ではありません
- 403トークンにその操作の範囲が付いていない(`insufficient_scope`)。範囲は発行するときに決まり、あとから増やせません。
- 404その投稿がない、ほかの人の下書きである、または**書き換え・削除でほかの人の投稿を指した**(`post_not_found`)。ID の存在を他人に伝えないため、権限が無い場合も 404 です。
- 413リクエスト本文が大きすぎます
- 415Content-Type は application/json にしてください
- 422入力が規則を満たしていません
- 429呼び出しの回数が上限を超えました
- 500サーバの内部で問題が起きました
投稿を消す
DELETEhttps://api.framed.dog/v1/posts/{post_id}
自分の投稿だけを消します。ほかの人の投稿を指すと 404 です。
元に戻せません。 配信オリジンはすぐ 404 になり、その投稿へのいいね・コメント・
通報も一緒に消えます。
パスパラメータ
| 項目 | 型 | 説明 |
|---|---|---|
| post_id必須string | string | 投稿の ID(作成・一覧の応答の
|
応答(204)削除しました(本文なし)。
返りうるステータス
- 204削除しました(本文なし)。
- 401API キーが無いか、有効ではありません
- 403トークンにその操作の範囲が付いていない(`insufficient_scope`)。範囲は発行するときに決まり、あとから増やせません。
- 404その投稿がない、ほかの人の下書きである、または**書き換え・削除でほかの人の投稿を指した**(`post_not_found`)。ID の存在を他人に伝えないため、権限が無い場合も 404 です。
- 429呼び出しの回数が上限を超えました
- 500サーバの内部で問題が起きました
投稿へのコメントの一覧
GEThttps://api.framed.dog/v1/posts/{post_id}/comments
その投稿のコメントを古い順に返します(会話として読む順なので、新しい順にはしません)。
一度に 100 件までです。
パスパラメータ
| 項目 | 型 | 説明 |
|---|---|---|
| post_id必須string | string | 投稿の ID(作成・一覧の応答の
|
応答(200)コメントの一覧。
| 項目 | 型 | 説明 |
|---|---|---|
| data必須Comment[] | Comment[] | コメント。古い順。 |
ここに無い項目を送ると 422 になります。
返りうるステータス
- 200コメントの一覧。
- 401API キーが無いか、有効ではありません
- 403トークンにその操作の範囲が付いていない(`insufficient_scope`)。範囲は発行するときに決まり、あとから増やせません。
- 404その投稿がない、ほかの人の下書きである、または**書き換え・削除でほかの人の投稿を指した**(`post_not_found`)。ID の存在を他人に伝えないため、権限が無い場合も 404 です。
- 429呼び出しの回数が上限を超えました
- 500サーバの内部で問題が起きました
コメントする
POSThttps://api.framed.dog/v1/posts/{post_id}/comments
その投稿にコメントします。本文はプレーンテキストで、HTML として解釈されません。
同じ投稿に何件でも書けます(1 人 1 件の制限はありません)。
パスパラメータ
| 項目 | 型 | 説明 |
|---|---|---|
| post_id必須string | string | 投稿の ID(作成・一覧の応答の
|
リクエスト本文(application/json)
| 項目 | 型 | 説明 |
|---|---|---|
| body必須string | string | コメントの本文。プレーンテキストです(HTML として解釈されません)。 前後の空白を取り除いたうえで、空でなく 500 文字以内であること。 改行は
|
ここに無い項目を送ると 422 になります。
応答(201)コメントしました。
| 項目 | 型 | 説明 |
|---|---|---|
| id必須string | string | コメントの ID。
|
| post_id必須string | string | コメントした先の投稿の ID。
|
| author_handle必須string | string | コメントした人のハンドル。 |
| body必須string | string | コメントの本文(プレーンテキスト)。 |
| 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トークンにその操作の範囲が付いていない(`insufficient_scope`)。範囲は発行するときに決まり、あとから増やせません。
- 404その投稿がない、ほかの人の下書きである、または**書き換え・削除でほかの人の投稿を指した**(`post_not_found`)。ID の存在を他人に伝えないため、権限が無い場合も 404 です。
- 413リクエスト本文が大きすぎます
- 415Content-Type は application/json にしてください
- 422入力が規則を満たしていません
- 429呼び出しの回数が上限を超えました
- 500サーバの内部で問題が起きました
いいねを付ける
PUThttps://api.framed.dog/v1/posts/{post_id}/like
その投稿にいいねを付けます。何度呼んでも同じ結果で、すでに付いていても数は増えません。
呼び出しが失敗して再試行しても、数が狂うことはありません。
本文は要りません(送っても無視します)。
パスパラメータ
| 項目 | 型 | 説明 |
|---|---|---|
| post_id必須string | string | 投稿の ID(作成・一覧の応答の
|
応答(200)いまのいいねの状態。
| 項目 | 型 | 説明 |
|---|---|---|
| post_id必須string | string | いいねを付けた投稿の ID。
|
| liked必須boolean | boolean | いいねが付いているか。 |
| like_count必須integer | integer | その投稿のいいねの数。 |
ここに無い項目を送ると 422 になります。
返りうるステータス
- 200いまのいいねの状態。
- 401API キーが無いか、有効ではありません
- 403トークンにその操作の範囲が付いていない(`insufficient_scope`)。範囲は発行するときに決まり、あとから増やせません。
- 404その投稿がない、ほかの人の下書きである、または**書き換え・削除でほかの人の投稿を指した**(`post_not_found`)。ID の存在を他人に伝えないため、権限が無い場合も 404 です。
- 429呼び出しの回数が上限を超えました
- 500サーバの内部で問題が起きました
いいねを外す
DELETEhttps://api.framed.dog/v1/posts/{post_id}/like
その投稿のいいねを外します。付いていなくても成功します(PUT と同じく冪等です)。
パスパラメータ
| 項目 | 型 | 説明 |
|---|---|---|
| post_id必須string | string | 投稿の ID(作成・一覧の応答の
|
応答(204)外しました(本文なし)。
返りうるステータス
- 204外しました(本文なし)。
- 401API キーが無いか、有効ではありません
- 403トークンにその操作の範囲が付いていない(`insufficient_scope`)。範囲は発行するときに決まり、あとから増やせません。
- 404その投稿がない、ほかの人の下書きである、または**書き換え・削除でほかの人の投稿を指した**(`post_not_found`)。ID の存在を他人に伝えないため、権限が無い場合も 404 です。
- 429呼び出しの回数が上限を超えました
- 500サーバの内部で問題が起きました
コメントを書き換える
PATCHhttps://api.framed.dog/v1/comments/{comment_id}
自分のコメントだけを書き換えます。ほかの人のコメントを指すと 404 です。投稿は変えられません。
パスパラメータ
| 項目 | 型 | 説明 |
|---|---|---|
| comment_id必須string | string | コメントの ID(作成・一覧の応答の
|
リクエスト本文(application/json)
| 項目 | 型 | 説明 |
|---|---|---|
| body必須string | string | コメントの本文。プレーンテキストです(HTML として解釈されません)。 前後の空白を取り除いたうえで、空でなく 500 文字以内であること。 改行は
|
ここに無い項目を送ると 422 になります。
応答(200)書き換えました。
| 項目 | 型 | 説明 |
|---|---|---|
| id必須string | string | コメントの ID。
|
| post_id必須string | string | コメントした先の投稿の ID。
|
| author_handle必須string | string | コメントした人のハンドル。 |
| body必須string | string | コメントの本文(プレーンテキスト)。 |
| 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トークンにその操作の範囲が付いていない(`insufficient_scope`)。範囲は発行するときに決まり、あとから増やせません。
- 404そのコメントがない、または**ほかの人のコメントを指した**(`comment_not_found`)。投稿と同じ理由で 404 です。
- 413リクエスト本文が大きすぎます
- 415Content-Type は application/json にしてください
- 422入力が規則を満たしていません
- 429呼び出しの回数が上限を超えました
- 500サーバの内部で問題が起きました
コメントを消す
DELETEhttps://api.framed.dog/v1/comments/{comment_id}
自分のコメントだけを消します。ほかの人のコメントを指すと 404 です。元に戻せません。
パスパラメータ
| 項目 | 型 | 説明 |
|---|---|---|
| comment_id必須string | string | コメントの ID(作成・一覧の応答の
|
応答(204)削除しました(本文なし)。
返りうるステータス
- 204削除しました(本文なし)。
- 401API キーが無いか、有効ではありません
- 403トークンにその操作の範囲が付いていない(`insufficient_scope`)。範囲は発行するときに決まり、あとから増やせません。
- 404そのコメントがない、または**ほかの人のコメントを指した**(`comment_not_found`)。投稿と同じ理由で 404 です。
- 429呼び出しの回数が上限を超えました
- 500サーバの内部で問題が起きました
投稿
本文は format で書き方を選びます。画面の投稿フォームのタブと同じものです(画面の「文章」の代わりに Markdown を使います)。
markdownMarkdown- ふつうの文章に向きます。保存のときに画面の「文章」と同じ形に移し、フレームを使わずにタイムラインへ出ます。中の HTML はタグにならず、書いたとおりの文字として出ます(スクリプトは動きません)。元の Markdown は残さず、あとで読むと
formatはrichです。 htmlHTML(省略したときの既定)- HTML ドキュメントをそのまま。CSS と JavaScript を含められ、サーバは書き換えません(サニタイズしません)。そのままで安全なのは、投稿が Framed! 本体とは別のドメイン(
<post_id>.usercontents.frmd.spot)のフレームの中で動き、閲覧者のサインイン状態やほかの投稿に触れられないからです。 reblogリブログ- ほかのページの URL(
url)を、200 文字までの文(text、プレーンテキスト)を添えて共有します。画面にはリンク先の Open Graph から作ったリンクカードが出ます。
PATCHは本文を丸ごと置き換えます。書き方は元と違ってもかまいません。ID と URL は変わらず、書き換えは次に開いた人にすぐ届きます。タグと公開の状態は変わりません。tagsで作るときにタグを 5 個まで付けられます。あとから付け外しはできません。成り立たないタグは黙って捨てずに422にします。- 書き換え・削除ができるのは自分の投稿だけです。ほかの人の投稿を指すと
404になります(403にすると、その ID の投稿が在ることを他人に伝えてしまうため)。 - 削除は元に戻せません。配信オリジンはすぐ開けなくなり、いいね・コメントも一緒に消えます。
POST /v1/postsは画面の下書きに触りません。画面で書きかけのものは消えません。- 宛先は本体のタイムラインだけです(スペース宛ての投稿はまだ API から作れません)。
コメントといいね
コメントはプレーンテキストです(投稿と違って HTML として解釈されません)。本体の画面に地の文として並ぶためで、500 文字まで、改行以外の制御文字は受け付けません。
いいねは何度呼んでも同じ結果になります(押した人ごとに 1 件で、状態は行の有無で表すため)。だから作成は POST ではなく PUT です。呼び出しが失敗して再試行しても、数が狂うことはありません。
- コメントは投稿の下に作り(
POST /v1/posts/…/comments)、書き換え・削除は ID で直接指します(/v1/comments/<comment_id>)。 - 書き換え・削除ができるのは自分のコメントだけです。ほかの人のコメントを指すと
404です。 - いいねはほかの人の投稿にも付けられます(それが本来の使い方です)。 ただし、ほかの人の下書きには付けられません。
- コメントの一覧は古い順です(会話として読む順なので)。
MCP サーバ
Claude などの AI エージェントから、投稿の操作を MCP(Model Context Protocol)で使えます。REST と同じ規則・同じ回数の上限(合わせて数えます)で動きます。 コメントといいねのツールはまだありません。
- URL:
https://api.framed.dog/user-mcp(Streamable HTTP) - つなぎ方 1: URL だけ(おすすめ)。クライアントに URL を登録すると、ブラウザで Framed! が開きます。 「許可する」を押せばつながり、トークンのコピーは要りません(MCP の認可仕様の OAuth 2.1。動的クライアント登録と Client ID Metadata Document に対応)。許可したアプリは トークンの画面の「つないだアプリ」に並び、そこで解除できます
- つなぎ方 2: トークン。OAuth に対応していないクライアントや、スクリプトから使うとき。
Authorization: Bearer <ユーザーAPIトークン>ヘッダを付けます。範囲postsが要ります(get_meだけは範囲を問いません) - エージェントは、あなたの名前でタイムラインに投稿します。作成・書き換え・削除はすぐに公開の場に効き、削除は元に戻せません。エージェントには、 実行前に中身をあなたに見せて確かめるよう指示してあります。
- スペースのサイトを扱う MCP サーバ(
https://api.framed.dog/mcp、スペースの API キー)とは別物です。
ツール
get_me自分のアカウントを確かめる読み取りだけこのトークンの持ち主(ハンドル・表示名・画像・自己紹介)、このトークンで使える範囲(scopes)、投稿とプロフィールの入力の規則、呼び出し回数の上限を返す。最初に必ず呼ぶこと。範囲の無いツールを呼ぶと insufficient_scope で失敗する。
list_my_posts自分の投稿の一覧読み取りだけ自分の投稿を新しい順に返す。本文は含まない(get_post で読む)。画面で書きかけの下書きも含み、published が false のものがそれ。format は html / rich(文章か Markdown で書いたもの)/ reblog。
get_post投稿を取得読み取りだけ投稿を本文(配信している HTML)ごと返す。ほかの人の公開済みの投稿も読める(下書きは本人だけ)。リブログなら reblog に URL と文が入る。
create_post投稿する利用者本人の名前で投稿し、本体のタイムラインに直ちに公開する(下書きにはならない)。
format で書き方を選ぶ: markdown(markdown に Markdown。スクリプトは動かない。ふつうの文章はこれを勧める)/
html(html に HTML。CSS と JavaScript も投稿ごとの別ドメインのフレームで動く)/
reblog(url に共有する URL、text に添える 200 字までの文。画面にはリンクカードが出る)。
tags でタグを 5 個まで付けられる(あとから変えられない)。
実行前に、投稿する中身を利用者に見せて確かめること。
update_post投稿を書き換え公開中の内容を変える自分の投稿の本文を丸ごと置き換える。書き方(format)は元と違ってよい。ほかの人の投稿は書き換えられない(post_not_found)。
ID と URL は変わらず、書き換えは見ている人に直ちに届く。タグと公開の状態は変わらない。
Markdown で書いた投稿も、元の Markdown は残っていない(get_post の html は組み立てた文書)。書き直すときは新しく書くこと。
実行前に、どの投稿をどう変えるかを利用者に確かめること。
delete_post投稿を削除公開中の内容を変える自分の投稿を削除する。URL は開けなくなり、ついていたいいね・コメントも一緒に消える。元に戻せない。実行前に必ず利用者に確かめること。
update_profileプロフィールを書き換え公開中の内容を変える自分の表示名(display_name)・ハンドル(handle)・自己紹介(bio)を書き換える。渡した項目だけが変わり、結果は get_me と同じ形。
display_name と bio は null か空の文字列で外れる(表示名が無いと画面にはハンドルが出る)。bio はプレーンテキストで改行を使える。
ハンドルを変えると、古いハンドルはすぐ空いて誰でも取れ、古いプロフィールの URL は開けなくなる(転送しない)。
使われているハンドルは handle_taken。規則を外れた項目が 1 つでもあれば validation_failed で、どの項目も変わらない。上限は get_me の rules.profile。
実行前に、何をどう変えるかを利用者に確かめること。範囲 profile が要る。
set_profile_iconプロフィールの画像を設定公開中の内容を変える自分のアカウントの画像を設定する(あれば置き換える)。png に 256×256 の PNG を base64 にしたものを渡す(1MiB まで)。
切り抜き・縮小はしないので、正方形に切り抜いて 256×256 に縮めてから渡すこと。大きさが違えば validation_failed。
結果は get_me と同じ形で、icon_url が新しい画像の URL になる。実行前に、どの画像にするかを利用者に確かめること。範囲 profile が要る。
remove_profile_iconプロフィールの画像を外す公開中の内容を変える自分のアカウントの画像を外す。画面には名前の先頭の 1 文字が出る。設定していなくても成功する。外した画像は戻せない(もう一度設定するには画像が要る)。実行前に利用者に確かめること。範囲 profile が要る。
エラー
エラー(RFC 9457 Problem Details)。機械的な分岐には code を使ってください。
失敗は application/problem+json(RFC 9457)で返します。形と code の意味は Framed! 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 として壊れているか、空です。
- unauthorized401API キーが無いか、有効ではありません
Authorization: Bearer <API キー>が無い、形が違う、存在しない、失効しているのいずれかです。どれに当たるかは返しません。- insufficient_scope403この資格情報には、その操作の範囲が付いていません
API キーには触れる範囲(
pages/data/files/files_write)、ユーザーAPIトークンには範囲(posts/comments/likes/profile)が付いています。範囲は発行するときに決まり、あとから増やせません。必要な範囲を選んで発行し直してください。- not_found404そのエンドポイントはありません
パスが間違っています。ベース URL に
/v1が含まれているか確かめてください。- post_not_found404その投稿はありません
パスの
post_idの投稿がありません。削除されたか、ID が間違っています。書き換え・削除では、他人の投稿を指したときもこれになります(ID の存在を他人に教えないため)。ほかの人の下書きも同じです。- comment_not_found404そのコメントはありません
パスの
comment_idのコメントがありません。削除されたか、ID が間違っています。他人のコメントを書き換え・削除しようとしたときもこれになります(ID の存在を他人に教えないため)。- method_not_allowed405そのメソッドは使えません
エンドポイントが受け付けるメソッドは
Allowヘッダに入っています。- handle_taken409そのハンドルはすでに使われています
ハンドルは大文字・小文字を区別せずに一意です(
Appleがいればappleは使えません)。別のハンドルを指定してください。- 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の照合用の番号を添えて問い合わせてください。
制限
呼び出しの回数
- トークンごとに 60 回/分。スペースの API キーとは別に数えます。
- 送信元の IP アドレスごとに 120 回/分。認証の前に数えるので、 トークンの無いリクエストも含みます(
api.framed.dogの 2 つの API で共通の窓です)。 - 1 分ごとに数え直します。上限を超えると
429(rate_limited)を返し、Retry-Afterに待つ秒数を入れます。 - 成功した応答には
RateLimit-Limit・RateLimit-Remaining・RateLimit-Resetが付きます。
大きさと規則
- リクエスト本文は 1,048,576 バイトまで。投稿の HTML は 262,144 文字まで(Markdown から組み立てた HTML にもかかります)、Markdown は 262,144 バイトまで、リブログの文は 200 文字まで、コメントは 500 文字まで。
GET /v1/postsと コメントの一覧は、上限の件数までを 返します(ページングはまだありません)。- ほかの人の投稿の一覧(タイムライン)は読めません。読めるのは自分の投稿の一覧と、ID を指定した 1 件です。
- 削除した投稿・コメントは元に戻せません。
OpenAPI
この API は OpenAPI 3.1.0 で定義しています。クライアントの生成や API ツールへの取り込みには、次の文書を使ってください(スペースのサイトを扱う API とは別の文書です)。