API Reference
Cloud Labs

Cloud Labs API

Litmus integrates with automated cloud laboratories to execute experiments without manual intervention. Currently supported providers are Enko Cloud Lab (ECL) and Strateos.

List Providers

GET /cloud-labs/providers

List available cloud lab providers and their capabilities.

Response

{
  "providers": [
    {
      "id": "ecl",
      "name": "Enko Cloud Lab",
      "protocol_format": "sll",
      "supported_experiment_types": [
        "CELL_VIABILITY_IC50",
        "MIC_MBC_ASSAY",
        "QPCR_EXPRESSION"
      ],
      "status": "available"
    },
    {
      "id": "strateos",
      "name": "Strateos",
      "protocol_format": "autoprotocol",
      "supported_experiment_types": [
        "CELL_VIABILITY_IC50",
        "MIC_MBC_ASSAY"
      ],
      "status": "available"
    }
  ]
}

Get Provider Details

GET /cloud-labs/providers/{provider_id}

Get detailed information about a specific cloud lab provider.

Response

{
  "id": "ecl",
  "name": "Enko Cloud Lab",
  "description": "Automated cloud laboratory using Symbolic Lab Language",
  "protocol_format": "sll",
  "supported_experiment_types": [
    "CELL_VIABILITY_IC50",
    "MIC_MBC_ASSAY",
    "QPCR_EXPRESSION"
  ],
  "capabilities": {
    "cell_lines": ["HeLa", "HEK293", "A549"],
    "plate_formats": ["96-well", "384-well"],
    "detection_methods": ["absorbance", "fluorescence", "luminescence"]
  },
  "pricing": {
    "base_cost_usd": 150,
    "per_sample_usd": 5
  },
  "turnaround_days": {
    "min": 3,
    "max": 7
  },
  "status": "available"
}

Get Supported Experiment Types

GET /cloud-labs/supported-types

Get experiment types supported by cloud lab translation.

Response

{
  "supported_types": [
    {
      "experiment_type": "CELL_VIABILITY_IC50",
      "providers": ["ecl", "strateos"],
      "description": "Cell viability and IC50 determination"
    },
    {
      "experiment_type": "MIC_MBC_ASSAY",
      "providers": ["ecl", "strateos"],
      "description": "Minimum inhibitory/bactericidal concentration"
    },
    {
      "experiment_type": "QPCR_EXPRESSION",
      "providers": ["ecl"],
      "description": "Gene expression analysis via qPCR"
    }
  ]
}

Interpret Experiment

POST /cloud-labs/interpret

Use LLM to interpret an experiment intake and extract structured parameters for cloud lab translation.

Request Body

{
  "intake": {
    "experiment_type": "MIC_MBC_ASSAY",
    "hypothesis": {
      "statement": "Compound X inhibits E. coli growth"
    },
    "mic_mbc_assay": {
      "target_organisms": ["Escherichia coli"],
      "test_compounds": [
        {"name": "Compound X", "concentrations_ug_ml": [0.5, 1, 2, 4, 8, 16, 32]}
      ]
    }
  },
  "provider_id": "ecl"
}

Response

{
  "interpretation": {
    "experiment_type": "MIC_MBC_ASSAY",
    "parameters": {
      "organisms": [
        {"name": "Escherichia coli", "strain": "ATCC 25922"}
      ],
      "compounds": [
        {
          "name": "Compound X",
          "concentrations": [0.5, 1, 2, 4, 8, 16, 32],
          "unit": "ug/ml"
        }
      ],
      "replicates": 3,
      "incubation_hours": 18,
      "detection_method": "absorbance_600nm"
    },
    "confidence": 0.95,
    "notes": "Standard CLSI broth microdilution protocol"
  }
}

Translate to Protocol

POST /cloud-labs/translate

Translate an experiment intake to a cloud lab protocol format.

Request Body

{
  "intake": {
    "experiment_type": "MIC_MBC_ASSAY",
    "mic_mbc_assay": {
      "target_organisms": ["Escherichia coli"],
      "test_compounds": [
        {"name": "Compound X", "concentrations_ug_ml": [0.5, 1, 2, 4, 8, 16, 32]}
      ]
    }
  },
  "provider_id": "ecl"
}

Response (ECL - SLL Format)

{
  "provider_id": "ecl",
  "protocol_format": "sll",
  "protocol": {
    "name": "MIC Assay - Compound X",
    "steps": [
      {
        "operation": "dispense",
        "source": "media_reservoir",
        "destination": "assay_plate",
        "volume": "100uL"
      },
      {
        "operation": "serial_dilution",
        "compound": "Compound X",
        "start_concentration": "32ug/mL",
        "dilution_factor": 2,
        "steps": 7
      }
    ]
  },
  "estimated_cost_usd": 250,
  "estimated_turnaround_days": 5
}

Response (Strateos - Autoprotocol Format)

