Postman quick start: Download the Collection, import it into Postman, set base_url, user_name, and api_key variables, then submit a task and poll the result.
Download Postman CollectionInclude your username and API Key in the request headers:
How to get an API Key: Sign in with a plan that includes API access, go to Account Center, and generate an API Key. The key is shown only once—save it securely.
If you are using the API via RapidAPI, authentication is handled by the platform:
New solve submission limits vary by account plan and apply to the total number of new solve tasks submitted by the same user per minute; result polling is not counted. When the service is busy, the API may return 429 service_busy. Node count, vehicle count, solve time, and monthly quota vary by plan. See pricing page。
Requests submitted through the direct YazRoute API (not RapidAPI) and successfully accepted into the queue are automatically written to Account Center history for later review and download.
Important: You can set time_limit_seconds yourself; if omitted, the system uses your plan default maximum solve time.
Webhook note: callback_url is optional. When provided, the server synchronously sends an HTTP POST upon solve completion (blocking the worker for at most 10 seconds), with a single attempt and no retries. Your callback endpoint should respond with 2xx within 10 seconds. If the callback times out or fails, the solve result is unaffected and you can still retrieve it via polling. Note: the callback blocks the worker for up to 10 seconds, so a fast response from your endpoint is recommended.
Submit endpoint (POST /api/v1/solve) returns:
Result endpoint (GET /api/v1/solve/result/{request_id}) returns:
Polling requires any currently valid API Key under the same account; deleted, revoked, disabled, or expired keys cannot access the result.
关于 distances 与 routes:routes 按车辆 id 作为 key(如 "Vehicle 7"),distances 为普通数组;只有实际有路线的车辆会出现在 routes 中。读取 distances[i] 时,请取 routes 按车辆 id 升序后的第 i 个 key 所对应的路线距离,不要默认 distances[i] 一定对应 "Vehicle i"。
Note: task results are retained during the TTL window so clients can poll repeatedly; after the TTL expires, polling returns 404.
Note:
1. For users calling via RapidAPI, authentication is handled by RapidAPI. You do not need to provide X-User-Name and X-Api-Key headers.
2. The submit endpoint is asynchronous, so POST /api/v1/solve usually only needs a short client timeout; reserve longer time for polling or webhook handling if you need the final result.
3. Solve time is configurable: You can specify solve time via time_limit_seconds; if omitted, your plan max_solve_time is used by default.
4. This API is asynchronous: call POST /api/v1/solve to get request_id, then poll GET /api/v1/solve/result/{request_id} for final result.
5. During polling, use result.phase to distinguish queued vs solving; when queued, use result.queue_depth for queue depth.
// 接口调用示例(API v1):
// - 先在「账户中心」生成 API Key(仅显示一次)
// - 请求头需携带用户名与 API Key
const userName = 'your_username';
const apiKey = 'your_api_key';
const payload = {
name: 'input_data_sample',
objective: 'min_total_cost',
node_num: 6,
node_positions: [],
vehicle_num: 2,
vehicle_fixed_costs: [100, 120],
vehicle_unit_distance_costs: [1.2, 1.5],
distance_matrix: [
[0, 98, 60, 50, 61, 39],
[94, 0, 67, 60, 36, 91],
[11, 51, 0, 37, 62, 30],
[19, 44, 91, 0, 55, 51],
[27, 69, 75, 41, 0, 36],
[80, 44, 62, 12, 73, 0]
],
start_nodes: [0, 0],
end_nodes: [0, 0],
node_demands: [0, 10, 10, 10, 10, 10],
vehicles_capacity: [100, 100],
node_time_windows: [[0, 500], [0, 500], [0, 500], [0, 500], [0, 500], [0, 500]],
node_service_time: [0, 2, 3, 4, 5, 6],
vehicle_speeds: [30, 30],
max_working_hours: 8,
base_start_time: [9, 0, 0],
// time_limit_seconds 可省略;省略时按当前套餐默认 max_solve_time 执行
time_limit_seconds: 120,
// late_penalty_per_min 可选(元/分钟);>0 时启用软时间窗,允许迟到并计入惩罚成本;省略或 null 时为硬时间窗
// late_penalty_per_min: 10,
// callback_url 可选;提供后服务器求解完成时会同步 POST 一次结果到该地址(最多阻塞 10 秒,不重试)
// callback_url: 'https://your-server.com/webhook/vrp-result'
};
const response = await fetch('https://yazroute.com/api/v1/solve', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-User-Name': userName,
'X-Api-Key': apiKey
},
body: JSON.stringify(payload)
});
// 解析提交响应(异步任务)
const submitData = await response.json();
if (!response.ok || !submitData.success) {
console.error('提交失败:', submitData.error || submitData.detail);
return;
}
const requestId = submitData.request_id;
let finalData = null;
const maxPollMs = 15 * 60 * 1000; // 最多轮询 15 分钟
const pollStart = Date.now();
const backoffMs = [2000, 3000, 5000]; // 推荐轮询退避:2s -> 3s -> 5s
let pollAttempt = 0;
// 轮询最终结果
while (true) {
if (Date.now() - pollStart > maxPollMs) {
console.error('轮询超时,请稍后重试。request_id:', requestId);
break;
}
const pollResp = await fetch(`https://yazroute.com/api/v1/solve/result/${requestId}`, {
method: 'GET',
headers: {
'Content-Type': 'application/json',
'X-User-Name': userName,
'X-Api-Key': apiKey
}
});
const pollData = await pollResp.json();
if (!pollResp.ok) {
console.error('轮询失败:', pollData.error || pollData.detail);
break;
}
if (pollData.result && pollData.result.status === 'processing') {
const phase = pollData.result.phase || 'processing';
if (phase === 'queued') {
console.log('排队中... queue_depth=', pollData.result.queue_depth);
} else if (phase === 'solving') {
console.log('计算中...');
} else {
console.log('处理中... phase=', phase);
}
const waitMs = backoffMs[Math.min(pollAttempt, backoffMs.length - 1)];
pollAttempt += 1;
await new Promise(resolve => setTimeout(resolve, waitMs));
continue;
}
finalData = pollData;
break;
}
if (finalData && finalData.success) {
const result = finalData.result;
console.log('总成本:', result.total_cost);
console.log('求解时间:', result.time, '秒');
console.log('路线数量:', Object.keys(result.routes).length);
console.log('路线详情:', result.routes);
for (const [vehicle, path] of Object.entries(result.routes)) {
console.log(`${vehicle}:`, path);
}
console.log('距离列表:', result.distances);
console.log('载重字典:', result.loads);
console.log('时间窗:', result.time_windows);
} else {
console.error('请求失败:', finalData?.error);
}
// 提交成功响应(POST /api/v1/solve,HTTP 200):
{
"success": true,
"result": {
"status": "accepted",
"phase": "queued",
"message": "Task accepted. Poll /api/v1/solve/result/{request_id} for completion."
},
"error": null,
"request_id": "api_153ca66c55de4162"
}
// 轮询中响应(GET /api/v1/solve/result/{request_id},HTTP 200):
{
"success": true,
"result": {
"status": "processing",
"phase": "queued",
"queue_depth": 3
},
"error": null,
"request_id": "api_153ca66c55de4162"
}
// 轮询成功响应(GET /api/v1/solve/result/{request_id},HTTP 200):
{
"success": true,
"result": {
"success": true,
"error": null,
"total_cost": 273,
"routes": {
"Vehicle 0": [1, 3, 0, 2],
"Vehicle 1": [1, 4, 5, 2]
},
"distances": [139, 134],
"loads": {
"Vehicle 0": [0, 10, 20, 30, 40],
"Vehicle 1": [0, 10, 20, 30, 40]
},
"time_windows": {
"Vehicle 0": [
["09:00:00", "09:02:00"],
["11:02:00", "11:06:00"],
["11:44:00", "11:45:00"],
["13:45:00", "13:48:00"]
],
"Vehicle 1": [
["09:00:00", "09:02:00"],
["10:14:00", "10:19:00"],
["11:31:00", "11:37:00"],
["13:41:00", "13:44:00"]
]
},
"time": 3.04,
"request_id": "api_153ca66c55de4162"
},
"error": null,
"request_id": "api_153ca66c55de4162"
}
API 返回的错误信息均为英文,下方示例为实际返回格式。
// Authentication failed (401) - missing headers:
{
"success": false,
"error": "Missing X-User-Name or X-Api-Key header"
}
// Authentication failed (401) - invalid key:
{
"success": false,
"error": "Invalid username or API Key (or expired/revoked)"
}
// Authentication failed (401) - invalid RapidAPI proxy secret:
{
"success": false,
"error": "Invalid RapidAPI proxy secret"
}
// Exceeds plan limit (400):
{
"success": false,
"error": "Node count (20) exceeds plan limit (15). Please upgrade your plan"
}
// Validation failed (422):
{
"success": false,
"error": "Validation failed",
"detail": [
{
"loc": ["body", "time_limit_seconds"],
"msg": "time_limit_seconds must be a positive integer",
"type": "value_error"
}
]
}
// Validation failed (422) - depot demand must be 0:
{
"success": false,
"error": "Validation failed",
"detail": [
{
"loc": ["body"],
"msg": "Depot/start/end node 1 demand must be 0 (got 10)",
"type": "value_error"
}
]
}
// Forbidden (403) - plan does not support API access:
{
"success": false,
"error": "Your current plan does not support API access. Please upgrade your plan"
}
// Forbidden (403) - polling with a different account (request_id ownership mismatch):
{
"success": false,
"error": "No permission to access this request result"
}
// Too many requests (429) - rate limit:
{
"success": false,
"error": "Too many requests. Please try again later",
"code": "rate_limit_exceeded",
"retry_after_seconds": 60
}
// Too many requests (429) - service busy:
{
"success": false,
"error": "Service is busy. Current queue depth is 3. Please try again later",
"code": "service_busy",
"retry_after_seconds": 10
}
// Too many requests (429) - monthly quota:
{
"success": false,
"error": "Monthly API quota exceeded (500 requests). Please try again next month or upgrade your plan",
"code": "monthly_quota_exceeded"
}
// Solve failed (HTTP 200, success: false):
{
"success": false,
"result": null,
"error": "No feasible solution found. Please review your constraints",
"request_id": "api_153ca66c55de4162"
}
// Result polling failed (404) - request id not found or expired:
{
"success": false,
"error": "Request id not found or expired"
}