Send any optimisation problem. Get one answer back.
Routing, scheduling, rostering, packing, allocation, and anything else with decisions, constraints and a cost. Describe the problem once, name a solver or a meta-solver, and pay per solve-second with a hard cost cap on every run.
{
"api_version": "1",
"problem": {
"variables": [
{"name": "chairs", "lower": 0},
{"name": "tables", "lower": 0}
],
"constraints": [
{"expr": "4*chairs + 8*tables <= 160", "name": "machine_hours"},
{"expr": "2*chairs + 3*tables <= 75", "name": "material"}
],
"objective": {"sense": "max", "expr": "45*chairs + 80*tables"}
},
"solver": "highs",
"options": {"compute_preset": "cpu-standard", "time_limit_seconds": 5, "tags": ["quickstart"]}
}
"solver": "highs","compute_preset": "cpu-standard","time_limit_seconds": 5
Show the whole envelope
{
"api_version": "1",
"problem": {
"variables": [
{"name": "chairs", "lower": 0},
{"name": "tables", "lower": 0}
],
"constraints": [
{"expr": "4*chairs + 8*tables <= 160", "name": "machine_hours"},
{"expr": "2*chairs + 3*tables <= 75", "name": "material"}
],
"objective": {"sense": "max", "expr": "45*chairs + 80*tables"}
},
"solver": "highs",
"options": {"compute_preset": "cpu-standard", "time_limit_seconds": 5, "tags": ["quickstart"]}
}
- objective
- 1750
- hold
- settled
- wall_seconds
- 0.4
- solver_used
- highs
- outcome
- solved
- termination_status
- OPTIMAL
- chairs
- 30
- tables
- 5
Optimisation is hard to buy
The maths has eighty years behind it. Using it in production is where teams stall, because the solver landscape is fragmented.
Each solver is different
Own API, model format and licensing. Expertise in one transfers poorly to the next.
API, format, licence
Constraints get reformulated
Native for one engine, rebuilt for another. Results come back in as many shapes as there are solvers.
n solvers, n formats
Not every constraint is supported
A requirement can land outside what your engine takes. You either move the whole model or approximate it away, and the model stops matching the real problem.
one constraint, a new engine
Engines need different hardware
Some run on a CPU, some want a GPU. Picking an engine now means provisioning the machine it runs on, before you know whether it wins.
CPU or GPU, per engine
Choosing is the expertise
Which engine suits your constraints is itself a research question. Answering it well needs a specialist in a field that is not yours.
the choice is the job
The best engine keeps moving
Solvers ship releases, and the one that won on your instances last year may not win now. Nobody on your team is paid to re-run that benchmark.
each release reshuffles it
Data models weld to vendors
Commit to a solver and your schema quietly commits too. Outgrowing it means unpicking the weld under pressure.
one envelope instead
Write the model. We run everything under it.
Nothing on that list is about your business. It is all machinery, and the machinery is ours.
- Write the model: the decisions, the constraints, the objective.
- Set a deadline and a cost cap for the run.
- Read the answer, in the same shape every time.
- Learning a new API, model format and licence for each engine.
- Reformulating the same constraints for the next engine.
- Dropping a requirement because the engine will not take it.
- Provisioning a GPU box for a run that lasts a minute.
- Deciding which engine suits the problem in front of you.
- Re-running the benchmarks every time a solver ships.
- Letting a vendor's schema into your database.
Add a constraint next quarter and your model changes. Nothing else does.
One envelope, versioned
Four parts. We own and validate the wrapper. The problem inside is yours.
{
"api_version": "1",
"problem": {
"variables": [
{"name": "chairs", "lower": 0},
{"name": "tables", "lower": 0}
],
"constraints": [
{"expr": "4*chairs + 8*tables <= 160",
"name": "machine_hours"},
{"expr": "2*chairs + 3*tables <= 75",
"name": "material"}
],
"objective": {
"sense": "max",
"expr": "45*chairs + 80*tables"
}
},
"solver": "highs",
"options": {
"compute_preset": "cpu-standard",
"time_limit_seconds": 5,
"tags": ["quickstart"]
}
}
- api_version
- The wire version. Always "1" today.
- problem
- Your model: variables, constraints, an objective. Opaque to us, validated by the solver.
- solver
- A concrete solver name, or a meta-solver name: a named set of member engines, any of which may take the job.
- options
- time_limit_seconds, compute_preset, webhook, idempotency_key, tags. All optional.
We treat your problem body as opaque. The manager validates the envelope and meters compute, but never reads your model.
Submit, track, fetch
Submit returns an id and a queued status at once. Register a signed webhook and the answer comes to you, or hold one request open on the wait call until the problem ends. Fetch the solution with one call.
- solved
- an optimal or within-tolerance solution
- no_solution
- proven infeasible or unbounded, and billed, because the proof is the product
- limit
- a budget stopped the solve; the incumbent is returned if one exists
- error
- the engine broke on this model; not retried, pick another solver or reformulate
Built for solvers that crash and networks that drop
A crashed or stalled solve is detected and re-queued, and picked up again. You are billed once, for the attempt that succeeded. Terminal webhooks retry with backoff, then dead-letter into a log you can inspect and replay.
One envelope, two attempts, one bill
- Envelope size
- up to 20 MB
- Time limit
- 300 s by default, 6 h at most
- Batch submit
- up to 100 envelopes in one call
- Webhook retries
- 1 min, 5 min, 25 min, 2 h, then dead-letter
- Signature
- X-Solve-Signature, HMAC SHA-256 over the raw body
- Billing after a crash
- once, successful attempt only
- Cancelled while queued
- free, hold released
- Rate limiting
- 429 with Retry-After
Every engine we run, and whether it answers right now
No engines are published on this site yet.
Open engines run on our side. Commercial engines run bring-your-own-licence. A meta-solver is a named set of member engines, not a black box, and the engine used and its price are reported on every result.
Metered like compute, quoted before it runs
cost = base_fee + ceil(seconds × effective_rate)
Every engine has a published base fee and a rate per second of the compute it reserves, and every compute preset multiplies that rate. The maximum cost follows from the engine, the preset and the runtime you set, and it is reserved from your balance before the solve starts. You pay the seconds you used. Cancel any time and pay for those seconds, never more. Free credits on signup, no card.
A REST API you can read in one sitting
Versioned endpoints, structured errors that name the field at fault, signed webhooks with a visible delivery log, and an event stream for when you cannot receive them. Every integration has the same three moves: submit, track, fetch.
Write the model in Python and read the solution back as objects. Submit, wait, webhook checks and idempotent retries are wrapped for you. The Studio runs it in the browser, with nothing to install.
Scoped keys, hashed secrets, guarded egress
Keys
Named keys work only on the optimisation API and can be revoked one by one, so you rotate one without touching the rest.
Secrets
Stored only as hashes. The raw secret is shown once and never again.
Webhook egress
Targets are checked against private and metadata ranges before we connect, so a hijacked URL cannot reach internal services.
Retention
Payloads are purged on a published schedule, 90 days by default. Metadata stays for your audit trail.
Questions engineers actually ask
Can I force a specific solver?
Yes. Name a concrete solver in the envelope and it is honoured exactly. A meta-solver is for when you would rather not choose.
Which problem classes are supported?
Anything the connected engines solve: LP, MIP, NLP, CP, scheduling and routing. The envelope is class-agnostic by design.
What happens if a solve crashes mid-run?
It is detected and re-queued automatically, and picked up again. You see it in the attempt history, and you are billed once, for the attempt that succeeded.
How long do you keep my problem data?
Payloads are purged on a published schedule, 90 days by default. Metadata stays for your audit trail. After the purge a fetch returns 410 purged.
Your first solve is five minutes away
Run a real model against a real solver, in the browser. No account, no credit card.