Skip to content
JAOT

Solve

The Solve endpoints are the core of the JAOT API. Send any optimization problem as JSON and receive the optimal solution. JAOT supports linear programming (LP), integer programming (IP), mixed-integer programming (MIP), and binary problems.

POST /api/v2/solve

Solve an optimization problem synchronously. The request blocks until the solver finishes or the time limit is reached.

Authentication: Requires API key or JWT token.

Request Body

FieldTypeRequiredDescription
namestringNoA descriptive name for the problem
objectiveobjectYesObjective function definition
objective.sensestringYes"minimize" or "maximize"
objective.expressionstringYesMathematical expression (e.g. "50*chairs + 40*tables")
variablesarrayYesList of decision variable definitions
variables[].namestringYesVariable name used in expressions
variables[].typestringYes"continuous", "integer", or "binary"
variables[].lower_boundnumberNoLower bound (default: 0)
variables[].upper_boundnumberNoUpper bound (default: infinity)
constraintsarrayYesList of constraint definitions
constraints[].namestringNoDescriptive constraint name
constraints[].expressionstringYesConstraint expression (e.g. "2*chairs + 3*tables <= 240")
optionsobjectNoSolver options
options.time_limit_secondsnumberNoMaximum solve time in seconds (default: 60)
options.gap_tolerancenumberNoOptimality gap tolerance (default: 0.0001)
templatestringNoTemplate name for template-based solving
inputobjectNoInput data for template-based solving

Response

FieldTypeDescription
statusstringSolve status (see table below)
objective_valuenumberOptimal objective function value
variablesarrayVariable names and their optimal values
solutionobjectVariable-value map for quick access
solve_time_secondsnumberWall-clock solve time
gapnumberOptimality gap (0.0 = proven optimal)
iterationsnumberSolver iterations performed
nodesnumberBranch-and-bound nodes explored
credits_usednumberCredits consumed by this solve
credits_remainingnumberOrganization credit balance after solve

Status values:

StatusMeaning
optimalGlobally optimal solution found
feasibleSolution found, but optimality not proven
infeasibleNo feasible solution exists
unboundedObjective is unbounded
time_limitTime limit reached; best solution (if any) returned
errorSolver exception

Examples

import httpx

API_URL = "https://api.jaot.io/api/v2"
headers = {"Authorization": "Bearer ok_live_your_key_here"}

response = httpx.post(f"{API_URL}/solve", headers=headers, json={
    "name": "furniture_production",
    "variables": [
        {"name": "chairs", "type": "integer", "lower_bound": 0, "upper_bound": 100},
        {"name": "tables", "type": "integer", "lower_bound": 0, "upper_bound": 80},
    ],
    "objective": {"sense": "maximize", "expression": "50*chairs + 40*tables"},
    "constraints": [
        {"name": "assembly_hours", "expression": "2*chairs + 3*tables <= 240"},
        {"name": "finishing_hours", "expression": "4*chairs + 2*tables <= 200"},
    ],
    "options": {"time_limit_seconds": 30},
})

result = response.json()
print(f"Status: {result['status']}")
print(f"Revenue: ${result['objective_value']}")
print(f"Chairs: {result['solution']['chairs']}, Tables: {result['solution']['tables']}")

Response

{
  "status": "optimal",
  "objective_value": 3500.0,
  "variables": [
    {"name": "chairs", "value": 30, "type": "integer"},
    {"name": "tables", "value": 60, "type": "integer"}
  ],
  "solution": {"chairs": 30, "tables": 60},
  "solve_time_seconds": 0.045,
  "gap": 0.0,
  "iterations": 12,
  "nodes": 1,
  "credits_used": 2,
  "credits_remaining": 93
}

Errors

HTTP CodeErrorDescription
400bad_requestInvalid problem definition (undefined variable, invalid bounds)
401unauthorizedMissing or invalid API key
402insufficient_creditsNot enough credits to solve this problem
429rate_limitedToo many requests

Insufficient credits response:

{
  "error": "insufficient_credits",
  "credits_needed": 5,
  "credits_available": 2,
  "message": "This problem requires 5 credits, but you only have 2."
}

POST /api/v2/solve/async

Start an asynchronous solve. Returns immediately with a task ID. Use polling or WebSocket to retrieve the result when it completes.

Authentication: Requires API key or JWT token.

Request Body

Same as POST /api/v2/solve.

Response

FieldTypeDescription
task_idstringUnique task identifier for polling
statusstringAlways "pending" on creation
messagestringConfirmation message
ws_urlstringWebSocket URL for real-time updates
poll_urlstringPolling URL for status checks
estimated_creditsnumberEstimated credit cost

Examples

import httpx

API_URL = "https://api.jaot.io/api/v2"
headers = {"Authorization": "Bearer ok_live_your_key_here"}

# For large problems, use async mode
response = httpx.post(f"{API_URL}/solve/async", headers=headers, json={
    "name": "warehouse_routing",
    "variables": [
        {"name": f"route_{i}", "type": "binary"}
        for i in range(500)
    ],
    "objective": {
        "sense": "minimize",
        "expression": " + ".join(f"{cost}*route_{i}" for i, cost in enumerate(costs)),
    },
    "constraints": warehouse_constraints,
    "options": {"time_limit_seconds": 120},
})

task = response.json()
print(f"Task ID: {task['task_id']}, Status: {task['status']}")

Response

{
  "task_id": "b7a3c9e2-1234-5678-abcd-ef0123456789",
  "status": "pending",
  "message": "Task queued for processing",
  "ws_url": "/api/v2/ws/executions/b7a3c9e2-1234-5678-abcd-ef0123456789",
  "poll_url": "/api/v2/solve/async/b7a3c9e2-1234-5678-abcd-ef0123456789",
  "estimated_credits": 15
}

Tip: Use async mode for problems with more than 1,000 variables or long time limits. Async solves run on dedicated workers and support real-time progress updates via WebSocket.

Polling for Results

Use GET /api/v2/solve/async/{task_id} to check the status of an async solve.

Pending:

{"task_id": "b7a3c9e2-...", "status": "pending", "message": "Task is waiting to be processed"}

Running:

{"task_id": "b7a3c9e2-...", "status": "running", "progress": 0.45, "objective_value": 1234.56}

Completed:

{"task_id": "b7a3c9e2-...", "status": "completed", "result": {"status": "optimal", "objective_value": 3500.0, "..."}}

To retrieve async execution results, see the Executions page.


POST /api/v2/solve/validate

Validate a problem without solving it. No credits are charged. Useful for checking problem definitions before committing.

Authentication: Requires API key or JWT token.

Request Body

Same as POST /api/v2/solve.

Response (Valid Problem)

{
  "valid": true,
  "estimated_credits": 3,
  "num_variables": 5,
  "num_constraints": 8,
  "variable_types": {
    "continuous": 2,
    "integer": 3,
    "binary": 0
  }
}

Response (Invalid Problem)

{
  "valid": false,
  "errors": ["Objective references undefined variables: {'unknown_var'}"]
}

POST /api/v2/solve/async/{task_id}/cancel

Cancel a running async task.

Authentication: Requires API key or JWT token.

Response

{"task_id": "b7a3c9e2-...", "cancelled": true, "message": "Task cancellation requested"}

If the task already completed:

{"task_id": "b7a3c9e2-...", "cancelled": false, "message": "Task already completed, cannot cancel"}