Naruko Todoke の使い方に戻る

開発者向け

Todoke API / Webhook の使い方

お客様のシステムから Naruko Todoke を呼び出して、SMS・オートコール・FAX の一斉配信やクリック発信を自動化できます。 配信結果や受信 FAX は Webhook で受け取れます。本番(live)と サンドボックス(test)の 2 環境があり、test は実送信・実課金されません。

ベース URL: https://hub.naruko.app/api/todoke/v1

1

事前準備(API キーの発行)

コンソールの API キー画面 でキーを発行します。キーは nrk_test_…(サンドボックス)と nrk_live_…(本番)の 2 環境。まずは test から始めるのがおすすめです。

  • 平文キーは発行時に一度だけ表示されます(サーバーには sha256 ハッシュのみ保存され、再表示できません)。失くしたらローテーションで作り直します。
  • キーは失効(revoke)・ローテーション(rotate)できます。漏えい時はローテーションで即座に旧キーを無効化してください。
  • test キーと live キーはデータも分離されます(test の宛先・ジョブ・Webhook は本番と混ざりません)。
API キー画面。ラベルと環境(サンドボックス / 本番)を選んで発行し、発行済みキーの失効・ローテーションができる
API キー画面(発行・失効・ローテーション)
2

認証

各リクエストに API キーを付けます。Authorization: Bearer <key> を推奨、代替として X-Api-Key: <key> も使えます。

curl https://hub.naruko.app/api/todoke/v1/me \
  -H "Authorization: Bearer nrk_test_xxxxxxxx"
# {"account":{"id":1,"name":"…","status":"active","plan":null},"environment":"test"}
  • 認証に失敗(未提示 / 無効 / 失効 / 期限切れ)すると 401 を返します。
  • レート制限は 1 分あたり 120 リクエスト(同一アカウントの複数キーは合算)。超過すると 429Retry-After / X-RateLimit-* を返すので、Retry-After 秒待って再試行します。
3

主要エンドポイント

すべて https://hub.naruko.app/api/todoke/v1 配下です。

メソッドパス用途
GET/me疎通確認(キーの有効性と account / environment を返す)
POST/delivery-jobs配信ジョブ受付(SMS / オートコール / FAX / email 一斉送信・202 受付)
GET/delivery-jobs/{id}ジョブの状態取得
GET/delivery-jobs/{id}/deliveries宛先単位の到達ログ
GET/delivery-jobs/{id}/statsジョブの集計(到達率・失敗率)
POST/delivery-jobs/{id}/cancelジョブのキャンセル
POST/delivery-jobs/{id}/reschedule予約日時の変更(scheduled のみ)
POST/click-to-callクリック発信(担当者 → 顧客の 2 レグ発信)
POST/sandbox/webhook-eventsサンドボックスでダミー Webhook を送出(test キー専用)
4

配信ジョブを投げる(一斉送信)

宛先リスト(コンソールの 連絡先 で作成)へ一斉送信します。受付は 202 Acceptedjob_id 返却)で実送信は非同期。 Idempotency-Key(任意)でリトライ時の二重受付を防げます。

curl -X POST https://hub.naruko.app/api/todoke/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_typesms / autocall / fax / email
  • target_speclist_id(宛先リスト)か contact_ids(個別指定)のいずれか。
  • 状態取得は GET /delivery-jobs/{id}、到達ログは .../deliveries、集計は .../stats
  • 課金チャネル(sms / autocall / fax)はカード未登録だと 402payment_method_required)。
  • 送信の進捗・確定(sent / delivered / failed / dead)は Webhook で受け取るのが基本です。

クリック発信(Click to Call)

CRM や Excel マクロから「担当者 → 顧客」の 2 レグ発信を起こせます。先に担当者を鳴らし、応答したら顧客へダイヤルしてつなぎます。 発信元番号(from_phonenumber_id)は自組織所有の番号を指定します。

curl -X POST https://hub.naruko.app/api/todoke/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"}
5

Webhook を受け取る

コンソールの Webhook 画面 で通知先 URL と購読イベントを登録し、署名鍵(whsec_…)を控えます。 通知形式は 生 JSON(raw)のほか、Slack・Microsoft Teams・LINE 公式アカウント(Messaging API) のテンプレートも選べるので、受信サーバーを用意しなくても既存のチャットツールへ通知できます。

イベント種別とペイロード

type意味
delivery.sent送信を実行した
delivery.delivered到達を確認した
delivery.failed1 回の試行が失敗した
delivery.deadリトライ上限に達し確定失敗した
fax.receivedFAX を受信した(着信・live 固定)

生 JSON(raw)で受け取る場合のペイロード例:

{
  "id": "evt_XXXXXXXX",
  "type": "delivery.delivered",
  "created_at": "2026-07-06T09:00:00+09:00",
  "environment": "live",
  "data": {
    "delivery_id": 987,
    "job_id": 45,
    "send_type": "sms",
    "to": "090****8888",
    "status": "delivered",
    "result_code": null
  }
}

data.to は個人情報保護のため一部伏字(先頭 3 桁・末尾 4 桁以外)になります。 id を冪等キーにして二重処理を防いでください。2xx を返すと配信成功とみなします。

署名の検証

raw 形式には X-Naruko-Signature ヘッダが付きます。 署名対象は "{timestamp}.{生ボディ}" の HMAC-SHA256(16 進)で、 ヘッダは t=<unix秒>,v1=<hex> の形式です(Stripe と同方式)。 受信側は 生のボディで検証してから処理します(改ざん・リプレイ防止)。

PHP

use Naruko\Todoke\WebhookSignature;

$payload = file_get_contents('php://input');
$header  = $_SERVER['HTTP_X_NARUKO_SIGNATURE'] ?? '';
if (! WebhookSignature::verify($payload, $header, getenv('NARUKO_WEBHOOK_SECRET'))) {
    http_response_code(400); exit;
}
$event = json_decode($payload, true);
// $event['type'] = delivery.sent | delivery.delivered | delivery.failed | delivery.dead
// $event['id'] を冪等キーにして二重処理を防ぐ。2xx を返すと配信成功。

Node.js(素の crypto)

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));
}

再送(リトライ)

  • 受信側が 2xx を返さない(またはタイムアウト)と、指数バックオフで最大 5 回再送します(間隔: 1 分 → 5 分 → 30 分 → 2 時間 → 6 時間)。
  • 1 回の送信のタイムアウトは 5 秒。受信処理は短時間で 2xx を返し、重い処理は非同期に回してください。
  • すべて失敗すると確定失敗になります。Webhook 画面から直近の配信ログ確認・手動再送ができます。
6

サンドボックス(test)で試す

test キーなら、メッセージを送らずに Webhook 連携を試せます。 POST /sandbox/webhook-events がダミーの配信イベントを、 登録済みの test Webhook エンドポイントへ実際に署名付きで送ります(実送信・実課金なし)。

curl -X POST https://hub.naruko.app/api/todoke/v1/sandbox/webhook-events \
  -H "Authorization: Bearer nrk_test_xxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{"type":"delivery.sent"}'
# {"event_id":"evt_…","type":"delivery.sent","environment":"test","endpoints_notified":1}
  • 受信側には通常の Webhook(X-Naruko-Signature 付き・data.sandbox=true)が届くので、上の署名検証をそのまま試せます。
  • live キーでサンドボックスを呼び出すと 403(サンドボックスは test 専用)。