Love API Reference
ゲーム世界観ドキュメント管理システム「Love」のREST API。
基本情報
- Base URL:
https://love.stagbeetle.group/api/v1 - Format: JSON (UTF-8必須、Shift_JISは400で拒否)
- レスポンス形式:
{"data": ...}(204は空) - エラー形式:
{"error": "message"} - 認証: なし(IPアロー方式、現在は全許可)
- 姉妹システム: Fudo(
https://box.stagbeetle.group/)と同じVPS上で稼働、別バイナリ
概念
Title (タイトル) ─┬─ Worldview Pages (世界観ページ)
├─ Chronology Events (年代史)
├─ Glossary Terms (用語集)
├─ Characters (登場人物) ─┬─ Relationships (相関)
│ └─ History Events (人物史)
└─ [Phase 4: Songs / BGM / SE]
各タイトルが独立した世界観を持ち、配下に複数カテゴリのデータを管理する。
Titles (タイトル)
| Method | Path | Description | Body |
|---|---|---|---|
| GET | /titles |
タイトル一覧 | — |
| POST | /titles |
タイトル作成 | {slug, name, description?, cover_image_url?} |
| GET | /titles/{slug} |
タイトル取得 | — |
| PUT | /titles/{slug} |
タイトル更新 | {name, description, cover_image_url} |
| DELETE | /titles/{slug} |
タイトル削除(カスケード削除) | — |
Title オブジェクト
{
"id": 1,
"slug": "test-game",
"name": "テストゲーム",
"description": "テスト用タイトル",
"cover_image_url": "/uploads/covers/abc.png",
"sort_order": 0,
"created_at": "2026-04-09 02:57:40",
"updated_at": "2026-04-09 02:57:40"
}
Worldview (世界観)
タイトル配下の世界観ページ群。Markdownで自由記述。
| Method | Path | Description | Body |
|---|---|---|---|
| GET | /titles/{slug}/worldview |
ページ一覧 | — |
| POST | /titles/{slug}/worldview |
ページ作成 | {slug, name, content?} |
| PUT | /titles/{slug}/worldview/{pageId} |
ページ更新 | {name, content} |
| DELETE | /titles/{slug}/worldview/{pageId} |
ページ削除 | — |
WorldviewPage オブジェクト
{
"id": 1,
"title_id": 1,
"slug": "geography",
"name": "地理",
"content": "# 大陸\n\n広大な大陸が広がっている...",
"sort_order": 0,
"created_at": "...",
"updated_at": "..."
}
Chronology (年代史)
時系列イベント。架空の暦に対応するため year/month/day はすべて文字列。
| Method | Path | Description | Body |
|---|---|---|---|
| GET | /titles/{slug}/chronology |
イベント一覧 | — |
| POST | /titles/{slug}/chronology |
イベント作成 | {era?, year?, month?, day?, event_name, description?, sort_order?} |
| PUT | /titles/{slug}/chronology/{eventId} |
イベント更新 | 同上 |
| DELETE | /titles/{slug}/chronology/{eventId} |
イベント削除 | — |
ChronologyEvent オブジェクト
{
"id": 1,
"title_id": 1,
"era": "第一紀",
"year": "100",
"month": "3",
"day": "15",
"event_name": "王国建国",
"description": "初代国王が王国を建てる",
"sort_order": 1,
"created_at": "...",
"updated_at": "..."
}
Glossary (用語集)
| Method | Path | Description | Body |
|---|---|---|---|
| GET | /titles/{slug}/glossary |
用語一覧 | — |
| POST | /titles/{slug}/glossary |
用語作成 | {term, reading?, category?, description?} |
| PUT | /titles/{slug}/glossary/{termId} |
用語更新 | 同上 |
| DELETE | /titles/{slug}/glossary/{termId} |
用語削除 | — |
GlossaryTerm オブジェクト
{
"id": 1,
"title_id": 1,
"term": "マナ",
"reading": "まな",
"category": "魔法",
"description": "魔法エネルギーの源",
"created_at": "...",
"updated_at": "..."
}
Characters (登場人物)
| Method | Path | Description | Body |
|---|---|---|---|
| GET | /titles/{slug}/characters |
キャラ一覧 | — |
| POST | /titles/{slug}/characters |
キャラ作成 | Character 全フィールド (slug, name 必須) |
| PUT | /titles/{slug}/characters/{characterId} |
キャラ更新 | Character 全フィールド |
| DELETE | /titles/{slug}/characters/{characterId} |
キャラ削除(相関・人物史もカスケード) | — |
Character オブジェクト
{
"id": 1,
"title_id": 1,
"slug": "hero",
"name": "勇者アルト",
"name_kana": "ゆうしゃあると",
"role": "主人公",
"age": "17",
"gender": "男",
"affiliation": "冒険者ギルド",
"occupation": "騎士",
"avatar_url": "/uploads/characters/abc123.png",
"description": "## 背景\n小さな村出身の若き騎士...",
"sort_order": 0,
"created_at": "...",
"updated_at": "..."
}
description は Markdown 対応。
Character Relationships (相関関係)
| Method | Path | Description | Body |
|---|---|---|---|
| GET | /titles/{slug}/character-relationships |
タイトル内全相関一覧(from/to名前付き) | — |
| POST | /titles/{slug}/character-relationships |
相関作成 | {from_character_id, to_character_id, relation_type, description?} |
| PUT | /titles/{slug}/character-relationships/{relId} |
相関更新 | {relation_type, description} |
| DELETE | /titles/{slug}/character-relationships/{relId} |
相関削除 | — |
CharacterRelationship オブジェクト
{
"id": 1,
"title_id": 1,
"from_character_id": 1,
"to_character_id": 2,
"relation_type": "宿敵",
"description": "幼少期からのライバル",
"from_name": "勇者アルト",
"from_slug": "hero",
"to_name": "魔王ザード",
"to_slug": "villain",
"created_at": "..."
}
from_name, from_slug, to_name, to_slug はGET時のみ含まれるJOIN結果。
Character History Events (人物史)
各キャラクターの人生イベント。
| Method | Path | Description | Body |
|---|---|---|---|
| GET | /titles/{slug}/characters/{characterId}/history |
人物史一覧 | — |
| POST | /titles/{slug}/characters/{characterId}/history |
イベント作成 | {era?, year?, month?, day?, event_name, description?, sort_order?} |
| PUT | /titles/{slug}/characters/{characterId}/history/{eventId} |
イベント更新 | 同上 |
| DELETE | /titles/{slug}/characters/{characterId}/history/{eventId} |
イベント削除 | — |
CharacterHistoryEvent オブジェクト
ChronologyEvent と同じ構造で character_id フィールドを持つ。
Image Upload (画像アップロード)
| Method | Path | Description | Body |
|---|---|---|---|
| POST | /upload/image?dir={subdir} |
画像アップロード | multipart/form-data (file フィールド) |
- 上限: 10MB
- 対応形式: jpg / jpeg / png / gif / webp
dirクエリ: 保存サブディレクトリ(英数字・ハイフン・アンダースコアのみ)。例:characters,covers- 戻り値:
{"data": {"url": "/uploads/{dir}/{random}.ext"}} - アップロード後のURLはそのままブラウザでアクセス可能(
https://love.stagbeetle.group/uploads/...)
エラーレスポンス
{"error": "title not found"}
| Code | 意味 |
|---|---|
| 200 | 取得成功 |
| 201 | 作成成功 |
| 204 | 更新/削除成功(ボディ無し) |
| 400 | リクエスト不正(必須フィールド欠落、UTF-8でない等) |
| 404 | リソース未発見 |
| 500 | サーバーエラー |
使用例
タイトル作成 → キャラ作成 → 相関設定の流れ
# 1. タイトル作成
curl -X POST https://love.stagbeetle.group/api/v1/titles \
-H 'Content-Type: application/json' \
-d '{"slug":"my-game","name":"My RPG","description":"自作RPG"}'
# 2. キャラ2人作成
curl -X POST https://love.stagbeetle.group/api/v1/titles/my-game/characters \
-H 'Content-Type: application/json' \
-d '{"slug":"hero","name":"勇者","role":"主人公","age":"17"}'
curl -X POST https://love.stagbeetle.group/api/v1/titles/my-game/characters \
-H 'Content-Type: application/json' \
-d '{"slug":"villain","name":"魔王","role":"敵"}'
# 3. 相関設定
curl -X POST https://love.stagbeetle.group/api/v1/titles/my-game/character-relationships \
-H 'Content-Type: application/json' \
-d '{"from_character_id":1,"to_character_id":2,"relation_type":"宿敵"}'
# 4. 用語追加
curl -X POST https://love.stagbeetle.group/api/v1/titles/my-game/glossary \
-H 'Content-Type: application/json' \
-d '{"term":"魔法","reading":"まほう","category":"基本","description":"マナを使った技術"}'
画像アップロード → キャラに設定
# 1. 画像アップロード
curl -X POST 'https://love.stagbeetle.group/api/v1/upload/image?dir=characters' \
-F 'file=@hero.png'
# レスポンス: {"data":{"url":"/uploads/characters/abc123.png"}}
# 2. キャラ更新でavatar_urlに設定
curl -X PUT https://love.stagbeetle.group/api/v1/titles/my-game/characters/1 \
-H 'Content-Type: application/json' \
-d '{"slug":"hero","name":"勇者","avatar_url":"/uploads/characters/abc123.png"}'
注意事項
UTF-8必須
リクエストボディは厳密にUTF-8でないと拒否される(400エラー)。Windows等のシェルから日本語を送る場合は文字コードに注意。
文字列フィールドの空値
PUT時、未指定フィールドは空文字で上書きされる。部分更新は未対応(全フィールドを送る必要あり)。
slug の制約
URL-safe な英数字とハイフンを推奨。重複は同一title_id内で不可(UNIQUE制約)。
ファイルパス
- アップロードされたファイルは
/opt/love/uploads/{dir}/に保存 - DBには相対URL
/uploads/{dir}/{filename}で記録 - ブラウザからは
https://love.stagbeetle.group/uploads/...でアクセス可能 - タイトル削除時、関連ファイルは自動削除されない(手動削除が必要)