For ERP/MRP vendors and IT integrators

Solver API for JSS & FJSS

Commercial access to the high-performance calculation engine for ERP/MRP developers and IT integrators. REST in, optimized sequence out.

For ERP/MRP vendors and IT integrators

Add an APS module to your system in an afternoon

Your ERP already knows the routings, the machines and the due dates. It just cannot schedule them. Post that data to the commercial solver gateway, poll the job and receive a feasible, optimized sequence. Two input formats: structured JSON or compact DZN.

Authentication

Every call carries a B2B bearer token: Authorization: Bearer <your_api_key>. Solving is asynchronous — POST returns a job_id, GET returns the status and the result.

JSON calls

Recommended

Solver input is passed as a structured model_data object instead of raw DZN text. The gateway includes a normalization layer, so you write plain developer notation and the engine converts it to the set structures the MiniZinc compiler requires.

Endpoints

  • POST/api/commercial/v1/solve/json— Start solving (asynchronous)
  • GET/api/commercial/v1/solve/json/{job_id}— Job status and results
  • Array notation (recommended): pass sets as plain arrays of integers, e.g. "tasks": [[1, 2], [3, 4]].
  • Range notation (compact): describe a set as a string range, e.g. "1..15" — the engine expands it automatically.
  • Single-element sets: 229, [229] or "{229}" are all accepted; "{206, 207}" works for several elements.
  • Native notation (optional): {"set": [1, 2, 3]} passes through untouched.

Small JSON example

3 machines, 2 jobs, 4 tasks, 6 operations — submitted with one extra constraint and a 60 s time limit.

Request

curl -i -X POST https://api.makespan.pl:443/api/commercial/v1/solve/json \
  -H "Authorization: Bearer $MAKESPAN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "schedule_id": "json-small-schedule-uuid",
  "user_id": "json-small-user-uuid",
  "model_data": {
    "no_mach": 3,
    "no_jobs": 2,
    "no_task": 4,
    "no_optt": 6,
    "tasks": [[1, 2], [3, 4]],
    "optts": [[1, 2], [3], [4, 5], [6]],
    "optt_mach": [1, 2, 2, 2, 3, 1],
    "optt_dur": [10, 15, 20, 12, 8, 5]
  },
  "constraints_text": "constraint start[1] >= 5;",
  "time_limit_seconds": 60
}'

Response

202 Accepted
{
  "job_id": "job-0c19ea48",
  "status": "queued",
  "schedule_id": "json-small-schedule-uuid",
  "estimated_wait_seconds": 9
}

Status query (GET)

Poll the job_id returned by POST. Once status is completed, result_json carries the optimized schedule.

Request

curl -i -X GET https://api.makespan.pl:443/api/commercial/v1/solve/json/job-0c19ea48 \
  -H "Authorization: Bearer $MAKESPAN_API_KEY"

Response

200 OK
{
  "job_id": "job-0c19ea48",
  "schedule_id": "json-small-schedule-uuid",
  "status": "completed",
  "error_message": null,
  "started_at": "2026-08-22T16:43:40.947288Z",
  "finished_at": "2026-08-22T16:43:41.242836Z",
  "result_json": {
    "start": [5, 15, 0, 15],
    "dur": [10, 20, 8, 5],
    "b": [true, false, true, false, true, true],
    "objective": 35
  }
}

DZN calls (MiniZinc Text)

Native / compact

This format accepts solver input written as raw DZN text (where newline characters are encoded as \n).

Endpoints

  • POST/api/commercial/v1/solve— Start solving (asynchronous)
  • GET/api/commercial/v1/solve/{job_id}— Job status and results
  • Why DZN: the notation is extremely compact — the same model takes far fewer bytes than the equivalent JSON payload, which matters at thousands of operations.
  • DZN is also the native input format of the solver compiler, so there is no conversion or normalization layer between your request and the engine.

Small DZN example

The same model — 3 machines, 2 jobs, 4 tasks, 6 operations — sent as a single dzn_text string.

Request

curl -i -X POST https://api.makespan.pl:443/api/commercial/v1/solve \
  -H "Authorization: Bearer $MAKESPAN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "schedule_id": "14e6636f-8388-4e57-8dfd-f428c5fe1190",
  "user_id": "79f04043-fec5-4081-b276-774412df0821",
  "dzn_text": "no_mach = 3;\nno_jobs = 2;\nno_task = 4;\nno_optt = 6;\ntasks = [1..2, 3..4];\noptts = [1..2, 3..3, 4..5, 6..6];\noptt_mach = [1, 2, 2, 2, 3, 1];\noptt_dur = [10, 15, 20, 12, 8, 5];",
  "constraints_text": "constraint start[1] >= 5;",
  "time_limit_seconds": 60
}'

Response

202 Accepted
{
  "job_id": "job-0c19ea48",
  "status": "queued",
  "schedule_id": "14e6636f-8388-4e57-8dfd-f428c5fe1190",
  "estimated_wait_seconds": 9
}

Status query (GET)

The finished job returns result_dzn: objective plus the start, dur and b arrays in DZN notation.

Request

curl -i -X GET https://api.makespan.pl:443/api/commercial/v1/solve/job-0c19ea48 \
  -H "Authorization: Bearer $MAKESPAN_API_KEY"

Response

