Source: https://maps.vietmap.vn/docs/map-api/vrp/ # Vehicle Routing Problem (VRP) [![VRP]][VRP] [VRP]: https://maps.vietmap.vn/docs/assets/VRP-jpg.webp * * * The **Vehicle Routing Problem (VRP)** is the everyday problem of a dispatcher: you have *n* vehicles and *m* stops, and you need to decide **which vehicle takes which stops, and in what order** — while respecting vehicle capacity, time windows and working hours. The VIETMAP VRP API solves it on the real Vietnamese road network, so the plan it returns accounts for one-way streets, restricted roads and actual driving times rather than straight-line distance. ## TSP, VRP or Matrix — which one do I need? | Your question | API | | --- | --- | | "One vehicle, many stops — what order should it visit them in?" | [TSP](https://maps.vietmap.vn/docs/map-api/tsp-version/tsp-v4/) | | "Several vehicles and many stops — who takes what, in what order?" | **VRP** (this page) | | "How long does it take between each pair of points?" (you do the planning yourself) | [Distance Matrix](https://maps.vietmap.vn/docs/map-api/matrix-version/matrix-v4/) | | "I already know the stop order — give me the road path and toll cost." | [Routing](https://maps.vietmap.vn/docs/map-api/route-version/route-v4/) | ## Constraints and the fields that model them | Constraint | Fields | Playground | | --- | --- | --- | | Vehicle load limits (items, weight, volume) | vehicle `capacity`, job `delivery` / `pickup` | [Open sample dimensions](https://tools.vietmap.vn/playground/vrp?sample=dimensions) · [pickup-delivery](https://tools.vietmap.vn/playground/vrp?sample=pickup-delivery) | | Customer delivery slots | job `time_windows` | [Open sample time-windows](https://tools.vietmap.vn/playground/vrp?sample=time-windows) | | Driver shift hours | vehicle `time_window` | — | | Only some vehicles can do some jobs (cold chain, licence, equipment) | `skills` on both vehicle and job | [Open sample skills](https://tools.vietmap.vn/playground/vrp?sample=skills) | | Jobs that must not be dropped when the fleet is short | job `priority` | [Open sample priority](https://tools.vietmap.vn/playground/vrp?sample=priority) | | Round trip from a depot | vehicle `start` = `end` | — | ## Costing A VRP request is billed as `vehicles × stops` transactions — 3 vehicles across 20 stops costs 60 transactions. See [How Pricing Works](https://maps.vietmap.vn/docs/map-api/console/request-to-transaction/) before you size a daily plan. !!! tip "Try it in the Playground" Call VRP with real data, no code required: **[Open Playground](https://tools.vietmap.vn/playground/vrp)** Or try it in [Postman](https://app.getpostman.com/run-collection/10912981-433d17b2-76d7-416e-beb2-468b9682b7a7?action=collection%2Ffork). ## URL ``` https://maps.vietmap.vn/api/vrp?api-version=1.1&apikey={your-apikey} ``` The `apikey` query parameter is required. [Register here](https://maps.vietmap.vn/console-v2/register) to get one. ## Method **POST** ## Parameters |Key|Type|Required|Default|Example|Description| |--- |--- |--- |--- |--- |--- | |jobs|array|yes|none||Array of [Job objects](#job-object). Each job is a single place to visit (e.g. a delivery or pickup stop). At least one job is required.| |vehicles|array|yes|none||Array of [Vehicle objects](#vehicle-object) describing the fleet available to serve the jobs. At least one vehicle is required.| ## Job object |Key|Type|Required|Default|Example|Description| |--- |--- |--- |--- |--- |--- | |id|integer|yes|none|1|Unique identifier of the job. Must be unique across all jobs in the request.| |location|array, double|yes|none|[106.112456,10.684922]|Coordinates of the job, in `[longitude, latitude]` order.| |service|integer|no|0|1|Time spent servicing the job once the vehicle arrives, in **seconds**. Defaults to `0`.| |delivery|array|no|none|[1,2]|Goods loaded at the vehicle's start and dropped off at this job. Array of integers describing multidimensional quantities (e.g. `[items, weight, volume]`); the number and order of dimensions must match the vehicle's `capacity`.| |pickup|array|no|none|[1,2]|Goods collected at this job and carried back to the vehicle's end. Array of integers describing multidimensional quantities; same dimension order as `delivery` and the vehicle's `capacity`.| |skills|array|no|none|[1]|Array of integers listing the skills this job **requires**. The job can only be served by a vehicle whose `skills` include all of these values.| |priority|integer|no|0|1|Priority of including this job in the solution. Integer in the range `[0, 10]`; higher values make the job more likely to be served when not all jobs can be assigned.| |time_windows|array|no|none|[[0,1400]]|Array of `[start, end]` windows during which the service may **start**. Times are in seconds — either relative to the planning horizon or absolute Unix timestamps (see [Constraints](#constraints)). Omitting it means the job can be served at any time.| ## Vehicle object |Key|Type|Required|Default|Example|Description| |--- |--- |--- |--- |--- |--- | |id|integer|yes|none|1|Unique identifier of the vehicle. Must be unique across all vehicles in the request.| |start|array, double|conditional|none|[106.112456,10.684922]|Coordinates where the vehicle begins its route, in `[longitude, latitude]` order. Optional, but at least one of `start` / `end` must be provided (see [Constraints](#constraints)).| |end|array, double|conditional|none|[106.112456,10.684922]|Coordinates where the vehicle ends its route, in `[longitude, latitude]` order. Optional, but at least one of `start` / `end` must be provided. Use the same value as `start` for a round trip.| |capacity|array|no|none|[0,3]|Maximum load the vehicle can carry, as an array of integers describing multidimensional quantities (e.g. `[items, weight, volume]`). The dimension order must match the jobs' `delivery` / `pickup` arrays.| |skills|array|no|none|[1]|Array of integers listing the skills this vehicle **has**. A job is eligible only if all of its required `skills` are present here.| |time_windows|array|no|none|[[0,14400]]|Working hours of the vehicle as `[start, end]` (in seconds). Times follow the same convention as job `time_windows` (see [Constraints](#constraints)). Omitting it means the vehicle has no time constraint.| ## Constraints * **Start / end.** A vehicle needs at least one of `start` and `end`. Without `end` the route finishes at its last job; without `start` it begins at its first job (the solver picks which). Same coordinates for both = round trip. * **Capacity.** `capacity`, `delivery` and `pickup` are integer arrays of the same length, one entry per dimension (e.g. `[items, weight, volume]`). Deliveries are loaded at `start`; pickups are carried to `end`. The load at every step of the route must stay within `capacity` on every dimension. Put the most limiting dimension first. * **Skills.** A job with `skills` can only go to a vehicle whose `skills` contain all of them. No `skills` on either side means no restriction. * **Priority.** `0`–`10`. When not every job fits, higher-priority jobs are kept; dropped jobs appear in `unassigned`. * **Time windows.** Seconds, in one of two conventions used consistently across the request: relative to the start of the planning horizon (`[0, 14400]` = the first 4 hours) or absolute Unix timestamps. `arrival` in the response uses the same convention as your input. No `time_window` (vehicle) / `time_windows` (job) means no time constraint. ## Example [:material-play-circle: Run VRP on the Playground](https://tools.vietmap.vn/playground/vrp){ .md-button .md-button--primary } **Body** ```json { "vehicles": [ { "id": 1, "start": [ 106.5983012, 10.8879148 ], "end": [ 106.5983012, 10.8879148 ], "profile": "bike", "time_window": [ 1685953800, 1686418200 ], "skills": [ 1, 1000 ], "breaks": [ { "id": 1000, "time_windows": [ [ 1685966400, 1685970000 ] ], "service": 3600 }, { "id": 1, "time_windows": [ [ 1685986200, 1685988000 ] ], "service": 54000.0 }, { "id": 2000, "time_windows": [ [ 1686052800, 1686056400 ] ], "service": 3600 }, { "id": 2, "time_windows": [ [ 1686072600, 1686074400 ] ], "service": 54000.0 }, { "id": 6000, "time_windows": [ [ 1686398400, 1686402000 ] ], "service": 3600 } ], "speed_factor": 0.6 }, { "id": 7, "start": [ 106.7086064, 10.814915 ], "end": [ 106.7086064, 10.814915 ], "profile": "bike", "time_window": [ 1685953800, 1686418200 ], "skills": [ 1, 7000 ], "breaks": [ { "id": 1000, "time_windows": [ [ 1685966400, 1685970000 ] ], "service": 3600 }, { "id": 5, "time_windows": [ [ 1686331800, 1686333600 ] ], "service": 54000.0 }, { "id": 6000, "time_windows": [ [ 1686398400, 1686402000 ] ], "service": 3600 } ], "speed_factor": 0.6 } ], "jobs": [ { "id": 1001, "description": "HOME", "location": [ 106.5983012, 10.8879148 ], "service": 0, "priority": 3, "time_windows": [ [ 1685986200, 1685988000 ] ], "skills": [ 1000 ] }, { "id": 304, "description": "CO.OP FOOD NGUYỄN VĂN QUÁ", "location": [ 106.6287481, 10.8362058 ], "service": 1800, "time_windows": [ [ 1685948400, 1685980800 ], [ 1686034800, 1686067200 ], [ 1686121200, 1686153600 ], [ 1686207600, 1686240000 ], [ 1686294000, 1686326400 ], [ 1686380400, 1686412800 ] ], "skills": [ 1 ] }, { "id": 337, "description": "CO.OP FOOD TỈNH LỘ 15-1031", "location": [ 106.513876765966, 11.0885457429547 ], "service": 1800, "time_windows": [ [ 1685948400, 1685980800 ], [ 1686034800, 1686067200 ], [ 1686121200, 1686153600 ], [ 1686207600, 1686240000 ], [ 1686294000, 1686326400 ], [ 1686380400, 1686412800 ] ], "skills": [ 1 ] } ] } ``` Request truncated; some `vehicles` and `jobs` entries omitted. ### Request body description ### Vehicles | Parameter | Type | Description | |--------------|--------|------------------------------------------------------| | id | number | Unique identifier of the vehicle. | | start | array | Coordinates where the vehicle begins its route, in `[longitude, latitude]` order. | | end | array | Coordinates where the vehicle ends its route, in `[longitude, latitude]` order. Use the same value as `start` for a round trip. | | profile | string | Routing profile that determines speed and allowed roads (e.g. `bike`, `car`, `truck`). | | time_window | array | Working hours of the vehicle as `[start, end]` (in seconds, Unix timestamps in this example). The vehicle only operates within this window. | | skills | array | Array of integers listing the skills the vehicle **has**. A job is eligible only if all of its required skills are present here. | | breaks | array | List of mandatory breaks the vehicle must take. Each break is an object with `id`, `time_windows` (allowed `[start, end]` slots, in seconds) and `service` (break duration, in seconds). | | speed_factor | number | Multiplier applied to the profile's default speed. `< 1` slows the vehicle down, `> 1` speeds it up (e.g. `0.6` = 60% of the default speed). | ### Jobs | Parameter | Type | Description | |--------------|--------|------------------------------------------------------| | id | number | Unique identifier of the job. | | description | string | Free-text label for the job, returned as-is to help identify the stop. | | location | array | Coordinates of the job, in `[longitude, latitude]` order. | | service | number | Time spent servicing the job once the vehicle arrives, in **seconds**. | | priority | number | Priority of including the job in the solution, in the range `[0, 10]`. Higher values make the job more likely to be served. | | time_windows | array | Array of `[start, end]` windows (in seconds) during which the service may start. The job can have several disjoint windows. | | skills | array | Array of integers listing the skills the job **requires**. The job can only be served by a vehicle that has all of these skills. | **Response** ```swift { "code": 0, "summary": { "cost": 12400, "unassigned": 0, "service": 196200, "duration": 12400, "waiting_time": 237145, "priority": 3, "distance": 109272, "computing_times": { "loading": 37, "solving": 61, "routing": 11 } }, "unassigned": [], "routes": [ { "vehicle": 1, "cost": 12400, "service": 196200, "duration": 12400, "waiting_time": 237145, "priority": 3, "distance": 109272, "steps": [ { "type": "start", "location": [ 106.5983012, 10.8879148 ], "arrival": 1685956255, "duration": 0, "distance": 0 }, { "type": "break", "id": 6000, "service": 3600, "waiting_time": 177741, "arrival": 1686220659, "duration": 12400, "distance": 109272 }, { "type": "end", "location": [ 106.5983012, 10.8879148 ], "arrival": 1686402000, "duration": 12400, "distance": 109272 } ], "geometry": "ipmaA}|riSsAHGpB?\\ExC?l@CnBC`@OrAENK?EBCJ@FcBtBm@x@{B|CY^U`@GPG\\e@nCSp@uAlCWd@{C|F_AjBcAfB{AvCS^w@|A[j@Ub@INo@nAm@jAk@fAq@tAwBfEy@zAyAvCqAfCe@~@[j@c@z@mDxGs@vAOVw@dBw@xAi@fAOXs@rAKPyApCGLwA~CMXcUrNi@\\iHnEyBtAg[vRsCdBo[~RsCfB_CzA}BvAiC`BqBnAgEhCoMdIuAx@kNxIqAx@gAr@cDjBwDbCaF|CoBpA{@n@oAdAsCfCaDrC_FfEy@v@qApAc@f@i@t@g@r@w@~AQf@uGrP}IxUqFxNcBrEmB~EgCrGiCpGsAhDmDbJ{BpGwBtFkFhNgDzImC`H{@bBeCbE_BpCcAbBwDlG{FnJsDjGqH~LwFfJaC`EgDtFaEnHoAvCyBlFk@tAmAvCi@nA]v@eBfEeH~PwBxEgBpDgAzBaBhDqBbEmBzDkCzF_BbEwAbFoAfE{GnUSt@I`@w@fDOLKVoAfEc@lAM?MBQLELgAPaAg@eAk@eE_Cc@WqAu@uDsB_GcDaDeBuEkCwAu@}@i@kDkBkBeAy@e@aDcBcAk@uD{BgA`EgAfEfAgEfAaE_CsAqBgAcGeDQKmGkD}CcBtBuBTUlBkDfBcDbB{C`AcBl@}@NOVQ|BkAfDeBfD_B|C}AlDeBd@~@LIiB_EoEgJMYe@aAUc@{FsLqAcCoCyFwAaD[aAQy@WuAs@eE_@}Bc@iCc@mC]wBy@}E_@cC[oBi@_DMs@AKk@kDu@yEyA}IIk@CYAy@BSXmBXgBuBi@mAY{@QcAGkADyCReCNy@?}@IkAWs@GeD[iB]WSIMa@s@sAsCqAsCWc@KIUO[I_F{@qCiAgCgA{Ae@s@M_Eq@IGY]MSeAkCKSc@c@i@]{@m@kGwEgAs@c@W[MqLcDuA[cASwFi@oASyC]gC_@KEoBaAy@KkAAkILoE?]@wOLk@BQDkGhCyD|AyB|@mAj@_DpAkS~HcAh@_E~AoGjCqDxAgXzKsElB_G~BiMfFcEdBmAf@cCbA[LWHcKdEcBp@YLoHxCgFxBq`@~OwDxAgDvAwThJk@T[LqCjAsFrBiAd@}EtBkN~FcBp@qAj@c@Vo@`@kCnBqCpBuB\\u@NgA{AeE_HcBwBm@m@aFcE_DuCeFwFqA}AiKuPg@k@aCaC{D{DoCiCk@t@cA~@[VULmFfBw@Xo@TgBl@yBt@yMlEsGlB_Ct@uBl@kCh@cCl@eCj@m@LiEz@{Ev@q@JqG`AeDj@oDn@kDl@iAR^\\_@]hASjDm@nDo@dDk@pGaAp@KzEw@hE{@l@MdCk@bCm@jCi@tBm@~Bu@rGmBxMmExBu@fBm@n@Uv@YxDmAr@YTMZWbA_Aj@u@Xo@Va@hAaBlBeClHiJ`BmBtCsDnBiCb@g@d@_@bE{BxHmElBaAzB_AvIaDbAa@jHoCnE{AjJmDpCsAf@[d@a@jA_BpAqBfBgDtBqE|@gCn@cBr@aBv@cB|@kBlBqDfBcD~AsClE}HZg@zBoDNWxDkG|AkCj@gApB{DhAoBt@oAlBuDp@sAhAqB`C{DrB_DpCcEbBwCpAsBz@yAx@sApByCx@yAbCoDjAmB`EiGLS~CeFv@kAd@k@v@q@p@i@LOV_@x@wAFSFUD]Ac@]{DOmB?e@L{ALu@FOLQh@OlAQ`@GXKXOnCyCVSXITCT?d@Jp@\\bBpAXL`@N\\Df@@t@CrADvFP`@B~@HlEXhET`BJtCJf@BbFXv@Hx@JxIrAXDbFv@hANlFJ`IXrBFnBBrAHrAPpCb@dAHp@AnDSxAIzAKlAMl@M`LmEhH{CtCmA~@a@hBu@`EeBn@WbSiInCkAlEgBpAi@bCaA`Bk@|Bs@fCu@jBo@`H{BNGfA[vDgAjDiAlBm@zIoCfKcDpH_CxAc@dHyBdBi@pAa@pAa@xBw@`A]h@ObA[rAa@rAa@`Cy@bAa@~BsBvOwNfBaBvGgG~@_A~AwAlDcDdIkHzKgKdC}Bf@c@hC_Cn@m@RQnAgAd@e@`A_A`EsDvAsAzAwAhAeApCeCLMr@o@`B{AxCsCd@a@rF_FtBcB|E{DrAcArEuDnCwBhDkCt@c@jBy@p@[|@c@|CgBl@]pBgA|CgBrC_BdCuAz@i@@ArL_H~BsA|BsAhDuBLEb@?`AFTD`BXjBd@rA^fEhAl@Rz@^x@\\PJhAr@ZVRLPDZDZ@~@ClDc@fCGdE@rBB^BzE^`BNxIp@dE`@zFr@zCd@tIhApGv@pGz@hXrDpDh@lEh@~Ex@pANX@tEJpBBzLP`ABdBDtEJV@fCDpADhAFhBNhBRRBlALt@HxBTzAN^Dt@@rD@l@?|L@dVAl@ErCc@ZEfAOfBUp@ChAB~ATj@LdEhAtA^|Cx@b@LjDfAfGnBf@N`Bf@hA^NFjCx@t@VrBn@v@VfAZTD\\@|ABvED|A@nA@~@BDyC?]FqBrAInAIhDW~AMxAKrDYtBKz@FxANn@Dx@@VCVEb@Qn@U`DsA`@MdB_@NAl@?jE?rMB^F|Bl@La@b@{@r@mAJUh@{AVq@Jm@Hy@DiAFa@Pm@P_@vByDr@yA\\o@s@Ur@T]n@s@xAwBxDQ^Ql@G`@EhAIx@Kl@Wp@i@zAKTs@lAc@z@M`@dG|Ap@PzA^bHjB|@X\\J~DtAx@V~Ah@x@XJPzAaAFH`A`Bb@hAXvANnANzAJrA@f@EXKJc@Nn@fDT|AJzAHdBBX`@nA@JEP[r@CR@XRv@?TEx@Mz@qESS@IHGJ]zAMRGDWAwAYERDSvAXV@FELS\\{AFKHIRApER`ENV@xBDbBD`CHpDNrDLjFLj@?hAGfDQ`AUvAi@b@I`AMtF_@nBK`CKxAIfG_@v@AT?h@BvB^xAP`@BdBH`@Fj@N^Jv@VfBp@jBt@hA^XHhBf@fDtAl@\\}ApB]d@\\e@|AqBV[~@gA`AqA|BaDx@kAdAyARWlGwIf@u@r@aAj@s@zCsEfAyAVWjBgBdAaArEuEbA_AbAaA`@g@pAaCJOhAgBr@y@~AuBxAkB|AqBl@w@~@kAl@u@LOxAkB^e@tAgBp@_Aq@~@uAfB_@d@yAjBMNm@t@_AjAm@v@}ApByAjBsCnDgBkB_@[WOg@Se@QwAY}@EuCAmBL_A?gACy@Gy@IoBQa@IkAYsBi@OIeL~@c@FyALg@?kFu@yB]}AUs@KsBWsJyAUEWCuHmAmAQToALm@@Y?Q_@oAmAqBo@eAg@y@MSq@eAs@kAGIb@WrBqApCgBxBsAdEaCzJqFFH^t@GX@JdAfBLBLCr@a@fC{AhB}@VQ`Am@hCyALGZODCj@Y`DgBc@u@_@s@e@u@Sa@GIdMaHdE_CvAe@RM~EoC^SfBaArCyAbAe@NDP?REFENMFQBMC[IQMMQGYAy@w@]_@oC_DyAaBnBuA|DgCtDaC|CqBdAo@i@WF[GOYg@KO]aArA_@]mBBQmAwBVOf@_@dAq@TSRKP_@w@eAxBoApFmCJKP[F[`@mEH{@h@iGjADZ@~BJx@D@w@Ds@D]VuA^kBXFl@Jm@KYGk@KaBWs@MaAQq@Mk@IaBYsDo@KC_AMqAOq@Gm@G}C_A_AYkA_@iBk@yAe@iA]]Ue@c@c@_@aFeEk@e@q@m@USm@y@s@aAQSaAsA{@eAU_@]YQKm@_@iAm@}@g@}@g@|@f@|@f@hAl@l@^eIdMiAhBy@hA[b@o@nAYt@i@dBOt@QvAGf@cAlJE`@KZWr@SZe@b@g@XsAj@sDxAi@XkAp@aAv@_A|@_AhAa@l@{@~A_@~@c@Lm@Bs@g@a@P`@QkCeBeCeBK[IcBEyAG}B[_HCu@Y{DGCw@Im@O[Q_Au@uAmAw@q@YWw@s@wAoAyBkB{GyDkAzAjA{AkCqAi@Yo@[{@e@KEaB{@wAo@q@[SK[MqAi@w@Y_Bk@kC{@sAo@WIw@[qAe@cA_@UASGRFNNdA^BMNg@@[CuBKmBKmAm@oEAU@KH[T_@Zg@d@u@dAcBT_@zBeEYI{Aq@]OeAg@m@YCAc@UcCsAiAk@UK_@S}C}A{GgDyDoB{CqAcDsAgBq@}@]{@a@e@Wa@a@g@Oj@eIVmCoDFwFJkDHbACfBEOkEAq@MgDEuACyBAgAA_@Aw@AMM_@OWa@s@m@mAMo@EyAASq@_OMeDEcAEeBA}@SuP?OO{IKg@a@gBEYIeCBa@J{@V{ALa@X_@HMZaB?a@OsAa@uAIc@GcCEk@G]h@Ij@Il@Il@INAp@KNAjAOjBYT?Ra@H[?KC_@@YJyAC]EOGMMe@E_AE}@CmAT}ABU?QI[NMh@e@`@a@hAkApAuAFON[z@cAOMsAiAWUaAw@eDoCk@e@gAo@q@_@[Oi@YN]FG|Aw@zBcAhB}@r@_@BKGWg@qAaA}BWk@aAyBQ]QWOQGKc@cAkAcDOi@Me@q@}BcA{BOY_@yA??Ka@]L\\Mj@zBNXd@l@\\lAp@|BLd@Nh@jAbDb@bAFJNPPVP\\`AxBVj@`A|Bf@pAFVCJs@^iB|@{BbA}Av@GFO\\o@x@kAXaDl@{Bb@KFEH@TXl@FXH|@BfA?|CBxBJlCJfDZ`FB\\HbCBRTx@|@|BDRF\\Dj@FbCHb@`@tANrA?`@Ir@Ql@ILY^M`@WzAKz@C`@@fAF|@DX`@fBJf@Dh@HpH?NRtP@|@DdBDbALdDZlHTpEkH\\e@Hi@LmCz@mAb@sBp@DRHx@ZbCNn@j@fBX`BN`B{@@u@Cy@Mk@Mc@Kb@Jj@Lx@Lt@Bz@Al@AD|CJ~EAz@Kx@Cx@CTQz@Uj@GPKj@Gj@@JFJ?NCd@Kv@E\\rATJDVPb@\\LPTZRLjBf@BHCf@@FFHJBp@DETCv@Kx@?d@N@HBlAr@rAv@bAj@xChBdBdAXPb@ZfAf@IxAGbATF??VJnLhG~HvE|FdDrChBzBfANF{@~Ae@|@a@t@m@z@k@v@]|AWv@Yl@w@|Au@dBe@v@]j@[h@i@~@MRqAtBeBnDUlBIr@Kr@WzACNY~Ai@zCe@tCG~@s@Zq@^i@Z}BhA[PQTSd@cAbCmBaBL]M\\gByAq@k@_C{Ao@a@gCaBuAy@wA}@a@W{@g@_@Uk@]sBqAmCcBo@c@mCkBgC}AoA{@\\gA]fAUMeBoAKKi@i@e@_@e@]sA_AOMk@_@u@g@e@[OKo@e@oDcCm@_@OK}@o@gAu@oKiHm@_@GEcAs@wA_Aa@Ys@e@cH}EcDZmBZUDuAl@wAb@o@XqBjAWNy@b@Ua@Ya@YGu@CoAH{@Ro@J{@Jk@Js@RyCx@yCx@yCb@]Jq@PmAd@MWgBqD]u@\\t@fBpDLVLVvCrGl@rAh@jA^v@lDrHbD`Hn@pAd@dAzAbDrAvC`@v@t@pAl@bAj@|@lAjBFJbErGpApB`BjCrCtEl@~@n@bA`A|Az@tAXb@hAhBzBrDxA|B|BrDh@x@Vn@Hf@r@xDt@hEt@bEX|AV`Ah@vAjAjCzA`D`@`Af@rATfAt@vGBf@E~@GlCBlAFj@ThCT|ENpAL|@Tz@d@rAd@rAXl@JNa@`BGl@EXEnCAdAA`AMdCg@zDAd@Cr@rAI" } ] } ``` Response truncated; middle elements omitted. ### Response body description | Parameter | Type | Description | |------------------|---------|------------------------------------------------------------------------| | code | number | Status code of the response. `0` indicates the problem was solved successfully. | | summary | object | Aggregated metrics across **all** routes in the solution. | | summary.cost | number | Total cost of the solution (the objective value the solver minimizes, derived mainly from travel time). | | summary.unassigned | number | Number of jobs that could not be assigned to any vehicle. | | summary.service | number | Total service time spent at all visited jobs, in **seconds**. | | summary.duration | number | Total travel (driving) time across all routes, in **seconds**. | | summary.waiting_time | number | Total time vehicles spend waiting for time windows to open, in **seconds**. | | summary.priority | number | Sum of the `priority` values of all assigned jobs. | | summary.distance | number | Total distance covered by all routes, in **meters**. | | summary.computing_times | object | Time the solver spent in each phase, in **milliseconds**. | | summary.computing_times.loading | number | Time spent loading and preparing the input, in milliseconds. | | summary.computing_times.solving | number | Time spent optimizing the routes, in milliseconds. | | summary.computing_times.routing | number | Time spent computing the route geometries, in milliseconds. | | unassigned | array | List of jobs that could not be served, with their `id` and `location`. Empty when every job is assigned. | | routes | array | One entry per vehicle that is used in the solution. | | routes[].vehicle | number | `id` of the vehicle that performs this route. | | routes[].cost | number | Cost contribution of this route to `summary.cost`. | | routes[].service | number | Total service time at the jobs on this route, in **seconds**. | | routes[].duration | number | Total travel (driving) time of this route, in **seconds**. | | routes[].waiting_time | number | Time the vehicle waits for time windows on this route, in **seconds**. | | routes[].priority | number | Sum of the `priority` values of the jobs on this route. | | routes[].distance | number | Distance covered by this route, in **meters**. | | routes[].steps | array | Ordered list of stops the vehicle makes along the route. | | routes[].steps[].type | string | Type of the step: `start`, `job`, `pickup`, `delivery`, `break`, or `end`. | | routes[].steps[].id | number | `id` of the job or break this step refers to (present for `job`, `pickup`, `delivery` and `break` steps). | | routes[].steps[].location | array | Coordinates of the step, in `[longitude, latitude]` order (present for `start`, `end` and job steps). | | routes[].steps[].service | number | Service or break duration at this step, in **seconds**. | | routes[].steps[].waiting_time | number | Time the vehicle waits at this step before service can start, in **seconds**. | | routes[].steps[].arrival | number | Time the vehicle arrives at this step, in **seconds** (relative to the planning horizon or as a Unix timestamp, matching the input `time_windows`). | | routes[].steps[].duration | number | Cumulative travel time from the start of the route up to this step, in **seconds**. | | routes[].steps[].distance | number | Cumulative distance from the start of the route up to this step, in **meters**. | | routes[].geometry | string | Full route geometry as a `google polyline 5` encoded string. | !!! tip "Try it with your own data" Enter your own addresses, coordinates or parameters and see the result on a map, with a cURL command to copy: **[Open VRP on the Playground](https://tools.vietmap.vn/playground/vrp)** ## Frequently asked questions ### What is a VRP API? You send a list of vehicles and a list of stops. The API returns one route per vehicle with the visiting order, arrival time at each stop, cumulative distance and duration, plus the jobs no vehicle could take. ### What is the difference between TSP and VRP? TSP takes a list of `point` values and returns one route for one vehicle. VRP takes `vehicles` plus `jobs` and returns several routes plus `unassigned`. With a single vehicle, [TSP](https://maps.vietmap.vn/docs/map-api/tsp-version/tsp-v4/) is far cheaper: TSP costs `m` transactions, VRP costs `n × m`. ### What constraints can VRP handle? `capacity` on the vehicle with `delivery` / `pickup` on the job for load limits; `time_windows` on both vehicles and jobs for opening hours; `skills` so only an equipped vehicle can take a job; `priority` to choose which jobs survive when not everything fits. See [Constraints and the fields that model them](#constraints-and-the-fields-that-model-them). ### How many transactions does one VRP call cost? `vehicles × stops`. Three vehicles across twenty stops is 60 transactions. See [How Pricing Works](https://maps.vietmap.vn/docs/map-api/console/request-to-transaction/).