Skip to main content
POST /v1/solve runs a declarative constraint-satisfaction / assignment spec (staff scheduling, coverage rostering, resource allocation) through HASP’s self-hosted CP-SAT solver and returns the computed assignment. It is the same deterministic solving capability behind the solve Studio workflow step and the solve.run agent tool — the request body is the spec (version, resources, slots, constraints, preferences, options), sent directly to the solver with no reimplementation of its validation. For the full constraint vocabulary (HARD_TYPES/SOFT_TYPES, size and magnitude bounds) and worked spec examples, see apps/solver/README.md — this page does not restate it.

Literal specs only

Unlike the workflow step and the solve.run agent tool, POST /v1/solve does not accept resources_from/slots_from — sending either is rejected with a 422 VALIDATION_FAILED. An integrator calling this endpoint already holds its own resource/slot data and is sending it directly; the workflow step and the agent tool are the surfaces that source resources/slots from a project’s live HASP records instead.

Infeasible is a 200

optimal, feasible, and infeasible are all successful outcomes — every one returns HTTP 200. On infeasible, data.assignments is empty and data.conflicts names the subset of your declared constraints that cannot be simultaneously satisfied, in your spec’s own vocabulary (constraint/slot ids). A 4xx/5xx on an infeasible solve would be a bug — treat infeasible as a normal, actionable result, not an error to catch.

Request

options.time_limit_seconds is capped at 30 (422 above that); omit it to use the engine’s 10-second default.

Response — optimal

Response — infeasible

Auth and billing

Requires the workflow.run capability (granted by the control:workflows PAT scope — the same scope that grants triggering a workflow run, since a direct solve is the same class of metered compute action). Delegated agent credentials cannot currently call this endpoint; an agent solves through the solve.run tool instead. Each call meters one agent_actions action (and, on the API surface, one api_agent_actions action) — see Rate Limits for the org-level RPM/daily buckets this endpoint also draws from.

Auditing

Every call — optimal, feasible, or infeasible — records a workflow.solve_completed audit event carrying the solver status, conflict ids, and the sha256 of the exact spec sent to the solver. Because solving is deterministic, the hash makes any recorded solve independently reproducible without the spec itself (which may carry workforce identifiers) living in the audit row.

Error codes

See Errors for the full error envelope shape.