AutoML
Create, manage, and monitor automated machine learning jobs. AutoML automatically selects the best model architecture, hyperparameters, and feature engineering for your dataset and prediction task.
All endpoints require authentication via X-API-Key header and the appropriate scope.
AutoMLJob Object
{
"_id": "Xk3pQ9rT2mB7nW4sA",
"jobId": "f22a9764e2ed836b9799a50b",
"name": "Churn Prediction Model",
"problemType": "tabular",
"predictorType": "auto",
"status": "training",
"progress": 45,
"owner": "user_456",
"organizationId": "org_xyz",
"trainingConfig": { "preset": "medium_quality", "timeLimit": 600, "metric": "accuracy" },
"hardware": { "cpuCount": 4, "memoryGb": 16, "gpuCount": 0, "diskGb": 20 },
"environmentId": "custom",
"datasetInfo": {
"name": "Customer Data Q4 2024",
"size": 45000,
"rows": 0,
"columns": 0,
"targetColumn": "churned",
"featureColumns": ["usage_days", "monthly_spend", "support_tickets", "plan_type"],
"volumeId": "vol_customers_001",
"path": "data/customers.csv"
},
"outputVolumeId": "vol_models_001",
"cost": { "estimatedTotal": 10.5, "currentCost": 0 },
"metrics": { "trainingTimeHours": 0 },
"createdAt": "2025-02-01T09:55:00Z",
"updatedAt": "2025-02-01T12:30:00Z"
}
jobId is the job's ID everywhere in the API; :id in a path also accepts _id. status is one of pending, preparing, running, training, evaluating, stopping, completed, failed, cancelled, with status_message describing progress. A failed job carries error (and failure_reason). A completed job records its scores in metrics and its trained models in models_info (best_model, leaderboard and, for tabular jobs, the trained predictor's details). Its scores (metrics.val_score, metrics.test_score, the leaderboard's) are AutoGluon's in models_info.eval_metric, where higher is always better: an error metric (RMSE, MAE, MASE, log loss and the like) is reported negative, and its value is the score with the sign flipped (a val_score of -19990.88 in root_mean_squared_error is an RMSE of 19,990.88). Each model's validation score is as it serves: a binary model calibrated to a decision threshold is scored with it, as its test score and results are. metrics.feature_importance holds each feature's permutation importance as a share of the total, computed on the rows metrics.feature_importance_rows names ({"data": "validation" | "test", "rows": n}), which the model was not trained on. datasetInfo holds volumeId and path when the job trains on a volume, or s3_path when it trains on an uploaded file. organizationId is set when the owner belongs to an organization.
GET /api/v1/mlops/automl-jobs
List all AutoML jobs accessible to the authenticated user.
Scope: ml-workbench:read
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
status | string | No | Filter by status: pending, preparing, running, training, evaluating, stopping, completed, failed, cancelled |
q | string | No | Search by job name or description |
limit | integer | No | Number of results to return (default: 50, max: 200) |
cursor | string | No | meta.nextCursor of the previous page; omit for the first page |
sort | string | No | Sort field; prefix with - for descending (default: -createdAt) |
Response 200 OK
{
"data": [
{
"_id": "Xk3pQ9rT2mB7nW4sA",
"jobId": "f22a9764e2ed836b9799a50b",
"name": "Churn Prediction Model",
"problemType": "tabular",
"predictorType": "auto",
"status": "training",
"progress": 45,
"owner": "user_456",
"organizationId": "org_xyz",
"trainingConfig": { "preset": "medium_quality", "timeLimit": 600, "metric": "accuracy" },
"datasetInfo": { /* see the AutoMLJob object */ },
"createdAt": "2025-02-01T09:55:00Z",
"updatedAt": "2025-02-01T12:30:00Z"
}
],
"meta": {
"total": 10,
"limit": 50,
"nextCursor": null,
"requestId": "req_abc123"
}
}
POST /api/v1/mlops/automl-jobs
Create a new AutoML job.
Scope: ml-workbench:write
Datasets are project volumes (uploaded through the UI or the volume data endpoints). Reference one by its volume id (from GET /mlops/automl-datasets); a volume
is a directory, so when it holds more than one data file, pass datasetFile
with the file key (discover files with GET /mlops/automl-datasets/:id/files). You
may also pass an s3:// path or a URL directly as dataset.
A job can also train straight from one of your data sources (dataSourceId)
or add-ons (addonId), with read naming what to read. Nothing is copied
first: the job receives the source's connection through STRONGLY_SERVICES, as
an app does, and reads every row read-only. The source is refused with 400
when it does not exist, cannot be read as read says, or is of a type a job
cannot read (API keys, Memcached, RabbitMQ, SQS, MQTT, Marqo), and with 403
when you may not use it. A target column the platform cannot list (a query, a
document store) is checked when the job reads: the job fails naming the columns
it found.
{
"name": "Churn from Postgres",
"dataSourceId": "ds_sales_pg",
"read": { "table": "churn", "schema": "public" },
"targetColumn": "churned",
"hardware": { "cpuCount": 2, "memoryGb": 8, "diskGb": 20 },
"outputVolumeId": "vol_models_001"
}
| Source type | read |
|---|---|
| SQL (Postgres and compatible, MySQL and compatible, SQL Server, Oracle, Snowflake, BigQuery, Redshift, ClickHouse, ...) | { "table", "schema"? } or { "query" } (read-only) |
| MongoDB | { "collection", "filter"? } or { "collection", "pipeline" } (no $out/$merge) |
| Elasticsearch, CouchDB | { "collection" } (an index or database), with an optional filter |
| DynamoDB, Firestore | { "collection" } (a table or collection) |
| Couchbase, ArangoDB, SurrealDB | { "collection" } or { "query" } (a read-only SQL++, AQL or SurrealQL SELECT) |
| Neo4j, Neptune | { "query" } (Cypher or openCypher, read-only) |
| TigerGraph | { "collection" } (a vertex type) |
| Milvus, Pinecone, Weaviate, Qdrant, Chroma, Vespa | { "collection" } (Pinecone also namespace; Vespa namespace/documenttype). A vector becomes one column per dimension |
| Google Sheets, Airtable, Baserow, NocoDB, SeaTable, Grist | { "sheet" } (Google Sheets: optional, the first worksheet) |
| S3, MinIO, GCS, Azure Blob | { "object_key" }: a CSV, TSV, Parquet or JSON file, or a prefix ending in / |
| Redis | { "key_pattern" }: one row per key (a hash or a JSON value) |
| Kafka, Pulsar | { "topic" }: every message from the first to the last when the job starts; nothing is consumed |
The trained model is written to a shared volume: pass exactly one of
outputVolumeId (an existing shared volume) and outputVolumeName (a new one
the platform creates). Otherwise the request is refused with 400 validation-error.
Request Body
{
"name": "Churn Prediction Model",
"dataset": "vol_customers_001",
"datasetFile": "data/customers.csv",
"targetColumn": "churned",
"featureColumns": ["usage_days", "monthly_spend", "support_tickets", "plan_type"],
"problemType": "tabular",
"predictorType": "auto",
"preset": "medium_quality",
"timeLimit": 600,
"metric": "accuracy",
"hardware": { "cpuCount": 4, "memoryGb": 16, "diskGb": 20, "gpuCount": 0 },
"outputVolumeId": "vol_models_001",
"environmentId": "custom",
"advanced": { "excludeModels": ["KNN"] }
}
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Human-readable job name |
dataset | string | One source | Project dataset volume id (from GET /mlops/automl-datasets), an s3:// path, or a URL |
dataSourceId | string | One source | A data source to train from, with read |
addonId | string | One source | An add-on to train from, with read |
read | object | With a data source or add-on | What to read (see the table above) |
targetColumn | string | Yes | Name of the column to predict |
datasetFile | string | No | File key within the volume, when it holds more than one data file |
featureColumns | string[] | No | Specific columns to use as features. All non-target columns used if omitted |
problemType | string | No | Data modality: tabular (default), multimodal, timeseries |
predictorType | string | No | auto (default, AutoGluon infers), BinaryClassifier, MultiClassifier, Regressor |
preset | string | No | AutoGluon quality preset: best_quality, high_quality, good_quality (tabular), medium_quality (default), optimize_for_deployment (tabular) |
timeLimit | integer | No | Maximum training time in seconds (default: 600) |
metric | string | No | Optimization metric (e.g. accuracy, f1, rmse). Default: accuracy |
hardware | object | Yes | Pod sizing: { cpu_count, memory_gb, disk_gb }, with optional gpuCount, gpu_type (e.g. nvidia-t4, nvidia-a10g) useSpot (true trains on cheaper spot capacity, which can be reclaimed) and spotFallback (with useSpot, true, the default, falls back to on-demand when no spot is available; false waits for spot) |
outputVolumeId | string | One of the two | The shared volume the trained model is written to |
outputVolumeName | string | One of the two | The name of a new shared volume to create for the trained model |
environmentId | string | No | Training environment: custom (default) or an existing environment id |
advanced | object | No | Advanced settings, by section (see Advanced settings); an omitted section keeps its defaults |
Advanced settings
The sections of advanced, as the create page's Advanced step sets them. A job records what it ran with as advanced_config, and its page shows it on the Configuration tab.
| Section | For | Keys |
|---|---|---|
model_selection | Tabular | enable_gbm, enable_cat, enable_xgb, enable_rf, enable_xt, enable_knn, enable_lr, enable_nn_torch, enable_fastai, enable_tabpfn, enable_ft_transformer, enable_automm (booleans: the model families to train); included_models, excluded_models (AutoGluon model names) |
ensemble | Tabular | num_bag_folds, num_bag_sets, save_bag_folds, num_stack_levels, dynamic_stacking, fit_weighted_ensemble, fit_full_last_level_weighted_ensemble, use_orig_features, refit_full, set_best_to_refit_full, keep_only_best, save_space |
data_handling | Tabular | feature_generator (auto or none), enable_text_ngram_features, enable_text_special_features, enable_raw_text_features, enable_vision_features, feature_prune, feature_prune_threshold, sample_weight_column |
training | Tabular | infer_limit (seconds per row), infer_limit_batch_size, calibrate, calibrate_decision_threshold, fit_strategy (sequential or parallel), verbosity, learning_curves, raise_on_model_failure |
hpo | Tabular | enabled, strategy (auto, random or bayesian), num_trials, time_limit_per_trial (seconds), scheduler (local or fifo) |
model_hyperparameters | Tabular | Per family: gbm, cat, xgb, rf, nn_torch, fastai (each family's AutoGluon hyperparameters). Values given are fixed for every model of the family, and tuning searches only the others; omit the section to train with AutoGluon's defaults for the preset, which hpo searches |
custom | Tabular | hyperparameters_json, ag_args_json, ag_args_fit_json, ag_args_ensemble_json (JSON strings) |
timeseries | Time series | prediction_length, freq (e.g. D, H, W, M), id_column, timestamp_column, known_covariates, static_features, eval_metric_seasonal_period, quantile_levels |
multimodal | Multimodal | text_columns, image_columns, backbone, max_text_length, image_size, augmentation, use_ensemble, ensemble_size, ensemble_mode (one_shot or sequential), clean_ckpts |
Response 201 Created
{
"data": {
"_id": "Xk3pQ9rT2mB7nW4sA",
"jobId": "f22a9764e2ed836b9799a50b",
"name": "Churn Prediction Model",
"problemType": "tabular",
"predictorType": "auto",
"status": "pending",
"progress": 0,
"owner": "user_456",
"organizationId": "org_xyz",
"trainingConfig": { "preset": "medium_quality", "timeLimit": 600, "metric": "accuracy" },
"hardware": { "cpuCount": 4, "memoryGb": 16, "gpuCount": 0, "diskGb": 20 },
"environmentId": "custom",
"createdAt": "2025-02-01T09:55:00Z",
"updatedAt": "2025-02-01T09:55:00Z"
},
"meta": {
"requestId": "req_abc123"
}
}
GET /api/v1/mlops/automl-jobs/:id
Get a single AutoML job by ID.
Scope: ml-workbench:read
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
id | string | Yes | AutoML job ID |
Response 200 OK
Returns the full AutoMLJob object.
DELETE /api/v1/mlops/automl-jobs/:id
Delete an AutoML job. Running jobs must be stopped before deletion.
Scope: ml-workbench:write
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
id | string | Yes | AutoML job ID |
Response 204 No Content
POST /api/v1/mlops/automl-jobs/:id/stop
Stop a running AutoML job. The job will be marked as stopped and training will be terminated.
Scope: ml-workbench:write
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
id | string | Yes | AutoML job ID |
Response 200 OK
The job, as GET /mlops/automl-jobs/:id shows it, status cancelled.
POST /api/v1/mlops/automl-jobs/:id/deploy
Deploy the best model from a completed AutoML job. Makes the model available for inference via the model registry.
Scope: ml-workbench:write
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
id | string | Yes | AutoML job ID |
Response 200 OK
{
"data": {
"success": true,
"modelId": "model_xyz789",
"modelName": "Churn Prediction Model",
"version": 1,
"deploymentStatus": "building",
"message": "Best model registered and deployment started",
"baselineJobId": "bjob_123"
},
"meta": {
"requestId": "req_abc123"
}
}
When the job wrote no reference rows for the model's drift baseline, baseline_note (why no baseline was built) is returned instead of baselineJobId.
GET /api/v1/mlops/automl-jobs/:id/logs
Retrieve an AutoML job's training log: the trainer pod's while it exists, then the tail the job's record keeps. With no query parameters, the whole log.
Scope: ml-workbench:read
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
id | string | Yes | AutoML job ID |
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
lines | integer | No | Only the last N lines |
since | string | No | Only the lines written at or after this ISO 8601 time |
Response 200 OK
{
"data": {
"logs": "Beginning AutoGluon training ...\nFitting model: LightGBM ...\n"
},
"meta": {
"requestId": "req_abc123"
}
}
logs is the training log as one text block.
GET /api/v1/mlops/automl-jobs/stats
Get aggregate statistics for the AutoML jobs you can see.
averageAccuracy averages the validation accuracy of the completed jobs
optimized for accuracy, and is null when there are none (another metric's
score is not an accuracy). What AutoML jobs cost is shown in
FinOps only.
Scope: ml-workbench:read
Response 200 OK
{
"data": {
"totalJobs": 10,
"activeJobs": 1,
"completedJobs": 6,
"failedJobs": 2,
"averageAccuracy": 0.87,
"totalModels": 42
},
"meta": {
"requestId": "req_abc123"
}
}
GET /api/v1/mlops/automl-datasets
List the shared dataset volumes the authenticated user can train on, most
recently updated first. A volume is a directory; use It pages with limit and cursor (Pagination).
GET /mlops/automl-datasets/:id/files to list the files inside it.
Scope: ml-workbench:read
Response 200 OK
{
"data": {
"datasets": [
{
"_id": "vol_customers_001",
"name": "Customer Data Q4 2024",
"description": "",
"scope": "shared",
"dataFileCount": 1,
"hasData": true,
"isShared": true,
"owner": "user_456",
"updatedAt": "2025-02-01T09:00:00Z",
"accessLevel": "owner"
}
]
},
"meta": { "total": 1, "limit": 50, "nextCursor": null, "requestId": "req_abc123" }
}
dataFileCount counts the training files (.csv, .tsv, .json, .parquet, .data, .txt, .xlsx, .xls) in the volume's data. accessLevel is owner or shared.
POST /api/v1/mlops/automl-datasets/uploads
Get a presigned URL to upload a local training dataset file. PUT the file bytes
to the returned uploadUrl, then reference the returned s3Path as the
dataset in POST /mlops/automl-jobs. This is the programmatic equivalent of the
UI's dataset uploader.
Scope: ml-workbench:write
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
filename | string | Yes | Dataset file name (e.g. titanic.csv) |
contentType | string | No | MIME type (default text/csv) |
Response 201 Created
{
"data": {
"datasetId": "f22a9764e2ed836b9799a50b",
"uploadUrl": "https://s3.amazonaws.com/strongly-dev/mlops/automl/jobs/.../input/titanic.csv?X-Amz-...",
"s3Path": "mlops/automl/jobs/f22a9764e2ed836b9799a50b/input/titanic.csv",
"bucket": "strongly-dev",
"expiresInSeconds": 3600
},
"meta": {
"requestId": "req_abc123"
}
}
Then PUT the raw file bytes to uploadUrl and create the job:
curl -X PUT "$uploadUrl" -H "Content-Type: text/csv" --data-binary @titanic.csv
# then POST /mlops/automl-jobs with { "dataset": "<s3Path>", "targetColumn": "Survived", ... }
GET /api/v1/mlops/automl-datasets/:id/files
List the data files inside a project dataset volume, so you can pick which one
to train on (pass its key as datasetFile to POST /mlops/automl-jobs).
Scope: ml-workbench:read
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Dataset volume id (from GET /mlops/automl-datasets) |
Response 200 OK
{
"data": {
"volumeId": "vol_customers_001",
"dataVersion": null,
"files": [
{ "key": "data/customers.csv", "name": "customers.csv", "size": 45000, "lastModified": "2025-02-01T09:00:00Z", "isDirectory": false }
]
},
"meta": {
"requestId": "req_abc123"
}
}
Only training files (.csv, .tsv, .json, .parquet, .data, .txt, .xlsx, .xls) are listed, sorted by name.
GET /api/v1/mlops/automl-datasets/:id/columns
Get the column headers of a dataset file in a project volume (to choose the target and feature columns). Reads only the header row.
Scope: ml-workbench:read
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Dataset volume id |
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
file | string | No | File key within the volume. Optional when the volume has exactly one data file |
Response 200 OK
{
"data": {
"volumeId": "vol_customers_001",
"dataVersion": null,
"file": "projects/proj_1/volumes/vol_customers_001/customers.csv",
"columns": ["usage_days", "monthly_spend", "support_tickets", "plan_type", "churned"]
},
"meta": {
"requestId": "req_abc123"
}
}
GET /api/v1/mlops/automl-jobs/:id/status
A job's status as the trainer reports it: status, progress, statusMessage, error,
failureReason, createdAt, finishedAt, updatedAt, and while it runs k8s (the pod's live
diagnostics: scheduling, image pulls, restarts). Lighter than the whole job.
Scope: ml-workbench:read
| Parameter | Type | Required | Description |
|---|---|---|---|
id | string | Yes | AutoML job id |
Response 200 OK
GET /api/v1/mlops/automl-jobs/:id/metrics
A job's training results: metrics, the leaderboard of the models it trained, the
bestModel and trialCount.
Scope: ml-workbench:read
| Parameter | Type | Required | Description |
|---|---|---|---|
id | string | Yes | AutoML job id |
Response 200 OK