Open Application Platform Docs

Plan re-costing

Price an edited plan exactly as given — per-leg distance, duration and road geometry, with arrival times — without resequencing it. Stated constraints (time windows, capacity, skills, vehicle ceilings) are judged and reported as violations, never refused.

plan.recost Stable node

How to call it

REST

POST /v1/plan/recost

GraphQL

query openPlanRecost

MCP

open_plan_recost

Price a plan exactly as given, without resequencing it: every leg measured on the road network with distance, duration and geometry, and arrival times projected from departure. Use it after editing a plan — adding a stop at a chosen position, removing one, reordering or reversing a route, or moving a start or end point. To have the engine PLACE a new stop instead, use open_routing_refine with the existing stops frozen. Billed per stop.

Request schema

Generated from the same validation rules the endpoint runs, so a field cannot be documented without being validated.

POST /v1/plan/recost

{
    "type": "object",
    "properties": {
        "departed_at": [],
        "jobs": {
            "type": "array",
            "minItems": 1,
            "maxItems": 2000,
            "items": {
                "type": "object",
                "properties": {
                    "amount": {
                        "type": [
                            "array",
                            "null"
                        ]
                    },
                    "id": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "maxLength": 128
                    },
                    "location": {
                        "type": "array"
                    },
                    "service_seconds": {
                        "type": [
                            "integer",
                            "null"
                        ],
                        "minimum": 0
                    },
                    "skills": {
                        "type": "array",
                        "items": {
                            "type": "string",
                            "maxLength": 64
                        }
                    },
                    "time_windows": {
                        "type": [
                            "array",
                            "null"
                        ]
                    }
                },
                "required": [
                    "location"
                ]
            }
        },
        "matrix": {
            "type": [
                "string",
                "null"
            ],
            "maxLength": 200
        },
        "options": {
            "type": [
                "object",
                "null"
            ],
            "properties": {
                "geometry": {
                    "type": [
                        "boolean",
                        "null"
                    ]
                }
            }
        },
        "profile": {
            "type": [
                "string",
                "null"
            ],
            "enum": [
                "car",
                "van",
                "truck",
                "bike",
                "foot",
                "motorcycle"
            ]
        },
        "region": {
            "type": [
                "string",
                "null"
            ],
            "enum": [
                "NA",
                "EU",
                "AU",
                "ASIA",
                "na",
                "eu",
                "au",
                "asia"
            ]
        },
        "routes": {
            "type": "array",
            "minItems": 1,
            "maxItems": 200,
            "items": {
                "type": "object",
                "properties": {
                    "reverse": {
                        "type": [
                            "boolean",
                            "null"
                        ]
                    },
                    "stops": {
                        "type": "array",
                        "maxItems": 2000,
                        "items": {
                            "type": "string",
                            "maxLength": 128
                        }
                    },
                    "vehicle_id": {
                        "type": "string",
                        "maxLength": 128
                    }
                },
                "required": [
                    "vehicle_id"
                ]
            }
        },
        "vehicles": {
            "type": "array",
            "minItems": 1,
            "maxItems": 200,
            "items": {
                "type": "object",
                "properties": {
                    "capacity": {
                        "type": [
                            "array",
                            "null"
                        ]
                    },
                    "end": {
                        "type": [
                            "array",
                            "null"
                        ]
                    },
                    "id": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "maxLength": 128
                    },
                    "max_distance_meters": {
                        "type": [
                            "integer",
                            "null"
                        ],
                        "minimum": 0
                    },
                    "max_tasks": {
                        "type": [
                            "integer",
                            "null"
                        ],
                        "minimum": 0
                    },
                    "max_travel_time_seconds": {
                        "type": [
                            "integer",
                            "null"
                        ],
                        "minimum": 0
                    },
                    "return_to_start": {
                        "type": [
                            "boolean",
                            "null"
                        ]
                    },
                    "skills": {
                        "type": "array",
                        "items": {
                            "type": "string",
                            "maxLength": 64
                        }
                    },
                    "start": {
                        "type": [
                            "array",
                            "null"
                        ]
                    },
                    "time_window": {
                        "type": [
                            "array",
                            "null"
                        ]
                    }
                }
            }
        }
    },
    "additionalProperties": false,
    "required": [
        "jobs",
        "routes",
        "vehicles"
    ]
}

Request example

