mcpField
C
contentstudio

contentstudio

github.com/contentstudioioマーケティング・グロース6130 回インストール3 週間前に更新
リポジトリ

contentstudio について

CLI とホスト型 MCP サーバーを使ってソーシャルメディアを管理する ContentStudio スキルです。ワークスペース、アカウント、投稿、メディアを扱い、認証やワークスペース確認、公開などの変更前の安全確認を求めます。

主な機能

  1. 01ホスト型 ContentStudio MCP への接続
  2. 02ワークスペースとソーシャルアカウントの管理
  3. 03投稿とメディアの作成・管理
  4. 04一覧結果のページネーション処理
  5. 05変更前のドライラン

活用シーン

  1. 01ソーシャルメディア投稿の予約や管理
  2. 02ワークスペース別のアカウントとメディア確認
  3. 03公開や送信前の変更内容の確認

MCP 対応

アカウントの OAuth 認証を通じて、https://mcp.contentstudio.io/mcp のホスト型 ContentStudio MCP サーバーに接続します。利用可能な MCP ツールを優先し、対象外の作業や MCP ツールが使えない場合は CLI を使います。

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/contentstudioio/contentstudio-agent --skill contentstudio

インストール後、Claude Code で/contentstudioを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

.gitignore
mcp.json
LICENSE
package.json
CHANGELOG.md
README.md
package-lock.json
.claude-plugin/
marketplace.json
plugin.json
.cursor-plugin/
plugin.json
.github/workflows/
check-skill-sync.yml
.grok-plugin/
plugin.json
scripts/
verify-analytics.sh
src/
cliCtx.ts
api.ts
config.ts
src/commands/
aiVideo.ts
analytics.ts
approvalWorkflows.ts
auth.ts
analyticsReports.ts
comments.ts
connect.ts
facebook.ts
contentCategories.ts
crud.ts
lookups.ts
plannerShareLinks.ts
media.ts
scheduling.ts

詳細

ホスト型 MCP サーバー(Cursor、Grok Bot、Grok Build プラグイン)

このスキルをプラグインとしてインストールすると、ホスト型 ContentStudio MCP サーバー https://mcp.contentstudio.io/mcp にも接続します。初回利用時に、ユーザーは OAuth を通じて ContentStudio アカウントにサインインします。API キーは必要ありません。

ContentStudio MCP ツール(たとえば fetch_workspaces、fetch_posts、create_post)が利用可能な場合は、まずそれらを使用してください。以下の CLI は、MCP ツールが接続されていない場合、または MCP ツールでは対応できないタスクに限って使用してください。投稿の公開、削除、承認を行うツールを実行する前に、何が行われるかをユーザーに示し、確認を待ってください。

ContentStudio CLI が存在しない場合はインストールする

npm install -g contentstudio-cli
# or
pnpm install -g contentstudio-cli

npm リリース:https://www.npmjs.com/package/contentstudio-cli contentstudio-agent GitHub:https://github.com/contentstudioio/contentstudio-agent contentstudio API ドキュメント:https://api.contentstudio.io/api-docs 公式ウェブサイト:https://contentstudio.io


プロパティ値
namecontentstudio
descriptionContentStudio パブリック API を介して投稿をスケジュールし、メディア/アカウントを管理するソーシャルメディア自動化 CLI
allowed-toolsBash(contentstudio:*)

⚠️ 認証が必要です

contentstudio CLI コマンドを実行する前に、必ず認証してください。 有効な API キーがない場合、すべてのコマンドは失敗します。

ほかの操作を行う前に、認証状況を確認してください。

contentstudio auth:status

has_api_key が false の場合は、次のいずれかの方法で認証してください。ユーザーは ContentStudio Dashboard → Settings → API Keys からキーを生成できます。

  1. API キー(対話形式) — キーを CLI の設定ファイルに保存します。
contentstudio auth:login --api-key cs_...
  1. 環境変数(ヘッドレス/エージェントのランタイム) — CLI は環境から CONTENTSTUDIO_API_KEY を読み込み、設定ファイルよりも優先します。
export CONTENTSTUDIO_API_KEY=cs_...

ヘッドレス環境へのデプロイに関する注意(OpenClaw、CI、デーモン): シェルでの export はサービスプロセスに引き継がれません。エージェントの実際の環境に CONTENTSTUDIO_API_KEY を設定してください。たとえば、systemd の Environment=(systemctl edit)、EnvironmentFile=、または Docker の -e/Compose の environment: を使用してから、サービスを再起動します。宣言された要件(たとえば OpenClaw の requires.env)に基づいて動作を制限するランタイムは、この変数がプロセス環境に設定されるまでブロックされたままになります。

次に、ワークスペースが選択されていることを確認してください。

contentstudio --json workspaces:current

active_workspace_id が null の場合は、ワークスペースを一覧表示して、ユーザーに選択してもらってください。

contentstudio --json workspaces:list
contentstudio workspaces:use <workspace_id>

エージェントの実行ルール

  • 安定して解析可能な出力を得るため、サブコマンドの前には必ず --json を指定してください。
  • レスポンスの形式:
    • 成功時:{"ok": true, "data": <payload>, "pagination"?: {...}}
    • エラー時:{"ok": false, "error": {"type": "<ErrorType>", "message": "...", "http_status": <int>, "hint": "..."}}
  • エラー時の 終了コードは 0 以外です。returncode と ok の両方を確認してください。
  • 標準出力のみを解析してください。ユーザー向けのメッセージは標準エラー出力に送られます。
  • 投稿/コメント/メディアに対する変更操作を行う前に、まず --dry-run を付けて実行し、ペイロードが正しいことを確認してください。--dry-run では API にアクセスしません。
  • 「共有リンク」は意味が曖昧です。どちらを指すのか確認してください。 この名称は、互いに無関係な 2 つの機能に使われています。クライアントとスケジュール済み 投稿 を共有する機能(コメント/承認用)と、公開中の 分析ダッシュボード を共有する機能です。この API から利用できるのは前者のみで、planner-share-links:* として提供されています。ダッシュボードの共有はウェブアプリ専用です。ユーザーがどちらを指しているか明言していない場合は、実行前に確認してください。CLI がたまたま対応している方だと決めつけないでください。詳しい説明は Planner share links の囲み内に記載されています。
変更を伴う操作の前に対象ワークスペースを確認する

CLI は、アクティブなワークスペース(workspaces:use で設定されたワークスペース)をデフォルトで暗黙的に使用します。このデフォルトは、読み取り専用の呼び出し(workspaces:list、accounts:list、posts:list、media:list など)なら問題ありません。アクティブなワークスペースをそのまま使用してください。

ただし、変更を伴う操作(accounts:connect、accounts:add-bluesky、accounts:add-facebook-group、accounts:remove、posts:create、posts:update、posts:delete、posts:approve、posts:reject、comments:add、media:upload、workspaces:update、workspaces:delete、labels:create、labels:update、labels:delete、campaigns:create、campaigns:update、campaigns:delete、team:add、team:update、team:remove、categories:create、categories:update、categories:delete、categories:shuffle、category-slots:create、category-slots:update、category-slots:delete、approval-workflows:create、approval-workflows:update、approval-workflows:delete、approval-workflows:duplicate、approval-workflows:set-default、approval-workflows:remove-default、planner-share-links:create、planner-share-links:update、planner-share-links:delete、planner-share-links:send-invitations、すべての inbox:* 書き込み(inbox:send、inbox:comment-add、inbox:comment-delete、inbox:review-reply、inbox:update、inbox:tag-*、…)、および ai-video:generate/ai-video:run-tool/ai-video:cancel-job)を行う場合は、ワークスペースがすでにアクティブでも、必ず最初にユーザーに確認してください。変更対象がアクティブなワークスペースだと決めつけないでください。

AI 動画の生成にはクレジットがかかります。 ai-video:generate と ai-video:run-tool は、--dry-run なしで呼び出した時点で、実際の(課金対象となる)ジョブを送信します。フラグが対応している場合は、先に ai-video:estimate を実行し、見積もりと費用をユーザーに提示したうえで、実行前に実際の呼び出しを --dry-run してください。ai-video:cancel-job も、すでに消費された作業の分が課金される場合があります。確認なしにユーザーに代わってジョブをキャンセルしないでください。

Inbox への書き込みは顧客に直接表示されます。 inbox:send、inbox:comment-add、inbox:review-reply は、実際のソーシャルプラットフォーム上で実在の人物にテキストを公開し、プロバイダー側で取り消すことはできません。必ず最初に --dry-run を実行して、送信するメッセージの全文をユーザーに提示し、送信前に明示的な承認を得てください。顧客への返信を作成して、そのまま一度の操作で送信してはいけません。

(workspaces:create は、ワークスペースの範囲に限定されない唯一の書き込み操作です。新しいワークスペースを作成し、アクティブなワークスペースを無視します。)

手順:

  1. contentstudio --json workspaces:current を実行して、現在アクティブなワークスペースを確認します。
  2. ユーザーに「現在アクティブなワークスペースは <name>(<id>)です。このワークスペースで接続/投稿/削除しますか、それとも別のワークスペースにしますか?」と伝えます。
  3. 別のワークスペースを希望する場合は、workspaces:list を実行して選択してもらい、次のいずれかを行います。
    • workspaces:use <id> を実行して、デフォルトを切り替えます。または
    • 1 回限りの操作の場合は、単一の変更を伴う呼び出しに --workspace <id> を渡します(こちらを推奨します。アクティブなワークスペースは変更されません)。
  4. その後にのみ、変更を伴うコマンドを実行します。

ユーザーの依頼がアクティブなワークスペースを示唆しているように見える場合(「Facebook ページを接続して」「下書き投稿を作成して」など)でも、この確認は必須です。ユーザーが CLI で現在アクティブなワークスペースを忘れたまま、頭の中で別のコンテキストに切り替えている可能性があります。

ページネーション — 先回りして対応し、黙って切り捨てない

すべてのリストコマンドは、1ページに収まる件数を超える結果がある場合、JSON モードで pagination ブロックを返します。

{
  "ok": true,
  "data": [ /* current page of items */ ],
  "pagination": {
    "current_page": 1,
    "per_page": 10,
    "total": 48,
    "last_page": 5,
    "from": 1,
    "to": 10,
    "has_more": true
  }
}

必須ルール:pagination.has_more === true の場合、返された内容より多くのデータがあります。現在のページを「すべての結果」として黙って扱ってはいけません。以下の3つの方法から1つを選んでください。

  1. ユーザーに尋ねる(リクエストが曖昧な場合のデフォルト):

    「48件あるワークスペースのうち、10件を取得しました。残りも取得しますか?それとも、作業には最初の10件で十分ですか?」

  2. 自動でページネーションする — ユーザーのリクエストからすべてのデータを求めていると判断できる場合(例:「自分のアカウントをすべて一覧表示して」「下書きの投稿をすべて表示して」「キューに入っている投稿をすべて削除して」):

    • --per-page <total> を指定して再度呼び出し、1回のリクエストですべて取得します:
      contentstudio --json workspaces:list --per-page 48
      
    • または、total が大きい場合(>200)、取得件数を制限するために --page 2、--page 3、…、--page <last_page> を順に指定します。
  3. ページネーションせず、フィルターを使う — ユーザーが特定の条件を指定した場合(例:「Facebook アカウントのみ」)、ページネーションする代わりに、該当するフィルターフラグ(--platform facebook、--search "..."、--status draft)を使用します。結果が少なければ、ページネーションは不要です。

エージェント向け簡易判断フロー
Did the user say "all" / "every" / "complete list" / "every single"?
  → YES: auto-paginate using --per-page <pagination.total>
  → NO:
      Did the user give a specific count? ("show me top 5", "first 20 posts")
        → YES: respect that count; use --per-page accordingly
        → NO:
            pagination.has_more === true?
              → YES: ASK the user before assuming you have everything
              → NO: you have all the data; proceed
例

ユーザー:「自分のワークスペースを一覧表示して」 エージェントの対応:

  1. contentstudio --json workspaces:list --per-page 50 を実行します(ページネーションを避けられるよう、多めのデフォルトを使用)。
  2. pagination.has_more が引き続き true の場合、「N 件あるワークスペースのうち、50件を確認しました。N 件すべて取得しますか?」と伝えます。

ユーザー:「下書きの投稿をすべて削除して」 エージェントの対応:

  1. contentstudio --json posts:list --status draft --per-page 1 を実行して、total を確認します。
  2. contentstudio --json posts:list --status draft --per-page <total> を実行して、すべて取得します。
  3. data[] を順に処理し、各投稿を削除します。
  4. 最初のページだけを削除して「完了しました」と報告することは決してありません。

ユーザー:「自分の Facebook アカウントを表示して」 エージェントの対応:

  1. --platform facebook フィルターを使用します。通常は0件か少数の結果が返るため、ページネーションは不要です。
  2. has_more が引き続き true(Facebook アカウントが20件を超える)の場合は、自動取得する前にユーザーに確認します。
ページネーションされるエンドポイント

すべての *:list コマンドはページネーションされます: workspaces:list、accounts:list、posts:list、comments:list、media:list、campaigns:list、categories:list、labels:list、team:list、approval-workflows:list、planner-share-links:list、ai-video:jobs。

category-slots:list と planner-share-links:activity は一度にすべての結果を返し、pagination ブロックは含みません。カテゴリーのスロット数は少なく、アクティビティの結果には独自の total が含まれるためです。

リスト以外のコマンド(auth:whoami、posts:create、posts:delete、media:upload、ai-video:tools、ai-video:models、ai-video:job など)のレスポンスには、pagination は含まれません。


コマンドリファレンス

すべてのコマンドは contentstudio <group>:<command> として実行します。

認証
コマンド目的
auth:login --api-key cs_...API キーを保存して検証します
auth:logout保存されている認証情報を忘れます
auth:whoami/me を呼び出し、ユーザー情報を返します
auth:statusローカル設定を表示します(キーは伏せ字)
ワークスペース
コマンド目的
workspaces:listユーザーのワークスペースを一覧表示します
workspaces:use <id>アクティブなワークスペースを設定します
workspaces:currentアクティブなワークスペースを表示します
workspaces:create --name <n> --logo <url> --timezone <tz> [--super-admin-id <id>] [--note <t>] [--instagram-posting-method api|mobile] [--first-day-day <Day> --first-day-key <0-6>]新しいワークスペースを作成します(ワークスペースのスコープ対象外)
workspaces:update [<id>] [--name] [--logo] [--timezone] [--note] [--instagram-posting-method] [--first-day-day --first-day-key]ワークスペースを更新します(デフォルトはアクティブなワークスペース。1つ以上のフィールドが必須)
workspaces:delete <id>ワークスペースを削除します
workspaces:limitsプランの利用上限と残りの利用枠を表示します(下記の 一括処理の前に利用上限を確認する を参照)
workspaces:create / workspaces:update:
  • --name は35文字以下で、英字/スペース/数字/ピリオドのみ使用できます。
  • --logo は URL である必要があります。--timezone は IANA 形式の文字列です(例:Asia/Karachi)。
  • --super-admin-id(作成時のみ)— 作成先のアカウント所有者です。複数のスーパー管理者を管理している場合は必須です。
  • 週の開始日は、2つのフラグを組み合わせて指定します:--first-day-day <Sunday..Saturday> + --first-day-key <index>。キーは曜日のインデックスです(Sunday=0 … Saturday=6)。両方を指定すると first_day: {day, key} が構成されます。
  • workspaces:update は <id> が省略された場合、アクティブなワークスペースを既定で使用し、少なくとも1つのフィールドを指定する必要があります。
  • エラー:削除に失敗した場合は WORKSPACE_DELETE_FAILED(422)、ワークスペースが存在しない場合は404です。

