Skip to main content

Optimization API

Preview
This feature is in preview. It is being refined with early feedback, so its screens and behavior may change between releases, and it may need to be switched on for your organization before it appears. See experimental features for how preview works in Dime.Scheduler.

A solverSolverThe optimizer that assigns and sequences a set of tasks across a set of resources automatically, weighing skills, travel time and availability. It is a licensed module and produces a proposal, not a change. takes a set of resourcesResourceAn entity that can carry out work - a person, vehicle, tool, or room - that you schedule on the planning board., a window and the work that has to fit in it, and comes back with a plan: which resource does what, when, and in which order. Dispatchers start one from the planning board and review the outcome on the solver runs page; an AI agent can start one through the MCP optimization tools. The optimization endpoints are the third entry point, for integrations that want to trigger a run from a workflow of their own, say every evening for the next day, or when a batch of orders lands from the back office.

Whichever entry point starts it, a run is recorded as a solver runSolver runOne execution of the solver, listed on the solver runs page with its scores, status and the before-and-after of every appointment it touched. A run reaches the board only when a planner applies it., so a run started from the API shows up on the solver runs page like any other.

There are three solvers, each with its own endpoint:

EndpointSolverProblem it solves
POST /optimization/fieldServiceField serviceRoutes: assigns and sequences appointmentsAppointmentA task scheduled to a resource for a specific period - the scheduled instance you see on the planning board. across several resources and days to minimize travel timeTravel timeThe time needed to get from one appointment to the next, calculated from their locations. The planning board can show it in front of each appointment and fold it into the schedule. and distance (a vehicle routing problem).
POST /optimization/professionalServicesProfessional servicesAssignment: spreads tasksTaskA unit of work that belongs to a job. It appears in the open task list until it is scheduled to a resource. over resources and time by availability and requirements, where travel plays no role.
POST /optimization/dailyRouteDaily routeSequence: reorders one resource's appointments on one day into the shortest routeRouteThe path between a set of stops drawn on the map, with travel time and distance per leg. The route sequence grid lists the same stops as rows. (a traveling salesman problem).

Licenses and setup​

The solvers are optional modules, and each endpoint checks the tenant's license before it does anything:

  • /optimization/fieldService requires the Field Service solver subscription.
  • /optimization/professionalServices requires the Professional Services solver subscription.
  • /optimization/dailyRoute requires the Advanced Map module.

A tenant without the subscription gets HTTP 403 with the title Solver not licensed (or Advanced map not available for the daily route). The field service and professional services solvers also need the solver API key to be configured in Application Setup; without it the call fails with HTTP 500 and the message Solver API key not configured.

Request​

The field service and professional services requests share most of their shape:

NameData TypeDefaultRequiredDescription
startDatestring (date)✔️Start of the window the solver may plan into.
endDatestring (date)✔️End of the window.
resourcesstring[]✔️Resource numbers the solver may plan onto. At least one must exist.
itemsobject[]The work to hand the solver, see below.
options.timeZonestringTime zone the dates are interpreted in. Defaults to the caller's time zone, then to UTC.
options.terminationstringHow long the solver may search, as an ISO 8601 duration. Capped by the server.
options.saveAndPublishbooleanfalseAlso publish the changed appointments to every receiver, see Response.
notificationEmailstringWhere to send the explanation when the problem turns out to be infeasible.
incrementalModebooleanfalseField service only. Keep the existing planning and only add the unplanned work around it.
reassignmentobjectField service only, see below.

Each entry in items names one piece of work:

NameData TypeDefaultRequiredDescription
typestring✔️APPOINTMENT, TASK or PLANNED_TASK.
jobNostringWith TASK and PLANNED_TASK: the job of the task.
taskNostringWith TASK and PLANNED_TASK: the task.
appointmentGuidstring (uuid)With APPOINTMENT: the appointment.

A TASK is an open taskOpen taskA task that has not been scheduled yet. It waits in the open task list to be placed on the planning board. that still has to be planned; a PLANNED_TASK and an APPOINTMENT are work that is already on the board and may be moved. An item that cannot be found, or that lacks the identifier its type needs, fails the whole request with HTTP 400.

reassignment is for the field service solver and narrows a run to re-planning around one resource, the case where a technician calls in sick and their day has to be handed out:

NameData TypeDefaultRequiredDescription
modeint0 keeps every appointment's date and time and only changes who does it; 1 keeps the resource and reshuffles that resource's appointments on the selected day.
originalResourceIdintThe resource whose work is being reassigned.
originalDateStartstring (date)Start of the day or period being reassigned.
originalDateEndstring (date)End of that period.

The daily route request is smaller, because the scope is one resource on one day:

NameData TypeDefaultRequiredDescription
datestring (date)✔️The day to reorder.
resourcestring✔️The resource number.
options.timeZonestringAs above.
options.saveAndPublishbooleanfalseAs above.

Response​

All three answer synchronously; the call returns when the solver is done, so allow for a request that takes longer than a normal API call. The response has the same shape for each:

NameData TypeDescription
successbooleanWhether the solver found a plan.
errorMessagestringWhy it did not, when success is false.
optimizedAppointmentsobject[]The proposed appointments, in the shape GET /appointment returns them.
totalTravelTimeintTravel time of the proposed plan in seconds. Field service only.
totalDistanceintDistance of the proposed plan in meters. Field service only.

A run started from the API always applies its result: the appointments in the response have been written to the board by the time you receive them, the same as the Apply results automatically option of the in-product dialog. There is no review-first mode on the API; use the solver runs page when a dispatcher should confirm a plan before it lands. options.saveAndPublish controls what happens next. Left off, the appointments change on the board and in the response only. Switched on, the changes are also published to every receiver, which is the pipeline that tells the back officeBack officeThe ERP or business system Dime.Scheduler plans for - most often Microsoft Dynamics 365 Business Central. It owns the master data and remains authoritative over what it receives., connected clients and webhookWebhookThe generic connector that POSTs every appointment change as JSON to a URL you choose. It delivers the message and leaves interpretation to the receiving system. subscribers about an edit made on the board. Leave it off when your own system is the one that will read the response and does not need to hear about it twice.

When the hard constraints cannot all be satisfied, the field service and professional services solvers answer with HTTP 400 and send a detailed explanation to notificationEmail rather than returning a partial plan. Invalid input (an unknown resource, a bad time zone, an item that does not exist) is also answered with HTTP 400 and the reason in the problem body.

  • See POST /optimization/fieldService, POST /optimization/professionalServices and POST /optimization/dailyRoute in the REST API reference.
  • Example body for POST /optimization/fieldService:
    {
    "startDate": "2026-03-02T00:00:00",
    "endDate": "2026-03-06T23:59:59",
    "resources": ["LINDA", "JOHN"],
    "items": [
    { "type": "TASK", "jobNo": "SVC001", "taskNo": "1000" },
    { "type": "APPOINTMENT", "appointmentGuid": "ad37cfba-f502-4592-883d-4b10433722fe" }
    ],
    "incrementalMode": true,
    "options": {
    "timeZone": "Europe/Brussels",
    "saveAndPublish": false
    }
    }
  • Example body for POST /optimization/dailyRoute:
    {
    "date": "2026-03-02",
    "resource": "LINDA",
    "options": { "timeZone": "Europe/Brussels" }
    }

Read more​