Experiments
Create, run, monitor, and manage GPU-powered experiments with automatic logging, QC gates, and status lifecycle.
Experiments API
Experiments are the core research unit in Hubify. Each experiment runs on GPU compute (or CPU), streams logs in real time, passes through QC gates, and stores results back to the lab.
Experiment Status Lifecycle
queued → running → pass / fail / blocked
| Status | Description |
|---|---|
queued | Waiting for a compute pod or manual trigger |
running | Actively executing on a pod |
pass | Completed successfully and passed QC |
fail | Completed with errors or failed QC |
blocked | Waiting on a dependency or manual unblock |
Create an Experiment
Convex ID of the lab this experiment belongs to.
Human-readable experiment title (e.g., "MCMC Chain — Planck 2018 + BAO").
Convex ID of the parent project, if applicable.
Custom identifier (e.g., "EXP-054"). Auto-generated if omitted.
Compute target: H200, H100, A100, or CPU.
Experiment configuration as a JSON object. Stored as a string internally.
GPU type override.
Batch size for data loading.
Number of training epochs.
Script path to execute on the pod.
Environment variables to set.
Experiment template name (e.g., mcmc, anomaly-sweep, fisher-forecast).
Queue priority: critical, high, normal, low.
Estimated runtime in seconds. Used for scheduling and cost projection.
curl -X POST https://api.hubify.com/v1/experiments \
-H "Authorization: Bearer $HUBIFY_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"labId": "j57a8k9m2n3p4q5r",
"title": "MCMC Chain — Planck 2018 + BAO",
"experimentId": "EXP-054",
"computeMode": "H200",
"config": {
"script": "run_cobaya.py",
"batch_size": 1,
"env": {"COBAYA_PACKAGES": "/workspace/packages"}
},
"priority": "high",
"estimatedSeconds": 7200
}'
const experiment = await hubify.experiments.create({
labId: "j57a8k9m2n3p4q5r",
title: "MCMC Chain — Planck 2018 + BAO",
experimentId: "EXP-054",
computeMode: "H200",
config: {
script: "run_cobaya.py",
batch_size: 1,
env: { COBAYA_PACKAGES: "/workspace/packages" },
},
priority: "high",
estimatedSeconds: 7200,
});
Convex document ID.
Parent lab ID.
Parent project ID.
Display identifier (e.g., "EXP-054").
Experiment title.
Current status.
Summary of results after completion.
GPU type or CPU.
JSON-encoded configuration.
Queue priority.
Position in the queue (when queued).
Estimated runtime.
Actual runtime (after completion).
Creation timestamp (ms).
Completion timestamp (ms).
List Experiments
Lab ID to list experiments for.
Filter by status: queued, running, pass, fail, blocked.
Filter by parent project.
Results per page.
Pagination cursor.
curl "https://api.hubify.com/v1/experiments?labId=j57a8k9m2n3p4q5r&status=running" \
-H "Authorization: Bearer $HUBIFY_TOKEN"
const experiments = await hubify.experiments.list({
labId: "j57a8k9m2n3p4q5r",
status: "running",
});
Get an Experiment
curl https://api.hubify.com/v1/experiments/EXP-054 \
-H "Authorization: Bearer $HUBIFY_TOKEN"
const experiment = await hubify.experiments.get({ experimentId: "EXP-054" });
Update an Experiment
Update metadata or status of an experiment. Use this to manually transition status (e.g., unblock a blocked experiment).
Updated title. New status. Valid transitions depend on current status. Result summary (typically set on completion). Updated priority.
curl -X PATCH https://api.hubify.com/v1/experiments/EXP-054 \
-H "Authorization: Bearer $HUBIFY_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"status": "queued",
"priority": "critical"
}'
await hubify.experiments.update({
experimentId: "EXP-054",
status: "queued",
priority: "critical",
});
Delete an Experiment
Delete an experiment and its associated logs. Does not delete figures generated by the experiment.
curl -X DELETE https://api.hubify.com/v1/experiments/EXP-054 \
-H "Authorization: Bearer $HUBIFY_TOKEN"
await hubify.experiments.delete({ experimentId: "EXP-054" });
Experiment Logs
Stream or retrieve logs for a running or completed experiment.
List Logs
Experiment Convex ID.
Filter by log level: info, warn, error, debug.
Number of log entries to return.
curl "https://api.hubify.com/v1/experiments/EXP-054/logs?level=error&limit=50" \
-H "Authorization: Bearer $HUBIFY_TOKEN"
const logs = await hubify.experiments.getLogs({
experimentId: "EXP-054",
level: "error",
limit: 50,
});
Subscribe to Logs (Real-Time)
// Real-time log subscription via Convex
client.onUpdate(
api.experimentLogs.list,
{ experimentId: "j57a8k9m2n3p4q5r" },
(logs) => {
logs.forEach((log) => console.log(`[${log.level}] ${log.message}`));
}
);
Experiment Metrics
After an experiment completes, metrics are available in the result and associated log entries.
curl https://api.hubify.com/v1/experiments/EXP-054/metrics \
-H "Authorization: Bearer $HUBIFY_TOKEN"
const metrics = await hubify.experiments.getMetrics({
experimentId: "EXP-054",
});
// { runtime: 3847, gpuUtilization: 0.94, peakVram: 78.2, costUsd: 4.27 }
Total runtime in seconds.
Average GPU utilization (0-1).
Peak VRAM usage in GB.
Total compute cost in USD.
Total log entries.
Error-level log entries.