API ドキュメント
配送プラットフォームを RouteMate と連携するために必要な情報をまとめています。
目次
はじめに
RouteMate Integration API を使うと、既存システムから配送ジョブをプログラムで取り込み、ルートを自動最適化し、ジョブ状況を照会できます。
ベース URL
https://api.routemate.app/v1仕組み
- 連携を作成する: RouteMate Web アプリの「Integrations」で「Create Integration」をクリックすると、client_id と client_secret が発行されます。
- アクセストークンを取得する: 認証情報を 1 時間有効な一時 bearer token に交換します。
- ジョブを取り込む: 配送停止地点を POST で送信します。RouteMate が住所をジオコーディングし、ルート順序を最適化してドライバーに割り当てます。
- ステータスを確認する: いつでもジョブの進捗を確認し、どの停止地点が完了したかを把握できます。
要件
- Team または Enterprise プランの RouteMate アカウント
- RouteMate Web アプリ上で作成された組織
- client credentials を持つ有効な連携
クライアントクレデンシャルフロー
この API は OAuth2 の client credentials を利用します。secret は保存されず、サーバーには SHA-256 ハッシュのみが保持されます。
セキュリティモデル
- client secret は SHA-256 でハッシュ化され、平文では保存されません
- アクセストークンは JWT ではない opaque token で、有効期限は 1 時間です
- トークンは単一用途で、あなたの連携範囲に限定されます
- すべてのリクエストは HTTPS 経由で送信する必要があります
- 各リクエストに token を含めてください: Authorization: Bearer <token>
重要: client_secret は連携作成時に一度だけ表示されます。環境変数や secrets manager などに安全に保存してください。紛失した場合は RouteMate ダッシュボードから再生成する必要があります。
アクセストークンを取得
/v1/integration-tokenリクエスト本文
| Field | Type | Required | Description |
|---|---|---|---|
| client_id | string | Yes | 連携の client ID(rm_ci_ で始まります) |
| client_secret | string | Yes | 連携の client secret(rm_cs_ で始まります) |
リクエスト例
curl -X POST https://api.routemate.app/v1/integration-token \
-H "Content-Type: application/json" \
-d '{
"client_id": "rm_ci_abc123...",
"client_secret": "rm_cs_xyz789..."
}'成功レスポンス 200
{
"access_token": "rm_at_e5988dd1b91a4ff3827c5d2ed416ccbe37ae227a",
"token_type": "Bearer",
"expires_in": 3600
}エラーレスポンス
400client_id または client_secret が不足しています
401認証情報が無効です(secret が違う、または client_id が不明)
403連携が無効化されています
ジョブと停止地点を取り込む
/v1/integration-importリクエストヘッダー
| Field | Type | Required | Description |
|---|---|---|---|
| Authorization | string | Yes | Bearer <access_token> |
| Content-Type | string | Yes | application/json |
| Idempotency-Key | string | No | 重複インポートを防ぐための一意キー(24 時間有効) |
リクエスト本文 — ジョブ項目
| Field | Type | Required | Description |
|---|---|---|---|
| external_job_id | string | Yes | このジョブに対するあなたの一意識別子(連携内で一意である必要があります) |
| title | string | Yes | ジョブタイトル(例: Morning Deliveries - Zone A) |
| driver_email | string | Yes | 割り当てるドライバーのメールアドレス。RouteMate アカウントがあればアプリでルートを確認でき、なければ招待が作成されます。 |
| scheduled_date | string | No | 予定日(ISO 形式: YYYY-MM-DD) |
| timezone | string | No | IANA タイムゾーン(例: Australia/Brisbane または America/New_York) |
| metadata | object | No | ジョブに添付するカスタムなキーと値のデータ |
| stops | array | Yes | 停止地点オブジェクトの配列(下の停止地点フィールドを参照) |
リクエスト例
curl -X POST https://api.routemate.app/v1/integration-import \
-H "Authorization: Bearer rm_at_your_token_here" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: order-batch-2026-03-09-001" \
-d '{
"external_job_id": "BATCH-2026-03-09-A",
"title": "Morning Deliveries - Zone A",
"driver_email": "driver@example.com",
"scheduled_date": "2026-03-09",
"timezone": "Australia/Brisbane",
"stops": [
{
"external_stop_id": "ORD-1001",
"address": "1 George St, Brisbane QLD 4000, Australia",
"label": "John Smith",
"notes": "Leave at front door",
"priority": 1,
"parcel_count": 2
},
{
"external_stop_id": "ORD-1002",
"address": "100 Queen St, Brisbane QLD 4000, Australia",
"label": "Jane Doe",
"notes": "Ring doorbell",
"priority": 2
},
{
"external_stop_id": "ORD-1003",
"address": "South Bank Parklands, Brisbane QLD 4101, Australia",
"label": "Bob Wilson",
"priority": 3,
"parcel_count": 1
}
]
}'成功レスポンス 200
{
"job_id": "e7ad097b-bc51-4d01-9b04-0e372d80613a",
"external_job_id": "BATCH-2026-03-09-A",
"route_id": "1c2a8c0b-1b69-4a04-85b1-608b2ebe3878",
"driver_email": "driver@example.com",
"driver_resolved": true,
"driver_user_id": "573b6bee-aa3d-4cb0-af87-620bba0db049",
"stops_imported": 3,
"stops_geocoded": 3,
"stops_geocode_failed": 0,
"optimization": {
"total_distance_km": 12.4,
"total_duration_minutes": 25,
"encoded_polyline": "fvmfDqmfe\\bPtA..."
},
"stops": [
{
"external_stop_id": "ORD-1001",
"address": "1 George St, Brisbane QLD 4000, Australia",
"latitude": -27.4710,
"longitude": 153.0234,
"label": "John Smith",
"notes": "Leave at front door",
"sort_order": 0,
"priority": 1,
"parcel_count": 2,
"status": "pending"
},
{
"external_stop_id": "ORD-1003",
"address": "South Bank Parklands, Brisbane QLD 4101, Australia",
"latitude": -27.4753,
"longitude": 153.0208,
"label": "Bob Wilson",
"notes": null,
"sort_order": 1,
"priority": 3,
"parcel_count": 1,
"status": "pending"
},
{
"external_stop_id": "ORD-1002",
"address": "100 Queen St, Brisbane QLD 4000, Australia",
"latitude": -27.4688,
"longitude": 153.0281,
"label": "Jane Doe",
"notes": "Ring doorbell",
"sort_order": 2,
"priority": 2,
"parcel_count": 1,
"status": "pending"
}
],
"deep_link": "https://app.routemate.app/app/jobs/e7ad097b-...",
"warnings": [
{ "code": "ADDRESS_GEOCODED", "message": "3 stop(s) were geocoded from address text" },
{ "code": "ROUTE_OPTIMIZED", "message": "Route optimized: 12.4 km, 25 min" }
]
}注: 注: stops 配列は、送信順ではなく sort_order に基づく最適化された配送順序で返されます。
警告コード
| Field | Type | Required | Description |
|---|---|---|---|
| ROUTE_OPTIMIZED | info | No | 距離と時間を含めてルートが正常に最適化されました |
| ADDRESS_GEOCODED | info | No | 1 つ以上の停止地点が住所テキストからジオコーディングされました |
| DRIVER_AUTO_ADDED | info | No | ドライバーは RouteMate アカウントを持っており、自動的に組織へ追加されました |
| DRIVER_NOT_FOUND | warning | No | このメールアドレスに対応する RouteMate アカウントが見つかりませんでした。招待が作成されました。 |
| GEOCODE_FAILED | warning | No | 停止地点の住所をジオコーディングできませんでした。代わりに latitude/longitude を指定してください。 |
ジョブステータスを確認
/v1/integration-jobsクエリパラメータ
| Field | Type | Required | Description |
|---|---|---|---|
| external_job_id | string | No | インポート時に送信した外部ジョブ ID |
| job_id | string | No | RouteMate 内部のジョブ UUID |
external_job_id または job_id のいずれかを少なくとも 1 つ指定する必要があります。
リクエスト例
curl "https://api.routemate.app/v1/integration-jobs?external_job_id=BATCH-2026-03-09-A" \
-H "Authorization: Bearer rm_at_your_token_here"成功レスポンス 200
{
"job_id": "e7ad097b-bc51-4d01-9b04-0e372d80613a",
"external_job_id": "BATCH-2026-03-09-A",
"title": "Morning Deliveries - Zone A",
"status": "assigned",
"driver_email": "driver@example.com",
"driver_resolved": true,
"driver_user_id": "573b6bee-...",
"route_id": "1c2a8c0b-...",
"scheduled_date": "2026-03-09",
"timezone": "Australia/Brisbane",
"metadata": {},
"stop_count": 3,
"status_counts": {
"pending": 2,
"completed": 1
},
"deep_link": "https://app.routemate.app/app/jobs/e7ad097b-...",
"stops": [
{
"external_stop_id": "ORD-1001",
"address": "1 George St, Brisbane QLD 4000",
"latitude": -27.4710,
"longitude": 153.0234,
"label": "John Smith",
"notes": "Leave at front door",
"status": "completed",
"priority": 1,
"parcel_count": 2
},
...
],
"created_at": "2026-03-09T08:30:00.000Z",
"updated_at": "2026-03-09T10:15:00.000Z"
}ジョブステータス
| Field | Type | Required | Description |
|---|---|---|---|
| pending | status | No | ジョブは作成済みですが、ドライバーはまだ割り当てまたは解決されていません |
| assigned | status | No | ドライバーが割り当てられ、アプリでルートを確認できます |
| in_progress | status | No | ドライバーがルートを開始しました |
| completed | status | No | すべての停止地点の配達が完了しました |
停止地点フィールド
インポートリクエスト内の各停止地点で利用できるフィールド一覧です。
| Field | Type | Required | Description |
|---|---|---|---|
| external_stop_id | string | Yes | この停止地点に対するあなたの一意識別子(ジョブ内で一意である必要があります) |
| address | string | Yes | 完全な住所。latitude/longitude がない場合はジオコーディングされます。 |
| latitude | number | No | 10 進数の緯度。longitude と一緒に渡すとジオコーディングを省略します。 |
| longitude | number | No | 10 進数の経度。latitude と一緒に渡すとジオコーディングを省略します。 |
| label | string | No | 表示ラベル(例: 顧客名、注文番号) |
| notes | string | No | ドライバー向けの配送メモ |
| service_type | string | No | サービス種別(例: delivery、pickup、service_call) |
| duration_minutes | number | No | この停止地点での想定作業時間(分) |
| time_window_start | string | No | 最短配送時刻(ISO 8601 datetime) |
| time_window_end | string | No | 最遅配送時刻(ISO 8601 datetime) |
| priority | number | No | 優先度(数値が小さいほど高優先度)。既定値: 0 |
| parcel_count | number | No | この停止地点の荷物数。既定値: 1 |
| metadata | object | No | この停止地点に添付するカスタムなキーと値のデータ |
ヒント: ヒント: latitude と longitude を直接渡す方がジオコーディングより高速で信頼性があります。
ルート最適化
各インポートは配達順序を自動的に最適化し、走行距離と時間を最小化します。
最適化の仕組み
- 座標のない停止地点はすべて住所テキストからジオコーディングされます
- 最初の停止地点は出発地、最後の停止地点は目的地として扱われます
- 中間の停止地点は Google Routes API を使って最短走行ルートに最適化されます
- 各停止地点の sort_order フィールドが最適化後の順序を反映するよう更新されます
- ルートポリライン、総距離、推定所要時間が計算されます
レスポンス項目
| Field | Type | Required | Description |
|---|---|---|---|
| optimization.total_distance_km | number | No | ルート総距離(キロメートル) |
| optimization.total_duration_minutes | number | No | 推定総走行時間(分) |
| optimization.encoded_polyline | string | No | 地図上にルートを描画するための Google Encoded Polyline |
注: 注: 最適化には有効な座標を持つ停止地点が少なくとも 2 つ必要です。一部の停止地点でジオコーディングに失敗した場合、成功した停止地点だけでルートが最適化されます。
冪等性
失敗したリクエストを安全に再試行し、重複ジョブを作成しません。
インポートリクエストには一意の Idempotency-Key ヘッダーを含めてください。同じキーが 24 時間以内に再送されると、API は重複ジョブを作成せず、最初の成功レスポンスを返します。
curl -X POST https://api.routemate.app/v1/integration-import \
-H "Authorization: Bearer rm_at_your_token" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: batch-2026-03-09-zone-a" \
-d '{ ... }'
# Safe to retry — same Idempotency-Key returns cached response
curl -X POST https://api.routemate.app/v1/integration-import \
-H "Authorization: Bearer rm_at_your_token" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: batch-2026-03-09-zone-a" \
-d '{ ... }'ベストプラクティス: 本番環境では常に Idempotency-Key を使用してください。ネットワークリトライで重複データが生まれないよう、決定的なキーを使うのが最善です。
エラー処理
すべてのエラーは error フィールドを含む JSON を返します。
{
"error": "Rate limit exceeded",
"retry_after_seconds": 45
}
// またはバリデーションエラーの場合:
{
"error": {
"code": "VALIDATION_ERROR",
"messages": [
"external_job_id is required",
"stops[0].address is required"
]
}
}| ステータス | 意味 | 対応 |
|---|---|---|
| 200 | 成功 | リクエストは正常に完了しました |
| 400 | 不正なリクエスト | エラーメッセージを確認し、リクエスト本文を修正してください |
| 401 | 未認証 | トークンが無効または期限切れです。新しいトークンを取得してください。 |
| 403 | 禁止 | 連携が無効化されています。管理者に連絡してください。 |
| 404 | 未検出 | ジョブまたはエンドポイントが存在しません |
| 405 | 許可されていないメソッド | 正しい HTTP メソッド(POST または GET)を使用してください |
| 429 | リクエスト過多 | retry_after_seconds 後に再試行してください |
| 500 | サーバーエラー | exponential backoff で再試行し、継続する場合はサポートへ連絡してください。 |
レート制限
レート制限は各連携ごとに 1 分間のローリングウィンドウで適用されます。
| プラン | リクエスト / 分 | インポートあたり最大停止地点数 |
|---|---|---|
| Team | 60 | 200 |
| Enterprise | Custom | Custom |
レート制限時、API は retry_after_seconds フィールド付きの HTTP 429 を返します。
完全なコード例
主要言語向けのコピペ可能な例です。すべて認証、インポート、照会の完全な流れを示します。
#!/bin/bash
# RouteMate API Integration Example
API_BASE="https://api.routemate.app/v1"
CLIENT_ID="rm_ci_your_client_id"
CLIENT_SECRET="rm_cs_your_client_secret"
# Step 1: Get access token
TOKEN=$(curl -s -X POST "$API_BASE/integration-token" \
-H "Content-Type: application/json" \
-d "{
\"client_id\": \"$CLIENT_ID\",
\"client_secret\": \"$CLIENT_SECRET\"
}" | jq -r '.access_token')
echo "Access Token: $TOKEN"
# Step 2: Import a job with stops
RESULT=$(curl -s -X POST "$API_BASE/integration-import" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: my-batch-001" \
-d '{
"external_job_id": "BATCH-001",
"title": "Morning Deliveries",
"driver_email": "driver@example.com",
"scheduled_date": "2026-03-10",
"timezone": "Australia/Brisbane",
"stops": [
{
"external_stop_id": "STOP-1",
"address": "1 George St, Brisbane QLD 4000",
"label": "Customer A",
"parcel_count": 2
},
{
"external_stop_id": "STOP-2",
"address": "100 Queen St, Brisbane QLD 4000",
"label": "Customer B",
"notes": "Leave at reception"
}
]
}')
echo "$RESULT" | jq .
# Step 3: Query job status
JOB_ID=$(echo "$RESULT" | jq -r '.job_id')
curl -s "$API_BASE/integration-jobs?job_id=$JOB_ID" \
-H "Authorization: Bearer $TOKEN" | jq .Webhook
配達完了時にリアルタイム通知を受け取れます。
Webhook サポートは近日公開予定です。URL を登録すると、次のようなイベントで POST 通知を受け取れるようになります。
- job.completed — ジョブ内のすべての停止地点の配達が完了しました
- stop.completed — 1 つの停止地点の配達が完了しました(配達証明を含む)
- stop.failed — 配達の試行が失敗しました
- driver.location — ドライバーのリアルタイム GPS 更新
先行アクセスに興味がありますか? お問い合わせください.