RouteMateRouteMate
开发者指南

API 文档

集成 RouteMate 配送平台所需的一切内容。

概览

快速开始

RouteMate 集成 API 允许你通过程序导入配送任务、自动优化路线,并从现有系统中查询任务状态。

基础 URL

https://api.routemate.app/v1

工作原理

  1. 创建集成:在 RouteMate Web 应用中进入“集成”,点击“创建集成”。你将获得 client_id 和 client_secret。
  2. 获取访问令牌:使用凭证换取一个有效期 1 小时的临时 bearer token。
  3. 导入任务:通过 POST 提交配送停靠点。RouteMate 会对地址进行地理编码、优化路线顺序,并将任务分配给司机。
  4. 查询状态:你可以随时查看任务进度,确认哪些停靠点已经完成。

要求

  • 拥有 Team 或 Enterprise 套餐的 RouteMate 账户
  • 已在 RouteMate Web 应用中创建组织
  • 已启用并拥有客户端凭证的集成
身份验证

客户端凭证流程

该 API 使用 OAuth2 客户端凭证。你的 secret 不会被明文保存,我们的服务器仅保存 SHA-256 哈希。

安全模型

  • 客户端 secret 会以 SHA-256 哈希形式保存,不会明文存储
  • 访问令牌是不透明令牌(不是 JWT),有效期为 1 小时
  • 令牌是单次用途并且仅限于你的集成范围
  • 所有请求都必须通过 HTTPS 发送
  • 每个请求都要携带令牌:Authorization: Bearer <token>

重要: 你的 client_secret 只会在创建集成时显示一次。请安全保存,例如使用环境变量或密钥管理器。如果丢失,必须在 RouteMate 控制台中重新生成。

端点

获取访问令牌

POST/v1/integration-token
使用凭证换取 bearer token
调用此端点以获取一个短期访问令牌。请在后续请求的 Authorization 头中携带它。

请求体

FieldTypeRequiredDescription
client_idstringYes你的集成 client ID(以 rm_ci_ 开头)
client_secretstringYes你的集成 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
}

错误响应

400缺少 client_id 或 client_secret

401凭证无效(secret 错误或 client_id 未知)

403该集成已被禁用

端点

导入任务与停靠点

POST/v1/integration-import
创建包含停靠点的配送任务
导入一个包含一个或多个停靠点的配送任务。RouteMate 会为缺少坐标的地址做地理编码、优化配送顺序,并将路线分配给司机。

请求头

FieldTypeRequiredDescription
AuthorizationstringYesBearer <access_token>
Content-TypestringYesapplication/json
Idempotency-KeystringNo防止重复导入的唯一键(24 小时内有效)

请求体 — 任务字段

FieldTypeRequiredDescription
external_job_idstringYes你为该任务设置的唯一标识(每个集成内必须唯一)
titlestringYes任务标题(例如 Morning Deliveries - Zone A)
driver_emailstringYes要分配的司机邮箱。如果司机已有 RouteMate 账户,会在应用中看到路线;否则会创建邀请。
scheduled_datestringNo计划日期,ISO 格式(YYYY-MM-DD)
timezonestringNoIANA 时区(例如 Australia/Brisbane 或 America/New_York)
metadataobjectNo附加到任务的自定义键值数据
stopsarrayYes停靠点对象数组(见下方停靠点字段)

请求示例

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 以优化后的配送顺序返回,而不是按你提交的原始顺序。

警告代码

FieldTypeRequiredDescription
ROUTE_OPTIMIZEDinfoNo路线已成功优化并返回距离与时长
ADDRESS_GEOCODEDinfoNo一个或多个停靠点已根据地址文本完成地理编码
DRIVER_AUTO_ADDEDinfoNo司机已拥有 RouteMate 账户,并已自动加入你的组织
DRIVER_NOT_FOUNDwarningNo未找到该邮箱对应的 RouteMate 账户。已创建邀请。
GEOCODE_FAILEDwarningNo某个停靠点地址无法完成地理编码。请改为提供 latitude/longitude。
端点

查询任务状态

GET/v1/integration-jobs
获取任务详情和停靠点状态
查询任务的当前状态,包括所有停靠点及其配送状态。结果仅限于你的集成范围内。

查询参数

FieldTypeRequiredDescription
external_job_idstringNo你的外部任务 ID(即导入时提供的那个值)
job_idstringNoRouteMate 内部任务 UUID

必须至少提供 external_job_id 或 job_id 其中一个。

请求示例

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"
}

任务状态

FieldTypeRequiredDescription
pendingstatusNo任务已创建,但司机尚未分配或解析
assignedstatusNo司机已分配,并可在应用中查看路线
in_progressstatusNo司机已开始路线
completedstatusNo所有停靠点都已完成配送
参考

停靠点字段

导入请求中每个停靠点可用字段的完整列表。

FieldTypeRequiredDescription
external_stop_idstringYes你为该停靠点设置的唯一标识(在任务内必须唯一)
addressstringYes完整街道地址。如果未提供 latitude/longitude,将自动进行地理编码。
latitudenumberNo十进制度纬度。如果同时提供 longitude,则跳过地理编码。
longitudenumberNo十进制度经度。如果同时提供 latitude,则跳过地理编码。
labelstringNo显示标签(例如客户姓名或订单号)
notesstringNo司机配送说明
service_typestringNo服务类型(例如 delivery、pickup 或 service_call)
duration_minutesnumberNo该停靠点的预计服务时长,单位为分钟
time_window_startstringNo最早送达时间(ISO 8601 datetime)
time_window_endstringNo最晚送达时间(ISO 8601 datetime)
prioritynumberNo优先级(数值越小优先级越高)。默认值:0
parcel_countnumberNo该停靠点的包裹数量。默认值:1
metadataobjectNo附加到该停靠点的自定义键值数据

提示: 提示:直接提供 latitude 和 longitude 会比地理编码更快、更可靠。

功能

路线优化

每次导入都会自动优化配送顺序,以减少行驶距离和时间。

优化如何工作

  1. 所有没有坐标的停靠点都会根据地址文本进行地理编码
  2. 第一个停靠点被视为起点,最后一个停靠点被视为终点
  3. 所有中间停靠点都会通过 Google Routes API 优化为最短驾驶路线
  4. 每个停靠点的 sort_order 字段都会更新为优化后的顺序
  5. 系统会计算路线折线、总距离和预计时长

响应字段

FieldTypeRequiredDescription
optimization.total_distance_kmnumberNo路线总距离,单位公里
optimization.total_duration_minutesnumberNo预计总驾驶时间,单位分钟
optimization.encoded_polylinestringNo用于在地图上绘制路线的 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 分钟窗口内应用。

套餐请求 / 分钟每次导入最大停靠点
Team60200
EnterpriseCustomCustom

发生限流时,API 会返回 HTTP 429,并附带 retry_after_seconds 字段。

示例

完整代码示例

适用于常见语言的复制即用示例。所有示例都展示完整流程:认证、导入和查询。

#!/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 — 单个停靠点已完成配送(包含交付证明)
  • stop.failed — 一次配送尝试失败
  • driver.location — 司机实时 GPS 更新

想提前体验? 联系我们.

准备开始集成?

在 RouteMate 控制台中创建集成凭证,几分钟内即可开始导入任务。