Compile a liquid-handling plan (Flex robot, pipettes, deck labware, liquids, tra
Compile a liquid-handling plan (Flex robot, pipettes, deck labware, liquids, transfer/distribute/serial-dilute/mix/delay steps) into a self-contained Python protocol, run a static volume tracker and a real opentrons simulation, and return a pass/fail report with platemap, reagent-usage, and simulation-log artifacts. This proves the protocol runs, never that the experiment is scientifically valid.
Paid test badge: not yet. The checks above are free: we call the tool without paying and read the payment request it sends back. The Verified badge needs paid calls whose answers match the promised output, and nobody can buy a badge.
Endpoint
POST https://lab.api.williamrobinson.dev/v1/lab/compile
| Category | Code and developer |
|---|---|
| Provider host | lab.api.williamrobinson.dev |
| Networks | eip155:8453 |
| Payment schemes | exact |
| Self-reported calls, 30 days | 1 from 1 payers (the provider's figure, not ours) |
Our checks, last 30 days
We never call tools that send, buy, move money or file anything, not even without paying.
Example input (from the provider)
{
"body": {
"labware": [
{
"id": "plate",
"label": "PCR plate",
"slot": "A1",
"type": "opentrons_96_wellplate_200ul_pcr_full_skirt"
},
{
"id": "tips50",
"label": "50 uL tips",
"slot": "A2",
"type": "opentrons_flex_96_tiprack_50ul"
},
{
"id": "mmix_res",
"label": "Master mix reservoir",
"slot": "B1",
"type": "nest_12_reservoir_15ml"
},
{
"id": "tubes",
"label": "Sample tubes",
"slot": "B2",
"type": "opentrons_24_tuberack_nest_1.5ml_snapcap"
}
],
"liquids": [
{
"deadVolumeUl": 300,
"id": "mastermix",
"location": {
"labware": "mmix_res",
"volumeUl": 5000,
"wells": "A1"
},
"name": "PCR master mix"
},
{
"deadVolumeUl": 20,
"id": "samples",
"location": {
"labware": "tubes",
"volumeUl": 200,
"wells": "A1:D2"
},
"name": "Patient samples"
}
],
"name": "PCR setup with 8-sample column and column-12 dilution series",
"options": {
"defaultNewTip": "once",
"forbidCrossLiquidTipReuse": true,
"trashSlot": "A3"
},
"pipettes": [
{
"model": "flex_8channel_50",
"mount": "left"
},
{
"model": "flex_1channel_50",
"mount": "right"
}
],
"robot": "flex",
"steps": [
{
"dests": {
"labware": "plate",
"wells": "A1:H12"
},
"kind": "distribute",
"newTip": "once",
"source": {
"labware": "mmix_res",
"well": "A1"
},
"volumeUl": 20
},
{
"dest": {
"labware": "plate",
"well": "A1"
},
"kind": "transfer",
"newTip": "always",
"source": {
"labware": "tubes",
"well": "A1"
},
"volumeUl": 5
},
{
"dest": {
"labware": "plate",
"well": "B1"
},
"kind": "transfer",
"newTip": "always",
"source": {
"labware": "tubes",
"well": "A2"
},
"volumeUl": 5
},
{
"dest": {
"labware": "plate",
"well": "C1"
},
"kind": "transfer",
"newTip": "always",
"source": {
"labware": "tubes",
"well": "B1"
},
"volumeUl": 5
},
{
"dest": {
"labware": "plate",
"well": "D1"
},
"kind": "transfer",
"newTip": "always",
"source": {
"labware": "tubes",
"well": "B2"
},
"volumeUl": 5
},
{
"dest": {
"labware": "plate",
"well": "E1"
},
"kind": "transfer",
"newTip": "always",
"source": {
"labware": "tubes",
"well": "C1"
},
"volumeUl": 5
},
{
"dest": {
"labware": "plate",
"well": "F1"
},
"kind": "transfer",
"newTip": "always",
"source": {
"labware": "tubes",
"well": "C2"
},
"volumeUl": 5
},
{
"dest": {
"labware": "plate",
"well": "G1"
},
"kind": "transfer",
"newTip": "always",
"source": {
"labware": "tubes",
"well": "D1"
},
"volumeUl": 5
},
{
"dest": {
"labware": "plate",
"well": "H1"
},
"kind": "transfer",
"newTip": "always",
"source": {
"labware": "tubes",
"well": "D2"
},
"volumeUl": 5
},
{
"kind": "serial_dilute",
"labware": "plate",
"mixRepetitions": 3,
"mixUl": 15,
"newTip": "always",
"transferUl": 10,
"wells": "A12:H12"
},
{
"kind": "delay",
"message": "Incubate before sealing",
"seconds": 60
}
]
},
"bodyType": "json",
"method": "POST",
"type": "http"
}
Promised output schema (from the provider)
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"properties": {
"input": {
"additionalProperties": false,
"properties": {
"body": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"additionalProperties": false,
"properties": {
"labware": {
"items": {
"additionalProperties": false,
"properties": {
"id": {
"description": "Caller-assigned identifier, unique within its array.",
"pattern": "^[A-Za-z0-9_-]{1,32}$",
"type": "string"
},
"label": {
"maxLength": 128,
"minLength": 1,
"type": "string"
},
"slot": {
"enum": [
"A1",
"A2",
"A3",
"B1",
"B2",
"B3",
"C1",
"C2",
"C3",
"D1",
"D2",
"D3"
],
"type": "string"
},
"type": {
"enum": [
"opentrons_96_wellplate_200ul_pcr_full_skirt",
"corning_96_wellplate_360ul_flat",
"nest_96_wellplate_2ml_deep",
"corning_384_wellplate_112ul_flat",
"nest_12_reservoir_15ml",
"nest_1_reservoir_195ml",
"opentrons_24_tuberack_nest_1.5ml_snapcap",
"opentrons_flex_96_tiprack_50ul",
"opentrons_flex_96_tiprack_200ul",
"opentrons_flex_96_tiprack_1000ul"
],
"type": "string"
}
},
"required": [
"id",
"type",
"slot"
],
"type": "object"
},
"maxItems": 12,
"minItems": 1,
"type": "array"
},
"liquids": {
"items": {
"additionalProperties": false,
"properties": {
"deadVolumeUl": {
"maximum": 50000,
"minimum": 0,
"type": "number"
},
"id": {
"description": "Caller-assigned identifier, unique within its array.",
"pattern": "^[A-Za-z0-9_-]{1,32}$",
"type": "string"
},
"location": {
"additionalProperties": false,
"properties": {
"labware": {
"description": "Caller-assigned identifier, unique within its array.",
"pattern": "^[A-Za-z0-9_-]{1,32}$",
"type": "string"
},
"volumeUl": {
"exclusiveMinimum": 0,
"maximum": 300000,
"type": "number"
},
"wells": {
"description": "A well or well range: \"A1\", \"A1:H1\" (column), \"A1:A12\" (row), or \"A1:H12\" (rectangle), expanded row-major.",
"pattern": "^[A-P](?:[1-9]|1[0-9]|2[0-4])(?::[A-P](?:[1-9]|1[0-9]|2[0-4]))?$",
"type": "string"
}
},
"required": [
"labware",
"wells",
"volumeUl"
],
"type": "object"
},
"name": {
"maxLength": 200,
"minLength": 1,
"type": "string"
}
},
"required": [
"id",
"name",
"location"
],
"type": "object"
},
"maxItems": 32,
"type": "array"
},
"name": {
"maxLength": 200,
"minLength": 1,
"type": "string"
},
"options": {
"additionalProperties": false,
"properties": {
"defaultNewTip": {
"enum": [
"always",
"once",
"never"
],
"type": "string"
},
"forbidCrossLiquidTipReuse": {
"type": "boolean"
},
"trashSlot": {
"description": "Flex default is A3. Column 1 or 3 only (column 2 and the column-4 staging area are not valid trash locations).",
"enum": [
"A1",
"B1",
"C1",
"D1",
"A3",
"B3",
"C3",
"D3"
],
"type": "string"
}
},
"required": [
"trashSlot",
"defaultNewTip",
"forbidCrossLiquidTipReuse"
],
"type": "object"
},
"pipettes": {
"items": {
"additionalProperties": false,
"properties": {
"model": {
"enum": [
"flex_1channel_50",
"flex_1channel_1000",
"flex_8channel_50",