開発者向け
お客様のシステムから、SMS・オートコール・FAX の一斉配信、クリックトゥコール、通話履歴の取得、 SIPプロファイルと発信プレフィックスの管理を自動化できます。配信結果や受信 FAX は Webhook で受け取れます。 本番の live とサンドボックスの test の 2 環境があり、 test ではメッセージが送信されず、料金も発生しません。
ベース URL: https://hub.naruko.app/api/public/v1
コンソールの「共通 → API キー」でキーを発行します。サンドボックスのキーは nrk_test_…、本番のキーは nrk_live_… で始まります。まずは test から始めるのがおすすめです。 このページで説明するすべての API を、同じキーで利用できます。
範囲の限定は、通話履歴・受信 FAX・配信・電話発信だけに働きます。 ほかの機能は、キャンペーンや電話番号を選んでも組織全体を扱えます。
| 機能 | 使用可能な API | 扱える範囲 |
|---|---|---|
| 通話履歴 | /calls | キャンペーン・電話番号に限定できる |
| 受信 FAX | /fax-receipts | キャンペーン・電話番号に限定できる |
| 配信 | /delivery-jobs・/media・/sender-numbers・/openai-realtime/{id}/test-call | キャンペーン・電話番号に限定できる |
| 連絡先 | /contacts・/contact-lists | 組織全体 |
| 電話発信 | /click-to-call | キャンペーン・電話番号に限定できる |
| キャンペーン設定 | /campaigns・/phonenumbers | 組織全体 |
| OpenAI 連携設定 | /openai-realtime。テスト発信だけは配信です | 組織全体 |
| PBX 接続 | /sip-profiles・/caller-id-prefixes | 組織全体 |

