配信API と 記事JSON
投入する形式は1つだけです。あとは配信先の設定に従って自動で出し分けます。 対話的に試す場合は Swagger UI / ReDoc をご利用ください。
認証
環境変数 AUTOPOST_API_KEY を設定すると、配信系のエンドポイントが X-API-Key ヘッダで保護されます。
未設定の場合は認証なしで動くため、ローカル開発以外では必ず設定してください。
curl -X POST https://aisnsiodev-seobuilder.hf.space/v1/articles \
-H "X-API-Key: $AUTOPOST_API_KEY" \
-H "Content-Type: application/json" \
-d @article.json
エンドポイント
| メソッド / パス | 説明 | 認証 |
|---|---|---|
GET /v1/health | 稼働確認とバージョン、登録クライアント数 | 不要 |
GET /v1/platforms | 対応媒体と能力(canonical可否・予約可否・本文形式) | 不要 |
GET /v1/features | 機能カタログ 931項目と実装状況 | 不要 |
GET /v1/library | 記事ライブラリの一覧 | 不要 |
GET /v1/library/{slug} | 記事1件の生JSON | 不要 |
GET /v1/clients | クライアント一覧(認証情報はマスクして返す) | 必要 |
POST /v1/clients | クライアントの登録・更新 | 必要 |
POST /v1/articles | 記事を配信する。?dry_run=true で送信せず内容だけ返す | 必要 |
GET /v1/jobs/{id} | 配信ジョブの結果 | 必要 |
PUT /v1/jobs/{id}/results | 手動投稿(note / Ameba)の公開URLを記録 | 必要 |
POST /v1/clients/{id}/line/broadcast | 任意のURLをLINE友だちへ配信 | 必要 |
SEO運用API
配信APIのほかに、記事診断・キーワード・順位・計測・ワークフロー・レポートのエンドポイントがあります。
参照系は認証不要、変更系は write / publish スコープを要求します。
| メソッド / パス | 説明 |
|---|---|
GET /v1/analyze/{slug} | 記事を診断する(タイトル長・キーワード配置・読みやすさ・出典・表記ゆれ・薬機法表現) |
GET /v1/schema/{slug} | Article / BreadcrumbList / FAQPage / HowTo のJSON-LDを生成する |
GET /v1/llmo/{slug} | AI検索に引用されやすいかを診断する |
GET /v1/write/suggest/{slug} | タイトル案・メタ説明・FAQ・alt・要約をまとめて出す |
POST /v1/write/draft | 本文を生成する(要 ANTHROPIC_API_KEY) |
GET / POST /v1/keywords | キーワード台帳。クラスタリング・カバレッジ・カニバリ検出つき |
GET / POST /v1/ranks | 順位の記録と分析(変動・競合比較・シェアオブボイス) |
POST /v1/events | 計測イベントを記録する(同意が無ければ保存しない) |
GET /v1/analytics | 流入チャネル・記事別・CTA位置別・KPI進捗 |
GET / POST /v1/workflow/{slug} | 下書き→レビュー→承認→公開の状態管理 |
GET / POST /v1/schedule | 予約公開・繰り返し・編集カレンダー |
POST /v1/delivery/retry/{job_id} | 失敗した配信先だけ再実行する |
POST /v1/delivery/withdraw | 配信を撤回する(下書き化できない媒体は手作業として返す) |
GET /v1/reports/{client} | 月次レポート(?fmt=html でそのまま共有できる形) |
GET /v1/integrations | 外部連携の設定状況(未設定は未設定と返す) |
GET / POST /v1/keys | スコープ付きAPIキーの発行・失効 |
GET /v1/features | 機能カタログ全項目と実装状況 |
記事を書く・畳む
記事を作るところから畳むところまでのエンドポイントです。全体像は運用の一周にあります。
| メソッド / パス | 説明 |
|---|---|
POST /v1/briefs | キーワードから制作指示書を作る(SERP・共起語・関連質問・自社記事・一次データを束ねる) |
GET /v1/briefs/{key}/markdown | 指示書をMarkdownで受け取る。書き手にそのまま渡せる |
POST /v1/briefs/{key}/check | 書き上がった原稿が指示書を満たしているか照合する |
POST /v1/articles/draft | 記事を新規作成する(保存前にスキーマ検証) |
PUT /v1/articles/draft/{slug} | 記事を保存する。直前の版を必ず控える |
POST /v1/articles/draft/review | 保存せずに今の内容を診断する(エディタが打鍵のたびに呼ぶ) |
GET /v1/articles/draft/{slug}/versions | 保存履歴(日時・メモ・文字数・診断スコア) |
GET /v1/articles/draft/{slug}/diff | 版どうしの差分。?from=3&to=5 |
POST /v1/articles/draft/{slug}/restore/{n} | 古い版に戻す。戻す前の状態も版として残る |
GET /v1/inventory | 全記事の棚卸し。7つの判断と、その理由を返す |
POST /v1/inventory/{slug}/decide | 仕分けに対する人の判断を記録する |
GET / POST /v1/glossary | 用語集。/extract で記事本文から候補を拾う |
POST /v1/glossary/autolink | 本文の用語を用語ページへリンクする(初出のみ) |
POST /v1/bulk | 一括操作。既定は dry-run、危険な操作は確認トークンを要求する |
GET /v1/import/sources | 取り込める形式(WordPress / RSS / JSON / Markdown) |
POST /v1/import | 既存記事を取り込む。既定は下見、apply:true で実行 |
GET /v1/technical/canonical | そのページが自分をどう名乗っているかを実際に取得して調べる(HTTPヘッダとHTMLの食い違い) |
POST /v1/contact | お問い合わせを受け取る。認証不要。保存してから CONTACT_TO へメールで通知する |
POST /v1/assistant | アシスタントに質問する。認証不要。自社データを含む回答には鍵かログインが要る |
POST /v1/quick/read | URLを読んで、下書き・画像候補・出せる先をまとめて返す |
POST /v1/quick/preview | 媒体ごとに、実際に出る文面と文字数を返す |
POST /v1/quick/post | 選んだ先に出す(公開デモは常にドライラン) |
POST /v1/tenants | クライアントを登録する(画面から。すぐに配信エンジンへ反映される) |
POST /v1/tenants/{id}/targets | 配信先を足す。足りない認証情報を名指しで返す |
PUT /v1/tenants/{id}/targets/{tid}/credentials | 認証情報を入れる(暗号化して保存。値は返らない) |
POST /v1/invites | 一度きりの招待リンクを作る(パスワードは本人が決める) |
POST /v1/bots | クライアントのボットを作る |
POST /v1/bots/{id}/sources | 学習させるページを足す(同じサイト内を最大30ページ辿る) |
POST /v1/bots/{id}/try | 公開する前に答えさせて確かめる |
GET /v1/b/{public_id} | 公開したボットの設定(訪問者向け・認証不要) |
POST /v1/b/{public_id}/ask | ボットに質問する(訪問者向け・認証不要) |
GET /v1/ops/durability | このホスティングでデータが残るかどうか |
POST /v1/ops/backup/cloud | いますぐ Space外へ退避する(管理者のみ) |
POST /v1/ops/cdn/purge | CDNのキャッシュを破棄する(管理者のみ) |
POST / GET /v1/billing/{client_id}/trial | 無料期間を始める / 残りを見る |
POST /v1/payments/{client_id}/portal | 支払い方法の変更・解約の窓口(Stripeへ送るだけ) |
POST /v1/gbp/{location_id}/reviews/fetch | 口コミをGoogleから取り込む |
POST /v1/gbp/{location_id}/reviews/{review_id}/reply | 口コミに返信する |
PATCH /v1/gbp/{location_id}/hours | 営業時間を更新する |
POST /v1/social/pinterest | 記事の画像をピンとして出す |
POST /v1/social/tiktok | 短尺動画を投稿する(動画のURLが要る) |
GET / PUT /v1/mentions/{client_id} | エゴサーチで監視する語 |
POST /v1/mentions/{client_id}/scan | 公開フィードから言及を拾う |
PUT /v1/schedule/{job_id}/time | 予約の実行時刻を変える |
GET / PUT /v1/cadence/{client_id} | 週に何本出すかと、その実績 |
GET /v1/entities | 社名・製品名の表記ゆれを洗い出す |
POST /v1/entities/definition | 引用されやすい定義文の雛形 |
GET /v1/enrich/podcast/episodes | 音声にした記事の一覧(配信は /podcast.xml) |
GET / PUT /v1/settings | プラットフォーム設定(管理者のみ。秘密の値は返らない) |
POST /v1/settings/test/{group} | 設定した接続を実際に試す(メール / AI / 通知) |
認可のしくみ
APIキーを1本も発行していない間は、AUTOPOST_API_KEY による共有鍵(それも未設定ならローカル開発として無認証)で動きます。
POST /v1/keys でキーを発行すると、以後はスコープによる判定に切り替わります。
いまどのモードで動いているかは GET /v1/security/status で必ず確認できます。
# 閲覧専用キーをクライアントに渡す
curl -X POST .../v1/keys -H "X-API-Key: $ADMIN" \
-d '{"name":"クライアント閲覧用","role":"viewer"}'
# 生のキーは発行時にしか返らない(保存しているのはハッシュのみ)
記事JSON
1本の記事を表す共通フォーマットです。必須は client_id / slug / title / body_markdown の4つだけです。
| 項目 | 説明 |
|---|---|
client_id | 配信設定を引くクライアントID |
slug | URL用の文字列。空白や / ? # & は使えません |
title / body_markdown | タイトルと本文(Markdown) |
excerpt | 要約。teaser・SNS短文・meta description に使われます |
tags / category | 媒体側の分類欄へ引き渡されます |
cta | LINE誘導CTA。省略するとクライアント設定から補完されます |
variants | 媒体別の別原稿。{"qiita": {"title": ..., "body_markdown": ...}} |
social | SNS別の投稿文。省略時は本文から自動生成 |
targets | この記事だけの配信先。省略時はクライアントの既定配信先 |
fallback | 別原稿が無い媒体の扱い。teaser(既定)/ skip / full |
publish_at / draft | 予約公開の日時 / 下書きとして置くか |
{
"client_id": "demo",
"slug": "ai-inquiry-automation-small-business-2026",
"title": "中小企業がAIで問い合わせ対応を自動化する手順【2026年版】",
"excerpt": "問い合わせ対応の7割はAIで一次対応できます。導入の順番・費用感・失敗しない設計を、実際の運用フローに沿って解説します。",
"body_markdown": "問い合わせ対応に追われて本業の時間が削られていませんか。この記事では、月商500万円規模の会社が **追加の人員なし** で一次対応を自動化した手順をそのまま公開します。\n\n## なぜ今、問い合わせ対応をAI化すべきか\n\n2026年時点で、LINEやWebフォーム経由の問い合わせのうち約7割は「営業時間」「料金」「対応エリア」など定型の質問です。ここをAIが即答するだけで、返信までの平均時間は数時間から数十秒に縮まります。\n\n## ステップ1:よくある質問を20個書き出す\n\n過去3か月の問い合わせを見返し、頻度順に20個だけ抜き出します。最初から網羅しようとしないことが成功のコツです。\n\n## ステップ2:LINE公式アカウントに一次対応を置く\n\n問い合わせ窓口をLINEに寄せると、AI応答・ステップ配信・予約導線をひとつにまとめられます。\n\n## ステップ3:人が対応すべき問い合わせだけ通知する\n\nAIが答えられない質問はスタッフのLINEグループへ転送。転送率は初月で15%前後、2か月目には10%を切るのが目安です。\n\n## 費用感と導入期間\n\n初期設定は2〜3週間、月額はツール費込みで数千円〜数万円のレンジに収まります。\n\n## まとめ\n\n完璧を目指さず、20問の一次対応から始めるのが最短ルートです。",
"tags": [
"AI活用",
"問い合わせ対応",
"LINE公式アカウント",
"業務効率化"
],
"category": "AI活用",
"cover_image_url": "https://example.com/images/ai-inquiry.jpg",
"cta": {
"line_url": "https://lin.ee/XXXXXXX",
"offer": "御社の問い合わせをAI化した場合の削減時間を無料で試算します",
"label": "LINEで無料試算を受け取る",
"positions": [
"middle",
"bottom"
]
},
"variants": {
"qiita": {
"title": "LINE Messaging API × LLMで問い合わせ一次対応Botを最小構成で作る",
"body_markdown": "## 構成\n\nWebhook → 関数 → LLM → 返信、の4段です。\n\n## 実装のポイント\n\n1. FAQ 20問をシステムプロンプトに入れる\n2. 確信度が低い場合は人へ転送するフラグを返させる\n3. 会話ログは個人情報を除いて保存する\n\n## まとめ\n\n最初は20問で十分です。",
"tags": [
"LINE",
"LLM",
"Python"
]
}
},
"social": {
"linkedin": "問い合わせ対応の7割は定型質問。AIで一次対応を自動化した中小企業の手順を公開しました。",
"x": "問い合わせ対応をAIで自動化する手順(2026年版)をまとめました。最初は「よくある質問20個」からで十分です。",
"line_broadcast": "【新着】問い合わせ対応をAIで自動化する手順を公開しました。まずは20問から。"
},
"publish_at": null,
"draft": false,
"fallback": "teaser"
}
クライアント設定
clients.yaml に配信先・認証情報・CTAの既定値をまとめます。認証情報は ${ENV_VAR} 記法で環境変数から読み込むため、
ファイルにトークンを直接書く必要はありません。${VAR:-default} で既定値も指定できます。
clients:
- id: demo
name: デモ:AI活用支援サービス
site_url: https://example.com
line_url: https://lin.ee/XXXXXXX
line_offer: 「AI集客の無料診断」をLINEで受け付け中
utm_campaign: demo_blog
default_targets: [wordpress:main, hatena:main, devto:main, note:main, line:main]
targets:
wordpress:main:
role: primary
credentials:
site_url: https://example.com
username: ${WP_USER}
app_password: ${WP_APP_PASSWORD}
options:
canonical_meta: rank_math_canonical_url
line:main:
credentials:
channel_access_token: ${LINE_CHANNEL_ACCESS_TOKEN}
options:
mode: broadcast
template: flex
CLI
python -m autopost platforms
python -m autopost validate article.json --clients clients.yaml
python -m autopost publish article.json --clients clients.yaml --dry-run
python -m autopost publish today/*.json --clients clients.yaml \
--targets wordpress:main,line:main
自分で動かす
pip install -e ".[test]"
python -m pytest
AUTOPOST_API_KEY=xxx AUTOPOST_CLIENTS=data/clients.yaml \
uvicorn seobuilder.app:app --port 7860
Dockerで動かす場合は docker build -t seobuilder . && docker run -p 7860:7860 --env-file .env seobuilder です。