一括処理の前に上限を確認してください。 workspaces:limits は { plan, limits[], usage_reset } を1回の低コストな呼び出しで返します。キャッシュされません — リクエストごとに実際のデータから生成されるため、直前に行った書き込みもすでに反映されています。上限に途中で気づいてユーザーの作業が未完了のままになるのを避けるため、(投稿を20件作成する、メディアのフォルダーをアップロードする、画像を生成するなどの)一括操作を行う前に実行してください。

  • limits[] の各エントリーは { key, label, used, limit, remaining, scope, is_unlimited, is_on_plan, unit, period, resets_at, note } です。
  • scope によって used/remaining の実際の集計対象が決まるため、一括処理の規模を決める前に必ず確認してください:
    • account — この値はアカウント上のすべてのワークスペースで共有されます。remaining: 3 の social_accounts は、アカウント全体であと3件であり、このワークスペースであと3件という意味ではありません。アカウント単位のキー:workspaces、social_accounts、team_members、listening_topics、automations、media_storage。
    • workspace — このワークスペースのみが対象です。8つのクレジットカウンターが該当します:x_posting_credits、listening_mentions、ai_text_credits、ai_image_credits、ai_video_credits、video_clip_credits、ai_auto_reply_credits、api_credits。
  • 安定した識別子は key です。label や note を条件分岐に使用しないでください。 どちらもローカライズされています。バックエンドは8つのロケールに対応する limits.labels.<key> を使って label を解決し、複数のローカライズ済みの断片から実行時に note を組み立てます。そのため、英語以外のアカウントの API キーでは、同じエントリーでも表示テキストが異なります。
  • limit: null だけでは判定できません — ブール値を確認してください:is_unlimited: true は上限なしを意味し、is_on_plan: false はプランにその機能が含まれていないことを意味します(これは上限なしではなく、明確にゼロです)。limit/remaining が null の場合に 0 として表示しないでください。
  • unit は count または bytes です(bytes は media_storage のみ)。period は monthly または lifetime です。resets_at は monthly のエントリーでは ISO 8601 形式のタイムスタンプ、lifetime のエントリーでは null です。
  • 14個のキーは常にすべて存在します:workspaces、social_accounts、team_members、x_posting_credits、listening_topics、listening_mentions、ai_text_credits、ai_image_credits、ai_video_credits、video_clip_credits、ai_auto_reply_credits、automations、media_storage、api_credits。
  • api_credits は API 呼び出しと Webhook 配信で共有される1つのプールです。ここで消費すると、そちらでも消費されます。
  • usage_reset(last_reset_at/next_reset_at、オフセット付きの ISO 8601 形式)は、月次カウンターがリセットされるタイミングを示します。
  • レスポンス本文に rate_limit ブロックや cache ブロックはありません。 呼び出し元ごとのレート上限は、代わりにレスポンスヘッダー X-RateLimit-Limit/X-RateLimit-Remaining で公開されます。429 は RateLimitError として通知されます(終了コード5)。
ソーシャルアカウント(読み取り+接続)
コマンド目的
accounts:list [--platform <p>] [--search <q>]接続済みのソーシャルアカウントを一覧表示します
platforms:list新しいアカウントの接続でサポートされているプラットフォームを一覧表示します
accounts:connect <platform>新しいアカウントを接続するための1回限りのOAuth URLを生成します
accounts:connect <platform> --reconnect --account-id <id>有効期限切れまたは無効なアカウントを更新します
accounts:add-bluesky --handle <h> --app-password <p>Blueskyアカウントを接続します(ブラウザー不要。アプリパスワードを使用)
accounts:add-facebook-group --name <n> [--image <url>]Facebookグループの接続を手動で追加します
accounts:remove <account_id>ソーシャルアカウントを削除(接続解除)します。account_id は accounts:list に表示されるアカウントの id です。save_social 権限が必要です(権限がない場合は403)。

accounts:list のフィルターに使用する --platform の値:facebook、linkedin、twitter、instagram、youtube、tiktok、pinterest、gmb。

accounts:connect で使用する <platform> の値:facebook、facebook-profile、instagram、instagram-via-facebook、twitter、linkedin、pinterest、tiktok、youtube、threads、gmb、tumblr。

