Creating Experiments
Experiments are the top-level organizational unit in the MATIH experiment tracking system. Each experiment groups related training runs, typically corresponding to a specific ML problem or model iteration.
Creating via REST API
POST /api/v1/experiments
Content-Type: application/json
X-Tenant-ID: acme-corp
{
"name": "fraud-detection-v3",
"description": "Fraud detection model using transaction features",
"artifact_location": "s3://matih-artifacts/fraud-v3",
"tags": {
"team": "risk-analytics",
"domain": "fraud",
"priority": "high"
}
}Response
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "fraud-detection-v3",
"description": "Fraud detection model using transaction features",
"artifact_location": "s3://matih-artifacts/fraud-v3",
"lifecycle_stage": "active",
"created_at": "2026-02-12T10:30:00",
"last_updated": "2026-02-12T10:30:00",
"tags": {
"team": "risk-analytics",
"domain": "fraud",
"priority": "high"
}
}Creating via ExperimentTracker SDK
For programmatic usage within training scripts, use the ExperimentTracker class:
from src.tracking.experiment_tracker import ExperimentTracker, ExperimentConfig
tracker = ExperimentTracker(tracking_uri="http://mlflow:5000")
experiment_id = tracker.create_experiment(
ExperimentConfig(
name="fraud-detection-v3",
description="Fraud detection model using transaction features",
tags={"team": "risk-analytics", "domain": "fraud"},
artifact_location="s3://matih-artifacts/fraud-v3",
tenant_id="acme-corp",
)
)The ExperimentConfig dataclass automatically adds a matih.tenant_id tag when tenant_id is provided:
@dataclass
class ExperimentConfig:
name: str
description: str = ""
tags: dict[str, str] = field(default_factory=dict)
artifact_location: Optional[str] = None
tenant_id: Optional[str] = None
def __post_init__(self):
if self.tenant_id:
self.tags["matih.tenant_id"] = self.tenant_idNaming Conventions
Follow these naming conventions for experiments:
| Pattern | Example | Use Case |
|---|---|---|
{domain}-{task}-v{N} | fraud-detection-v3 | Versioned experiments per task |
{team}/{project} | risk-team/transaction-scoring | Team-scoped experiments |
{model_type}-{dataset} | xgboost-customer-churn | Model-dataset combinations |
Idempotent Creation
The get_or_create_experiment method ensures experiments are created only once:
experiment_id = tracker.get_or_create_experiment(
name="fraud-detection-v3",
tenant_id="acme-corp",
)
# Returns existing experiment ID if "acme-corp/fraud-detection-v3" already existsListing Experiments
GET /api/v1/experiments?search=fraud&lifecycle_stage=active&limit=10
X-Tenant-ID: acme-corpResponse:
{
"experiments": [
{
"id": "...",
"name": "fraud-detection-v3",
"description": "Fraud detection model using transaction features",
"lifecycle_stage": "active",
"tags": {"team": "risk-analytics"}
}
],
"total": 1
}Updating and Deleting
Experiments support partial updates and soft deletion:
# Update experiment name/description
PATCH /api/v1/experiments/{experiment_id}?name=fraud-detection-v4
# Soft-delete (archive)
DELETE /api/v1/experiments/{experiment_id}
# Restore archived experiment
POST /api/v1/experiments/{experiment_id}/restoreDeleted experiments transition to lifecycle_stage: "deleted" and can be restored at any time.
Source Files
| File | Path |
|---|---|
| Experiments API | data-plane/ml-service/src/api/experiments.py |
| ExperimentTracker | data-plane/ml-service/src/tracking/experiment_tracker.py |