200 OK
{
  "job_id": "job-0c19ea48",
  "schedule_id": "14e6636f-8388-4e57-8dfd-f428c5fe1190",
  "user_id": "79f04043-fec5-4081-b276-774412df0821",
  "status": "completed",
  "result_dzn": "objective = 35;\nstart = [5, 15, 0, 15];\ndur = [10, 20, 8, 5];\nb = [true, false, true, false, true, true];",
  "error_message": null,
  "started_at": "2026-08-21T14:03:49.924494Z",
  "finished_at": "2026-08-21T14:03:50.435426Z"
}

Webhooks: Asynchronous event integration

Event-driven

For ERP/MRP-class production systems, webhooks are the recommended integration method with makespan.online instead of continuously polling for job status.

What they do and why use them

Production schedule optimization is computationally heavy. Depending on problem size and the configured time_limit_seconds, a run can take from a few seconds to several minutes.

  • Zero polling: instead of sending GET requests every 2 seconds — which creates unnecessary network traffic and can trigger rate limits — your system sends a single POST /solve and passively waits for the result.
  • Event-driven architecture: as soon as the MiniZinc engine finishes — regardless of success, error or timeout — the makespan.online gateway sends an asynchronous POST notification to the URL configured in your tenant portal.
  • Resource savings: ideal for background integration — your application releases the worker thread and resumes planning only when the webhook arrives.

Webhook configuration

Simply configure a Webhook URL in your account settings (Tenant Portal), e.g. https://your-erp-system.pl/api/v1/makespan-callback. Our server will send a POST request there with Content-Type: application/json.

Best practice: Your receiving server should respond immediately with status 200 OK or 202 Accepted (ideally within 2 seconds). Process and store the result asynchronously in the background to prevent the gateway from closing the connection due to timeout.

Webhook notification examples

Notification for a JSON job

When the original job was sent in JSON format, the webhook returns the result in result_json.

{
  "job_id": "job-ccc5892d",
  "schedule_id": "json-small-schedule-uuid-vps-test",
  "status": "Success",
  "error_message": null,
  "solver_seconds": 12.35,
  "finished_at": "2026-08-26T06:59:44.125Z",
  "result_json": {
    "start": [5, 15, 0, 15],
    "dur": [10, 20, 8, 5],
    "b": [true, false, true, false, true, true],
    "objective": 35
  }
}
Notification for a DZN job

When the original job was sent in DZN format, the webhook returns the result in result_dzn.

{
  "job_id": "job-0c19ea48",
  "schedule_id": "14e6636f-8388-4e57-8dfd-f428c5fe1190",
  "status": "Success",
  "error_message": null,
  "solver_seconds": 18.12,
  "finished_at": "2026-08-26T07:11:05.435Z",
  "result_dzn": "objective = 35;\nstart = [5, 15, 0, 15];\ndur = [10, 20, 8, 5];\nb = [true, false, true, false, true, true];"
}

Key parameters

status
Job execution status. Possible values: Success (schedule found), Timeout (time limit exceeded; best solution so far is returned), Error (compilation or validation error).
solver_seconds
Actual time in seconds spent by the engine on JSS calculations.
finished_at
ISO 8601 timestamp marking the end of optimization.

REST, not a rewrite

Two endpoints are all you integrate: POST to start solving, GET to collect the status and the result. No agents, no on-prem installation, no schema migration on your side.

Solving is asynchronous, so a long run never blocks your ERP transaction.

Zero polling

Webhooks remove the need to poll GET /solve/{job_id} every few seconds. Your ERP sends one POST and resumes work only when the gateway pushes the completed result.

Event-driven architecture

The gateway pushes a notification as soon as the solver finishes — whether the job succeeds, times out or fails validation — so your system reacts to real events instead of checking for them.

Resource savings

Background integration without blocking worker threads. Your application scales better because it does not hold connections open while the engine is optimizing.

It keeps improving until time runs out

As soon as the solver finds the first schedule satisfying every constraint, it does not stop. It keeps searching for a better objective — for example a shorter makespan — until the granted time_limit_seconds is exhausted.

You always receive the best schedule found within your time budget.

More constraints, not more solve time

Counter-intuitively, adding constraints usually shortens the solve, not lengthens it.

Technically: every constraint prunes the search tree of the optimization problem, so the remaining space to explore is smaller and the search moves through it faster.

Sandbox & docs

A free sandbox key, deterministic sample datasets and complete developer documentation (Swagger UI and ReDoc) for your integration team.

The solver constraint library currently counts around 10 items. Next to simple ones — such as "job A may start between date X and date Y" — it covers several advanced constraints:

  • Sequence-dependent setup times
  • Transportation / transfer times between machines
  • Minimum and maximum time lags between operations of one job (delay windows)
  • Machine unavailability windows (maintenance)

Predictable volume pricing

A flat developer base fee plus solve-volume tiers, so you can price your own APS add-on with confidence.

Engine specification

Problem classes
JSS, Flexible JSS (alternative machines)
Input formats
JSON (model_data) or DZN (MiniZinc Text)
Execution model
asynchronous — POST job, GET status
Objectives
Makespan minimization, due-date & lateness penalty cost minimization
Multi-criteria objectives
minimization: total setup times + makespan
Max operations
300 per schedule on standard tiers
Transport
HTTPS / JSON, bearer token auth
Hosting
EU (Nuremberg, Germany)

Want to see it on your routings?

Request free beta access and bring one week of real production data.

Planner dashboard