{
  "provider_id": "strateos",
  "protocol_format": "autoprotocol",
  "protocol": {
    "refs": {
      "assay_plate": {
        "new": "96-pcr",
        "store": {"where": "cold_4"}
      }
    },
    "instructions": [
      {
        "op": "dispense",
        "object": "assay_plate",
        "reagent": "lb_broth",
        "columns": [{"column": 0, "volume": "100:microliter"}]
      }
    ]
  },
  "estimated_cost_usd": 275,
  "estimated_turnaround_days": 4
}

Validate for Cloud Lab

POST /cloud-labs/validate

Validate that an intake can be translated for a specific cloud lab provider.

Request Body

{
  "intake": {
    "experiment_type": "MIC_MBC_ASSAY",
    "mic_mbc_assay": {...}
  },
  "provider_id": "ecl"
}

Response

{
  "valid": true,
  "provider_id": "ecl",
  "warnings": [
    "Compound concentrations will be rounded to available stock dilutions"
  ],
  "estimated_cost_usd": 250,
  "estimated_turnaround_days": 5
}

Response (Invalid)

{
  "valid": false,
  "provider_id": "ecl",
  "errors": [
    {
      "field": "mic_mbc_assay.target_organisms",
      "message": "Organism 'Custom strain XYZ' not available at this provider"
    }
  ]
}

Translate Experiment

POST /cloud-labs/experiments/{experiment_id}/translate

Translate an existing experiment to a cloud lab protocol.

Request Body

{
  "provider_id": "ecl"
}

Response

Same as POST /cloud-labs/translate, plus creates a CloudLabSubmission record.

List Submissions

GET /cloud-labs/submissions

List cloud lab submissions for your experiments.

Query Parameters

ParameterTypeDescription
experiment_idstringFilter by experiment
provider_idstringFilter by provider
statusstringFilter by status
limitintegerResults per page
offsetintegerPagination offset

Response

{
  "submissions": [
    {
      "id": "sub_abc123",
      "experiment_id": "exp_xyz789",
      "provider_id": "ecl",
      "provider_submission_id": "ecl_run_456",
      "status": "running",
      "created_at": "2026-01-27T10:00:00Z",
      "started_at": "2026-01-27T10:05:00Z"
    }
  ],
  "total": 5,
  "limit": 20,
  "offset": 0
}

Get Submission Details

GET /cloud-labs/submissions/{submission_id}

Get detailed status and results of a cloud lab submission.

Response

{
  "id": "sub_abc123",
  "experiment_id": "exp_xyz789",
  "provider_id": "ecl",
  "provider_submission_id": "ecl_run_456",
  "protocol_format": "sll",
  "translated_protocol": {...},
  "status": "completed",
  "results": {
    "mic_values": {
      "Compound X": {
        "Escherichia coli": "4 ug/mL"
      }
    },
    "raw_data_url": "https://..."
  },
  "created_at": "2026-01-27T10:00:00Z",
  "completed_at": "2026-01-27T12:00:00Z"
}

Submission Status

StatusDescription
pendingSubmission created, not yet sent
submittedSent to cloud lab
queuedQueued at cloud lab
runningExperiment in progress
completedResults available
failedExecution failed
cancelledSubmission cancelled

Protocol Formats

SLL (Symbolic Lab Language)

Used by Enko Cloud Lab. A declarative format describing lab operations as steps:

{
  "steps": [
    {"operation": "dispense", "source": "...", "destination": "...", "volume": "100uL"},
    {"operation": "incubate", "temperature": "37C", "duration": "18h"}
  ]
}

Autoprotocol

Used by Strateos. A JSON-based protocol format with refs and instructions:

{
  "refs": {"plate": {"new": "96-pcr"}},
  "instructions": [
    {"op": "dispense", "object": "plate", "reagent": "media", "volume": "100:microliter"}
  ]
}

Workflow Example

import requests
 
API_URL = "https://api.litmus.science"
headers = {"Authorization": "Bearer YOUR_TOKEN"}
 
# 1. Check provider capabilities
providers = requests.get(f"{API_URL}/cloud-labs/providers", headers=headers).json()
 
# 2. Validate intake for provider
validation = requests.post(
    f"{API_URL}/cloud-labs/validate",
    json={"intake": intake, "provider_id": "ecl"},
    headers=headers
).json()
 
if not validation["valid"]:
    print("Validation errors:", validation["errors"])
    exit(1)
 
# 3. Translate to protocol
translation = requests.post(
    f"{API_URL}/cloud-labs/translate",
    json={"intake": intake, "provider_id": "ecl"},
    headers=headers
).json()
 
print(f"Estimated cost: ${translation['estimated_cost_usd']}")
print(f"Turnaround: {translation['estimated_turnaround_days']} days")
 
# 4. Submit experiment and translate
experiment = requests.post(
    f"{API_URL}/experiments",
    json=intake,
    headers=headers
).json()
 
submission = requests.post(
    f"{API_URL}/cloud-labs/experiments/{experiment['experiment_id']}/translate",
    json={"provider_id": "ecl"},
    headers=headers
).json()