AI エージェントによるアカウント接続のフロー:

  1. platforms:list を実行し、サポートされているプラットフォームと、それぞれが使用する方法(oauth/credentials/manual)を確認します。
  2. OAuthプラットフォーム(大半のプラットフォーム)の場合は、accounts:connect <platform> を呼び出し、返されたURLをユーザーに提示します。ユーザーはブラウザーでURLを開いて認証します。CLIが認証情報を扱うことはありません。
  3. Blueskyの場合は、ユーザーにハンドルとアプリパスワードを尋ね(https://bsky.app/settings/app-passwords を案内してください)、accounts:add-bluesky を呼び出します。
  4. Facebookグループの場合は、accounts:add-facebook-group --name "..." を呼び出すだけです。
投稿
コマンド目的
posts:list [--status draft|scheduled|...] [--date-from] [--date-to]投稿を一覧表示します
posts:get <post_id>1件の投稿を読み込みます(その投稿の posts:list の行と同一のペイロード)
posts:create -c "text" -i <account> -t <publish_type> [-s "YYYY-MM-DD HH:MM:SS"] [-m <image_url>]投稿を作成します(ショートカットモード)
posts:create -c "text" -t content_category --content-category-id <cat_id>コンテンツカテゴリの投稿を作成します(アカウントはカテゴリから取得します)
posts:create -c "text" -i <fb_account> -t draft --facebook-carousel '<json>'Facebookカルーセル投稿を作成します(カード2~10枚)
posts:create -c "text" -i <threads_account> -t draft --threads '<json>'Threadsの複数スレッド(連結)投稿を作成します(最大10件)
posts:create -c "text" -i <twitter_account> -t draft --twitter '<json>'Twitter/Xのスレッド形式のツイート投稿を作成します(最大10件)
posts:create -c "text" -i <account> -t draft --first-comment "..." --first-comment-account <id>最初のコメント付きの投稿を作成します
posts:create -c "text" -i <linkedin_account> -t draft --post-type poll --linkedin-options '<json>'LinkedInの投票投稿を作成します(テキストのみ)
posts:create -c "text" -i <ig_account> -t draft --post-type reel --video-url <url> --instagram-trial-reelInstagramのトライアルリールを作成します(最初にフォロワー以外に表示されます)
posts:create -c "common text" -i <fb_account> -i <tiktok_account> -t draft -m <img_url> --platform-overrides '<json>'プラットフォームごとにコンテンツを上書きして、同じ投稿を複数のプラットフォームに投稿します
posts:create -c "text" -i <account> -t scheduled -s "..." --repeat-type Week --repeat-times 4 --repeat-gap 1繰り返し投稿を作成します(独立した子投稿を4件生成します)
posts:create --body /path/to/body.jsonJSON形式の完全な本文を指定して投稿を作成します
posts:update <post_id> [same flags as posts:create]既存の投稿を更新します(本文は同じです)。投稿が公開済みまたは処理中の場合は拒否されます(422)
posts:delete <post_id> [--delete-from-social]投稿を削除します
posts:approve <post_id> [--comment "..."]承認待ちの投稿を承認します
posts:reject <post_id> [--comment "..."]承認待ちの投稿を却下します
-t / --publish-type の値は、scheduled、draft、queued、content_category です。(scheduled と draft では -s / --scheduled-at が必要です。)即時公開するタイプはありません。すぐに送信するには、次の分に予約してください。

posts:get <post_id> は、posts:list の該当投稿の行と同一のペイロードを持つ投稿を 1 件返します。書き込み後に投稿を再確認するには、一覧を再取得する代わりにこれを使用してください。削除済みの投稿、別のワークスペースにある投稿、不正な ID はすべて 404 を返すため、404 はその ID が存在したことがない証拠にはなりません。

posts:update <post_id> は、posts:create とまったく同じフラグと本文(--body とショートカットモードの両方)を受け取り、/workspaces/{w}/posts/{post_id} に PUT します。バックエンドでは、投稿のステータスが published または processing ではない場合に限り、更新が許可されます(それ以外の場合は 422 が返されます)。すでに添付されているワークフローを変更するには、更新時に(以下の)--approval-workflow-action を使用してください。 posts:create / posts:update のショートカットモードフラグ:

  • -c / --content(必須)— 投稿テキスト。
  • -i / --account <id>(繰り返し指定可)— 投稿先のアカウント ID。--content-category-id が指定されている場合を除き、必須です。
  • --content-category-id <id> — トップレベルの content_category_id を設定します。--publish-type content_category の場合、バックエンドで必須です。 指定すると、アカウントはカテゴリから導出されるため、--account は不要(省略可能)です。コンテンツカテゴリへの投稿では、--account の代わりにこちらを使用してください。
  • -s / --scheduled-at "YYYY-MM-DD HH:MM:SS" — 予約投稿の日時。CLI は解析可能な日付を YYYY-MM-DD HH:MM:SS(バックエンドで必須の date_format)に正規化し、通常の壁時計時刻文字列として送信します。**API は UTC ではなく、ワークスペースのタイムゾーンで日時を解釈します。**そのため、投稿したい現地時刻を指定し、タイムゾーンが不明な場合は workspaces:current で確認してください。scheduling:best-times はすでにそのタイムゾーンで候補時刻を返すため、そのまま渡せます。
  • -m / --image-url <url>(繰り返し指定可)、--video-url <url>、--media-id <id>(繰り返し指定可)— メディア。
  • --post-type <type> — 例:feed、reel、carousel、story、poll。post_type=carousel で画像が 2 枚以上添付されている場合、バックエンドがカルーセルを自動的に判定します。アンケートには、--post-type poll とテキストのみの --linkedin-options アンケートブロック(メディアなし)が必要です。
  • --label <id>(繰り返し指定可、最大 20 個)→ labels。
  • --campaign-id <id> → campaign_id。
  • --repeat-type Day|Week|Month + --repeat-times <1-30> + --repeat-gap <1-99> を指定 → scheduling.repeat。3 つすべてを同時に指定する必要があります(それ以外の場合、CLI はローカルでエラーになります)。また、repeat キーが存在する場合は常にバックエンドが必須とする enabled: true を CLI が送信します。
    • --publish-type scheduled でのみ有効です。 draft、queued、content_category は拒否され、呼び出し前に CLI がローカルでエラーになります。
    • --repeat-gap は --repeat-type Day の場合、3 以上である必要があります(コンポーザーは、これより短い日次の繰り返しを拒否します)。
    • 1 件の繰り返し投稿ではなく、独立した子投稿を N 件作成します。親投稿を編集または削除しても、子投稿には影響しません。子投稿には Twitter/X と YouTube のアカウントは引き継がれません。各子投稿には、投稿の承認者が引き継がれます。
    • 更新時に繰り返し設定が引き継がれることはありません。 繰り返し投稿に対して、繰り返しフラグなしで posts:update を実行すると、子投稿は作成されません。そのため、繰り返し投稿を読み取り、変更して書き戻しても安全です。読み書きの往復で誤ってシリーズを再作成することはありません。
    • 読み取り側(posts:get / posts:list)では、scheduling.repeat は {is_parent, is_child, parent_id, type, times, gap} です。enabled キーはなく、リクエスト専用です。読み取りペイロードの repeat ブロックをそのまま更新に渡しても、同じ意味にはならないため注意してください。
  • --linkedin-options '<json>' → linkedin_options(LinkedIn アカウント)。JSON オブジェクトを渡してください。CLI はローカルで解析し(無効な JSON の場合は ConfigError)、そのまま送信します。
    • 形式:{ "title"?: <string>, "poll"?: { "question": <≤140>, "options": <string[2..4], each ≤30>, "duration": "ONE_DAY" | "THREE_DAYS" | "SEVEN_DAYS" | "FOURTEEN_DAYS" } }
    • アンケートには --post-type poll とテキストのみのコンテンツ(画像・動画なし)が必要です。違反がある場合、バックエンドが検証し、422 を返します。
  • --facebook-collaborator <user_id>(繰り返し指定可、最大 10 個)→ facebook_options.collaborators(Facebook アカウント)。--facebook-carousel / --facebook-background-id とマージされます。
  • --instagram-collaborator <user_id>(繰り返し指定可、最大 3 個)→ instagram_options.collaborators(Instagram アカウント)。--instagram-trial-reel と同時に指定すると拒否されます(422)。
  • --instagram-trial-reel(ブール値、デフォルトは false)→ instagram_options.trial_reel.enabled。Instagram のトライアルリールを公開します。まずフォロワー以外に表示されるため、プロフィールのグリッドやフォロワーのフィードには表示されません。
    • --instagram-trial-reel-graduation SS_PERFORMANCE|MANUAL(デフォルトは SS_PERFORMANCE)→ instagram_options.trial_reel.graduation_strategy。SS_PERFORMANCE では、パフォーマンスが良ければ Instagram が自動的にフォロワー向けに公開します。MANUAL では Instagram アプリで手動で公開する必要があります(そのための API は Instagram にありません)。
    • --post-type reel のみ(feed+reel では不可)と動画が必要です。feed/carousel/story は拒否されます。CLI は事前検証を行わず、バックエンドが 422 を返します。
    • --instagram-collaborator と同時に指定すると拒否されます(422)。 トライアルリールと組み合わせた場合、ストーリーへのシェアは拒否されず、黙って無視されます。
    • ワークスペースがモバイルアプリ経由で Instagram に投稿する場合(instagram_posting_option=mobile)は利用できません。
  • --platform-overrides '<json>' → platform_overrides(トップレベル。投稿内の任意のプラットフォームで機能します)。プラットフォーム(facebook、instagram、twitter、linkedin、pinterest、youtube、tiktok、gmb、tumblr、threads、bluesky、telegram)をキーとする JSON オブジェクトを渡してください。CLI はローカルで解析し(無効な JSON の場合は ConfigError)、そのまま送信します。
    • プラットフォームごとの形式:{ "content": { "text"?: <string>, "post_type"?: <string>, "media"?: { "images"?: <url[] ≤10>, "video"?: <url> } } }。
    • text と post_type はそれぞれ独立して、共通のトップレベル content とマージされます。media のみを指定したオーバーライドでも、共通の text/post_type は引き継がれます。
    • media は一体として扱われます。オーバーライドの content に media キーが含まれている場合、そのプラットフォームのメディアはオーバーライドで完全に定義されます。オーバーライドで images/video のいずれかが省略されても、共通メディアの該当フィールドにはフォールバックしません。media キー全体を省略した場合は、共通の content.media がそのまま引き継がれます。これは、一部のプラットフォーム(例:TikTok)では画像と動画を混在させられないためです。
    • --platform-overrides 全体を省略すると、トップレベルの同じ content がすべての対象プラットフォームに公開されます。
    • オーバーライド画像は URL のみ(media_ids は不可)です。トップレベルのメディアと同じ検証が適用されます(画像は最大 10 枚、1 つのオーバーライド内で画像と動画を混在させることはできません)。
  • 承認 — 相互排他的な 2 つの方式(どちらか一方のみ指定):
    • 従来方式 --approver <user_id>(繰り返し指定可)+ --approve-option anyone|everyone(デフォルトは anyone)+ --approval-notes "..." → 承認者が 1 人以上指定された場合のみ approval: {approvers, approve_option, notes} を構築します。投稿の作成者は承認者になれません。anyone = 承認者のうち 1 人が承認すればよい。everyone = 全員の承認が必要です。
    • ワークフロー --approval-workflow-id <id> + --approval-workflow-notes "..." → approval_workflow: {workflow_id, notes?} — ワークフローを添付します(作成と更新のどちらでも機能します)。approval-workflows:list の id で ID を取得してください。
    • ワークフロー(更新のみ) --approval-workflow-action restart|resume|renotify_current|keep|remove + --approval-workflow-notes "..." → approval_workflow: {workflow_action, notes?} — すでに添付されているワークフローを変更します。posts:update でのみ有効です。
    • --approval-workflow-id / --approval-workflow-action のどちらか一方のみ指定でき、--approver をいずれかの --approval-workflow-* フラグと組み合わせることはできません。これらのルールに違反した場合、CLI はローカルでエラーになります(ConfigError)。
  • --facebook-background-id <id> → facebook_options.facebook_background_id(Facebook のテキストのみの投稿で使用できます。メディアを添付すると拒否されます)。有効な ID は facebook:text-backgrounds から取得してください。
  • --facebook-carousel '<json>' → facebook_options.carousel(Facebook アカウントのみ)。JSON オブジェクトを渡してください。CLI はローカルで解析し(無効な JSON の場合は ConfigError)、is_carousel_post: true を追加します。--facebook-background-id とマージされます(どちらかがもう一方を上書きすることはありません)。カード数/CTA/制限をバックエンドが検証し、誤りがある場合は 422 を返します。
    • 形式:{ "cards": [ { "image": <url, required>, "link": <url, required>, "title"?: <≤255>, "description"?: <≤1000> } ], "call_to_action"?, "end_card"?: <bool>, "end_card_url"?: <url>, "accounts"?: <string[]> }
    • カードは最小 2 枚、最大 10 枚です。 Facebook アカウント ID は、引き続きトップレベルの -i / --account(または carousel.accounts)に指定します。
    • call_to_action は次の 33 個の値のいずれかです:NO_BUTTON、ADD_TO_CART、APPLY_NOW、BET_NOW、BOOK_TRAVEL、BUY_NOW、BUY_TICKETS、CALL_NOW、CONTACT_US、DOWNLOAD、GET_DIRECTIONS、GET_OFFER、GET_QUOTE、GO_LIVE、INSTALL_MOBILE_APP、LEARN_MORE、LIKE_PAGE、LISTEN_MUSIC、OPEN_LINK、ORDER_NOW、PLAY_GAME、REGISTER_NOW、REQUEST_TIME、SAVE、MESSAGE_PAGE、WHATSAPP_MESSAGE、SHOP_NOW、SIGN_UP、SUBSCRIBE、USE_APP、WATCH_MORE、WATCH_VIDEO。
  • --threads '<json>' → threads_options(Threads アカウントのみ)。スレッド項目の JSON 配列を渡してください。CLI はローカルで解析し(無効な JSON の場合は ConfigError)、has_multi_threads: true と multi_threads: <array> を設定します。Threads アカウント ID はトップレベルの -i / --account に指定します。
    • 形式:[ { "message": <string>, "media"?: <url[] ≤10>, "media_ids"?: <string[] ≤10> } ]
    • 項目は最大 10 件です。 各項目には message または media が必要です。Threads ではメディアの混在が可能です。制限をバックエンドが検証し、超過した場合は 422 を返します。
  • --twitter '<json>' → twitter_options(Twitter/X アカウントのみ)。ツイート項目の JSON 配列を渡してください。CLI はローカルで解析し(無効な JSON の場合は ConfigError)、has_threaded_tweets: true と threaded_tweets: <array> を設定します。Twitter アカウント ID はトップレベルの -i / --account に指定します。これは --threads と同様の機能ですが、Twitter のスレッド形式のツイート向けです。
    • 形式:[ { "message": <string>, "media"?: <url[] ≤10>, "media_ids"?: <string[] ≤10> } ]
    • ツイートは最大 10 件です。 各項目には message または media が必要です。Twitter では 1 件のツイート内でメディアを混在させることはできません(画像と動画を同時に指定できません)。また、1 件のツイートにつき動画は最大 1 本です。CLI はツイートの内容を検証しません。これらの制限はバックエンドが適用し、違反がある場合は 422 を返します。
  • --first-comment "<message>" → first_comment(2,000 文字以下)。CLI は first_comment: { message, accounts? } を構築します。アカウントは --first-comment-account <id>(繰り返し指定可)で指定します。
    • --first-comment-account <id>(繰り返し指定可)→ first_comment.accounts。--first-comment メッセージを指定する場合、バックエンドは 1 つ以上のアカウントを必須とし、そのアカウントは投稿のメインの --account ID の一部でなければなりません。 CLI はクライアント側で処理をブロックしません。--first-comment-account を省略すると、バックエンドが 422 を返します。 (--facebook-carousel、--facebook-collaborator、--instagram-collaborator、--instagram-trial-reel、--instagram-trial-reel-graduation、--linkedin-options、--platform-overrides、--threads、--twitter はショートカットモードでのみ適用されます。--body の JSON モードでは、facebook_options(カルーセル+共同投稿者)、instagram_options(collaborators+trial_reel)、linkedin_options、threads_options、twitter_options、first_comment、approval、approval_workflow、トップレベルの platform_overrides がすでにネイティブでサポートされています。複数のプラットフォームオプションブロックを組み合わせた投稿には、こちらを使用してください。)

posts:list のペイロードには、投稿ごとに linkedin_options と approval_workflow が追加されました(既存のフィールドに加えて)。これらは --json 出力に自動的に表示されます。

スケジュール設定 — 投稿に最適な時間
コマンド目的
scheduling:best-times接続済みアカウントの履歴から算出した、ワークスペースで推奨される投稿時間帯のランキング
scheduling:best-times --account <platform>:<account_id>分析対象を特定のアカウントに限定します(複数指定可能)
scheduling:best-times --global-slots <n> --per-account-slots <n>返す推奨数(それぞれ1~24件)
scheduling:best-times --entities '<json>'アカウントごとの時間帯数を指定するための、完全なエンティティ配列

**時間帯(slot)**とは、推奨される投稿時間のことで、曜日と時刻で構成されます。時間帯は推奨度の高い順に返されるため、--global-slots 3 は投稿に最適な3つの時間帯を意味します。

  • 時刻は常にワークスペースのタイムゾーンで示され、meta.timezone にも記載されます。タイムゾーンを指定するパラメーターはありません。これは posts:create --scheduled-at が使用する時刻と同じなので、時間帯はそのままスケジュール設定できます。事前に UTC に変換しないでください。
  • 接続済みのすべてのアカウントを分析するには、--account を省略します。それ以外の場合は、accounts:list の1つの行にある platform と _id の両方を使って <platform>:<account_id> を渡します。例:--account facebook:<account_id>。対応プラットフォーム:facebook、instagram、linkedin、twitter、tiktok、youtube、pinterest、threads、gmb、tumblr、bluesky、telegram。
  • --entities '[{"id":"<account_id>","type":"facebook","slots":3}]' は、アカウントごとに異なる時間帯数を指定するための代替手段です。--account と併用することはできません。
  • --global-slots(API のデフォルトは5)は、統合された global ビューの件数を指定します。--per-account-slots(API のデフォルトは3)は、各アカウントのリストの件数を指定します。どちらも1~24で、呼び出し前に CLI が検証します。いずれも基盤となる分析や heatmap_matrix は変更しません。heatmap_matrix には、シグナルがあったすべての時間が常に含まれます。

レスポンスの形式(JSON エンベロープ内の data):

  • meta — {generated_at, timezone, warnings[], missing_entities[], ai_fallback_entities[]}。
  • global — 分析対象アカウントを統合した結果です。top_recommendations[](各要素は {rank, day, date, time, score, platform_breakdown}。time は "14" = 14:00 のような、時刻を表す文字列です)と、heatmap_matrix.data(疎な [hour, day_index, score] の三つ組。day_index は月曜日が0)および dates_key が含まれます。使用可能なデータがあるアカウントがない場合は null です。
  • individual — アカウント ID ごとにキー付けされた同じ内訳です。各項目には platform と source(data_driven または AI によるフォールバック)が含まれます。

履歴が少ないワークスペースでも HTTP 200 が返されます。 履歴が不十分なアカウントは meta.missing_entities に記載され、global が null になることがあります。これは読み取りの成功であり、エラーではありません。失敗として報告するのではなく、スキップされたアカウントをユーザーに伝えてください。meta.ai_fallback_entities に記載されたアカウントの結果は推定値であり、測定値ではありません。提示する際はその旨を伝えてください。

エラー:不明なアカウント、または接続済みアカウントがないワークスペースの場合は422、オプティマイザーが一時的に利用できない場合は502(BackendError)です。データがないと報告するのではなく、再試行してください。

読み取りは安全です。 scheduling:best-times は読み取りのみを行うため、--dry-run もワークスペースの確認も必要ありません。時間帯に基づいて投稿をスケジュール設定する操作は変更を伴うため、その手順には通常の --dry-run とワークスペース確認のルールが適用されます。

コメント/内部メモ
コマンド用途
comments:list <post_id>投稿のコメントを一覧表示します
comments:add <post_id> "message" [--note] [--mention <user_id>]公開コメントまたは内部メモを追加します
メディアライブラリ
コマンド用途
media:list [--type images|videos] [--sort recent|...]メディアアセットを一覧表示します
media:upload --file <local_path>ローカルファイルをアップロードします
media:upload --url <external_url>外部 URL からインポートします
AI 画像
コマンド用途
images:toolsこの API が呼び出せる画像ツールと、各ツールに必要な入力および制御オプション
images:modelsimages:generate が受け付けるモデル識別子
images:brand{configured, enabled} — --use-brand が何かを適用するかどうか
images:generate -p "<prompt>"プロンプト → 画像を生成し、メディアライブラリに保存します
images:generate -p "<edit>" --image-url <url>最初から生成する代わりに、既存の画像を編集します
images:product-image --product-image-url <url>商品写真を再構成します
images:headshot --image-url <url>人物の写真からプロフェッショナルな顔写真を作成します
images:face-swap --target-image-url <url> --face-image-url <url>一方の画像の顔を、もう一方の画像の被写体に合成します
images:outfit-swap --target-image-url <url> --outfit-image-url <url>バーチャル試着
images:upscale --image-url <url>画像の解像度を上げます
images:remove-background --image-url <url>背景から被写体を切り抜きます
images:tool <tool_key> --body '<json>'すべての制御設定を指定して任意のツールを使用します(image-to-image の style、aspect_ratio、image_resolution、image_quality、複数の attachments、reference_image_urls を利用する方法です)

どの生成でも同じペイロードが返されます。data.media_id は posts:create --media-id に渡すハンドルです。 この 2 段階の手順が AI 画像を公開する通常の方法です。Examples セクションの生成後に公開するレシピを参照してください。

{ "ok": true, "data": {
    "media_id": "66f1a2b3c4d5e6f708192a3b",   // → posts:create --media-id
    "url": "https://storage.googleapis.com/.../generated.png",
    "width": 1024, "height": 1024, "mime_type": "image/png",
    "model_used": "nano-banana-pro",            // may differ from --model
    "brand_applied": false,
    "credits": { "consumed": 1, "available": 412 },
    "persist_error": null } }
  • media_idは永続的に使えるハンドルであり、urlはそうではありません。 プレビューや次のツールへの入力にはurlを使います。保存しないでください。persist_errorとともに返されたurlは、一時的なプロバイダーリンクです。
  • 200を完了と判断する前に、persist_error(またはmedia_id !== null)を確認してください。 画像は生成され、料金も発生しましたが、保存できませんでした。media_storage_fullはワークスペースのメディアストレージがいっぱいであることを意味します(再試行すると別のクレジットが消費され、再び失敗します)。それ以外の場合は、1回再試行する価値があります。ユーザーには、今すぐurlからダウンロードするよう伝えてください。
  • ツールは連鎖して使えます。 ある呼び出しで取得したメディアライブラリのurlは、次の呼び出しへの有効な入力です(生成 → アップスケール → 背景削除)。呼び出しごとに別途料金が発生します。
  • 渡すすべての画像URLは、画像サービスがhttp(s)経由で公開取得できる必要があります(認証なし、期限切れの署名付きURLではない、プライベートバケットではない、ローカルパスではないこと)。まずmedia:upload --fileでローカルファイルをアップロードし、返されたURLを渡してください。サービスがダウンロードできないURLはValidationError(IMAGE_INPUT_REJECTED)となり、サービス障害ではありません。
  • 生成には時間がかかり、料金も発生します。 サーバーの期限は120秒、CLIの待機時間は150秒です(変更するには--timeout <seconds>を使います)。これらの呼び出しは再試行されません。生成をやり直すと画像クレジットをもう1つ消費する可能性があるため、組み込みの429/5xx再試行は無効になっています。ループではなく、意図を持って再試行してください。
  • --modelは任意です。 サービスのデフォルトを使う場合は省略してください。料金はモデルによって異なるため(ほとんどのモデルは画像クレジット1、gpt-image-2は5、gpt-image-2.5-flareは3、gpt-image-2.5-sunburstは5)、推測せずcredits.consumedを確認してください。images:modelsには各モデルのcredits_per_imageが表示されます。gpt-image-2.5-flareとgpt-image-2.5-sunburstを含む、一覧にあるすべてのモデルで生成と編集(--image-url)が可能です。
  • **--background <auto|opaque|transparent>**で画像の背景を設定します(image_backgroundとして送信されます)。この設定を反映するのはgpt-image-2.5-flareとgpt-image-2.5-sunburstのみで、ほかのモデルはすべて何も通知せずに無視します。ロゴ、ステッカー、切り抜き画像には--background transparentを使い、これら2つのモデルのいずれかと組み合わせてください。
  • model_usedはimages:modelsの値とは異なります。 プロバイダー名が先頭に付いて(fal-ai/nano-banana-pro、pixelcut/background-removal)、フォールバック後に実際に実行されたモデルを示します。この値を報告し、--modelとの一致を比較しないでください。
  • images:toolsのcontrolsが示すのは、公開ペイロードではなく基盤となるツールの設定です。 --resolution/--aspect-ratioの値はここから取得できますが、対応するフラグのない設定は送信できません。upscaleにはmodelとupscale_factorが記載されていますが、どちらもAPIのツールペイロードには含まれません。同様に、headshotとface-swapのaccepts_instructions: trueは利用できません。--instructionsがあるのはimages:product-imageのみです。未対応のフィールドを送信しても黙って破棄されるため、機能したように見えてしまいます。
  • **--dimensions**にはtext→imageのみで使える square、square_hd、portrait_4_5、landscape_16_9を指定します。正確なピクセル数はモデルが決定するため、返されたwidth/heightを確認してください。それ以外の値は呼び出し前にCLIによって拒否されます。
  • ブランド情報はブール値の読み取り専用です。 --use-brandを使えるのはimages:generateのみです。サーバー側で解決され、ブランドIDやブランドコンテンツが受け付けられたり返されたりすることはありません。ブランドプロファイルがない状態で--use-brandを指定してもエラーにはならず、brand_applied: falseになります。事前にimages:brandで確認できます。ツールのコマンドとimages:generate --image-urlは、常にbrand_applied: falseを返します。編集とツールではブランド情報は適用されません。
  • 生成を行うすべてのコマンドで--dry-runを指定すると、エンドポイントと本文が出力され、呼び出しは行われません。クレジットを消費する前に、ユーザーにプロンプトを確認してもらうために使ってください。3つの検出コマンドは読み取り専用のため、--dry-runは不要です。
  • レート制限は毎分30リクエストで、同じアカウントにおけるContentStudioアプリ独自のAI利用と共有されます。ここでRateLimitErrorが発生した場合は、丸1分待つ必要があります。
  • 動画ツール(image-to-video、motion-control、lip-sync、talking-avatar)はこのAPIでは利用できません。これらをリクエストすると、不明なキーと同じくNotFoundError(TOOL_NOT_FOUND)になります。
  • images:toolsが空のリストを返した場合は、カタログに一時的にアクセスできないことを意味し、ワークスペースにツールがないという意味ではありません。ツールがないとユーザーに伝えるのではなく、再試行してください。
  • サンプルワークスペースは読み取り専用です。3つの検出コマンドは動作しますが、生成経路の2つはどちらも403を返します。
AI ビデオ
コマンド目的
ai-video:tools有効な AI ビデオツールを一覧表示します(key、label、description?、inputs[]、controls[])
ai-video:modelsai-video:generate / ai-video:estimate で選択可能なすべてのモデルを一覧表示します(key、provider、modes[]、supported_resolutions?、supported_durations?、supported_ratios?、supports_audio?、デフォルト値)
ai-video:estimate [--duration] [--model] [--resolution] [--mode text-to-video|image-to-video|reference-to-video] [--audio] [--aspect-ratio] [--enhance-prompt]実際のクレジット数と所要時間を見積もります。送信も課金もされません
ai-video:generate --prompt "..." [--image-url | --reference-image-url <url> (repeatable)] [--model] [--duration] [--resolution] [--aspect-ratio] [--audio] [--enhance-prompt] [--style] [--use-brand]非同期の動画生成ジョブを送信します
ai-video:run-tool motion-control --image-url <url> --video-url <url>ドライビング動画の動きを元画像に適用します
ai-video:run-tool lip-sync --video-url <url> --audio-url <url>動画の口の動きを音声トラックに同期させます
ai-video:run-tool talking-avatar --image-url <url> --audio-url <url>静止画像を音声に合わせて動くトーキングアバターにします
ai-video:jobs [--status queued|processing|completed|failed|cancelled] [--page] [--per-page]この API を通じて送信された動画ジョブのページ分割リストです(チャット/内部ツールのジョブは含まれません)
ai-video:job <job_id>単一ジョブのステータスを表示します。終了状態の場合はローカルのスナップショット、それ以外の場合はライブポーリングします
ai-video:cancel-job <job_id>まだアクティブなジョブをキャンセルします。すでに消費された作業分については課金される場合があります

ai-video:generate の注意事項:

  • --prompt は必須で、最大1000文字です。
  • --image-url と --reference-image-url の両方を省略すると、text-to-video になります。--image-url を指定すると image-to-video に切り替わります。--reference-image-url(繰り返し指定可能、最大8個)を指定すると reference-to-video に切り替わります。--image-url と --reference-image-url は同時に指定できません。両方が設定されている場合、CLI はローカルで ConfigError を発生させます。
  • --use-brand(デフォルトは false)はブランドアセットをサーバー側で解決します。--brand-id フラグはなく、バックエンドもこれを受け付けません。
  • レスポンスの data:{ job_id, status_url (ai-video:job への相対パス), status, estimated_credits, estimated_seconds? }。status が終了状態になるまで、ai-video:job <job_id> をポーリングするか、status_url を直接取得してください。

ai-video:run-tool <tool_key> の注意事項:

  • tool_key は ai-video:tools のキーのいずれかです。現在は motion-control、lip-sync、talking-avatar です。CLI は送信前に必須の入力ペアをローカルで検証します(motion-control → 画像+動画、lip-sync → 動画+音声、talking-avatar → 画像+音声)。必須フラグがない場合は ConfigError を発生させます。
  • 事前見積もりはありません。レスポンスの estimated_credits / estimated_seconds は常に null です。上記のフラグで新しいツールに対応できない場合は、ai-video:tools を実行して各ツールで宣言されている inputs[] / controls[] を確認してください。

ai-video:jobs / ai-video:job / ai-video:cancel-job の注意事項:

  • ai-video:jobs が返すのは、この API を通じて送信されたジョブのみです。チャット/内部ツールで生成されたジョブは表示されません。
  • ジョブの status は queued、processing、completed、failed、cancelled のいずれかです。stage / message / result / credits / brand_applied はステータスに応じて含まれます。
  • ジョブがすでに完了、失敗、またはキャンセルされている場合、ai-video:cancel-job は JOB_ALREADY_TERMINAL による 409(ConflictError)を返します。不明な場合は、先に ai-video:job <job_id> を確認してください。

AI ビデオ固有のエラー(以下の標準表に加えて):403 INSUFFICIENT_VIDEO_CREDITS(クレジット不足。AuthError として通知されます)、403 STORAGE_LIMIT_EXCEEDED(AuthError として通知されます)、404 TOOL_NOT_FOUND / JOB_NOT_FOUND(NotFoundError)、409 JOB_ALREADY_TERMINAL(ConflictError)、502 AI_SERVICE_UNAVAILABLE / 504 AI_SERVICE_TIMEOUT(BackendError。短いバックオフの後、安全に再試行できます)。

参照テーブル(読み取り)
コマンド目的
campaigns:listキャンペーン(フォルダー)の一覧表示
categories:listコンテンツカテゴリーの一覧表示
labels:listラベルの一覧表示
team:listワークスペースのチームメンバーの一覧表示
approval-workflows:list承認ワークフローの一覧表示(項目の id を --approval-workflow-id として使用)

approval-workflows:list の各項目は { id, name, is_default, levels: [{ level_number, title, rule, members: [{ user_id }] }] } です。id は posts:create/posts:update の --approval-workflow-id として使用します。

approval-workflows:list には、このグループのほかのコマンドと同様に manage_workflow 権限が必要です。下記の 承認ワークフロー(書き込み) を参照してください。categories:list は コンテンツカテゴリー(書き込み)+投稿スロット のエントリーポイントです。

コンテンツカテゴリー(書き込み)+投稿スロット

コンテンツカテゴリーは常時利用する投稿の入れ物です。そこに追加した投稿は、個別に時刻を指定する代わりに、カテゴリーの毎週の スロット に振り分けられます。categories:list でカテゴリーを見つけてから、次のコマンドを使用します。

コマンド目的
categories:get <category_id>1つのカテゴリーを読み取る — レスポンスに slots[] が インラインで含まれる ため、2回目の呼び出しは不要です
categories:create --name <n> --color <color_N> [--account <id>…] [--allowed-member <user_id>…]カテゴリーを作成
categories:update <category_id> [--name] [--color] [--account…] [--allowed-member…]部分更新
categories:delete <category_id>カテゴリーを削除
categories:shuffle <category_id>カテゴリーの今後の投稿をスロットに再振り分け
category-slots:list <category_id>カテゴリーの週間スロットを一覧表示
category-slots:next <category_id> [--post-id <id>]次の空きスロットを特定
category-slots:create <category_id> --day <d> --hour <h> --minute <m> --period AM|PMスロットを1つ追加
category-slots:update <category_id> <slot_id> [--day] [--hour] [--minute] [--period]1つのスロットを部分更新
category-slots:delete <category_id> <slot_id>1つのスロットを削除
  • --name は100文字以下です。--color は color_1 ~ color_20 です(ラベル/キャンペーンと同じ列挙型)。
  • --account(複数回指定可能)は、プラットフォームをまたいだソーシャルアカウント ID の単一の フラットな リストです。プラットフォームごとのマップではありません。--allowed-member(複数回指定可能)にはチームメンバーの ユーザー ID を指定します。すべてワークスペースのチームに所属している必要があり、そうでない場合、呼び出しは422エラーになります。
  • どちらの書き込みコマンドも、指定した配列を 置き換えます。categories:update --account a1 を実行すると、カテゴリーに残るアカウントは1つだけです。
  • --day は小文字(sunday ~ saturday)で指定します。--hour は 0 ~ 12 の 12時間制 で、--period AM|PM と組み合わせます。12は0に正規化される ため、hour 12 + AM は午前0時、hour 12 + PM は正午です。--minute は 0 ~ 59 です。CLIは両方をJSONの 整数 として送信します。文字列 "12" はバックエンドの正午への正規化を通り抜け、スケジューラーが照合できない時間として保存されます。
  • スロットの各行には weekday_sorting(日曜日 = 0)が含まれます。これはスケジューラーが並べ替えに使用するインデックスなので、曜日の順序を名前から再計算するのではなく、この値で並べ替えてください。
  • 今後の投稿がないカテゴリーで categories:shuffle を実行すると、成功 エンベロープで {"shuffled_posts_count": 0} が返ります。0は結果であり、失敗ではありません。エラーではなく「振り分ける投稿はありません」と報告してください。
  • category-slots:next は {next_slot, timezone, scheduled} を返します。next_slot: null はHTTP 200で返され、カテゴリーに今後のスロットがないことを意味します。--post-id を指定すると、その投稿がどのスロットに割り当てられるかを問い合わせます。scheduled: true は、回答が空きスロットではなく、その投稿にすでに設定されている時刻であることを意味します。
  • エラー:CONTENT_CATEGORY_NOT_FOUND(404)、CONTENT_CATEGORY_ACCESS_DENIED(403)、CONTENT_CATEGORY_IS_GLOBAL(422 — グローバルカテゴリーはAPI経由で編集または削除できません)、CONTENT_CATEGORY_INVALID_ACCOUNT(422)、CONTENT_CATEGORY_SHUFFLE_FAILED(422)、CONTENT_CATEGORY_SLOT_NOT_FOUND(404)、CONTENT_CATEGORY_SLOT_DUPLICATE(422 — その曜日と時刻はすでに使用されています)。
承認ワークフロー(書き込み)
コマンド用途
approval-workflows:get <workflow_id>1 つのワークフローを読み取る
approval-workflows:create --name <n> --levels '<json>' [--draft]ワークフローを作成する
approval-workflows:update <workflow_id> [--name] [--levels '<json>'] [--draft] [--confirmed]部分更新する
approval-workflows:delete <workflow_id> [--force]ワークフローを削除する
approval-workflows:duplicate <workflow_id>ワークフローを新しいワークフローとして複製する
approval-workflows:set-default <workflow_id>ワークスペースのデフォルトに設定する
approval-workflows:remove-default <workflow_id>デフォルトの設定を解除する
approval-workflows:cascade-job <cascade_job_id>バックグラウンドのカスケード処理を確認する
  • このグループのすべてのコマンド(approval-workflows:list を含む)には、manage_workflow 権限が必要です。 投稿を読み取れる呼び出し元でも、ここでは 403 が返されることがあります。これは権限に関する応答であり、キーの誤りではないため、その場合にユーザーへ auth:login を案内しないでください。
  • --name は 120 文字以下です。--levels は JSON の配列です:[{"level_number":1,"title":"Editors","rule":"anyone"|"everyone","members":[{"user_id":"<id>"}]}]。level_number はペイロード内で一意である必要があり、メンバー ID は各レベル内で一意である必要があります。また、各メンバーはワークスペースのチームに所属している必要があります。
  • --draft は is_draft に対応します。担当者がいないレベルを含むワークフローは、フラグにかかわらず下書きになります。また、下書きをデフォルトにすることはできません。下書きに対して set-default を実行すると、CANNOT_SET_DRAFT_AS_DEFAULT(422)が返されます。
  • 作成/更新では is_default は受け付けられません。デフォルトにするには set-default を実行してください。
  • 更新時に --confirmed を指定すると、レビュー中の投稿に編集後のワークフローが再適用されます。 この場合、ワークフローの代わりに cascade_job_id を含む 202 が返されます。書き込みは完了していますが、再適用はまだ実行中です。変更がすべてに反映されたとユーザーに伝える前に、approval-workflows:cascade-job <id> で status が終端状態になるまで確認してください。--confirmed を指定しない場合、編集は今後の投稿にのみ適用されます。
  • 処理中の投稿がある場合、削除は拒否されます:context.in_flight_posts_count を含む 422 REQUIRES_FORCE_DELETE が返されます。この件数をユーザーに伝え、--force を付けて再実行する前に明示的な許可を得てください。強制削除すると、ワークフローが削除され、対象の投稿もクリーンアップされます(202 + cascade_job_id)。削除対象がワークスペースのデフォルトだった場合、応答には was_default: true も含まれ、別のワークフローをデフォルトに設定するまでデフォルトが存在しなくなるため、その旨を伝えてください。
  • エラー:APPROVAL_WORKFLOW_NOT_FOUND(404)、CANNOT_SET_DRAFT_AS_DEFAULT(422)、REQUIRES_FORCE_DELETE(422)、CASCADE_JOB_NOT_FOUND(404)。
Planner の共有リンク

Planner の共有リンクは、ワークスペース外のユーザーにスケジュール済みの投稿を表示する公開 URL で、 コメントや承認を許可することもできます。

停止 — どちらも「共有リンク」と呼ばれる、互いに無関係な機能があります。 ユーザーが「共有リンク」「リンクを共有」「クライアントにリンクを送る」など、どちらの機能か明示せずに言った場合は、何かを実行する前に確認してください。推測したり、前後の会話からどちらかを判断したりしないでください。2つの機能は異なるエンドポイントに異なるレコードを作成するため、互換性はありません。

おおよそ次のように尋ねてください。

「ContentStudio には、共有リンクと呼ばれるものが2種類あります。どちらをご希望ですか? (a)プランナーの共有リンク — クライアントに実際のスケジュール済み 投稿を表示し、コメントや承認/却下もできるようにします。 (b)アナリティクスの共有リンク — フォロワーの増加、エンゲージメント、人気の投稿などを表示する、リアルタイムの アナリティクスダッシュボード/レポートをクライアントに見せます。数値の閲覧のみで、投稿は表示されません。」

その後:

  • (a)→ planner-share-links:*(このセクション)。通常どおり進めます。
  • (b)→ ここでは利用できないことを伝えてください。 アナリティクスダッシュボードの共有には、パブリック API のエンドポイントがありません。Web アプリが使用する、内部のセッション認証済み API でのみ利用でき、API キーではアクセスできません。そのことを明確に伝え、ContentStudio の Web アプリ(Analytics → レポート → Share)を案内してください。 うまくいくことを期待して share-links:* を実行してはいけません。 アナリティクス:レポート、スケジュール、共有リンクの警告を参照してください。

(b)に対して「ここからは対応できませんが、利用できる場所はこちらです」と答えるのが正しい対応です。利用できるのがプランナーのリンクだけだからといって、こっそりプランナーのリンクを作成するのは誤りです。数値を求めているユーザーに投稿を渡すことになります。

ユーザーがすでに機能を明確に指定している場合(「プランナーの共有リンク」「クライアントにこれらの投稿を承認してもらう」→(a)、「アナリティクスの共有リンク」「レポート/ダッシュボードを共有する」→(b))、またはこの会話ですでに作成した特定のリンクについて作業を続けていることが明らかな場合に限り、確認を省略してください。確認を省略する場合も、指定された機能に応じて対応します。明確に(b)を指定された場合は、プランナーのリンクではなく、「ここでは利用できません」とすぐに伝えてください。

コマンド目的
planner-share-links:listワークスペースのプランナー共有リンクを一覧表示します
planner-share-links:get <link_id>1つのリンクを読み込みます
planner-share-links:create --name <n> [--plan <post_id>…] [--note <id>…] [--scope] [--view] [--calendar-date] [--password] [--single-post] [--allow-comments] [--allow-approval-actions] [--show-notes] [--social-selections '<json>']リンクを作成します
planner-share-links:update <link_id> [same fields, plus --disabled / --approval-flow / --approval-email / --approval-option]部分更新します
planner-share-links:delete <link_id>リンクを削除します
planner-share-links:send-invitations <link_id> --email <e>… --approval-option anyone|everyone承認を有効にして、1~10人のレビュー担当者にメールを送信します
planner-share-links:activity <link_id> [--type comment|action]クライアント側で行われた操作を確認します
  • <link_id> は RECORD の ID(リソースの id)であり、共有可能な URL に含まれる公開 link_id スラッグではありません。リソースは両方を返します。スラッグを渡すと 404 になります。
  • --name は 3~255 文字で、英字、数字、スペースのみ使用できます。名前から公開 URL のスラッグが直接生成されるため、句読点は使用できません。「Q3 Review!」は失敗し、「Q3 Review」は使用できます。
  • カレンダー期間のリンクを含め、すべての作成で --plan または --note のいずれかが必須です。期間が投稿の範囲を超えていても、プロダクトは表示されている投稿をスナップショットとして保存します。
  • --scope selection|future|all(デフォルトは selection)と --view list|calendar|compact_list(デフォルトは list)。future と all はカレンダー表示専用(--view calendar が必要)で、--calendar-date が必須です。また、外部からの承認を収集できません(これらのスコープでは --allow-approval-actions が拒否されます)。逆に、selection では --calendar-date は拒否されます。自由形式で指定でき、例は "2026-01-01 - 2026-03-31" です。
  • --single-post には --scope selection と --plan 1 つが必要です。
  • 4 文字以上の --password を指定すると、--password-protected が有効になります。更新時に保護を解除するには --no-password-protected を渡します。
  • --plan と filters は作成時のみ指定できます。更新エンドポイントはこのフィールドを受け付けず、黙って破棄するのではなく、そのまま拒否します。リンクに表示する投稿を変更するには、新しいリンクを作成してください。
  • レスポンスに password や approval_tokens が含まれることはありません。保留中の招待は、派生フィールド outstanding_invitations_count に表示されます。
  • planner-share-links:activity は、最新順の {total, data[]} を返します。各エントリは {type, post_id, name, email, comment, action, created_at} です。--type を指定するとコメントまたはアクションに絞り込まれ、省略すると両方が対象になります。
  • クライアントとのやり取りを一時停止するだけの場合は、:delete より planner-share-links:update <id> --disabled を優先してください。無効化は元に戻せますが、削除は元に戻せません。
  • エラー:SHARE_LINK_NOT_FOUND(404)、SHARE_LINK_TOKEN_REVOKE_FAILED(422)。
ラベル(書き込み)
コマンド目的
labels:create --name <n> --color <color_N>ラベルを作成
labels:update <label_id> [--name] [--color]ラベルを更新
labels:delete <label_id>ラベルを削除
キャンペーン(書き込み)
コマンド目的
campaigns:create --name <n> --color <color_N>キャンペーンを作成
campaigns:update <campaign_id> [--name] [--color]キャンペーンを更新
campaigns:delete <campaign_id>キャンペーンを削除

ラベルとキャンペーンでは、--name は 100 文字以下、--color は列挙値 color_1 ~ color_20 のいずれかです。更新時は --name および/または --color を渡してください(指定する場合は各フィールドが必須です)。

チームメンバー(書き込み)
コマンド目的
team:add --email <e> --role <r> [--membership team|client] [--permissions '<json>']メンバーを招待します
team:update <member_id> --role <r> --permissions '<json>' [--membership]メンバーのロール/権限を更新します
team:remove <member_id> [--confirmed]メンバーを削除します
  • member_id はメンバーシップ IDです。team:list の member_id フィールドを使用してください(ユーザーの id ではありません。これは別のフィールドです)。
  • --role(必須):admin、approver、または collaborator。
  • --email(team:add で必須):1 つのメールアドレス。
  • --membership(任意):team(内部)または client(外部。内部メモには表示されません)。デフォルトは team です。
  • --permissions(team:add では任意、team:update では必須):文字列として渡す、ロールに対応した JSON オブジェクトです(例:--permissions '{"addSocial":true}')。無効な JSON の場合はローカルで ConfigError が発生します。無効なロール/キーの組み合わせの場合はバックエンドから 422 が返されます。team:update は部分マージです。送信したキーのみが変更されます。ロールを変更すると、新しいロールでは無効なブール値キーは削除されます。
    • 共通のブール値(すべてのロール):accessSharedFolder、allow_workflow_management。
    • admin:フルアクセス。適用されるのは hasBillingAccess ブール値のみです。
    • collaborator のブール値:addBlog、addSocial、addSource、addTopic、viewTeam、rescheduleQueue、postsReview、changeFBGroupPublishAs、hasListeningAccess。
    • approver のブール値:approverCanEditPost、approverCanAddNotes、approverCanCreatePost(これらの設定がない承認者は、承認/却下のみ可能です)。
    • アカウントアクセス配列(すべてのロール。ワークスペース内に実在する接続済みアカウント ID が必要です。そうでない場合は 422 が返されます):facebook、instagram、threads、twitter、linkedin、pinterest、telegram、youtube、tiktok、tumblr、tumblr_blogs、tumblr_profiles、bluesky、gmb。
    • ブログ配列(すべてのロール。存在確認は行われません):wordpress、medium、shopify、webflow。
    • content_categories(すべてのロール。ワークスペース内に実在するカテゴリ ID が必要です。そうでない場合は 422 が返されます):コンテンツカテゴリ ID の配列。
  • team:remove:メンバーが承認ワークフローまたは処理中の投稿に含まれている場合、バックエンドはエラーコード REQUIRES_REMOVAL_CONFIRMATION(422)を返します。--confirmed を付けて再実行すると(?confirmed=true を送信)、削除を続行できます。404 = TEAM_MEMBER_NOT_FOUND。
ソーシャルアカウント(書き込み)
コマンド目的
accounts:remove <account_id> [--dry-run]ソーシャルアカウントを削除(接続解除)します(DELETE /workspaces/{w}/accounts/{account_id})
  • account_id は accounts:list で返されるアカウントの id です。
  • save_social 権限が必要です。権限のない呼び出し元には 403 が返されます。
  • エラー:401(API キーが無効または未指定)、403(save_social 権限なし)、404(ワークスペース内にアカウントが見つからない)、422(削除失敗)。成功時は、data 配列が空の 200 が返されます。
  • 変更を行うコマンドです。--dry-run でプレビューし、先にワークスペースを確認してください。
Facebook ヘルパー
コマンド目的
facebook:text-backgroundsFacebook の色付き背景プリセットを一覧表示します(プレーンテキスト投稿の facebook_options.facebook_background_id に id を指定します)
ソーシャル受信トレイ

受信トレイでは、3 種類の項目を要素に統合します。conversation(DM)、 post(コメント付きの投稿)、および review です。inbox:list が開始点であり、 それ以外のコマンドには、ここで返される ID を指定します。

指定する ID

受信トレイのコマンドには、各 inbox:list の行にある element_details オブジェクトの ID を指定します。element_details.element_id を使用してください。 すべての要素単位のコマンドで受け付けられます。

コマンド渡す ID
inbox:update (--element)element_details.element_id
inbox:tag-attach / inbox:tag-detachelement_details.element_id
inbox:mark-readelement_details.element_id
inbox:contact / inbox:contact-updateelement_details.element_id
inbox:messages / send / notes / note-add / bookmarkselement_details.element_id(t_… 形式)
inbox:comments / inbox:comment-addelement_details.post_id

値の形式は次のとおりです。

  • element_details.element_id — t_10000000000000001(会話)または 100000000000000001_200000000000000002(投稿)
  • element_details.post_id — 900000000000001_100000000000000001

行のトップレベルにある element_ref は内部参照であり、コマンドの引数ではありません。ID は必ず element_details から取得してください。

コマンドが空のリストを返したり、項目が見つからないと報告したりした場合は、結果をユーザーに説明する前に、この表で ID を確認してください。

ほとんどの書き込み操作で、次の情報も必要です。

  • platform_id — 項目が属する接続済みソーシャルアカウントです。バックエンドはそのアカウントのトークンを介して返信します。inbox:list のすべての行にある platform_id、または accounts:list で確認できます。
  • リスト行のプラットフォームのフィールド名は platform(platform_type ではありません)ですが、書き込みコマンドでは --platform-type を指定します。

読み取り

コマンド用途
inbox:list受信トレイを検索します。--type conversation|post|review(繰り返し指定可能)、--action all|marked_done|archived|assigned、--search、--tag、--channels '{"facebook":["<acct>"]}'、--page、--limit
inbox:summaryバケットごとの件数を表示します。「未読はありますか?」に答える手軽な方法です。
inbox:messages <conversation_id>DM スレッド内のメッセージです。ID = element_details.element_id。--sort-order asc|desc
inbox:comments <post_id>投稿のコメント(スレッド形式)です。ID = element_details.post_id
inbox:notes <conversation_id>内部メモ(チーム専用)です。ID = element_details.element_id。ページネーションあり
inbox:bookmarks <conversation_id>スター付きメッセージです。ID = element_details.element_id。ページネーションあり
inbox:contact <element_ref>項目に関連付けられた連絡先プロフィールです
inbox:tagsワークスペースの受信トレイタグ一覧です

返信 — 顧客に表示されるため、送信前に確認してください

コマンド用途
inbox:send <conversation_id>DM を送信します(ID = element_details.element_id)。--platform-type facebook|instagram、--platform-id、および --message と/または --file が必要です。--idempotency-key で再試行時の重複を防止します
inbox:comment-add <post_id>投稿にコメントします。--comment-id を指定するとスレッド形式の返信になり、--private-reply を指定すると代わりに Facebook DM を送信します。--attachment <path> でファイルを添付します
inbox:review-reply <review_id>レビューへの返信を追加または置き換えます(アップサート)。--platform-id、--reply
inbox:note-add <conversation_id>内部メモを追加します。--mention <user_id>(繰り返し指定可能)。顧客には表示されません

トリアージとモデレーション

コマンド用途
inbox:mark-read <element_ref>既読にします(冪等)
inbox:update状態を一括変更します。--element(繰り返し指定可能、最大 100 件)に加え、--status done|pending、--archived、--assigned のうちちょうど 1 つを指定します(--assigned-to '{"id":"<user>"}' と組み合わせます)
inbox:comment-hide / inbox:comment-unhide <comment_id>非表示/再表示にします。再表示には --platform-type と --platform-id が必要です
inbox:comment-like / inbox:comment-unlike <comment_id>Facebook のみ
inbox:comment-delete <comment_id>削除します。--platform-type と --platform-id が必要です。LinkedIn では --comment-urn も必要です
inbox:star / inbox:unstar <message_id>メッセージにスターを付けます/外します
inbox:message-delete <message_id>メッセージを論理削除します。--platform-id
inbox:review-reply-delete <review_id>レビューへの返信を削除します。--platform-id
inbox:contact-update <element_ref>--platform-id に加え、--name、--email、--phone、--company のいずれかを指定します
タグ
コマンド目的
inbox:tag-create--name(≤50)、--color — #33aa55 のような 16 進数の値。(古いタグでは color_1 と表示されることがありますが、現在 API ではこの形式は拒否されます。)
inbox:tag-update <tag_id>--name および/または --color
inbox:tag-delete--tag <id>(繰り返し指定可能、一括処理)
inbox:tag-mergeタグを新しいタグに統合します:--name、--color、--tag(繰り返し指定可能)
inbox:tag-attach <element_ref>--tag(繰り返し指定可能)、--platform-id、--inbox-type
inbox:tag-detach <element_ref> <tag_id>--platform-id、--inbox-type

受信トレイのページネーションに関する注意。 受信トレイの一覧コマンドでは、--per-page ではなく --limit を使用します(--per-page も別名として使用できます)。上のセクションに記載されたページネーションのルールはそのまま適用されます。pagination.has_more が true の場合、最初のページを受信トレイ全体として報告しないでください。

受信トレイのページサイズは 200 です。 それを超える受信トレイでは、--limit を 200 より大きくするのではなく、pagination.last_page まで --page 1、--page 2、…とページを取得してください。

受信トレイの制限。 CLI はこれらをローカルで検証するため、リクエストが送信される前に ConfigError として表示されます。

制限対象
--limit ≤ 200inbox:list、inbox:messages、inbox:comments
1 回の呼び出しにつき --element 参照は ≤ 100 件inbox:update
1 回の呼び出しにつき操作は1 つだけinbox:update — --status、--archived、--assigned は相互に排他的です。コマンドを分けて実行してください
タグ名は ≤ 50 文字inbox:tag-create

一括更新の部分的な成功。 一部の要素は更新され、残りは更新されなかった場合、inbox:update は HTTP 207 を返し、未更新の要素を missing_ids に列挙します。CLI はこれを警告として報告します。missing_ids が空でない場合は、バッチ全体が適用されたと報告するのではなく、変更されなかった要素をユーザーに伝えてください。

inbox:contact-update は連絡先全体を更新します。 連絡先は人であり、要素ごとの属性ではないため、変更はワークスペース内のそのアカウントにある、その連絡先に紐づくすべての要素に適用されます。レスポンスの updated_count に更新された件数が示されます。実行前に、この適用範囲をユーザーに伝えてください。

inbox:contact は個人データを返します。 顧客のメールアドレスと電話番号です。ユーザーが実際に求めたフィールドだけを返してください。求められていないのにレコード全体を要約に載せたり、永続的に保存される場所へ貼り付けたりしないでください。

inbox:messages にはアクティビティイベントも含まれます。 スレッドにはメッセージだけでなく、チームのアクティビティ記録も含まれます。アクティビティエントリは message: null と action ブロック(MARKED_AS_DONE、PENDING、ARCHIVED、…)を持ち、実行したチームメイトの名前が記載されます。また、total_messages とページネーションの件数にも含まれます。顧客のメッセージのみを対象とする場合は、action == null でフィルタリングしてください。アクティビティエントリをメッセージとして数えたり、顧客の発言として引用したり、最新の返信として扱ったりしないでください。CLI の human モードでは、これらは — marked as done — の行として表示されます。

返信はネストされており、ページネーションの対象ではありません。 inbox:comments では、返信は各スレッドの children の下にあり、トップレベルの行として個別に表示されることはありません。ページネーションで数えるのは個々のコメントではなくスレッド(total_threads)です。そのため、ページネーションブロックの「12 comments」は 12 スレッドを意味し、各スレッド内にはさらに多くの返信が含まれている場合があります。

送信時の 409 の処理。 inbox:send と inbox:comment-add で 409 が返された場合、配信結果は不明です。メッセージが顧客に届いた場合も、届かなかった場合もあります。CLI はこれを ConflictError として表示します。自動で再試行しないでください。inbox:messages で会話を再取得して届いたか確認し、再送信する前に確認結果をユーザーに伝えてください。

送信の確認。 inbox:send は sent_message.id_status を返します。値が unavailable の場合、プラットフォームは ID を返さずにメッセージを受け付けたため、後で照合するための ID はありません。配信は未確認であることを添えて、送信済みとして報告してください。 受信トレイ固有の応答。 inbox:* コマンドで 502 が返された場合、アイテムが存在しないのではなく、受信トレイサービスに一時的に接続できないことを示します。少し待ってから再試行してください。inbox:list の結果が空の場合は、正常に空のデータを取得できています。「見つかりません」ではなく、「一致する会話はありません」と報告してください。

アナリティクス

Facebook、Instagram、YouTube、Pinterest、LinkedIn、Google Business Profile、TikTok、Twitter/X、Meta Ads、Google Ads にわたる読み取り専用のパフォーマンスレポートと、ネットワーク横断の Campaigns & Labels レポート(合計133コマンド、バックエンドエンドポイントごとに1つ。汎用のパススルーはありません)。

ほとんどのコマンドでは、--platform-id(接続済みアカウント。accounts:list で確認できます)と、日付範囲またはネイティブ投稿IDのいずれかが必要です。広告とキャンペーン/ラベルの各コマンド群は例外です。詳細は以下を参照してください。

  • 日付範囲レポート — --start-date / --end-date(YYYY-MM-DD、両方必須)。多くのコマンドでは、任意で --timezone(IANA 名。既定値は UTC)、--date(範囲を上書きする 'YYYY-MM-DD - YYYY-MM-DD' 形式)、--limit / --offset、--order-by(選択肢はコマンドごとに異なります。--help を確認してください)、--media-type、--hashtags、--entity-type などの配列フィルター(複数の値にはフラグを繰り返します)も指定できます。
  • 単一アイテムの検索(*-single-post、*-single-pin、*-single-tweet、*-single-video)— --platform-id と --post-id(プラットフォームのネイティブID。ContentStudio 内部IDではありません)。日付範囲は不要です。
  • AI インサイトコマンド(*-ai-insights)では、さらに --type(コンパクトカードの場合は aiInsightsSummary、レポート全体の場合は aiInsightsDetailed)と --language(ISO 639-1。既定値は en)を指定します。どちらの広告プラットフォームにも、このコマンドがあります。
  • 広告レポート(analytics:meta-ads-*、analytics:google-ads-*)では、--platform-id ではなく --account-id を指定します。これは広告アカウントで、Meta では act_…、Google では顧客IDです。analytics:meta-ads-accounts / analytics:google-ads-accounts で確認できます。テーブルコマンドでは、--limit / --offset、--search、--order-by / --order-dir、ID フィルター(--campaign-id、--ad-set-id、--ad-group-id)も指定できます。チャートコマンドでは、--metric と --level も指定できます。analytics:*-ads-accounts ではアカウントの指定は不要です。アカウントを探すためのコマンドです。
  • Campaigns & Labels(analytics:campaigns-labels-*)は、POST を使う唯一のレポートです。フィルターはリスト形式なので、フラグを繰り返して指定します。--campaigns <id> --campaigns <id>、--labels <id>、およびネットワークごとのアカウントリスト(--facebook-accounts、--instagram-accounts、…)を指定してください。必須なのは --start-date / --end-date のみです。

任意のコマンドで正確なオプションを確認するには、contentstudio analytics:<command> --help を実行してください。必須/任意の別や列挙型の選択肢は、エンドポイントごとに異なります。

すべてのアナリティクスコマンドは読み取り専用です。キャンペーン/ラベルのコマンドが POST を使うのは、フィルターが配列だからにすぎません。そのため、どのコマンドにも --dry-run は指定できません(このフラグは、この CLI の別の場所にある変更を伴うコマンドにのみ存在します)。

コマンドから ANALYTICS_UPSTREAM_ERROR が返された場合(HTTP 200 で status: false。多くの場合、upstream_status: 401)、ContentStudio バックエンド独自のアナリティクスパイプラインで上流エラーが発生しています。リクエストが不正なわけではありません。「アナリティクスサービスは一時的に利用できません」と報告し、まったく同じ呼び出しをループで再試行しないでください。また、これをアカウントやワークスペースに問題がある証拠として扱わないでください。

Facebook(12)

コマンド目的必須
analytics:facebook-ai-insightsFacebook の AI 生成インサイト--platform-id, --start-date, --end-date
analytics:facebook-audience-growthFacebook のファン/フォロワー数の時系列推移--platform-id, --start-date, --end-date
analytics:facebook-audience-locationFacebook のオーディエンスの所在地(国/都市別の内訳)。--country で都市の一覧を絞り込めます--platform-id, --start-date, --end-date
analytics:facebook-engagementFacebook ページのエンゲージメントの時系列推移--platform-id, --start-date, --end-date
analytics:facebook-get-top-postsメディアタイプのフィルターを指定した Facebook の人気投稿--platform-id, --start-date, --end-date
analytics:facebook-impressionsFacebook ページのインプレッション数の時系列推移--platform-id, --start-date, --end-date
analytics:facebook-overview-top-postsFacebook の人気投稿(概要ウィジェット)--platform-id, --start-date, --end-date
analytics:facebook-publishing-behaviourインプレッションタイプ別の Facebook エンゲージメントの時系列推移--platform-id, --start-date, --end-date
analytics:facebook-reelsFacebook Reels のパフォーマンスの時系列推移--platform-id, --start-date, --end-date
analytics:facebook-single-postID を指定して Facebook の投稿を 1 件取得--platform-id, --post-id
analytics:facebook-summaryFacebook の概要 KPI — 現在と前の期間の比較--platform-id, --start-date, --end-date
analytics:facebook-video-insightsFacebook 動画の視聴時間と再生回数の時系列推移--platform-id, --start-date, --end-date

Instagram(15)

コマンド目的必須
analytics:instagram-active-usersInstagram のアクティブユーザー数(時間別、曜日別)--platform-id, --start-date, --end-date
analytics:instagram-ai-insightsInstagram の AI 生成インサイト--platform-id, --start-date, --end-date
analytics:instagram-audience-growthInstagram のフォロワー数の時系列推移--platform-id, --start-date, --end-date
analytics:instagram-country-cityInstagram のオーディエンスの国/都市別の内訳。--country で都市の一覧を絞り込めます--platform-id, --start-date, --end-date
analytics:instagram-demographics-ageInstagram のオーディエンスの年齢/性別の内訳--platform-id, --start-date, --end-date
analytics:instagram-engagementInstagram 投稿のエンゲージメントの時系列推移--platform-id, --start-date, --end-date
analytics:instagram-get-top-postsハッシュタグのフィルターを指定した Instagram の人気投稿--platform-id, --start-date, --end-date
analytics:instagram-hashtagsエンゲージメント別の Instagram 人気ハッシュタグ--platform-id, --start-date, --end-date
analytics:instagram-impressionsInstagram 投稿のインプレッション数の時系列推移--platform-id, --start-date, --end-date
analytics:instagram-publishing-behaviourメディアタイプ別の Instagram 投稿エンゲージメントの時系列推移--platform-id, --start-date, --end-date
analytics:instagram-reels-performanceInstagram Reels のエンゲージメントと視聴時間の時系列推移--platform-id, --start-date, --end-date
analytics:instagram-single-postID を指定して Instagram の投稿を 1 件取得--platform-id, --post-id
analytics:instagram-stories-performanceInstagram ストーリーズのインプレッション数、リーチ、インタラクションの時系列推移--platform-id, --start-date, --end-date
analytics:instagram-summaryInstagram の概要 KPI — 現在と前の期間の比較--platform-id, --start-date, --end-date
analytics:instagram-top-postsInstagram のパフォーマンス上位の投稿--platform-id, --start-date, --end-date

YouTube(20)

コマンド目的必須
analytics:youtube-ai-insightsYouTube が生成した AI インサイト--platform-id, --start-date, --end-date
analytics:youtube-demographicsYouTube の視聴者層データ — 年齢と性別、デバイスの種類、チャンネル登録者数の増減--platform-id, --start-date, --end-date
analytics:youtube-engagement-trendYouTube の累積エンゲージメントの経時的な傾向--platform-id, --start-date, --end-date
analytics:youtube-engagement-trend-dailyYouTube の日次増減によるエンゲージメントの傾向--platform-id, --start-date, --end-date
analytics:youtube-find-videoYouTube のトラフィックソースの内訳(視聴者が動画を見つけた方法)--platform-id, --start-date, --end-date
analytics:youtube-least-posts再生回数とエンゲージメントの順に並べた、YouTube のパフォーマンスが最も低い動画--platform-id, --start-date, --end-date
analytics:youtube-performance-schedule公開日別にグループ化した YouTube 動画のパフォーマンス指標--platform-id, --start-date, --end-date
analytics:youtube-publishing-behaviourYouTube の投稿数の経時的な推移とコンテンツタイプの内訳--platform-id, --start-date, --end-date
analytics:youtube-single-videoID で単一の YouTube 動画を取得--platform-id, --post-id
analytics:youtube-sorted-top-posts設定可能な指標で並べ替えた YouTube 動画--platform-id, --start-date, --end-date
analytics:youtube-subscriber-trendYouTube の累積チャンネル登録者数の経時的な推移--platform-id, --start-date, --end-date
analytics:youtube-subscriber-trend-dailyYouTube の日次増減によるチャンネル登録者数の推移--platform-id, --start-date, --end-date
analytics:youtube-summaryYouTube の概要 KPI — 現在の期間と前の期間の比較--platform-id, --start-date, --end-date
analytics:youtube-top-geographiesYouTube の上位地域 — 再生回数、総再生時間、視聴時間、視聴率の順に事前ソートされた国--platform-id, --start-date, --end-date
analytics:youtube-top-posts再生回数とエンゲージメントの順に並べた、YouTube の人気動画--platform-id, --start-date, --end-date
analytics:youtube-video-sharingYouTube の共有プラットフォームの内訳--platform-id, --start-date, --end-date
analytics:youtube-views-trendチャンネル登録者と未登録者に分けた YouTube の累積再生回数--platform-id, --start-date, --end-date
analytics:youtube-views-trend-dailyYouTube の日次増減による再生回数の傾向--platform-id, --start-date, --end-date
analytics:youtube-watch-time-trendチャンネル登録者と未登録者に分けた YouTube の累積総再生時間--platform-id, --start-date, --end-date
analytics:youtube-watch-time-trend-dailyYouTube の日次増減による総再生時間の傾向--platform-id, --start-date, --end-date

Pinterest(14)

コマンド目的必須
analytics:pinterest-ai-insightsPinterest による AI 生成インサイト--platform-id, --start-date, --end-date
analytics:pinterest-engagement-trendPinterest の累積エンゲージメントの経時的な推移--platform-id, --start-date, --end-date
analytics:pinterest-engagement-trend-dailyPinterest の日次差分エンゲージメントの推移--platform-id, --start-date, --end-date
analytics:pinterest-follower-trendPinterest の累積フォロワー数の経時的な推移--platform-id, --start-date, --end-date
analytics:pinterest-follower-trend-dailyPinterest の日次差分フォロワー数の推移--platform-id, --start-date, --end-date
analytics:pinterest-impressions-trendPinterest の累積インプレッション数の経時的な推移--platform-id, --start-date, --end-date
analytics:pinterest-impressions-trend-dailyPinterest の日次差分インプレッション数の推移--platform-id, --start-date, --end-date
analytics:pinterest-pin-performancePinterest のピンのパフォーマンス指標の経時的な推移--platform-id, --start-date, --end-date
analytics:pinterest-pin-postingPinterest の累積ピン投稿数の経時的な推移--platform-id, --start-date, --end-date
analytics:pinterest-pin-posting-dailyPinterest の日次差分ピン投稿数--platform-id, --start-date, --end-date
analytics:pinterest-pin-rollupPinterest のピンのパフォーマンス集計 — 現在の期間と前の期間--platform-id, --start-date, --end-date
analytics:pinterest-single-pinID で Pinterest のピンを 1 件取得--platform-id, --post-id
analytics:pinterest-summaryPinterest の概要 KPI — 現在の期間と前の期間--platform-id, --start-date, --end-date
analytics:pinterest-top-pinsPinterest のパフォーマンス上位および下位のピン--platform-id, --start-date, --end-date

LinkedIn(11)

コマンド目的必須
analytics:linkedin-ai-insightsLinkedIn による AI 生成インサイト--platform-id, --start-date, --end-date
analytics:linkedin-audience-growthLinkedIn のフォロワー数の経時的な増加--platform-id, --start-date, --end-date
analytics:linkedin-followers-demographics業界、国などの項目別に分類した LinkedIn フォロワーの属性--platform-id, --start-date, --end-date
analytics:linkedin-get-top-postsハッシュタグおよびメディアタイプで絞り込んだ LinkedIn の人気投稿--platform-id, --start-date, --end-date
analytics:linkedin-hashtagsエンゲージメント別の LinkedIn 人気ハッシュタグ--platform-id, --start-date, --end-date
analytics:linkedin-page-viewsLinkedIn ページビューの経時的な推移(デスクトップとモバイル)--platform-id, --start-date, --end-date
analytics:linkedin-posts-per-days曜日別の LinkedIn 投稿数の分布--platform-id, --start-date, --end-date
analytics:linkedin-publishing-behaviourメディアタイプ別の LinkedIn 投稿エンゲージメントの経時的な推移--platform-id, --start-date, --end-date
analytics:linkedin-single-postID で LinkedIn の投稿を 1 件取得--platform-id, --post-id
analytics:linkedin-summaryLinkedIn の概要 KPI — 現在の期間と前の期間--platform-id, --start-date, --end-date
analytics:linkedin-top-postsLinkedIn のパフォーマンス上位の投稿--platform-id, --start-date, --end-date

Google Business Profile(GMB)(10)

コマンド目的必須
analytics:gmb-actionsGMB の顧客アクション(クリック、通話、ルート検索)の推移--platform-id, --start-date, --end-date
analytics:gmb-ai-insightsGMB の AI 生成インサイト--platform-id, --start-date, --end-date
analytics:gmb-impressionsGMB のチャネル別、デバイス別インプレッション内訳の推移--platform-id, --start-date, --end-date
analytics:gmb-media-activityGMB のメディア(写真/動画)アクティビティの推移--platform-id, --start-date, --end-date
analytics:gmb-publishing-behaviorGMB の投稿数の推移とトピックタイプ別内訳--platform-id, --start-date, --end-date
analytics:gmb-reviewsGMB のレビュー — 評価、分布、日別アクティビティ--platform-id, --start-date, --end-date
analytics:gmb-search-keywordsリスティングが表示された GMB の検索キーワード上位--platform-id, --start-date, --end-date
analytics:gmb-single-postID を指定して単一の GMB 投稿を取得--platform-id, --post-id
analytics:gmb-summaryGMB の概要 KPI — 現在の期間と前の期間の比較--platform-id, --start-date, --end-date
analytics:gmb-top-postsGMB のパフォーマンス上位の投稿--platform-id, --start-date, --end-date

TikTok(8)

コマンド目的必須
analytics:tiktok-ai-insightsTikTok の AI 生成インサイト--platform-id, --start-date, --end-date
analytics:tiktok-engagement-trendTikTok の日別エンゲージメント推移--platform-id, --start-date, --end-date
analytics:tiktok-follower-trendTikTok のフォロワー数と再生回数の推移--platform-id, --start-date, --end-date
analytics:tiktok-publishing-behaviourTikTok の日別投稿数とエンゲージメント内訳の推移--platform-id, --start-date, --end-date
analytics:tiktok-single-postID を指定して単一の TikTok 投稿を取得--platform-id, --post-id
analytics:tiktok-sorted-top-posts設定可能な指標で並べ替えた TikTok 投稿--platform-id, --start-date, --end-date
analytics:tiktok-summaryTikTok の概要 KPI — 現在の期間と前の期間の比較--platform-id, --start-date, --end-date
analytics:tiktok-top-postsTikTok のパフォーマンス上位および下位の投稿--platform-id, --start-date, --end-date

Twitter/X(7)

コマンド目的必須
analytics:twitter-credits-usedワークスペースでの Twitter API クレジット使用量--platform-id, --start-date, --end-date
analytics:twitter-engagement-impressionTwitter のエンゲージメントとインプレッションの推移--platform-id, --start-date, --end-date
analytics:twitter-followers-trendTwitter のフォロワー数の推移--platform-id, --start-date, --end-date
analytics:twitter-least-tweetsTwitter のパフォーマンス下位のツイート--platform-id, --start-date, --end-date
analytics:twitter-single-tweetID を指定して単一の Twitter/X ツイートを取得--platform-id, --post-id
analytics:twitter-summaryTwitter の概要 KPI — 現在の期間と前の期間の比較--platform-id, --start-date, --end-date
analytics:twitter-top-tweetsTwitter のパフォーマンス上位のツイート--platform-id, --start-date, --end-date

Meta Ads(11)

コマンド用途必須
analytics:meta-ads-accounts接続済みの Meta 広告アカウントを一覧表示します—
analytics:meta-ads-ad-sets広告セットごとの指標を含む広告セット一覧--account-id, --start-date, --end-date
analytics:meta-ads-ads広告ごとの指標とクリエイティブの詳細を含む広告一覧--account-id, --start-date, --end-date
analytics:meta-ads-ai-insights広告アカウントに関する AI 生成インサイト--account-id, --start-date, --end-date, --type
analytics:meta-ads-campaignsキャンペーンごとの指標を含むキャンペーン一覧--account-id, --start-date, --end-date
analytics:meta-ads-demographics年齢、性別、地域または国別のオーディエンス内訳--account-id, --start-date, --end-date
analytics:meta-ads-performance-by-levelキャンペーン、広告セット、または広告別に分類した単一の指標--account-id, --start-date, --end-date
analytics:meta-ads-performance-by-placementパブリッシャープラットフォームと配置別に分類した単一の指標--account-id, --start-date, --end-date
analytics:meta-ads-performance-over-time1 つ以上の指標の日次時系列--account-id, --start-date, --end-date
analytics:meta-ads-results-by-objectiveキャンペーンの目的別にグループ化した成果と消化金額--account-id, --start-date, --end-date
analytics:meta-ads-summaryMeta Ads の主要 KPI — 現期間と前期間の比較--account-id, --start-date, --end-date

Google Ads(17)

コマンド用途必須
analytics:google-ads-accounts接続済みの Google Ads アカウントを一覧表示します—
analytics:google-ads-ad-groups広告グループごとの指標を含む広告グループ一覧--account-id, --start-date, --end-date
analytics:google-ads-ads広告ごとの指標を含む広告一覧--account-id, --start-date, --end-date
analytics:google-ads-ai-insights広告アカウントに関する AI 生成インサイト--account-id, --start-date, --end-date, --type
analytics:google-ads-campaignsキャンペーンごとの指標を含むキャンペーン一覧--account-id, --start-date, --end-date
analytics:google-ads-conversion-actionsアカウントに設定されているコンバージョン アクション--account-id, --start-date, --end-date
analytics:google-ads-conversion-funnelコンバージョンファネル — インプレッションからコンバージョンまで--account-id, --start-date, --end-date
analytics:google-ads-conversions-by-actionコンバージョン アクション別にグループ化したコンバージョン--account-id, --start-date, --end-date
analytics:google-ads-conversions-over-time時系列でのコンバージョン--account-id, --start-date, --end-date
analytics:google-ads-demographics年齢、性別、地域別のオーディエンス内訳--account-id, --start-date, --end-date
analytics:google-ads-keywordsキーワードごとの指標を含むキーワード一覧--account-id, --start-date, --end-date
analytics:google-ads-performance-by-levelキャンペーン、広告グループ、または広告別に分類した単一の指標--account-id, --start-date, --end-date
analytics:google-ads-performance-by-typeキャンペーンタイプ別に分類した単一の指標--account-id, --start-date, --end-date
analytics:google-ads-performance-over-time1 つ以上の指標の日次時系列--account-id, --start-date, --end-date
analytics:google-ads-search-terms検索語句ごとの指標を含む検索語句一覧--account-id, --start-date, --end-date
analytics:google-ads-shoppingショッピングキャンペーンの商品パフォーマンス--account-id, --start-date, --end-date
analytics:google-ads-summaryGoogle Ads の主要 KPI — 現期間と前期間の比較--account-id, --start-date, --end-date

キャンペーンとラベル(5)

コマンド用途必須
analytics:campaigns-labels-breakdownキャンペーン別・ラベル別の合計値、当期と前期の比較--start-date, --end-date
analytics:campaigns-labels-insights-breakdownキャンペーン別・ラベル別の日次時系列データ--start-date, --end-date
analytics:campaigns-labels-posts選択したキャンペーンとラベルの投稿別テーブル--start-date, --end-date
analytics:campaigns-labels-summaryキャンペーンとラベルの概要 KPI — 当期と前期の比較--start-date, --end-date
analytics:campaigns-labels-top-posts選択したキャンペーンとラベルのネットワーク別トップ 5 投稿--start-date, --end-date
アナリティクス:レポート、スケジュール、共有リンク

レポート生成は非同期です。reports:generate はすぐに ID を返し、処理は別の場所で行われます。そのため、作成レスポンスを完成したレポートとして扱わないでください。reports:get <id> --wait でポーリングするか、代わりに --callback-url を渡して通知を受け取ります。status が completed になり、export_url に値が入るとレポートは完了です。failed も終端状態です。reports:retry はリクエストを再構築せず、保存済みの定義から再実行します。

推測で進めず、まず reports:options を実行してください。これは、このワークスペースで生成できるレポートの種類と、それぞれで使用できるセクションを返します。また、製品内のセクション選択機能が参照するものと同じカタログです。

2 種類の競合レポートで指定するのは、アカウントではなく競合セットです。 facebook_competitor と instagram_competitor は保存済みのセットから生成されるため、competitor-reports:list から取得した --competitor-report-id が必要で、--accounts は無視されます。セット ID を --accounts に指定するのはよくある間違いですが、呼び出しが送信される前に拒否されます。以前は受け付けられた後に破棄され、数分後に「Combined report generation failed」として表面化していました。

⚠️ share-links:* コマンドは動作しません。どれも 404 になります。 これらのコマンドは /api/v1/workspaces/{w}/analytics/share-links を対象にしていますが、そのようなルートは存在しません。アナリティクスの共有リンクは、内部 SPA API(単数形のパスセグメントと異なる動詞を使う /api/analytics/share-link/create|list|update|delete)でのみ提供されています。この API は、API キーでは満たせないセッション/JWT 認証の背後にあるため、単純に接続先を変更することもできません。

認証、ワークスペース、キーの問題としてデバッグしたり、再試行したりしないでください。 呼び出し元側で修正できることはありません。ユーザーがアナリティクスダッシュボードを共有したい場合は、公開 API からは利用できないことを伝え、代わりに ContentStudio のウェブアプリ(Analytics → レポート → Share)を案内してください。

このセクションのその他のすべて(reports:*、report-schedules:*、competitor*:*)には影響がなく、通常どおり動作します。

アナリティクスダッシュボードの共有は、ウェブアプリのみで利用できる機能です。 クライアントはアカウントがなくても、数値をリアルタイムで表示するダッシュボードを確認できますが、そのリンクはウェブアプリで作成する必要があります。この API では提供されません(上記の警告を参照)。リンクには有効期限がありません。アプリで無効化または削除されるまで有効です。クライアントとの契約が一時停止しただけの場合は、後から戻せる無効化を選ぶのがおすすめです。このリンクは生成済みレポートとは別のもので、PDF ではなくリアルタイムのダッシュボードを表示します。

planner-share-links:* と混同しないでください。 こちらはクライアントのコメントや承認のために、スケジュール済みの投稿を共有する機能で、この API で完全にサポートされています。ユーザーが単に「共有リンク」と言った場合は、何を指しているのか確認してから操作してください。Planner share links の注意書きを参照してください。

report-schedules:run は即時送信をリクエストしますが、API はレポート ID を返さずにリクエストを受け付けたことだけを通知します。レポートが送信されたと伝える前に、report-schedules:get で確認し、last_run_at が更新されていることを確かめてください。

分析:競合他社

「レポート」という言葉は、異なる2つのものを指します。競合他社レポートは、ベンチマーク対象として保存された競合他社のセットです。ステータスはなく、ファイルも生成しません。比較数値は別途、competitors:compare で読み取ります。

作成の順序が重要です。競合他社は単なる ID ではなく、オブジェクト(competitor_id と name)なので、最初に competitors:search を実行してください。competitor-reports:create は、簡略形式の --competitors 'id:Name,id:Name' または JSON 配列を受け取り、自動的に展開します。

追跡できないページは、reason を含む空の結果として返されます。これは読み取りの成功であり、エラーではありません。失敗として報告するのではなく、追跡できなかったページとその理由をユーザーに伝えてください。

competitor-reports:update はセットを置き換えるため、新しい競合他社だけでなく、残したい競合他社をすべて送信してください。

比較データを読み取るときは、各行の state を確認してください。期間全体の測定が完了しているのは Processed のみです。それ以外の状態の競合他社に表示されるゼロは、測定されていないことを意味し、エンゲージメントがゼロという意味ではありません。これらを結果として提示しないでください。


例

保存されているキーが有効か確認する
contentstudio --json auth:whoami
# → {"ok": true, "data": {"id": "...", "email": "...", "full_name": "..."}}
投稿先の Facebook アカウントを見つける
contentstudio --json accounts:list --platform facebook --per-page 10
# Pick an _id, e.g. <account_id>
投稿作成後の例

変更を伴う投稿は、必ず最初に --dry-run を付けてプレビューしてください。{"ok": true, "data": {"dry_run": true, "endpoint": "...", "body": {...}}} が返され、API には一切アクセスしません。実際に作成するには --dry-run を外します。

1. プレーンテキストの下書き

contentstudio --json posts:create \
  -c "Our new blog is live!" \
  -i <account_id> \
  -t draft

2. テキスト+画像1枚、日付を指定して予約

contentstudio --json posts:create \
  -c "Our new blog is live! https://example.com/post" \
  -i <account_id> \
  -t scheduled \
  -s "2026-05-01 10:00:00" \
  -m https://example.com/hero.jpg

3. テキスト+複数画像(-m を繰り返します)

contentstudio --json posts:create \
  -c "Gallery drop 📸" \
  -i <account_id> \
  -t scheduled \
  -s "2026-05-02 09:00:00" \
  -m https://example.com/1.jpg \
  -m https://example.com/2.jpg \
  -m https://example.com/3.jpg

4. テキスト+動画

contentstudio --json posts:create \
  -c "Watch our launch reel 🎬" \
  -i <account_id> \
  -t scheduled \
  -s "2026-05-03 12:00:00" \
  --video-url https://example.com/launch.mp4

5. キューに追加する投稿(公開キューに入ります。時刻の明示的な指定はありません)

contentstudio --json posts:create \
  -c "Filler post for the queue" \
  -i <account_id> \
  -t queued

6. コンテンツカテゴリの投稿(アカウントはカテゴリから取得されます。--account は指定しません)

# Find a category id first:
contentstudio --json categories:list
# --content-category-id is required for -t content_category:
contentstudio --json posts:create \
  -c "Evergreen tip of the day" \
  -t content_category \
  --content-category-id <category_id>

7. 承認ワークフロー付きの投稿(承認者2名、全員の承認が必要です)

contentstudio --json posts:create \
  -c "Quarterly results announcement" \
  -i <account_id> \
  -t scheduled \
  -s "2026-05-05 08:00:00" \
  --approver <user_id_1> \
  --approver <user_id_2> \
  --approve-option everyone \
  --approval-notes "Legal + comms must both sign off"

8. ラベルとキャンペーンを指定した投稿(--label を繰り返します)

contentstudio --json posts:create \
  -c "Spring sale kickoff" \
  -i <account_id> \
  -t scheduled \
  -s "2026-05-06 10:00:00" \
  --label <label_id_1> \
  --label <label_id_2> \
  --campaign-id <campaign_id>

9. Facebook の背景色付きテキスト投稿(プレーンテキスト、メディアなし)

# Get a valid background id first:
contentstudio --json facebook:text-backgrounds
contentstudio --json posts:create \
  -c "Big news coming soon!" \
  -i <facebook_account_id> \
  -t draft \
  --facebook-background-id <background_id>

10. Facebook のカルーセル(Facebook のみ。カード2〜10枚) — プレビューしてから作成

# Preview:
contentstudio --json posts:create --dry-run \
  -c "Shop the new collection" \
  -i <facebook_account_id> \
  -t scheduled \
  -s "2026-07-01 10:00:00" \
  --facebook-carousel '{"cards":[{"image":"https://e.com/1.jpg","link":"https://e.com/p1","title":"Tee","description":"100% cotton"},{"image":"https://e.com/2.jpg","link":"https://e.com/p2","title":"Hoodie"},{"image":"https://e.com/3.jpg","link":"https://e.com/p3","title":"Cap"}],"call_to_action":"SHOP_NOW","end_card":true,"end_card_url":"https://e.com/shop"}'
# Drop --dry-run to create. The CLI adds "is_carousel_post": true.

カルーセルと背景色付きテキスト投稿(--facebook-background-id、例9)は、Facebook の異なる形式です。同じ投稿で両方を使わず、どちらか一方を使用してください。FB アカウント ID は -i / --account に指定します。

11. Threads の複数スレッド投稿(Threads のみ。連結できる項目は最大10件) — プレビューしてから作成

contentstudio --json posts:create --dry-run \
  -c "🧵 A thread on shipping CLIs" \
  -i <threads_account_id> \
  -t draft \
  --threads '[{"message":"1/ Start small."},{"message":"2/ Ship a demo.","media":["https://e.com/demo.mp4"]},{"message":"3/ Iterate in public."}]'
# Drop --dry-run to create. The CLI adds "has_multi_threads": true.

トップレベルの -c / --content は先頭の投稿です。各 --threads 項目は、順番に連結される返信です。項目内で先頭のテキストを繰り返さないでください。続きとして 1/、2/、…のように番号を付けます。各項目には message または media が必要です。

12. 最初のコメント付き投稿(公開後にコメントを自動投稿します。例:「プロフィールのリンク」) — プレビューしてから作成

contentstudio --json posts:create --dry-run \
  -c "New drop is live 🎉" \
  -i <account_id> \
  -t draft \
  --first-comment "🔗 link in bio" \
  --first-comment-account <account_id>
# Drop --dry-run to create. --first-comment-account is REQUIRED by the backend
# and must be a subset of the -i / --account IDs, else the API returns a 422.

13. Twitter/X のスレッド形式のツイート(Twitter のみ。最大10件) — プレビューしてから作成

contentstudio --json posts:create --dry-run \
  -c "Why we built a CLI 🧵" \
  -i <twitter_account_id> \
  -t draft \
  --twitter '[{"message":"1/ Start with the contract."},{"message":"2/ Show, don'\''t tell.","media":["https://e.com/x.jpg"]},{"message":"3/ Ship it."}]'
# Drop --dry-run to create. The CLI adds "has_threaded_tweets": true.
# Twitter rule: no mixed media in one tweet (no images+video together), max 1 video per tweet.

トップレベルの -c / --content は先頭のツイートです。各 --twitter 項目は、順番に連結されるフォローアップのツイートです。項目内で先頭のテキストを繰り返さないでください。続きとして 1/、2/、…のように番号を付けます。各項目には message または media が必要です。Twitter アカウント ID は -i / --account に指定します。

14. --body <file.json> による完全制御の本文(ショートカットフラグで指定できないフィールドに対応)

ショートカットフラグで指定できないフィールド(プラットフォームごとの platform_overrides、twitter_options/threads_options、timezone、hide_client など)が必要な場合は、--body を使用します。以下の ID 正規化を除き、JSON は記述したとおりに送信されるため、accounts に含まれるプラットフォーム向けに作成してください。Facebook のカルーセル本文、Threads の本文、Twitter の本文は、それぞれ個別の投稿であり、1つにまとめたペイロードではありません。

ラベルとキャンペーンは、返された labels:list/campaigns:list オブジェクトではなく、ID で指定してください。 API が受け付けるのは "labels": ["<label_id>"] と "campaign_id": "<campaign_id>" で、予約時刻は execute_time ではなく scheduling.scheduled_at です。CLI は、認識できる形式({ "id": … }/{ "_id": … }、単独の campaign キー、execute_time)を書き換え、ID のないラベルやキャンペーンは拒否するため、一覧の出力を基に記述した本文も引き続き使用できます。書き換えられない項目がある場合は、以前返されていた 500 {"message": "Server Error"} ではなく、フィールド名(errors: { "labels.0": [...] } など)を示す 400 の検証エラーが返されます。それでも、記載されている形式で記述してください。正規化は安全策であり、仕様ではありません。

// /tmp/post.json — a Facebook carousel via the full body schema
{
  "content": { "text": "Shop the collection" },
  "accounts": ["<facebook_account_id>"],
  "scheduling": { "publish_type": "scheduled", "scheduled_at": "2026-07-01 10:00:00" },
  "facebook_options": {
    "carousel": {
      "is_carousel_post": true,
      "cards": [
        { "image": "https://e.com/1.jpg", "link": "https://e.com/p1", "title": "Tee" },
        { "image": "https://e.com/2.jpg", "link": "https://e.com/p2", "title": "Hoodie" }
      ],
      "call_to_action": "SHOP_NOW",
      "end_card": true,
      "end_card_url": "https://e.com/shop"
    }
  },
  "labels": ["<label_id>"],
  "campaign_id": "<campaign_id>",
  "approval": { "approvers": ["<user_id>"], "approve_option": "anyone", "notes": "please review" }
}
contentstudio --json posts:create --body /tmp/post.json

Threads または Twitter/X のスレッド投稿では、そのアカウントと対応するブロックを含む本文を使用します。たとえば、{ "content": {...}, "accounts": ["<threads_account_id>"], "scheduling": {...}, "threads_options": { "has_multi_threads": true, "multi_threads": [...] } } のようにします(Twitter/X の場合は twitter_options.threaded_tweets を使用します)。

最適な時間に投稿を予約する
# 1. Ask for the best slots. Omit --account for every connected account.
contentstudio --json scheduling:best-times --global-slots 3
# → data.meta.timezone            e.g. "Asia/Karachi"
#   data.global.top_recommendations[0]  {rank: 1, day: "Wednesday",
#                                        date: "2026-08-19", time: "14", score: 100}
#   data.meta.missing_entities     accounts with too little history (skipped)

# 2. Narrow it to the account you're actually posting to.
#    <platform>:<account_id> — both from one accounts:list row.
contentstudio --json scheduling:best-times \
  --account facebook:<account_id> --per-account-slots 3

# 3. Show the user the ranked slots and let them pick. Then schedule at that
#    slot's date + hour AS-IS — the times are already workspace-local, so
#    converting to UTC would move the post.
contentstudio --json posts:create \
  -c "Launch day is here." \
  -i <account_id> \
  -t scheduled \
  -s "2026-08-19 14:00:00" \
  --dry-run

# 4. Drop --dry-run once the user approves the time and the text.

data.global が null の場合、ワークスペースの履歴が十分ではありません。エラーとして報告しないでください。スキップされたアカウント(meta.missing_entities)を伝え、代わりにユーザーが選んだ時刻で予約することを提案してください。

画像を生成して公開する(2 ステップ)
# 0. Optional: see what is available. Both are configuration, so cache them.
contentstudio --json images:models
contentstudio --json images:tools

# 1. Show the user the prompt first — generating costs an image credit.
contentstudio --json images:generate \
  -p "Flat-lay of autumn coffee beans on linen, warm daylight" \
  --dimensions square_hd --dry-run

# 2. Generate. Takes seconds; --json gives you data.media_id.
MEDIA_ID=$(contentstudio --json images:generate \
  -p "Flat-lay of autumn coffee beans on linen, warm daylight" \
  --dimensions square_hd | jq -r '.data.media_id')

# 3. Attach it. media_id goes in as --media-id, unchanged.
contentstudio --json posts:create \
  -c "Autumn blend is back." -i <account_id> -t draft \
  --media-id "$MEDIA_ID" --dry-run

# 4. Drop --dry-run once the user approves the image and the text. That creates a
#    draft; to send it instead, swap `-t draft` for
#    `-t scheduled -s "YYYY-MM-DD HH:MM:SS"`. There is no publish-now type —
#    --publish-type takes scheduled|draft|queued|content_category.

media_id が null の場合は、persist_error を確認してください。画像は data.url に存在しますが、メディアライブラリには保存されていないため、posts:create --media-id では取得できません。原因を解消する(media_storage_full → ストレージを空ける)か、プロバイダーのリンクが期限切れになる前に URL を使用してください。

編集や連続処理も同じ方法で行います。ある結果の url を次の入力にします。

# Edit an existing image (the prompt describes the change, not the whole picture)
contentstudio --json images:generate \
  -p "Make the background a snowy street at dusk" \
  --image-url https://example.com/base.png

# Clean up a product shot, then restage it
URL=$(contentstudio --json images:remove-background \
        --image-url https://example.com/mug.png | jq -r '.data.url')
contentstudio --json images:product-image --product-image-url "$URL" \
  --instructions "on a marble kitchen counter, morning light"

# A tool's own controls — the escape hatch reaches every field the API declares
contentstudio --json images:tool image-to-image --body '{
  "prompt": "same mug, editorial magazine styling",
  "attachments": ["https://example.com/mug.png"],
  "aspect_ratio": "4:5"
}' --dry-run

画像サービスがダウンロードできる URL だけを渡してください。ローカルファイルを使う場合は、先にアップロードしてください。

URL=$(contentstudio --json media:upload --file ./mug.png | jq -r '.data.url')
contentstudio --json images:upscale --image-url "$URL"
最近の下書き投稿を一覧表示する
contentstudio --json posts:list --status draft --per-page 5
投稿を削除する(ソーシャルメディアからも削除)
contentstudio --json posts:delete <post_id> --delete-from-social
投稿に内部メモを追加する(非公開)
contentstudio --json comments:add <post_id> "Double-check the link" --note
1 回の呼び出しでワークスペースを上書きする
contentstudio --json --workspace <other_ws_id> posts:list --per-page 3
受信トレイをトリアージする:未返信の DM を見つけて返信する
# 1. Cheap check first — is there anything to do?
contentstudio --json inbox:summary

# 2. List open conversations
contentstudio --json inbox:list --type conversation --action all --limit 20
# → per row: element_ref, platform, platform_id,
#            element_details.element_id  ← THIS is the conversation id

# 3. Read the thread. Use element_details.element_id (looks like t_1234...),
#    NOT element_ref — element_ref here returns an empty list.
contentstudio --json inbox:messages t_10000000000000001 --sort-order desc --limit 10

# 4. Find the account that owns the thread (gives you --platform-id)
contentstudio --json accounts:list --platform facebook

# 5. Preview the reply — ALWAYS do this, and show the text to the user
contentstudio --json inbox:send <conversation_id> \
  --platform-type facebook \
  --platform-id <account_id> \
  --message "Hi! Your order shipped this morning — tracking is on the way." \
  --dry-run

# 6. Only after the user approves, drop --dry-run
コメントに返信してから、スパムコメントを非表示にする
# Threaded reply. <post_id> is element_details.post_id, not element_ref.
contentstudio --json inbox:comment-add <post_id> \
  --platform-type facebook --platform-id <account_id> \
  --comment-id <comment_id> \
  --message "Thanks for the kind words!" --dry-run

# Hide spam rather than deleting it (reversible)
contentstudio --json inbox:comment-hide <comment_id> --dry-run
複数の会話をまとめてクリアする
contentstudio --json inbox:update \
  --element <element_ref_1> --element <element_ref_2> \
  --status done --dry-run
フォローアップ用のタグを会話に付ける
contentstudio --json inbox:tags                       # find or create a tag id
contentstudio --json inbox:tag-attach <element_ref> \
  --tag <tag_id> --platform-id <account_id> --inbox-type conversation --dry-run

エラー処理

error.typehttp_status典型的なヒント
AuthError401, 403有効なキーで auth:login を実行してください。
NotFoundError404リソースが存在しないか、このワークスペースにありません。
ValidationError422API からの、Laravel 形式でフラット化されたフィールドエラーです。
ConflictError409リソースはすでに存在するか、送信の配信結果が不明です。送信を再試行する前に確認してください。
RateLimitError429少し待ってから再試行してください。AI 画像コマンドの制限は 30 分あたり 30 回で、次の利用には 1 分間すべて待つ必要があります。
CreditLimitError403AI 画像クレジット(images:*)が不足しています。クレジットを追加するか、次のサイクルまでお待ちください。課金は発生していません。auth:login を再実行しても解決しません。
BackendError5xx またはネットワークエラー少し時間を置いてから再試行してください。
ConfigError—(ローカル)API キーまたはワークスペースがありません。auth:login を実行するか、フラグを渡してください。

error.type だけではわからない重要な点が 2 つあります。

  1. posts:* は検証エラーに 400 を返し、それ以外のすべてのエンドポイントは 422 を返します。 400 は ValidationError ではなく、汎用の ContentStudioError(終了コード 1)に対応します。そのため、ステータスコードやエラータイプだけで「これは検証エラーか」を判断しないでください。
  2. 代わりに、安定した error_code に基づいて分岐してください。 API の本文は error.response にそのまま保持されるため、切り替えに使う値は error.response.error_code です。値は VALIDATION_ERROR、CONTENT_CATEGORY_NOT_FOUND、CONTENT_CATEGORY_ACCESS_DENIED、CONTENT_CATEGORY_IS_GLOBAL、CONTENT_CATEGORY_SHUFFLE_FAILED、CONTENT_CATEGORY_INVALID_ACCOUNT、CONTENT_CATEGORY_SLOT_NOT_FOUND、CONTENT_CATEGORY_SLOT_DUPLICATE、APPROVAL_WORKFLOW_NOT_FOUND、CANNOT_SET_DRAFT_AS_DEFAULT、REQUIRES_FORCE_DELETE、CASCADE_JOB_NOT_FOUND、SHARE_LINK_NOT_FOUND、SHARE_LINK_TOKEN_REVOKE_FAILED、RATE_LIMIT_EXCEEDED です。

失敗と取り違えないように注意すべき成功レスポンスも 2 つあります。next_slot: null を含む 200(category-slots:next)と、shuffled_posts_count: 0 を含む 200(categories:shuffle)です。どちらも正常な応答です。


このスキルを使用しない場合

  • ユーザーが自身の ContentStudio バックエンド(Laravel ソース)の実行方法について尋ねている場合。この CLI が通信するのはデプロイ済み API のみです。
  • v1 API で提供されていないタスク(例:請求情報の変更、ソーシャルアカウントへの初回接続。これらは ContentStudio のウェブ UI で行います)。

このスキルの正式なバージョンは、このファイルの先頭にある frontmatter の version: フィールドです。

コメント