ページの一覧

ドキュメント

API リファレンス

voicast の API(/v1)と音声の接続の一覧。認証・形式・各エンドポイントの入力と返り・エラー。

Markdown で見る

基本#

  • URL: https://api.voicast.jp/v1
  • 認証: Authorization: Bearer vk_live_… か vk_test_…。キーの環境(本番かテスト)の中だけを読み書きします
  • 形式: JSON。時刻は Unix ミリ秒、ID は接頭辞付きの文字列(agt_・ten_・call_・sess_・con_)
  • エラー: { error, message, details?, request_id }。種類はエラーと制限
  • 呼び出しの ID: すべての応答に x-request-id(req_…)が付きます。エラーの本文の request_id と同じです。問い合わせのときに伝えてください
  • 回数の上限: API キーごとに 1 分 600 回。応答の x-ratelimit-limit・x-ratelimit-remaining・x-ratelimit-reset(枠の終わり、Unix 秒)で残りが分かり、超えると 429 と Retry-After(秒)

API キーは管理画面の「API キー」で作ります(管理者以上)。サービスのサーバーだけに置き、ブラウザやアプリには渡しません。

エンドポイント#

メソッド パス 内容
POST /v1/agents 会話の設定の作成
GET /v1/agents 会話の設定の一覧
GET /v1/agents/{id} 会話の設定の取得
PUT /v1/agents/{id} 会話の設定の変更(新しい版)
GET /v1/agents/{id}/versions 版の一覧
DELETE /v1/agents/{id} 会話の設定の削除
POST /v1/tenants テナントの作成
GET /v1/tenants テナントの一覧
GET /v1/tenants/{id} テナントの取得
PATCH /v1/tenants/{id} テナントの変更
POST /v1/tenants/{id}/secret 接続の鍵の作り直し
DELETE /v1/tenants/{id} テナントの削除
GET /v1/calls 通話の一覧
GET /v1/calls/{id} 通話の取得
GET /v1/calls/by-provider/{providerCallId} サービスの側の ID で通話を引く
GET /v1/calls/{id}/transcript 文字起こし
POST /v1/sessions Web・アプリのセッションの作成
GET /v1/usage 利用の内訳
POST /v1/webhooks/portal Webhook の設定画面のリンク
GET /v1/billing 請求の状態(残高・オートチャージ・1 分の値段・支払い方法)
POST /v1/billing/topups チャージの URL
GET /v1/tools/secret 通話中の道具の署名の鍵
POST /v1/tools/secret/rotate 署名の鍵の作り直し
GET /v1/connectors 連携先の一覧
GET /v1/connections 連携の一覧
POST /v1/connections 連携の作成(API キー・URL)
GET /v1/connections/{id} 連携の取得
PATCH /v1/connections/{id} 連携の設定
GET /v1/connections/{id}/options 連携の設定の選択肢
DELETE /v1/connections/{id} 連携の解除
GET /v1/tenants/{id}/connections テナントの連携の一覧
POST /v1/tenants/{id}/connect-links 事業者がつなぐ画面のリンク

音声の接続(API キーは使いません):

方式 URL 内容
WebSocket wss://voice.voicast.jp/ws 電話(Twilio の Media Streams)
POST https://voice.voicast.jp/v1/webrtc/offer Web・アプリ(WebRTC の offer)
PATCH https://voice.voicast.jp/v1/webrtc/offer ICE の候補を足す