各リクエストに API キーを付けます。Authorization: Bearer <key> を推奨、代替として X-Api-Key: <key> も使えます。
curl https://hub.naruko.app/api/public/v1/me \
-H "Authorization: Bearer nrk_test_xxxxxxxx"
# {"account":{"id":1,"name":"…","status":"active","plan":null},"environment":"test"}Retry-After / X-RateLimit-* を返すので、Retry-After 秒待って再試行します。 すべて https://hub.naruko.app/api/public/v1 配下です。 「使える機能」は、API キーを発行するときに選ぶ機能です。選ばなかった機能の API を呼ぶと 403 になります。
| メソッド | パス | 使える機能 | 用途 |
|---|---|---|---|
| GET | /me | どのキーでも | 疎通確認。account と environment を返します |
| POST | /media | 配信 | 原稿のアップロード。media_id を返します |
| POST | /media/cover-sheet | 配信 | FAX 送付状の作成。media_id を返します |
| GET | /contacts | 連絡先 | 宛先の一覧・検索。q で名前・番号・メールを絞り込みます |
| POST | /contacts | 連絡先 | 宛先の登録。id を返します |
| GET | /contacts/{id} | 連絡先 | 宛先 1 件 |
| GET | /contact-lists | 連絡先 | 宛先リストの一覧 |
| GET | /sender-numbers | 配信 | 発信元番号の一覧。キャンペーンに割り当て済みのものを返します |
| GET | /campaigns | キャンペーン設定 | キャンペーンの一覧。割り当て済みの発信元番号も返します |
| POST | /campaigns | キャンペーン設定 | キャンペーンの作成 |
| DELETE | /campaigns/{id} | キャンペーン設定 | キャンペーンの削除。割り当てていた番号は未割当に戻ります |
| PUT | /campaigns/{id}/channels | キャンペーン設定 | 同時発信数の割当。購入済みの本数が上限です |
| POST | /campaigns/{id}/phonenumbers | キャンペーン設定 | 購入済みの番号をキャンペーンへ割り当てます |
| DELETE | /campaigns/{id}/phonenumbers/{phonenumber} | キャンペーン設定 | 番号の割当を解除します |
| PUT | /campaigns/{id}/default-sender | キャンペーン設定 | 既定の発信元を決めます |
| PUT | /campaigns/{id}/send-window | キャンペーン設定 | 送信可能時間帯の上書き |
| GET | /phonenumbers | キャンペーン設定 | 購入済みの電話番号の一覧。未割当のものも返します |
| POST | /delivery-jobs | 配信 | 一斉配信の受付。SMS・オートコール・FAX・email に対応します |
| GET | /delivery-jobs/{id} | 配信 | ジョブの状態取得 |
| GET | /delivery-jobs/{id}/deliveries | 配信 | 宛先単位の到達ログ |
| GET | /delivery-jobs/{id}/stats | 配信 | ジョブの集計。到達率と失敗率を返します |
| POST | /delivery-jobs/{id}/cancel | 配信 | ジョブのキャンセル |
| POST | /delivery-jobs/{id}/reschedule | 配信 | 予約日時の変更。予約中のジョブだけ変更できます |
| GET | /fax-receipts | 受信 FAX | 受信 FAX の一覧。新しい順に返します |
| GET | /fax-receipts/{id} | 受信 FAX | 受信 FAX 1 件 |
| GET | /fax-receipts/{id}/content | 受信 FAX | 受信 FAX の PDF 本文。期限はありません |
| GET | /calls | 通話履歴 | 通話履歴の一覧。新しい順に返します |
| GET | /calls/{uniqueid} | 通話履歴 | 通話 1 件 |
| GET | /openai-realtime | OpenAI 連携設定 | OpenAI Realtime API 連携の一覧。API キーとシークレットは返しません |
| POST | /openai-realtime | OpenAI 連携設定 | 連携の作成 |
| PATCH | /openai-realtime/{id} | OpenAI 連携設定 | 連携の更新。送信した項目にだけ適用されます |
| DELETE | /openai-realtime/{id} | OpenAI 連携設定 | 連携の削除。使っている番号があるときは confirm が要ります |
| POST | /openai-realtime/{id}/register-webhook | OpenAI 連携設定 | Webhook URL をお使いの OpenAI プロジェクトへ登録します |
| GET | /openai-realtime/{id}/connection-check | OpenAI 連携設定 | 設定がそろっているかを項目ごとに確認します |
| POST | /openai-realtime/{id}/inbound-token | OpenAI 連携設定 | 着信トークンの再生成。新しい値を返します |
| POST | /openai-realtime/{id}/test-call | 配信 | テスト発信。通話料が発生します |
| POST | /click-to-call | 電話発信 | クリックトゥコール。担当者を鳴らしてから顧客へつなぎます |
| POST | /sandbox/webhook-events | どのキーでも | サンドボックスでダミー Webhook を送信。test キー専用です |
コンソールの 連絡先 で作成した宛先リストへ一斉送信します。受付は 202 Accepted で job_id を返し、実送信は非同期です。 Idempotency-Key を付けると、リトライ時の二重受付を防げます。
curl -X POST https://hub.naruko.app/api/public/v1/delivery-jobs \
-H "Authorization: Bearer nrk_test_xxxxxxxx" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{
"send_type": "sms",
"content": { "text": "こんにちは" },
"target_spec": { "list_id": 123 }
}'
# 202 {"job_id":45,"status":"queued"}| 項目 | 指定できる値 |
|---|---|
send_type | sms / autocall / fax / email |
target_spec.list_id | 宛先リストへ送る |
target_spec.contact_ids | 宛先を 1 件ずつ指定して送る |
| status | 意味 |
|---|---|
sent | 送信を実行した |
delivered | 到達を確認した |
failed | 1 回の試行が失敗した |
dead | 再送の上限に達し確定失敗した |
status は Webhook で受け取るのが基本です。 お支払い方法が未登録のとき、sms / autocall / fax は 402 と payment_method_required を返します。
オートコールと FAX は、発信元番号をキャンペーンへ割り当て、同時発信数を決めてから送ります。 キャンペーン管理 と同じことを API でも行えます。番号と同時発信数の購入はコンソールで行ってください。
# 1. キャンペーンを作る
curl -X POST https://hub.naruko.app/api/public/v1/campaigns \
-H "Authorization: Bearer $NARUKO_TODOKE_KEY" -H "Content-Type: application/json" \
-d '{"name":"9 月キャンペーン"}'
# 201 {"campaign":{"id":12,...}}
# 2. 購入済みで、まだどこにも割り当てていない番号を探す
curl "https://hub.naruko.app/api/public/v1/phonenumbers?unassigned=1&kind=voice" \
-H "Authorization: Bearer $NARUKO_TODOKE_KEY"
# 3. 番号を割り当てる。1 本目は既定の発信元になります
curl -X POST https://hub.naruko.app/api/public/v1/campaigns/12/phonenumbers \
-H "Authorization: Bearer $NARUKO_TODOKE_KEY" -H "Content-Type: application/json" \
-d '{"phonenumber_id":123}'
# 4. 同時発信数を割り当てる
curl -X PUT https://hub.naruko.app/api/public/v1/campaigns/12/channels \
-H "Authorization: Bearer $NARUKO_TODOKE_KEY" -H "Content-Type: application/json" \
-d '{"channels":2}'購入済みの本数を全キャンペーンの合計が超える割当は 422 になります。
content.mode に realtime を指定すると、読み上げではなく AI が応答します。 話す内容は OpenAI Realtime API 連携 に設定した応答の指示で決まるため、読み上げ本文も音声ファイルも要りません。
curl -X POST https://hub.naruko.app/api/public/v1/delivery-jobs \
-H "Authorization: Bearer $NARUKO_TODOKE_KEY" -H "Content-Type: application/json" \
-d '{
"send_type": "autocall",
"content": {
"mode": "realtime",
"realtime_integration_id": 7,
"realtime_amd": true,
"sender_phonenumber_id": 123
},
"target_spec": { "contact_ids": [456] }
}'| 項目 | 意味 |
|---|---|
realtime_integration_id | どの連携で会話させるか。指定が無いと 422 になります |
realtime_amd | 留守番電話の判定。有効にすると、人が応答したと判定できたときだけ AI へつなぎます。判定には数秒を要し、その間は無音になります |
sender_phonenumber_id | 発信元番号。番号ごとの応答の指示もこれで決まります |
OpenAI のプロジェクト ID や API キーを API から設定できます。 使える機能で OpenAI 連携設定 を選んだキーが必要です。 更新は送信した項目にだけ適用されます。
# 連携の一覧。API キーと Webhook シークレットは返りません
curl https://hub.naruko.app/api/public/v1/openai-realtime \
-H "Authorization: Bearer $NARUKO_TODOKE_KEY" -H "Accept: application/json"
# プロジェクト ID を変更する
curl -X PATCH https://hub.naruko.app/api/public/v1/openai-realtime/7 \
-H "Authorization: Bearer $NARUKO_TODOKE_KEY" -H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{"openai_project_id":"proj_xxxxxxxxxxxx"}'
# Webhook URL をお使いの OpenAI プロジェクトへ登録する
curl -X POST https://hub.naruko.app/api/public/v1/openai-realtime/7/register-webhook \
-H "Authorization: Bearer $NARUKO_TODOKE_KEY" -H "Accept: application/json"
# 設定がそろっているかを項目ごとに確認する。電話は発生しません
curl https://hub.naruko.app/api/public/v1/openai-realtime/7/connection-check \
-H "Authorization: Bearer $NARUKO_TODOKE_KEY" -H "Accept: application/json"
# 1 件だけ発信して、AI と会話できるかを確かめる
curl -X POST https://hub.naruko.app/api/public/v1/openai-realtime/7/test-call \
-H "Authorization: Bearer $NARUKO_TODOKE_KEY" -H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{"callee":"09000000000"}'
Webhook URL の登録は何度でも実行できます。同じ URL がすでに登録されている場合は、登録内容を変更しません。 既に他の URL の登録がある場合は、既存の登録は変更されず、この Webhook URL が追加登録されます。
テスト発信は実際に電話を発信するため、通話料が発生し、同時発信数の枠を 1 ch 使います。 使える機能で 配信 を選んだキーが必要です。結果は配信ジョブとして確認できます。 発信元はこの連携を使っていてキャンペーンに割り当て済みの番号から選ばれ、候補が複数あるときは sender_phonenumber_id で指定します。
openai_api_key と openai_webhook_secret は設定できますが、取得はできません。 設定済みかどうかは config.has_api_key で判断します。
CRM や Excel マクロから「担当者 → 顧客」の 2 レグ発信を起こせます。先に担当者を鳴らし、応答したら顧客へダイヤルしてつなぎます。 発信元番号は from_phonenumber_id で指定します。お使いの組織が保有する番号だけを指定できます。
curl -X POST https://hub.naruko.app/api/public/v1/click-to-call \
-H "Authorization: Bearer $NARUKO_TODOKE_KEY" \
-H "Content-Type: application/json" \
-d '{"from_phonenumber_id": 123, "agent": "2001", "callee": "0312349003", "caller_id": "0312340000"}'
# 202 {"accepted":true,"call_id":"c2c_XXXXXXXX"}| 用意するもの | 内容 |
|---|---|
| キャンペーンと電話番号 | 送信の発信元になり、受信もこの番号で受けます |
| 配信チャネル | ⚠️ 割り当てが 0 のキャンペーンでは FAX を送信できません。同時に送れる数も割り当てた数までです |
| API キー | 送信は test でも試せますが、受信は live のみです |
配信ジョブは宛先の IDと発信元番号の IDで指定します。 どちらも API で引けます。
# 宛先を登録する。external_id はお使いのシステムの顧客 ID と突き合わせるために使えます
curl -X POST https://hub.naruko.app/api/public/v1/contacts \
-H "Authorization: Bearer $NARUKO_TODOKE_KEY" \
-H "Content-Type: application/json" \
-d '{"name":"山田商店","fax":"0312345678","external_id":"cust-001"}'
# 201 {"contact":{"id":789,"fax_e164":"+81312345678", ...}}
# 発信元番号を引く。FAX 用でキャンペーンに割り当て済みのものが返ります
curl "https://hub.naruko.app/api/public/v1/sender-numbers?kind=fax" \
-H "Authorization: Bearer $NARUKO_TODOKE_KEY"
# {"data":[{"id":456,"number":"0312345600","kind":"fax","campaign_id":12}]} ① 原稿の PDF をアップロードして media_id をもらう → ② その ID を指定して配信ジョブを投げます。1 つの原稿を宛先リストへ一斉送信できます。
# ① 原稿の PDF をアップロードする。PDF のみ・最大 20MB
curl -X POST https://hub.naruko.app/api/public/v1/media \
-H "Authorization: Bearer $NARUKO_TODOKE_KEY" \
-F "file=@invoice.pdf"
# 201 {"media_id":123,"pages":2}
# ② FAX の配信ジョブを投げる
curl -X POST https://hub.naruko.app/api/public/v1/delivery-jobs \
-H "Authorization: Bearer $NARUKO_TODOKE_KEY" \
-H "Content-Type: application/json" \
-d '{
"send_type": "fax",
"content": { "media_id": 123, "sender_phonenumber_id": 456 },
"target_spec": { "list_id": 45 }
}'
# 202 {"job_id":67,"status":"queued"}| FAX だけの決まり | 内容 |
|---|---|
content.media_id | 原稿。必須です |
content.sender_phonenumber_id | 発信元番号。必須です |
| 宛先 | 連絡先の FAX 番号。入っていない宛先は送信されません |
| 原稿の形式 | PDF のみ・最大 20MB。送信用の形式への変換は Naruko 側で行います |
| 同時に送れる数 | 配信チャネルの割り当て数まで。割り当てが無いと 422 と todoke_channels_required を返します。⚠️ 超えた分は失敗にせず順番待ちになります |
| 失敗した宛先 | 既定で 3 回まで自動で再送します。確定失敗は delivery.dead で通知されます |
送付状を付けるときは POST /media/cover-sheet を使います。 本文の書類を document に入れて一緒に送ると 結合した 1 つの PDF になり、 media_id が返るので、そのまま配信ジョブへ渡せます。 ⚠️ 1 通あたりのページ上限を超えると 422 で返ります。
FAX のキャンペーンに割り当てた番号へ着信すると、fax.received が 登録した Webhook に届きます。
{
"event": "fax.received",
"data": {
"fax_recv_id": 123,
"campaign_id": 45,
"campaign_name": "請求書送付キャンペーン",
"caller_phonenumber": "+81312349001",
"received_at": "2026-08-29T10:00:00+09:00",
"download_url": "https://..."
}
}environment=test で登録した URL には届きません。download_url は24 時間で期限切れになります。受け取ったらすぐ取得して、お客様のシステム側に保存してください。取得に失敗したときは null で届きます。 受信サーバーが停止していたなどで Webhook を取りこぼしたときは、 GET /fax-receipts でいつでも一覧を引き直せます。 項目名は fax.received と同じです。
curl https://hub.naruko.app/api/public/v1/fax-receipts?since=2026-09-01T00%3A00%3A00%2B09%3A00 \
-H "Authorization: Bearer nrk_live_..."
# PDF は期限を気にせずこちらから取得できます
curl https://hub.naruko.app/api/public/v1/fax-receipts/123/content \
-H "Authorization: Bearer nrk_live_..." -o fax.pdfcampaign_id / since / until / per_page です。1 ページの件数は最大 100 です。+09:00 の + はそのままだと空白として解釈されます。download_url は 24 時間で期限切れですが、/content は期限がありません。 キャンペーンに割り当てた電話番号の着信とオートコールの発信について、 いつ終わったか・応答したか・何秒話したかを API で確認できます。 direction で inbound / outbound に絞り込めます。
1 つの通話が複数行になることがあります。 呼び出すたびに行が増えるためで、応答しなかった呼び出しの行も含まれます。 どの行をその通話の結果とするかは、受け取る側でご判断ください。
# 期間で引く
curl "https://hub.naruko.app/api/public/v1/calls?since=2026-09-01T00%3A00%3A00%2B09%3A00" \
-H "Authorization: Bearer nrk_live_..."
# 通話 ID で引く
curl https://hub.naruko.app/api/public/v1/calls/1700000000.42 \
-H "Authorization: Bearer nrk_live_..."{
"data": [
{
"uniqueid": "1700000000.42",
"direction": "inbound",
"calldate": "2026-09-20T12:52:04+09:00",
"calldate_answer": "2026-09-20T12:52:13+09:00",
"calldate_end": "2026-09-20T12:53:00+09:00",
"call_status": "ANSWERED",
"caller_phonenumber": "0312345678",
"callee_phonenumber": "0312340000",
"call_duration": 47,
"campaign_id": 11,
"campaign_name": "AI受付"
},
{
"uniqueid": "1700000001.7",
"direction": "outbound",
"calldate": "2026-09-20T13:10:00+09:00",
"calldate_answer": null,
"calldate_end": "2026-09-20T13:10:24+09:00",
"call_status": "NO ANSWER",
"caller_phonenumber": "0312340000",
"callee_phonenumber": "0312349003",
"call_duration": 0,
"campaign_id": 11,
"campaign_name": "AI受付"
}
],
"total": 2
}| 値 | 意味 |
|---|---|
| ANSWERED | 応答して通話が成立しました。 |
| NO ANSWER | 呼び出しましたが、応答がないまま終わりました。 |
| BUSY | 話中を返しました。AI 応答やルームへの着信で応答が間に合わなかったとき、チャネルが足りなかったときもこの値になります。 |
| FAILED | 接続できないまま終わりました。 |
| パラメータ | 説明 |
|---|---|
| uniqueid | 1 つの通話に絞り込みます。着信 Webhook で受け取った uniqueid をそのまま渡せます。 |
| direction | 通話の向きで絞り込みます。inbound か outbound を指定します。 |
| campaign_id | キャンペーンで絞り込みます。 |
| since | この時刻以降に始まった通話。日時は URL エンコードしてください。+09:00 の + は、そのままだと空白として解釈されます。 |
| until | この時刻までに始まった通話。書き方は since と同じです。 |
| per_page | 1 ページの件数。1 から 100 まで指定でき、既定は 50 です。 |
transferee_phonenumber でご確認ください。 コンソールの Webhook 画面 で通知先 URL と購読イベントを登録し、whsec_… で始まる署名鍵を控えます。 通知形式は JSON をそのまま送る raw のほか、Slack・Microsoft Teams・LINE 公式アカウント のテンプレートも選べるので、受信サーバーを用意しなくても既存のチャットツールへ通知できます。
| request_timing | 意味 |
|---|---|
| delivery.sent | 送信を実行した |
| delivery.delivered | 到達を確認した |
| delivery.failed | 1 回の試行が失敗した |
| delivery.dead | リトライ上限に達し確定失敗した |
| fax.received | FAX を受信した |
raw で受け取る場合のペイロード例:
{
"id": "evt_XXXXXXXX",
"request_timing": "delivery.delivered",
"created_at": "2026-07-06T09:00:00+09:00",
"environment": "live",
"data": {
"delivery_id": 987,
"job_id": 45,
"send_type": "sms",
"to": "09000000000",
"status": "delivered",
"result_code": null
}
}data.to は日本の番号なら 0 から始まる形式で、国外の番号は + から始まります。 id を冪等キーにして二重処理を防いでください。2xx を返すと、この通知は送信済みになります。
raw には X-Webhook-Signature ヘッダが付きます。 署名対象は "{t の値}.{raw データ}" の HMAC-SHA256 を 16 進で表したものです。 ヘッダは t=<unix秒>,v1=<hex> の形式です。 検証は raw データのまま行ってください。
PHP
use Naruko\Todoke\WebhookSignature;
$payload = file_get_contents('php://input');
$header = $_SERVER['HTTP_X_WEBHOOK_SIGNATURE'] ?? '';
if (! WebhookSignature::verify($payload, $header, getenv('WEBHOOK_SECRET'))) {
http_response_code(400); exit;
}
$event = json_decode($payload, true);
// $event['request_timing'] = delivery.sent | delivery.delivered | delivery.failed | delivery.dead
// $event['id'] を冪等キーにして二重処理を防ぐ。2xx を返すと配信成功。Node.js
const crypto = require("crypto");
function verify(rawBody, header, secret, toleranceSec = 300) {
const parts = Object.fromEntries(header.split(",").map((p) => p.trim().split("=")));
if (!parts.t || !parts.v1) return false;
if (Math.abs(Date.now() / 1000 - Number(parts.t)) > toleranceSec) return false;
const expected = crypto
.createHmac("sha256", secret)
.update(`${parts.t}.${rawBody}`)
.digest("hex");
return crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(parts.v1));
}test キーなら、メッセージを送らずに Webhook 連携を試せます。 POST /sandbox/webhook-events がダミーの配信イベントを、 登録済みの test Webhook エンドポイントへ実際に署名付きで送ります。メッセージは送信されず、料金も発生しません。
curl -X POST https://hub.naruko.app/api/public/v1/sandbox/webhook-events \
-H "Authorization: Bearer nrk_test_xxxxxxxx" \
-H "Content-Type: application/json" \
-d '{"request_timing":"delivery.sent"}'
# {"event_id":"evt_…","request_timing":"delivery.sent","environment":"test","endpoints_notified":1}X-Webhook-Signature 付きで届き、data.sandbox=true が入ります。上の署名検証をそのまま試せます。| メソッド | パス | 用途 |
|---|---|---|
| GET | /sip-profiles | 一覧・検索。?tag=タグ / ?q=label で部分一致 |
| POST | /sip-profiles | 登録。201 を返します |
| GET | /sip-profiles/{id} | 1 件取得 |
| PUT | /sip-profiles/{id} | 編集 |
| DELETE | /sip-profiles/{id} | 削除 |
入力フィールドはいずれも任意です。 label・ display_name・ server・ sip_domain・ transport・ username・ password ほか。 tags と codecs は配列で渡します。
curl -X POST https://hub.naruko.app/api/public/v1/sip-profiles \
-H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \
-d '{"label":"本社","tags":["営業","東京"],"server":"sip.example.jp","username":"u1","password":"p1"}'?tag=営業 でタグ絞り込み検索ができます。has_credentials で判断します。| メソッド | パス | 用途 |
|---|---|---|
| GET | /caller-id-prefixes | 一覧・検索。?q=prefix / name で部分一致 |
| POST | /caller-id-prefixes | 登録。並び順は自動で採番し、201 を返します |
| GET | /caller-id-prefixes/{id} | 1 件取得 |
| PUT | /caller-id-prefixes/{id} | 編集 |
| DELETE | /caller-id-prefixes/{id} | 削除 |
入力フィールドは prefix と name が必須、 emoji は任意です。 prefix に使えるのは数字と *# だけです。