{
    "vehicles": [
        {
            "id": "van-1",
            "start": {
                "lat": 45.5017,
                "lng": -73.5673
            },
            "return_to_start": true,
            "capacity": [
                10
            ]
        }
    ],
    "jobs": [
        {
            "id": "order-1001",
            "location": {
                "lat": 45.5088,
                "lng": -73.554
            },
            "service_seconds": 300,
            "amount": [
                2
            ]
        },
        {
            "id": "order-1002",
            "location": {
                "lat": 45.4972,
                "lng": -73.5786
            },
            "service_seconds": 300,
            "amount": [
                3
            ]
        }
    ],
    "routes": [
        {
            "vehicle_id": "van-1",
            "stops": [
                "order-1001",
                "order-1002"
            ]
        }
    ]
}

Response

What a successful call returns: the schema of `data` and `meta`, with a description of each field, followed by an example response from a real call.

POST /v1/plan/recost

Response schema

{
    "description": "The caller's routes, kept exactly as given, with distance, driving time and arrival time of every stop. Breaches of the stated constraints are reported in `violations`, never refused.",
    "data": {
        "type": "object",
        "properties": {
            "routes": {
                "type": "array",
                "items": {
                    "type": "object",
                    "properties": {
                        "vehicle_id": {
                            "type": "string"
                        },
                        "stop_count": {
                            "type": "integer",
                            "description": "Stops including start and end."
                        },
                        "task_count": {
                            "type": "integer",
                            "description": "Jobs on the route."
                        },
                        "distance_meters": {
                            "type": "integer"
                        },
                        "duration_seconds": {
                            "type": "integer",
                            "description": "Driving time."
                        },
                        "service_seconds": {
                            "type": "integer"
                        },
                        "waiting_seconds": {
                            "type": "integer"
                        },
                        "departure": {
                            "type": "string",
                            "description": "ISO 8601 with offset."
                        },
                        "completion": {
                            "type": "string",
                            "description": "When the last stop (or the end) is reached. ISO 8601 with offset."
                        },
                        "unreachable_legs": {
                            "type": "integer"
                        },
                        "violations": {
                            "type": "array",
                            "items": {
                                "type": "object",
                                "description": "A route-level breach. Which fields are present depends on `rule`.",
                                "properties": {
                                    "rule": {
                                        "type": "string",
                                        "enum": [
                                            "capacity",
                                            "max_tasks",
                                            "max_distance",
                                            "max_travel_time",
                                            "vehicle_time_window"
                                        ]
                                    },
                                    "message": {
                                        "type": "string"
                                    },
                                    "dimension": {
                                        "type": "string",
                                        "description": "capacity: the capacity dimension that overflows."
                                    },
                                    "load": {
                                        "type": "number",
                                        "description": "capacity: what the stops load."
                                    },
                                    "capacity": {
                                        "type": "number",
                                        "description": "capacity: what the vehicle carries."
                                    },
                                    "tasks": {
                                        "type": "integer",
                                        "description": "max_tasks: stops on the route."
                                    },
                                    "distance_meters": {
                                        "type": "integer",
                                        "description": "max_distance: distance of the route."
                                    },
                                    "duration_seconds": {
                                        "type": "integer",
                                        "description": "max_travel_time: driving time of the route."
                                    },
                                    "limit": {
                                        "type": "integer",
                                        "description": "max_tasks, max_distance, max_travel_time: the vehicle's limit."
                                    },
                                    "late_seconds": {
                                        "type": "integer",
                                        "description": "vehicle_time_window: how far past the working window the route ends."
                                    },
                                    "window_end": {
                                        "type": "string",
                                        "description": "vehicle_time_window: when the working window ends. ISO 8601 with offset."
                                    }
                                }
                            },
                            "description": "Route-level breaches."
                        },
                        "violation_count": {
                            "type": "integer",
                            "description": "Route and stop breaches on this route."
                        },
                        "stops": {
                            "type": "array",
                            "items": {
                                "type": "object",
                                "properties": {
                                    "type": {
                                        "type": "string",
                                        "enum": [
                                            "start",
                                            "job",
                                            "end"
                                        ]
                                    },
                                    "id": {
                                        "type": "string",
                                        "description": "The caller's job id. Jobs only."
                                    },
                                    "sequence": {
                                        "type": "integer",
                                        "description": "Position of the job on the route, from 1."
                                    },
                                    "reachable": {
                                        "type": "boolean",
                                        "description": "Whether the hop into this stop could be routed. An unreachable hop has no distance or time and is counted in `unreachable_legs`."
                                    },
                                    "departure": {
                                        "type": "string",
                                        "description": "Start only: when the vehicle leaves. ISO 8601 with offset."
                                    },
                                    "waiting_seconds": {
                                        "type": "integer",
                                        "description": "Start only, when the vehicle must wait for its working window to open."
                                    },
                                    "arrival": {
                                        "type": [
                                            "string",
                                            "null"
                                        ],
                                        "description": "ISO 8601 with offset. Null after an unreachable hop."
                                    },
                                    "arrival_epoch": {
                                        "type": [
                                            "integer",
                                            "null"
                                        ],
                                        "description": "`arrival` as Unix seconds."
                                    },
                                    "leg_distance_meters": {
                                        "type": [
                                            "integer",
                                            "null"
                                        ],
                                        "description": "Distance of the hop into this stop."
                                    },
                                    "leg_duration_seconds": {
                                        "type": [
                                            "integer",
                                            "null"
                                        ],
                                        "description": "Driving time of the hop into this stop."
                                    },
                                    "leg_geometry": {
                                        "type": [
                                            "string",
                                            "null"
                                        ],
                                        "description": "Encoded polyline (precision 5) of the hop into this stop. Present when `options.geometry` is true (the default)."
                                    },
                                    "distance_meters": {
                                        "type": [
                                            "integer",
                                            "null"
                                        ],
                                        "description": "Cumulative distance from the start."
                                    },
                                    "duration_seconds": {
                                        "type": [
                                            "integer",
                                            "null"
                                        ],
                                        "description": "Cumulative driving time from the start."
                                    },
                                    "violations": {
                                        "type": "array",
                                        "items": {
                                            "type": "object",
                                            "properties": {
                                                "rule": {
                                                    "type": "string",
                                                    "enum": [
                                                        "skills",
                                                        "time_window"
                                                    ]
                                                },
                                                "message": {
                                                    "type": "string"
                                                },
                                                "missing": {
                                                    "type": "array",
                                                    "items": {
                                                        "type": "string"
                                                    },
                                                    "description": "skills: the skills the vehicle lacks."
                                                },
                                                "late_seconds": {
                                                    "type": "integer",
                                                    "description": "time_window: how late the arrival is."
                                                },
                                                "window": {
                                                    "type": "object",
                                                    "description": "time_window: the window that was missed.",
                                                    "properties": {
                                                        "from": {
                                                            "type": "string",
                                                            "description": "ISO 8601 with offset."
                                                        },
                                                        "to": {
                                                            "type": "string",
                                                            "description": "ISO 8601 with offset."
                                                        }
                                                    }
                                                }
                                            }
                                        },
                                        "description": "Constraints this stop breaks. Present only when it breaks one."
                                    }
                                },
                                "required": [
                                    "type"
                                ]
                            }
                        }
                    }
                }
            },
            "summary": {
                "type": "object",
                "properties": {
                    "routes": {
                        "type": "integer"
                    },
                    "tasks": {
                        "type": "integer",
                        "description": "Jobs across all routes."
                    },
                    "distance_meters": {
                        "type": "integer"
                    },
                    "duration_seconds": {
                        "type": "integer",
                        "description": "Driving time across all routes."
                    },
                    "unreachable_legs": {
                        "type": "integer",
                        "description": "Hops that could not be routed."
                    },
                    "violations": {
                        "type": "integer",
                        "description": "Breaches across all routes and stops."
                    }
                }
            }
        }
    },
    "meta": {
        "type": "object",
        "properties": {
            "region": {
                "type": "string",
                "description": "The engine region used."
            },
            "profile": {
                "type": "string",
                "description": "The vehicle profile used."
            },
            "geometry": {
                "type": "boolean",
                "description": "Whether leg geometry was returned."
            },
            "geometry_format": {
                "type": [
                    "string",
                    "null"
                ],
                "description": "`polyline` when geometry was returned."
            },
            "departed_at": {
                "type": "string",
                "description": "The departure time the plan was timed from: `departed_at`, else the current time. ISO 8601 with offset."
            }
        },
        "additionalProperties": true
    }
}

