STORYAI API のエンドポイント、パラメータ、レスポンス、エラーの一覧です。APIキーの発行条件と管理方法は「API機能について」をご覧ください。
概要
作品の登録と分析、版の追加、再分析、分析結果の取得を、お客様のアプリケーションから実行できます。
ベースURL: https://api.storyai.app
認証
すべてのエンドポイントで、APIキーによる認証が必要です。リクエストヘッダーに次を含めてください。
Authorization: Bearer <YOUR_API_KEY>
- APIキーはブランドに結び付いています。APIで扱える作品は、キーを発行したブランドのすべての作品です。Web画面のプロジェクト権限(管理者・編集者・閲覧者)による絞り込みはかかりません。
- APIで登録した作品は、キーを発行した人が作成した作品として記録されます。
- 認証に失敗すると
403が返ります。ヘッダーが無いときはAPI key required.、キーが無効・削除済みのときはInvalid API key or associated account not found.です。 - キーはリクエストのたびに、発行時と同じ条件を満たしているか確認されます。条件を満たさなくなったキーは
403になり、reasonに理由が入ります。
reason | 原因 |
|---|---|
api_key_issuer_role_revoked | キーを発行した人が、ブランドのオーナー・システム管理者ではなくなった |
api_key_plan_not_allowed | ブランドのプランが、APIを利用できないプランに変わった |
発行者の役割やプランを元に戻すと、同じキーを再び使えます。使わせたくない場合は、オーナー・システム管理者がキーを削除してください(「API機能について」)。
- Web画面のログイン情報では
/api/v1/ak/...を呼び出せません。
エンドポイント一覧
| エンドポイント | メソッド | 説明 |
|---|---|---|
/api/v1/ak/work | POST | 作品を登録して分析する |
/api/v1/ak/work | GET | 作品一覧を取得する |
/api/v1/ak/work/:work_id | GET | 作品の情報と分析結果を取得する |
/api/v1/ak/work/:work_id/version | POST | 既存の作品に版を追加して分析する |
/api/v1/ak/work/:work_id/reanalyze | POST | 最新の版を再分析する |
| WebSocket(socket.io) | - | 分析状況の更新通知を受け取る |
作品の削除やタイトルの変更など、その他の操作はAPIにありません。Web画面で行ってください。
作品の登録と分析
POST /api/v1/ak/work
ファイルまたはテキストを送り、新しい作品を作って分析を始めます。分析は非同期で進みます。完了はWebSocketの通知か、GET /api/v1/ak/work/:work_id で確認してください。
リクエスト形式
multipart/form-data。送るファイルは合計 1000MB までです。超えると 413 になります。
パラメータ
| 名前 | 型 | 必須 | 説明 |
|---|---|---|---|
title | string | ○ | 作品のタイトル(1文字以上) |
has_copylight | string ("true") | ○ | 著作権の確認。"true" 固定で、それ以外は 400 |
analysis_type_id | number | ○ | 分析形式のID(下の表) |
category_id | number | ○ | カテゴリのID(下の表) |
genre_id | number | ○ | ジャンルのID(下の表) |
text | string | 本文を直接送る場合に使います。分析形式が「テキスト(13)」か「SNS投稿(10)」のときだけ使えます | |
posts | string(JSON配列) | SNS投稿を複数まとめて時系列で分析するときの本文一覧。例: '["1件目","2件目"]'。text と同時には指定できません | |
post_0, post_1, … | file | posts の各投稿に付けるメディア。番号は0始まりで、posts の並び順に対応します。同じ名前で複数送れます | |
description | string | 作品の説明 | |
project_id | number | 作品を入れるプロジェクトのID。自分のブランドのプロジェクト以外は 404 | |
reading_direction | string ("rl" / "lr") | 漫画を読む方向。既定は "rl"(右から左) | |
pdf_unit | string ("page" / "element") | PDFの読み取り単位。既定は "page"。page はページを画像として、element は文字要素を取り出して扱います | |
pdf_spread | string ("spread_rl" / "spread_lr") | PDFを見開きとして扱います。pdf_unit が "page" のときだけ有効です | |
remove_filler | string ("true" / "false") | 音声・動画の書き起こしから「えー」「あの」などのフィラーや言い直しを除きます。既定は false。音声・動画以外で true にすると 400 | |
extract_ocr | string ("true" / "false") | 動画の画面に映るスライドや文書の文字を読み取り、分析に含めます。既定は false。動画以外で true にすると 400 | |
user_analyze_prompt | string | 分析時にAIへ渡す追加の指示。Web画面の「ユーザープロンプト」と同じです | |
is_flame_analysis | string ("true" / "false") | 炎上リスク分析を行います。既定は false | |
thumbnail | file | 作品のサムネイル画像(png / jpg / jpeg / webp) | |
| 任意のキー | file | 分析するファイル。キー名は自由です(例: files)。分析形式に合った拡張子だけを受け付けます |
分析形式(analysis_type_id)と受け付けるファイル
| ID | 名称 | 拡張子 | text での直接入力 |
|---|---|---|---|
| 13 | テキスト | txt, doc, docx, pdf, md, epub | ○ |
| 14 | ドキュメント | doc, docx, pptx, pdf, md, epub | × |
| 8 | 画像(漫画・絵コンテなど) | zip, doc, docx, pdf, png, jpg, jpeg, gif, svg, webp | × |
| 7 | 動画 | mp4, mpeg, webm, avi | × |
| 12 | 音声 | wav, mp3, m4a, aac, flac, ogg | × |
| 10 | SNS投稿 | txt, png, jpg, jpeg, gif, webp, mp4, mov, zip | ○ |
| 4 | CSV / TSV 形式(ゲーム用の専用フォーマット) | csv, tsv, pdf | × |
ファイルとテキストの組み合わせ
text・posts・ファイルのどれも無いときは 400(テキストまたは少なくとも1つのファイルが必要です。)になります。- 複数のファイルや、テキストとファイルの併用ができるのは、画像(8)とSNS投稿(10)だけです。他の形式ではファイルを1つだけ送ってください。
- ZIPファイルは単独で送ります。ZIPと他のファイル、ZIPとテキストは一緒に送れません。
カテゴリ(category_id)
| ID | カテゴリ | ID | カテゴリ |
|---|---|---|---|
| 0 | あらすじ | 15 | |
| 1 | 筋書き | 16 | メールマガジン |
| 2 | シナリオ | 17 | ウェブトゥーン・4コママンガ |
| 4 | 小説 | 18 | 会議 |
| 6 | ブログ | 19 | スライド |
| 7 | ゲーム | 20 | 広告・宣伝 |
| 10 | 映像・動画 | 21 | パッケージ |
| 11 | 企業向けコンテンツ | 22 | 絵コンテ |
| 12 | マンガ | 23 | その他 |
| 13 | ウェブサイト | 24 | マーケティング・PR |
| 14 | X(旧Twitter) | 25 | 音楽・歌詞 |
| 26 | YouTube | ||
| 27 | TikTok |
ジャンル(genre_id)
エンタメ・物語系
| ID | ジャンル | ID | ジャンル |
|---|---|---|---|
| 0 | アクション | 21 | ドキュメンタリー |
| 1 | ホラー | 23 | エンターテインメント |
| 2 | SF | 67 | 映画・映像 |
| 3 | ミステリー | 68 | 演劇・舞台 |
| 4 | スリラー | 69 | 文学・書籍 |
| 5 | ドラマ | 71 | 絵本 |
| 6 | アドベンチャー | 74 | エッセイ・コラム |
| 7 | ファンタジー | 75 | 日記・ブログ |
| 8 | 犯罪 | 76 | ソーシャルゲーム |
| 9 | コメディ | 77 | ノベルゲーム |
| 10 | ロマンス | 78 | ウェブ小説 |
| 11 | ファミリー | 79 | ライトノベル |
| 12 | 伝記 | ||
| 13 | スポーツ | ||
| 14 | 音楽 | ||
| 15 | ミリタリー | ||
| 16 | ウエスタン | ||
| 17 | 歴史 | ||
| 18 | ミュージカル | ||
| 19 | フィルムノワール | ||
| 20 | 戦争 |
ビジネス・社会系
| ID | ジャンル | ID | ジャンル |
|---|---|---|---|
| 22 | 統合報告書 | 40 | 情報発信 |
| 26 | 海外・国際 | 42 | 政治 |
| 27 | エネルギー・環境 | 43 | 選挙 |
| 28 | チャリティ・社会貢献 | 44 | キャンペーン |
| 30 | 教育 | 52 | 宇宙 |
| 31 | 金融 | 72 | ビジネス・経済 |
| 35 | ステートメント | 73 | 自己啓発 |
| 36 | 採用 | 80 | 情報共有会議 |
| 39 | レポート | 81 | 意思決定会議 |
| 82 | アイデア出し会議 |
コンテンツ・メディア系
| ID | ジャンル | ID | ジャンル |
|---|---|---|---|
| 37 | ツイート | 45 | ストリーミング |
| 38 | コメント・レビュー | 83 | コミュニケーション |
| 41 | 自社商品・サービスの紹介 | 84 | メッセージ |
生活・文化系
| ID | ジャンル | ID | ジャンル |
|---|---|---|---|
| 24 | 不動産 | 55 | IT・テクノロジー |
| 25 | ウェルネス | 56 | AI・人工知能 |
| 29 | 住宅・暮らし | 57 | ブロックチェーン・暗号資産 |
| 32 | ヘルスケア | 58 | ファッション |
| 33 | ライフスタイル | 59 | コスメ・美容 |
| 34 | イベント | 60 | 食品・飲料 |
| 46 | リゾート | 61 | 飲食店 |
| 47 | 旅行 | 62 | 料理・レシピ |
| 48 | 遊技機・パチンコ・パチスロ | 63 | ペット |
| 49 | ウェディング | 64 | 趣味・娯楽 |
| 50 | 自動車 | 65 | アート・デザイン |
| 51 | 航空・鉄道 | 70 | 医療・医者・福祉 |
| 54 | アプリ | 99 | その他 |
表にないIDを指定すると 400(不正なジャンルIDです。 など)になります。
リクエスト例
curl
curl -X POST https://api.storyai.app/api/v1/ak/work \
-H "Authorization: Bearer YOUR_API_KEY" \
-F "title=サンプル小説" \
-F "description=テスト用の小説です" \
-F "analysis_type_id=13" \
-F "category_id=4" \
-F "genre_id=7" \
-F "has_copylight=true" \
-F "files=@story.txt"
Python
import requests
url = "https://api.storyai.app/api/v1/ak/work"
headers = {"Authorization": "Bearer YOUR_API_KEY"}
data = {
"title": "サンプル小説",
"description": "テスト用の小説です",
"analysis_type_id": 13,
"category_id": 4,
"genre_id": 7,
"has_copylight": "true",
}
files = {"files": open("story.txt", "rb")}
response = requests.post(url, headers=headers, data=data, files=files)
print(response.json())
TypeScript
const formData = new FormData()
formData.append('title', 'サンプル小説')
formData.append('description', 'テスト用の小説です')
formData.append('analysis_type_id', '13')
formData.append('category_id', '4')
formData.append('genre_id', '7')
formData.append('has_copylight', 'true')
const fileInput = document.getElementById('file') as HTMLInputElement
if (fileInput.files && fileInput.files[0]) {
formData.append('files', fileInput.files[0])
}
fetch('https://api.storyai.app/api/v1/ak/work', {
method: 'POST',
headers: { Authorization: 'Bearer YOUR_API_KEY' },
body: formData,
})
.then((response) => response.json())
.then((data) => console.log(data))
音声を、フィラーを除いて分析する例(curl)
curl -X POST https://api.storyai.app/api/v1/ak/work \
-H "Authorization: Bearer YOUR_API_KEY" \
-F "title=定例会議の録音" \
-F "analysis_type_id=12" \
-F "category_id=18" \
-F "genre_id=80" \
-F "has_copylight=true" \
-F "remove_filler=true" \
-F "files=@meeting.m4a"
SNS投稿を複数まとめて分析する例(curl)
curl -X POST https://api.storyai.app/api/v1/ak/work \
-H "Authorization: Bearer YOUR_API_KEY" \
-F "title=新商品キャンペーン投稿" \
-F "analysis_type_id=10" \
-F "category_id=14" \
-F "genre_id=37" \
-F "has_copylight=true" \
-F 'posts=["1件目の投稿本文","2件目の投稿本文","3件目の投稿本文"]' \
-F "post_0=@image_for_post1.png" \
-F "post_2=@video_for_post3.mp4"
レスポンス例(200 OK)
{
"id": 123,
"title": "サンプル小説",
"is_flame_analysis": false,
"work_versions": [
{
"id": 456,
"created_at": "2026-06-10T10:00:00.000Z",
"user": { "id": 1, "name": "ユーザー名" }
}
],
"url": "https://storyai.app/your-brand/works/123/detail"
}
url はWeb画面の作品ページです。この時点では、まだ分析結果はありません。
エラー
- 400: 必須項目の不足、表にないID、対応していない拡張子、組み合わせのルール違反、著作権の未確認。メッセージは
入力値が不正です: {項目}: {内容}の形です - 403: APIキーが無い・無効、またはキーの利用条件を満たさなくなった(上の「認証」を参照)
- 404:
project_idのプロジェクトが無い、または他のブランドのもの - 413: ファイルが合計1000MBを超えた(
reason:upload_size_limit_exceeded) - 429: 今月の分析回数の上限に達した(
今月の解析上限に達しました。) - 500: サーバー内部のエラー
作品一覧の取得
GET /api/v1/ak/work
APIキーのブランドに属する作品の一覧を取得します。
クエリパラメータ
| 名前 | 型 | 必須 | 既定値 | 説明 |
|---|---|---|---|---|
limit | number | 10 | 1ページの件数(1〜100) | |
page | number | 1 | ページ番号 | |
order_by | string | updated_at | 並べ替えの基準(id / created_at / updated_at) | |
order_direction | string | desc | 昇順・降順(asc / desc) | |
search | string | タイトルの部分一致で絞り込む。日本語はURLエンコードして送ります | ||
project_id | number | 指定したプロジェクトの作品だけを取得する |
リクエスト例
curl -G "https://api.storyai.app/api/v1/ak/work" \
-H "Authorization: Bearer YOUR_API_KEY" \
--data-urlencode "limit=20" \
--data-urlencode "order_by=created_at" \
--data-urlencode "search=物語"
レスポンス例(200 OK)
{
"count": 42,
"works": [
{
"id": 123,
"title": "サンプル小説",
"analysis_type_id": 13,
"category_id": 4,
"genre_id": 7,
"last_updated_by": { "id": 1, "name": "ユーザー名", "image": null },
"work_versions": [
{
"id": 456,
"created_at": "2026-06-10T10:00:00.000Z",
"is_standalone_analysis": false,
"user": { "id": 1, "name": "ユーザー名", "image": null }
}
],
"url": "https://storyai.app/your-brand/works/123/detail"
}
]
}
countは条件に合う作品の総数です。ページ送りに使ってください。work_versionsは新しい版から順に並びます。版ごとの分析状況は含まれません。完了したかどうかはGET /api/v1/ak/work/:work_idかWebSocketの通知で確かめてください。
作品の情報と分析結果の取得
GET /api/v1/ak/work/:work_id
作品の情報と分析結果を取得します。
パスパラメータ
| 名前 | 型 | 必須 | 説明 |
|---|---|---|---|
work_id | number | ○ | 作品のID |
クエリパラメータ
| 名前 | 型 | 必須 | 説明 |
|---|---|---|---|
work_version_id | number | 取得する版のID。省略すると最新の版です | |
include | string | 追加で取得するデータをカンマ区切りで指定します(下の表)。知らないキーを指定すると 400 |
include で指定できるキーは次のとおりです。
| 種類 | キー |
|---|---|
| 分析データ | emotion_analysis, co_occurrence_analysis, correspondence_analysis, wordcloud_analysis, network_analysis, timeline_analysis |
| グラフ画像のURL | emotion_chart_image(感情曲線), co_occurrence_chart_image(共起ネットワーク), character_network_images(人物相関図) |
- 分析データは
キー:項目1:項目2の形で、必要な項目だけに絞れます。入れ子の項目は.でつなぎます(例:emotion_analysis:summary:scores.final_story_evaluation)。 includeを指定しないと、感情の時系列データなど大きな結果は返りません。必要なものだけを指定してください。- グラフ画像は
{ "url", "expires_in", "content_type" }の形で返ります。urlは1時間だけ有効です。画像がまだ作られていない作品ではnullになります。 character_network_imagesは{ "overall": 全体図, "timeline": [期間ごとの図] }の形です。
リクエスト例
curl -X GET "https://api.storyai.app/api/v1/ak/work/123?work_version_id=456&include=emotion_analysis:summary,emotion_chart_image" \
-H "Authorization: Bearer YOUR_API_KEY"
レスポンス例(200 OK)
{
"id": 123,
"work_version_id": 456,
"project": { "id": 1, "name": "プロジェクト名" },
"user": { "id": 1, "name": "ユーザー名" },
"title": "サンプル小説",
"description": "テスト用の小説です",
"thumbnail": "https://...(1時間有効のURL)",
"analysis_type_id": 13,
"category_id": 4,
"genre_id": 7,
"comment": "版のコメント",
"is_diff": false,
"is_standalone_analysis": false,
"created_at": "2026-06-10T10:00:00.000Z",
"updated_at": "2026-06-10T10:20:00.000Z",
"sns_metrics": null,
"work_analysis_result": {
"ai_summary": "作品全体の要約…",
"final_evaluation_summary": "総合評価の説明…",
"total_point": 72,
"rank": "B",
"indicators": [
{
"key": "…",
"group": "…",
"status": "…",
"value": 0.81,
"percentage": 81,
"summary": "…"
}
]
},
"additional_tools_status": {
"status": 2,
"tools": { "word_cloud": 2, "cooccurrence": 2, "correspondence": 2, "network": 2 }
},
"url": "https://storyai.app/your-brand/works/123/detail",
"emotion_analysis": { "summary": "…" },
"emotion_chart_image": {
"url": "https://...",
"expires_in": 3600,
"content_type": "image/svg+xml"
}
}
work_analysis_resultは、分析が終わるまでnullです。additional_tools_statusは追加の分析(ワードクラウド・共起・コレスポンデンス・ネットワーク)の状況です。値は0未分析、1分析中、2完了、3失敗です。includeで指定した結果は同じ名前のキーで追加されます。まだ作られていないときはnullです。
エラー
- 400:
includeに知らないキーを指定した - 404: 作品が無い、または他のブランドの作品(
Work does not exist.)。指定した版が無い(Work Version does not exist.)
版の追加
POST /api/v1/ak/work/:work_id/version
既存の作品に新しい版を追加して分析します。分析形式・カテゴリ・ジャンルは元の作品のものを引き継ぎます。Web画面の「新しい版を追加」と同じ操作で、追加した版は「版の比較」で見比べられます。
リクエスト形式
multipart/form-data(ファイルは合計1000MBまで。超えると 413)。ファイルとテキストの組み合わせのルールは作品の登録と同じです。
パラメータ
| 名前 | 型 | 必須 | 説明 |
|---|---|---|---|
has_copylight | string ("true") | ○ | 著作権の確認("true" 固定) |
text | string | 本文(テキスト・SNS投稿の形式だけ) | |
comment | string | この版のコメント。Web画面の版の一覧に表示されます | |
reading_direction / pdf_unit / pdf_spread / remove_filler / extract_ocr | 作品の登録と同じです | ||
| 任意のキー | file | 分析するファイル |
リクエスト例
curl -X POST https://api.storyai.app/api/v1/ak/work/123/version \
-H "Authorization: Bearer YOUR_API_KEY" \
-F "has_copylight=true" \
-F "comment=第2稿。中盤の展開を修正" \
-F "files=@story_v2.txt"
レスポンス例(200 OK)
{
"id": 123,
"title": "サンプル小説",
"work_version_id": 457,
"work_version": {
"id": 457,
"created_at": "2026-06-11T09:00:00.000Z",
"user": { "id": 1, "name": "ユーザー名" }
},
"analysis_type_id": 13,
"category_id": 4,
"genre_id": 7,
"url": "https://storyai.app/your-brand/works/123/detail"
}
エラー
- 400: 入力値やファイル形式が正しくない
- 404: 作品が無い、または他のブランドの作品
- 413: ファイルが合計1000MBを超えた
- 429: 今月の分析回数の上限に達した
再分析
POST /api/v1/ak/work/:work_id/reanalyze
作品の最新の版をもう一度分析します。分析に失敗したときや、古い結果を今の仕組みで分析し直したいときに使います。版は増えず、結果は上書きされます。分析回数は使いません。
リクエスト形式
application/json
| 名前 | 型 | 必須 | 説明 |
|---|---|---|---|
only_nlp_analysis | boolean | ○ | true: 追加自然言語分析(ワードクラウド・共起・コレスポンデンス)だけをやり直します。false: 感情分析を含めてすべてやり直します |
Web画面の「再分析する」で「追加自然言語分析のみを再分析する」にチェックを入れた操作が true にあたります。
リクエスト例
curl -X POST https://api.storyai.app/api/v1/ak/work/123/reanalyze \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"only_nlp_analysis": false}'
レスポンス例(200 OK)
{ "message": "Re-analysis has been requested successfully." }
エラー
- 400:
only_nlp_analysisが真偽値でない - 404: 作品か最新の版が無い、または他のブランドの作品
分析状況の通知(WebSocket)
分析の完了や失敗を、問い合わせを繰り返さずに受け取れます。socket.io-client でベースURLに接続します。APIキーを渡せば、ほかのヘッダーは要りません。
import { io } from 'socket.io-client'
const socket = io('https://api.storyai.app', {
auth: { apiKey: 'YOUR_API_KEY' },
})
socket.on('notification', (data) => {
if (data.type === 'ANALYSIS_STATUS_UPDATE') {
// data.id: 版(work_version)のID
// data.status: 1 分析中 / 2 完了 / 3 失敗
console.log(`WorkVersion ${data.id} status: ${data.status}`)
}
})
- 接続時にも、キーの利用条件(発行者の役割・ブランドのプラン)を確認します。満たさない場合は接続が拒否され、
connect_errorのerr.data.reasonにapi_key_issuer_role_revokedかapi_key_plan_not_allowedが入ります。接続中に条件が変わった場合は、次に接続するときから拒否されます。 - 通知が届くのは、キーを発行した人がWeb画面で見られる作品だけです。APIで登録した作品は発行した人の作品になるため、通知が届きます。
- 通知に含まれるのは版のIDと状況だけで、本文は含まれません。
- 完了(
status: 2)を受け取ったら、GET /api/v1/ak/work/:work_idで結果を取得してください。
エラーレスポンスの形
エラーのときは次の形で返ります。
{
"error": "BADREQUEST",
"message": "入力値が不正です: title: タイトルは必須です。"
}
| ステータス | error | 主な原因 |
|---|---|---|
| 400 | BADREQUEST / VALIDATION_ERROR | パラメータの誤り、対応していないファイル、組み合わせのルール違反 |
| 403 | FORBIDDEN | APIキーが無い・無効・削除済み。発行者の役割やブランドのプランが利用条件を満たさない(reason 付き) |
| 404 | NOTFOUND | 作品・版・プロジェクトが無い、または他のブランドのもの |
| 413 | PAYLOADTOOLARGE | ファイルが合計1000MBを超えた(reason: upload_size_limit_exceeded) |
| 429 | TOOMANYREQUESTS | 今月の分析回数の上限(今月の解析上限に達しました。) |
| 500 | INTERNAL_SERVER_ERROR | サーバー内部のエラー |
413 のレスポンス例:
{
"error": "PAYLOADTOOLARGE",
"message": "Uploaded file exceeds the size limit.",
"reason": "upload_size_limit_exceeded"
}
利用の制限
- 月間の分析回数: 作品の登録と版の追加で1回ずつ使います。Web画面での分析と同じ回数(ブランド全体で共通)です。上限に達すると
429になります。再分析と結果の取得では使いません。上限は契約内容によって異なります。 - ファイルサイズ: 1回のリクエストで合計1000MBまでです。超えると
413になります。 - 分析にかかる時間: 分析は非同期で進みます。たくさんまとめて送ると、完了まで時間がかかります。
お問い合わせ
APIについてのご質問は、左メニューの「お問い合わせ」からご連絡ください。