MCP(https://api.voicast.jp/mcp)は MCP を見てください。


会話の設定の作成#

POST /v1/agents
入力 型 内容
name string 名前(1〜100 文字)
config AgentConfig 会話の設定(会話の設定)

返り: 201 Agent(config 付き、version: 1)。誤りは 422 invalid_config(details に項目ごとの誤り)。

ts
type Agent = { id: string; name: string; version: number; config?: AgentConfig; created_at: number; updated_at: number };

type AgentConfig = {
  greeting: string;            // 最初のあいさつ(300 文字まで)
  persona: string;             // 役割と話し方(1,000 文字まで)
  fields: { key: string; label: string; required?: boolean; type?: 'text' | 'phone' }[]; // 1〜20 個
  handoff_when: string[];      // 人に引き継ぐ条件(20 個まで)
  closing: string;             // 聞き取りが終わったときの締め(300 文字まで)
  closing_answered?: string;   // よくある質問で用が済んだときの締め
  faq?: { q: string; a: string }[];  // 50 個まで
  domain?: string;             // 業種(音声認識の手がかり)
  vocabulary?: string[];       // 用語(音声認識の手がかり、200 個まで)
  voice?: string;              // 声の名前(既定 Aoede)
  speaking_rate?: number;      // 話す速さ(既定 1.15)
  tools?: AgentTool[];         // 通話中の道具(10 個まで)
  connectors?: ConnectorEntry[]; // 連携(10 個まで)
};

type AgentTool = {
  name: string; description: string; url: string; confirm?: boolean;
  parameters?: { properties: Record<string, { type: 'string' | 'number' | 'integer' | 'boolean'; description?: string; enum?: string[] }>; required?: string[] };
};

type ConnectorEntry =
  | { connector: string; actions: string[]; confirm?: string[] }   // プリセット
  | { connection: string; actions: string[]; confirm?: string[] }; // 決まった連携(con_…)

会話の設定の一覧#

GET /v1/agents

返り: { data: Agent[] }(config なし)。

会話の設定の取得#

GET /v1/agents/{id}?version=

version(1 以上の整数)を省くと、いまの版です。返り: Agent(config 付き)。無ければ 404。

会話の設定の変更#

PUT /v1/agents/{id}
入力 型 内容
name string 任意。省くといまのまま
config AgentConfig 全体を渡す

返り: Agent(新しい版)。進行中の通話は始まったときの版のまま続きます。

会話の設定の版の一覧#

GET /v1/agents/{id}/versions

返り: { data: [{ version, created_at }] }(新しい順)。

会話の設定の削除#

DELETE /v1/agents/{id}

返り: 204。使っているテナントがあれば 409 in_use。通話の記録は残ります。

テナントの作成#

POST /v1/tenants
入力 型 内容
external_id string サービスの側の顧客の ID。英数字と . _ : - の 1〜100 文字。環境の中で重ならないこと
name string 任意。表示名(100 文字まで)
agent_id string 任意。既定の会話の設定

返り: 201 Tenant と secret(接続の鍵 vts_…。このときだけ)。同じ external_id があれば 409 conflict。

ts
type Tenant = { id: string; external_id: string; name: string; agent_id: string | null; status: 'active' | 'disabled'; created_at: number };

テナントの一覧#

GET /v1/tenants

返り: { data: Tenant[] }。

テナントの取得#

GET /v1/tenants/{id}

返り: Tenant(接続の鍵は返しません)。

テナントの変更#

PATCH /v1/tenants/{id}
入力 型 内容
name string 任意
agent_id string | null 任意。null で外す
status active・disabled 任意。disabled で電話と Web・アプリの接続を止める

返り: Tenant。渡した項目だけが変わります。

接続の鍵の作り直し#

POST /v1/tenants/{id}/secret

返り: { secret, previous_secret_expires_at }。古い鍵も 24 時間は通ります。

テナントの削除#

DELETE /v1/tenants/{id}

返り: 204。接続できなくなり、テナントの連携も取り消します。通話の記録は残ります。同じ external_id でまた作れます。

通話の一覧#

GET /v1/calls?tenant_id=&cursor=&limit=
クエリ 内容
tenant_id 任意。テナントで絞る
cursor 任意。続きの位置(前の応答の next_cursor をそのまま渡す)
limit 任意。1〜100(既定 50)
before 任意。以前の形のページ送り(この started_at より前に始まったもの)。同じミリ秒に始まった通話を飛ばすことがあるので cursor を使います。cursor と一緒には使えません(422)

返り: { data: Call[], has_more, next_cursor }(始まった時刻の新しい順)。has_more が true のあいだ、next_cursor を cursor に渡して続きを読みます(has_more が false なら next_cursor は null)。

ts
type Call = {
  id: string; tenant_id: string; agent: { id: string; version: number };
  provider_call_id: string | null;   // Twilio の CallSid、Web・アプリはセッションの ID
  from: string | null;               // かけてきた番号(電話で from を渡したとき)
  started_at: number; ended_at: number | null; duration_ms: number | null;
  outcome: 'completed' | 'answered' | 'handoff' | 'hangup' | 'error' | null; reason: string | null;
  fields: Record<string, string> | null;
  summary: string | null; category: string | null; has_transcript: boolean;
  channel: 'phone' | 'web'; output: 'audio' | 'text';
  billed_yen: number | null;         // この通話の利用料(税別の円、小数 3 桁まで)。通話中は null
};

billed_yen は、チャージ式なら残高から引いた額(秒数 × 1 分の値段 ÷ 60)、請求書払いなら秒数 × 契約の 1 分の値段 ÷ 60 です。請求書は月の合計秒数を分に切り上げるので、通話ごとの額の合計とは少しずれます(料金と請求)。

通話の取得#

GET /v1/calls/{id}

返り: Call。

サービスの側の ID で通話を引く#

GET /v1/calls/by-provider/{providerCallId}

Twilio の CallSid(CA…)か、セッションの ID(sess_…)で引きます。Twilio の <Connect> の action で結果を見るのに使います。返り: Call。記録が無ければ 404。

文字起こし#

GET /v1/calls/{id}/transcript

返り: { call_id, turns: [{ role: 'assistant' | 'user', text }] }。通話が終わってから作られます。無ければ 404。

セッションの作成#

POST /v1/sessions
入力 型 内容
tenant_id string テナントの ID
agent_id string 任意。省くとテナントの既定
output audio・text 任意。既定 audio

返り: 201 { id, tenant_id, agent_id, output, client_token, expires_at, webrtc_url, ice_servers }。client_token(vct_…)は 2 分・1 回だけ。ice_servers([{ urls, username?, credential? }])は RTCPeerConnection の iceServers にそのまま渡します(STUN と、使えるときは期限の短い TURN)。client_token・webrtc_url・ice_servers だけをブラウザやアプリに渡します。

エラー: 402(balance_depleted・payment_overdue・spending_cap_reached)、409 tenant_disabled、422 no_agent・invalid_request。

利用の内訳#

GET /v1/usage?from=&to=&group_by=
クエリ 内容
from・to 日付(YYYY-MM-DD、日本時間。to はその日を含む)か Unix ミリ秒(to はその時刻を含まない)。省くと今月の始まりから今まで。366 日まで
group_by 任意。tenant・day・channel

返り:

ts
type Usage = {
  environment: 'live' | 'test'; from: number; to: number;
  group_by: 'tenant' | 'day' | 'channel' | null; unit_price_yen: number;
  total: { calls: number; seconds: number; minutes: number; amount_yen: number };
  data: (({ tenant: { id: string; external_id: string; name: string } } | { day: string } | { channel: 'phone' | 'web' })
        & { calls: number; seconds: number; minutes: number; amount_yen: number })[];  // group_by が無ければ []
  note: string;
};

数えるのは期間内に終わった通話です。amount_yen は税別の目安です(料金と請求)。

Webhook の設定画面のリンク#

POST /v1/webhooks/portal
入力 型 内容
frame_origin string 任意。iframe で埋め込む親のオリジン
locale ja・en 任意。画面の言葉(既定 ja)

返り: 201 { url, expires_at }(15 分有効)。送り先の URL・受け取るイベント・署名の鍵を登録する画面です(結果の受け取り)。Webhook の送信が使えないときは 503 unavailable。

請求の状態#

GET /v1/billing

API キーの組織の請求の状態を返します(本番とテストの環境で共通)。管理画面の「請求」と同じ内容です。

ts
type Billing = {
  organization_id: string; month: string;            // 今月(日本時間、YYYY-MM)
  contract: { payment_method: 'card' | 'invoice'; per_minute_yen: number; invoice_days_until_due: number };
  has_card: boolean;                                   // オートチャージに使うカードを保存したか
  usage: { calls: number; seconds: number; minutes: number };  // 今月の通話(本番とテストの合計)
  estimate_yen: number;                                // チャージ式は今月に引いた額、請求書払いは見込み
  balance: { yen: number; milli_yen: number; depleted: boolean; next_expiry: { yen: number; at: number } | null } | null;  // チャージ式だけ
  auto_recharge: { enabled: boolean; threshold_yen: number; amount_yen: number; monthly_cap_yen: number | null;
                   recharged_this_month_yen: number; failures: number; max_failures: number } | null;  // チャージ式だけ
  topup: { min_yen: number; max_yen: number; quick_yen: number[]; credit_months: number };
  spending_cap_yen: number | null; cap_reached: boolean;
  payment: { failed_at: number; grace_ends_at: number; suspended: boolean } | null;  // 請求書払いの支払いの遅れ
  tax: 'excluded'; tax_rate: number;
  // ほかに price・stripe_enabled・subscription_status・threshold
};

チャージ#

POST /v1/billing/topups
入力 型 内容
amount_yen integer チャージの金額(税別の円、500〜300,000)

返り: 201 { url, amount_yen, tax_yen }。url は Stripe の支払いの画面です。利用者がブラウザで開いて払うと、残高に足されます。範囲の外は 422、請求書払いの組織は 409 invoice_billing。オートチャージ・月の上限・カードの変更は管理画面で行います(料金と請求)。

道具の署名の鍵#

GET /v1/tools/secret

返り: { secret, previous_secret_expires_at }。secret(whsec_…)は環境の通話中の道具の呼び出しに付く署名の鍵です。previous_secret_expires_at は作り直したあと古い鍵も並べる期限(無ければ null)。

道具の署名の鍵の作り直し#

POST /v1/tools/secret/rotate

返り: { secret, previous_secret_expires_at }。作り直してから 24 時間は、古い鍵の署名も並べて送ります。そのあいだに自社の側の鍵を差し替えます。

連携先の一覧#

GET /v1/connectors

返り: { data: Connector[] }。

ts
type Connector = {
  id: string; name: string; description: string;
  category: 'scheduling' | 'crm' | 'notify' | 'custom'; auth: 'oauth2' | 'api_key' | 'webhook_url';
  available: boolean;      // この voicast で使える
  needs_setup: boolean;    // つないだあとに設定が要る
  notify: boolean;         // 通話のあとに通知する
  env_only: boolean;       // 環境の連携だけ(埋め込みの連携の画面に出ない)
  inputs: { name: string; type: 'text' | 'password' | 'url' | 'number' }[];
  actions: { name: string; tool: string; description: string; confirm: boolean }[]; // tool は AI に見せる名前
};

連携の一覧#

GET /v1/connections?tenant_id=

tenant_id を省くとすべて、空(?tenant_id=)なら環境の連携だけ、ID ならそのテナントの連携だけ。解除したものは出しません。返り: { data: Connection[] }。

ts
type Connection = {
  id: string; connector: string; tenant_id: string | null;
  label: string;           // 相手のアカウント名(clinic@example.com・ワークスペース #チャンネル など)
  status: 'active' | 'needs_setup' | 'needs_reauth';
  config: object; created_by: string | null; created_at: number; updated_at: number;
};

連携の作成(API キー・URL)#

POST /v1/connections
入力 型 内容
connector teams・shannon_booking・http API キーか URL を貼る連携先だけ
secret string API キー・Webhook の URL(1〜2,000 文字)
input object 任意。shannon_booking は { base_url }、http は { base_url, header }
tenant_id string 任意。テナントの連携にする。shannon_booking・http は環境の連携だけで、付けると 422 invalid_request

返り: 201 Connection。保存の前に 1 回試しに呼び、失敗は 422 verify_failed。ログインでつなぐ連携先(OAuth)は、連携の画面のリンクか管理画面でつなぎます。

連携の取得#

GET /v1/connections/{id}

返り: Connection。

連携の設定#

PATCH /v1/connections/{id}
入力 型 内容
config object 連携先ごとの設定。渡した項目だけ変わります

返り: Connection。設定待ち(needs_setup)の連携は active になります。誤りは 422 invalid_config。設定の形は連携を見てください。

連携の設定の選択肢#

GET /v1/connections/{id}/options

連携先に問い合わせて、設定で選べるものを返します。

連携先 クエリ 返り
Google カレンダー・Microsoft 365 { calendars: [{ id, name, primary }] }
Google スプレッドシート spreadsheet・sheet { spreadsheets, sheets, headers }
kintone app { apps, fields: [{ code, label }] }
Chatwork { rooms }
LINE WORKS { users }
MCP サーバー { tools }

連携が切れていれば 409 needs_reauth。

連携の解除#

DELETE /v1/connections/{id}

返り: 204。連携先のトークンも取り消します。

テナントの連携の一覧#

GET /v1/tenants/{id}/connections

返り: { data: Connection[] }。

連携の画面のリンク#

POST /v1/tenants/{id}/connect-links
入力 型 内容
connectors string[] 任意。画面に出す連携先(google_calendar・m365_calendar・google_sheets・kintone・hubspot・slack・chatwork・lineworks・teams)
frame_origin string 任意。iframe で埋め込む親のオリジン(https)

返り: 201 { url, expires_at }(15 分有効)。使い方は連携。


電話(Twilio Media Streams)#

wss://voice.voicast.jp/ws

Twilio の <Connect><Stream> の接続先です。<Parameter> で次を渡します。

Parameter 内容
tenant テナントの ID
secret テナントの接続の鍵(vts_…)
agent 任意。会話の設定の ID
from 任意。かけてきた番号

鍵が違う・テナントが止まっている・料金の都合で断るときは、すぐに閉じます。手順は電話でつなぐ。

WebRTC の offer#

POST https://voice.voicast.jp/v1/webrtc/offer
入力 型 内容
sdp・type string WebRTC の offer
token string セッションの client_token(Pipecat のクライアントは requestData.token でも可)
pc_id・restart_pc string・boolean つなぎ直しのときだけ(token は要らない)

返り: { sdp, type, pc_id }。トークンが違う・期限切れ・使用済み・料金の都合で断るときは 403(料金の都合はいずれ POST /v1/sessions と同じ 402 にそろえる予定です)。

つないだら、データチャンネルで RTVI の client-ready を送り、そのあと 1 秒ごとに ping の文字列を送ります(Web・アプリでつなぐ)。

ICE の候補#

PATCH https://voice.voicast.jp/v1/webrtc/offer
入力 型 内容
pc_id string offer の返りの pc_id
candidates array [{ candidate, sdp_mid, sdp_mline_index }]

返り: { ok: true }。知らない pc_id は 404。