Response example

{
    "request_id": "req_01k8zq3m5n7p9r1t3v5x7z9b2d",
    "capability": "plan.recost",
    "billing": {
        "unit": "node",
        "quantity": 2,
        "counted": true,
        "breakdown": {
            "tasks": 2,
            "routes": 1
        }
    },
    "data": {
        "routes": [
            {
                "vehicle_id": "van-1",
                "stop_count": 4,
                "task_count": 2,
                "distance_meters": 6416,
                "duration_seconds": 832,
                "service_seconds": 600,
                "waiting_seconds": 0,
                "departure": "2026-10-23T09:27:48-04:00",
                "completion": "2026-10-23T09:51:40-04:00",
                "unreachable_legs": 0,
                "violations": [],
                "violation_count": 0,
                "stops": [
                    {
                        "type": "start",
                        "departure": "2026-10-23T09:27:48-04:00"
                    },
                    {
                        "type": "job",
                        "id": "order-1001",
                        "sequence": 1,
                        "reachable": true,
                        "leg_distance_meters": 1840,
                        "leg_duration_seconds": 245,
                        "leg_geometry": "y`vtGjr_`MJUNYL[h@gAHOFQBIHOc@g@MOa@]s@q@EGEEk@g@k@k@CCMMDO@EDMBMBOBQBO@KBM?G@OBQ?G@MBQ@MBMBMBOBOBMFSDSBGBIBGHOvAkE@EHQGEECa@_@ECMKKIwAiA_CmBq@m@ECIIOKoAcAs@i@KIIIOMgA{@QMCCGGGE_@[m@g@a@[kA_ACCECKGKGWSQOwAkAGEGEu@o@CCMIMKGEYSeAq@OKa@WGG[Sy@g@w@k@s@e@GEGE??YQgAu@c@[QKc@YMKKG@EBK@EVo@@EDKDM@Cb@cAFOBIt@oBBEDUJFBBFDx@l@??",
                        "arrival": "2026-10-23T09:31:53-04:00",
                        "arrival_epoch": 1792762313,
                        "distance_meters": 1840,
                        "duration_seconds": 245
                    },
                    {
                        "type": "job",
                        "id": "order-1002",
                        "sequence": 2,
                        "reachable": true,
                        "leg_distance_meters": 3108,
                        "leg_duration_seconds": 390,
                        "leg_geometry": "elwtGl}|_Mx@n@BBFD\\ZDDDBz@l@`@\\~BdB~AjAf@\\DDBBLDEPEJe@zAADENGNCFW|@Y|@CFA@ELCHGRq@jBABu@tBCHAFEJGNADg@vAKXq@lBABEHAHgA|C_@fASf@ADGPO^JHbAt@`CrBBBJHLJhCzBJL~BvBFDJJHF~@r@zAdABBHFLHdDfCBBFFFDJHvDlCRJDBRHXPx@f@D@HHJFVV|@x@BBLJTRJJTTlBdBLL`@\\h@f@ZXNLr@p@BBB@JJJHv@r@j@h@DDNLJJp@l@HHj@j@DBLLRRfB`BBBJJHFv@r@x@t@B@HHJJz@v@RRl@j@BBHHJHhAfAj@j@BBNLHHLLVT|@z@HFIPw@tBmAbDy@vBe@pACDIPIRg@pAO\\{A`ECDAFEJHHp@p@??",
                        "arrival": "2026-10-23T09:43:23-04:00",
                        "arrival_epoch": 1792763003,
                        "distance_meters": 4948,
                        "duration_seconds": 635
                    },
                    {
                        "type": "end",
                        "reachable": true,
                        "leg_distance_meters": 1468,
                        "leg_duration_seconds": 197,
                        "leg_geometry": "{cutG|wa`Md@f@LJFDDDFBBBFBDKBGrAkDFQBGp@eB@EFSFSBCb@mAl@}AjA{Cb@iAd@mABEFQJ[IG{ByBIGGIMKIKo@m@OMGI[Yc@a@e@c@m@m@ECIIKKaA}@EEu@q@CCIIKIq@o@{@y@ECIIII_@[[Y_@_@ECWWQOIIGE]]QO_@]CCKKYWKIu@q@MMYWCCKKKIACoAiAuAoAKIs@q@eA_AKKCCOOJO@A??",
                        "arrival": "2026-10-23T09:51:40-04:00",
                        "arrival_epoch": 1792763500,
                        "distance_meters": 6416,
                        "duration_seconds": 832
                    }
                ]
            }
        ],
        "summary": {
            "routes": 1,
            "tasks": 2,
            "distance_meters": 6416,
            "duration_seconds": 832,
            "unreachable_legs": 0,
            "violations": 0
        }
    },
    "meta": {
        "region": "NA",
        "profile": "car",
        "geometry": true,
        "geometry_format": "polyline",
        "departed_at": "2026-10-23T09:27:48-04:00",
        "mode": "sync"
    }
}

What it costs

Every point the solver must visit or depart from, including each vehicle's start and end.

Every billable response carries a billing block with the unit, the quantity and how the quantity was derived.

Errors it can return

Status Code Description
401 TOKEN_INVALID Unknown or revoked API token.
401 TOKEN_MISSING No API token. Send Authorization: Bearer <your token>.
403 CAPABILITY_NOT_ENABLED This capability is not enabled for your account. See :doc to enable it.
403 CAPABILITY_NOT_GRANTED_TO_KEY Your account has this capability, but this API key was not granted it.
403 OPEN_API_DISABLED Open Platform access is not enabled for this account.
422 VALIDATION_FAILED The request failed validation. See details.
429 RATE_LIMITED Too many requests. Please retry after the indicated delay.
500 INTERNAL_ERROR An unexpected error occurred. Quote the request_id when contacting support.