Lab instrument data, instantly accessible

Data Hub automatically captures and uploads lab instrument data, enabling scientists to focus on analyzing data rather than managing it.

Data Hub run detail with plate map visualization and comments
Data Hub home dashboard with instrument status and recent runs

Download instrument runs from your browser

Find a run by instrument, date, or who ran it. Open it to check the settings it ran with, read its plate maps and images right in the page, and download the files you need. Put your name on it so people know it was yours, and leave a note for whoever picks it up next.

  • Filter by instrument, measurement type, date, or who ran it
  • Read plate maps, kinetic traces, and images without downloading anything
  • Claim a run to put your name on it, and leave notes in its comment thread
  • Download one file, or the whole run as a ZIP
Web app guide

Automate your data processing workflows

Let your pipelines do the heavy lifting. They can check an instrument for its newest run, download the files, and pass them straight into the analysis you already run. Put it on a schedule and last night's plates are counted before you get in.

  • Authenticate with a token you create in the app, scoped and revocable
  • List instruments, runs, and files, and filter runs the way the app does
  • Pull instrument runs as ZIP archives
API reference
download_latest_run.py
import time, requests
BASE = "https://datahub.example.com/api/v1"
session = requests.Session()session.headers["Authorization"] = "Bearer dhub_your_token_here"
# Pick an active instrument and its latest run.instruments = session.get(f"{BASE}/instruments").json()iid = next(i["id"] for i in instruments if i["status"] == "active")
runs = session.get(f"{BASE}/instruments/{iid}/runs", params={"per_page": 1}).json()run_id = runs["data"][0]["run_id"]
# Download the run as a ZIP. On a cache miss the archive builds async, so poll until ready.url = f"{BASE}/instruments/{iid}/runs/{run_id}/download-archive"archive = session.get(url, headers={"Accept": "application/json"}).json()
while archive["status"] != "ready":    time.sleep(2)    archive = session.get(url, headers={"Accept": "application/json"}).json()
# download_url is a short-lived presigned S3 link and needs no auth.data = requests.get(archive["download_url"])
with open(f"{run_id}.zip", "wb") as f:    f.write(data.content)
print(f"Saved {run_id}.zip")

$ python download_latest_run.py

Saved 260710_OD595_kinetic_EEE.zip

$

Claude Desktop asking Data Hub about microscope runs over MCP

Let AI agents work with your data

Ask an agent about a run and it can find the one you mean, download its files, and start working on the data, without you leaving the conversation to go and fetch anything.

  • Connect Claude Code, Claude Desktop, or Cursor by pasting one URL
  • Ask which runs failed last week, then pull the files you need
  • Sign in from the client, so the agent acts with your own permissions
MCP setup

Engineers

Deploy Data Hub

Run the backend yourself: database, web app, and AWS infrastructure.

Operators and admins

Set up an instrument

Take a new instrument PC from a fresh install to uploading runs.

Everyone

Browse and analyze runs

Find runs, inspect processed results, claim work, download files, and leave lab notes.

Everyone

Instrument data preprocessing

What each supported instrument's processor extracts and shows on run detail.