SwarmLabs v3 API reference

Every schema below is documented from the live contract, not from guesses. The v3 surface is a small, public, computation-first API: scenario & strain catalogs plus four math-backed operations (GP surrogate prediction, growth-curve auto-fit, the VirtualLab Guard uncertainty gate, and UGC strain submission). See the verification ledger for the evidence behind every number, and why this API exists.

Base & auth GET /health GET /scenarios GET /strains GET /strain/{id} GET /media GET /gate GET /gate/{key} POST /predict POST /fit POST /guard POST /sample POST /submit-strain Live try-it

Base URL, auth, and CORS open

All routes are mounted under a single base path. The entire /v3/* surface is intentionally public — no API key is required — so that agents and static front-ends can call it directly.

ItemValue
base_urlstringhttps://swarmlabs.tools/api/v3
authnoneEvery /v3/* route bypasses the key check. Send requests without an Authorization header.
corsenabledResponses carry CORS headers; browser fetch() from any origin works.
content-typeapplication/jsonPOST bodies must be JSON. GET endpoints ignore the body.
Versioning. This is the 3.0.0 surface (/health reports api_version). Older /v1/* and /v2/* routes exist for legacy experiments but are not part of this reference and require an API key.

GET /health get

Liveness and catalog sizes. No auth. Useful as a one-line uptime probe.

curl https://swarmlabs.tools/api/v3/health
Response fieldTypeMeaning
okbooleanAlways true when the handler runs.
api_versionstringSemantic version, e.g. "3.0.0".
scenariosnumberCount of registered scenarios (currently 63).
strainsnumberCount of registered strains (currently 69).
medianumberCount of media recipes (currently 20).
always_onbooleantrue — the function is always warm.
gpubooleanfalse — inference is pure JS, CPU only.
// example response
{"ok":true,"api_version":"3.0.0","scenarios":63,"strains":69,"media":20,"always_on":true,"gpu":false}

GET /scenarios get

Full catalog of virtual-experiment scenarios. Each entry carries its published analytic formula, parameter bounds, and literature references — so a caller can both run the surrogate and check it against ground truth.

Field-value language (known gap). The domain value and scenario published formula text currently return Chinese labels (for example a Chinese phrase meaning "Biology / population dynamics"), and /strains name returns Chinese common names (for example the Chinese name for E. coli), even though this page and the rest of the site are English. The field keys are stable and English. An English-label pass over the scenario/strain catalogs is pending; the frontend pages are already fully English.
curl https://swarmlabs.tools/api/v3/scenarios
Response fieldTypeMeaning
countnumberNumber of scenarios in scenarios.
scenarios[]object[]Array of scenario records.
.keystringStable identifier, e.g. "bio_logistic", "microbio_monod".
.domainstringHuman-readable domain label.
.dimnumberInput dimensionality (1, 2, or 3).
.boundsnumber[][]Per-dimension [lo, hi] ranges for sampling.
.publishedstringThe analytic formula used as ground truth.
.refsstring[]Literature references behind the model.
// example scenario record
{"key":"bio_logistic","domain":"population dynamics","dim":1,
 "bounds":[[0,10]],"published":"Logistic growth L/(1+exp(-k(t-t0)))","refs":["Verhulst 1838"]}

GET /strains get

Strain registry, with optional filtering by taxonomy or substrate. Query parameters are case-insensitive substring matches.

# all strains
curl https://swarmlabs.tools/api/v3/strains
# only Escherichia, by genus query
curl "https://swarmlabs.tools/api/v3/strains?genus=Escherichia"
Query paramTypeEffect
genusstring?Substring match on taxonomy.genus.
phylumstring?Substring match on taxonomy.phylum.
substratestring?Substring match on growth_params.substrate.
Response fieldTypeMeaning
countnumberNumber of strains after filtering.
strains[]object[]Lightweight strain records.
.idstringStable strain id, e.g. "ecoli_K12_MG1655".
.namestringCommon name.
.genus / .speciesstringTaxonomy.
.mu_maxnumber?Max specific growth rate.
.Ksnumber?Monod half-saturation constant.
.substratestringPreferred carbon source.
// example record
{"id":"ecoli_K12_MG1655","name":"E. coli K-12 MG1655","genus":"Escherichia",
 "species":"coli","mu_max":0.81,"Ks":0.004,"substrate":"glucose"}

GET /strain/{id} get

Full record for one strain: taxonomy, genome, growth parameters, preferred media, growth conditions, and references. The {id} segment must be URL-encoded if it contains spaces.

curl https://swarmlabs.tools/api/v3/strain/ecoli_K12_MG1655
Response fieldTypeMeaning
strain_idstringSame as the path id.
taxonomyobjectdomain, phylum, class, genus, species, strain_name, common_name.
genomeobjectGenome metadata (size, gc_content, etc. when available).
growth_paramsobjectmu_max, Ks, substrate, temperature optimum, pH optimum.
media_preferenceobject[]Recommended media ids with notes.
conditionsobjectOptimal growth conditions.
refsstring[]Source literature.
created_atstringISO timestamp of registration.
Encoding note. taxonomy.genus is an exact match in some skills; when calling /strains?genus=... the genus value must be URL-encoded (e.g. E.%20coli for "E. coli").

GET /media get

Media recipe catalog used by fermentation scenarios and strain selection.

curl https://swarmlabs.tools/api/v3/media
Response fieldTypeMeaning
countnumberNumber of media.
media[]object[]Media records.
.idstringStable id, e.g. "LB".
.namestringRecipe name.
.typestring"complex" or "minimal".
.phnumber?Typical pH.
{"id":"LB","name":"Luria-Bertani Broth","type":"complex","ph":7}

GET /gate get

The verification gate ledger. One machine-readable trust decision per published scenario — PROCEED, PROCEED_WITH_HUMAN_CHECK, or BLOCK_AUTONOMOUS_ACTION — plus the uncertainty budget behind it. Generated offline by scripts/build_gate_ledger.py and served as a static asset, so an agent can ask "can this scenario be trusted right now?" without running Python. A BLOCK means: do not act autonomously on this scenario until a human or more data intervenes.

curl https://swarmlabs.tools/api/v3/gate
Response fieldTypeMeaning
totalnumberPublished scenarios (currently 62).
countsobject{PASS, MARGINAL, REFUTED, ERROR} verdict counts.
n_blockednumberScenarios whose gate is BLOCK_AUTONOMOUS_ACTION.
blockedstring[]Scenario keys that are currently blocked.
policyobjectThe thresholds and the verdict→gate map (single source of truth).
scenariosobjectMap key → {gate, verdict, rationale, uncertainty, report}.

GET /gate/{key} get

The same decision for a single scenario, with its first-class uncertainty budget: noise floor, calibration scale κ, single-sided coverage, calibration error and R². This is the quantitative honesty contract an agent should read before acting on a prediction.

curl https://swarmlabs.tools/api/v3/gate/surrogate_branin
// example response (abridged)
{"scenario_key":"surrogate_branin","gate":"PROCEED","verdict":"PASS",
 "uncertainty":{"noise_floor":0.03,"nominal_coverage":0.95,"coverage":0.95,
   "calibration_scale_kappa":1.0,"r2":0.99},"report":{...}}
Boundary, stated honestly. This endpoint answers the static question "is this scenario trustworthy?". Verifying a model's own arbitrary predictions against the noise-free ground truth requires the engine and is served by the MCP server (mcp/swarmlabs_vv_server.py, tool verify_prediction) — it is not faked here.

POST /predict post

Gaussian-process surrogate prediction. Supply a small training set and one or more query points; receive a posterior mean, standard deviation (uncertainty), and the normalized distance of each query from the training cloud. This is the math behind the verification ledger.

curl -X POST https://swarmlabs.tools/api/v3/predict \
  -H 'content-type: application/json' \
  -d '{"train_x":[[0],[2],[4],[6]],"train_y":[0.1,0.35,0.6,0.78],
       "query_x":[[1],[3],[5],[7],[9]],"noise_rel":0.03}'
Request fieldTypeReq?Meaning
train_xnumber[][]requiredRows of training inputs, one row per point, length = dim.
train_ynumber[]requiredTraining outputs, one per row of train_x.
query_xnumber[][]requiredRows of points to predict.
noise_relnumber?optionalRelative noise floor (default 0.03). Lower = more confident.
Response fieldTypeMeaning
meannumber[]Posterior mean, aligned with query_x.
stdnumber[]Posterior standard deviation (the uncertainty band).
distnumber[]Max normalized distance from each query to the training cloud. > 2.0 flags out-of-distribution.
No scenario needed. Unlike /sample, /predict is scenario-agnostic — it fits a GP purely from the rows you send. That is what makes it safe to call on real experimental data.

POST /fit post

Auto-fit kinetic growth models to time-series OD600 data by grid search, returning R² per model and the best fit. Minimum four [time, OD600] points.

curl -X POST https://swarmlabs.tools/api/v3/fit \
  -H 'content-type: application/json' \
  -d '{"data":[[1,0.2],[2,0.35],[4,0.5],[8,0.62],[12,0.68]],
       "models":["logistic","monod"]}'
Request fieldTypeReq?Meaning
datanumber[][]requiredRows of [time, OD600]; need ≥ 4 points (HTTP 400 otherwise).
modelsstring[]?optionalSubset of ["logistic","monod"]; default both.
Response fieldTypeMeaning
n_datanumberPoints received.
x_range / y_rangenumber[][min,max] of time and OD.
results[]object[]Per-model {model, r2, params}, sorted by R² descending.
best_modelstringHighest-R² model name.
notestringInterpretation guide (R²>0.95 excellent; >0.85 usable; <0.85 add data).
{"n_data":5,"x_range":[1,12],"y_range":[0.2,0.68],
 "results":[{"model":"logistic","r2":0.983,"params":{"k":0.65,"L":0.646,"x0":2}}],
 "best_model":"logistic","note":"R2>0.95 excellent; R2>0.85 usable; R2<0.85 add more data"}

POST /guard post

The VirtualLab Guard — an uncertainty gate that turns a GP fit into a per-point verdict. Each query is labeled pass (inside the trusted region), controlled (high variance but not far away), or reject (out-of-distribution, distance > 2.0). Returns the trusted ratio across all queries.

curl -X POST https://swarmlabs.tools/api/v3/guard \
  -H 'content-type: application/json' \
  -d '{"scenario":"micro_ecoli_glucose",
       "train_x":[[1],[2],[4],[8]],"train_y":[0.2,0.35,0.5,0.62],
       "query_x":[[3],[6],[30]],"noise_rel":0.03}'
Request fieldTypeReq?Meaning
train_x / train_ynumber[][] / number[]requiredSame as /predict.
query_xnumber[][]requiredPoints to gate.
scenariostring?optionalEchoed back in the response; no behavioral effect.
noise_relnumber?optionalDefault 0.03.
Response fieldTypeMeaning
scenariostringEcho of the request scenario (or "unknown").
nnumberNumber of queries.
countsobject{pass, controlled, reject} tally.
trusted_rationumberpass / n — the fraction of queries inside the trusted region.
mean / stdnumber[]GP posterior mean and standard deviation.
statusstring[]Per-query verdict, aligned with query_x.
Verdict rule. reject if normalized distance > 2.0; else controlled if std > 3 * stdev(train_y); else pass. The ledger's live guard panel calls exactly this route.

POST /sample post

Generate synthetic data points from a scenario's published ground-truth formula, with optional relative noise. Handy for bootstrapping a surrogate when you have no real measurements yet.

curl -X POST https://swarmlabs.tools/api/v3/sample \
  -H 'content-type: application/json' \
  -d '{"scenario":"micro_ecoli_glucose","n":3,"seed":1,"noise_rel":0.05}'
Request fieldTypeReq?Meaning
scenariostringrequiredA valid scenario key from /scenarios.
nnumber?optionalPoint count, clamped to 1–200 (default 12).
seednumber?optionalDeterministic RNG seed (default 1).
noise_relnumber?optionalRelative noise (default scenario noise or 0.05).
Response fieldTypeMeaning
scenariostringEcho of the request scenario.
nnumberPoints generated.
has_evaluatorbooleanWhether a ground-truth formula exists for the scenario.
points[]object[]{x:number[], y:number} samples.
// example response (scenario has a ground-truth evaluator)
{"scenario":"micro_ecoli_glucose","n":3,"has_evaluator":true,
 "points":[{"x":[2.365],"y":0.798},{"x":[5.043],"y":0.826},{"x":[0.506],"y":0.793}]}
Error shape. If the scenario has no evaluator, the route returns {"error":"no ground-truth evaluator for scenario: X (supply train_x/train_y to /predict)"} with HTTP 501. Use /predict instead when you bring your own data.

POST /submit-strain post

User-generated strain submission. Records are stored for review (status: "pending_review") and are not immediately merged into the public registry.

curl -X POST https://swarmlabs.tools/api/v3/submit-strain \
  -H 'content-type: application/json' \
  -d '{"strain_id":"my_new_strain","common_name":"My strain",
       "genus":"Myco","species":"bacter","mu_max":0.9,"Ks":0.01,
       "substrate":"glucose","user_id":"anonymous"}'
Request fieldTypeReq?Meaning
strain_idstringrequiredUnique id; duplicates return HTTP 409.
common_namestringrequiredDisplay name.
genus / speciesstringrequiredTaxonomy.
phylum / domainstring?optionalTaxonomy; domain defaults to "Bacteria".
mu_max / Ksnumber?optionalKinetic params.
substratestring?optionalPreferred carbon source.
genome_size / description? optionalExtra metadata.
user_idstring?optionalSubmitter tag (defaults "anonymous").
OutcomeHTTPBody
Accepted200Stored with status:"pending_review", submitted_at timestamp.
Missing fields400{"error":"Missing: strain_id, common_name, genus, species"}
Duplicate409{"status":"duplicate","message":"Strain X already submitted"}

Live try-it browser

Calls the real API from your browser. Edit the JSON, hit run, and read the raw response. This is the same route the verification ledger uses — try a query far outside the training range (e.g. 30) to see a reject.

// response appears here
See the verification ledger Why this API exists

SwarmLabs v3 API · public, computation-first · home