Tasks and training
Mubit groups your calls into tasks. These operations read the tasks, their training examples and settings, start a training run, and read the run's job.
All paths are under https://api.mubit.ai, with a management key in Authorization: Bearer. Management API covers keys, roles, pagination, retries and errors. The samples read the key from MUBIT_MANAGEMENT_KEY.
List tasks
GET /api/v1/tasks
Lists the tasks Mubit found in your calls, with their row counts, stage and active adapter version.
Role: read or higher.
| Name | In | Type | Required | Description |
|---|---|---|---|---|
project | query | string | no | |
limit | query | integer | no | Number of records to return (1-200) |
cursor | query | string | no | Sealed pagination cursor from previous page |
curl "https://api.mubit.ai/api/v1/tasks?project=$PROJECT_ID" \
-H "Authorization: Bearer $MUBIT_MANAGEMENT_KEY"Response 200: List of tasks
Each item of data:
| Field | Type | Required | Description |
|---|---|---|---|
id | string | yes | |
name | string | yes | |
project | string | yes | |
stage | string | yes | |
rows_count | integer | yes | |
active_version | integer, nullable | no | |
created_at | string (date-time) | yes |
{
"data": [
{
"id": "task_triage12",
"name": "Support Ticket Triage",
"project": "prj_prod",
"stage": "training",
"rows_count": 85,
"active_version": 2,
"created_at": "2026-10-10T00:00:00Z"
}
],
"next_cursor": null
}| Status | Meaning |
|---|---|
401 | Unauthenticated (missing, invalid, or expired token) |
403 | Forbidden (role_required, role_ceiling, project_scoped, forbidden, or a key that isn't a management key) |
500 | Internal server error |
Get task details
GET /api/v1/tasks/{task_id}
Returns one task with its stage, its dataset sizes and what to do next.
Role: read or higher.
| Name | In | Type | Required | Description |
|---|---|---|---|---|
task_id | path | string | yes |
curl "https://api.mubit.ai/api/v1/tasks/$TASK_ID" \
-H "Authorization: Bearer $MUBIT_MANAGEMENT_KEY"Response 200: Task details
| Field | Type | Required | Description |
|---|---|---|---|
id | string | yes | |
name | string | yes | |
project | string | yes | |
stage | string | yes | |
rows_count | integer | yes | |
holdout_count | integer | no | |
active_version | integer, nullable | no | |
recommendation | string | no |
{
"id": "task_triage12",
"name": "Support Ticket Triage",
"project": "prj_prod",
"stage": "ready",
"rows_count": 85,
"holdout_count": 18,
"active_version": 2,
"recommendation": "serve"
}| Status | Meaning |
|---|---|
401 | Unauthenticated (missing, invalid, or expired token) |
403 | Forbidden (role_required, role_ceiling, project_scoped, forbidden, or a key that isn't a management key) |
404 | Not found |
500 | Internal server error |
List task training examples
GET /api/v1/tasks/{task_id}/examples
Lists the task's training and held-out examples, one page of at most 50 (a higher limit returns 50). A row of the next training run has status next and split train. A row of the held-out test has status test and split holdout. A row left out of the next run has status left_out and says why in left_out_reason. input and expected_output are excerpts of at most 160 characters. A cursor belongs to its task and query (400 invalid_cursor otherwise). This route has its own limit: 120 requests a minute for an organization, across all its keys (429 rate_limited with Retry-After). The project's example review must be on (409 state_conflict otherwise).
Role: read or higher.
| Name | In | Type | Required | Description |
|---|---|---|---|---|
task_id | path | string | yes | |
limit | query | integer | no | Number of records to return (1-200) |
cursor | query | string | no | Sealed pagination cursor from previous page |
curl "https://api.mubit.ai/api/v1/tasks/$TASK_ID/examples" \
-H "Authorization: Bearer $MUBIT_MANAGEMENT_KEY"Response 200: Task examples
Each item of data:
| Field | Type | Required | Description |
|---|---|---|---|
id | string | yes | ex_ and the id of the call the row is made from |
input | string | yes | An excerpt of the row's input, at most 160 characters |
expected_output | string | no | An excerpt of the row's answer, at most 160 characters |
split | string: train, holdout | no | train for a row of the next training build (status next), holdout for a row of the held-out exam (status test); a row left out has none |
status | string | yes | next (a row of the next training build), test (a row of the held-out exam) or left_out (a row the next build leaves out) |
left_out_reason | string | no | Why a row with status left_out is not in the next run (no_verdict, person_rejected, row_filter, and others) |
{
"data": [
{
"id": "ex_98124",
"input": "Refund request for order #1234",
"expected_output": "Refund initiated for order #1234",
"split": "holdout",
"status": "test"
}
],
"next_cursor": null
}| Status | Meaning |
|---|---|
400 | Bad request (validation, invalid_cursor, out_of_bounds) |
401 | Unauthenticated (missing, invalid, or expired token) |
403 | Forbidden (role_required, role_ceiling, project_scoped, forbidden, or a key that isn't a management key) |
404 | Not found |
409 | The task's project has example review off (state_conflict, with details.reason feedback_review_off), or examples can't be read yet (engine_too_old) |
429 | Rate limited |
500 | Internal server error |
503 | Service unavailable (unavailable). Retry after the Retry-After seconds. |
Get training settings
GET /api/v1/tasks/{task_id}/settings
Returns the task's training settings: its base model, and the min_rows, max_rows and rate_max_per_day that apply to it. A figure with no value set is null; no default is made up for it. retrain_interval_s and training_window_days are always null: a task retrains when enough new rows arrive. The ETag header is a digest of these figures.
Role: read or higher.
| Name | In | Type | Required | Description |
|---|---|---|---|---|
task_id | path | string | yes |
curl "https://api.mubit.ai/api/v1/tasks/$TASK_ID/settings" \
-H "Authorization: Bearer $MUBIT_MANAGEMENT_KEY"Response 200: Task settings
| Field | Type | Required | Description |
|---|---|---|---|
base_model | string, nullable | no | |
rate_max_per_day | integer, nullable | no | |
min_rows | integer, nullable | no | |
max_rows | integer, nullable | no | |
retrain_interval_s | integer, nullable | no | |
training_window_days | integer, nullable | no |
{
"base_model": "Qwen/Qwen3-4B-Instruct-2507",
"rate_max_per_day": 100,
"min_rows": 20,
"max_rows": 500,
"retrain_interval_s": null,
"training_window_days": null
}| Status | Meaning |
|---|---|
401 | Unauthenticated (missing, invalid, or expired token) |
403 | Forbidden (role_required, role_ceiling, project_scoped, forbidden, or a key that isn't a management key) |
404 | Not found |
500 | Internal server error |
503 | Service unavailable (unavailable). Retry after the Retry-After seconds. |
Start training
POST /api/v1/tasks/{task_id}/train
Starts a training run for a new adapter version of the task, and answers 202 with its job. Read the job with Get job status. With dry_run: true nothing starts: the answer (200) says whether a run would start, with rows and need. The body takes reason and dry_run only; any other field is 400. While the run's dataset is still being built, the job has no id yet (null) and its status is preparing. Too few rows, or a run already in progress, is 409 state_conflict.
Role: admin.
| Name | In | Type | Required | Description |
|---|---|---|---|---|
task_id | path | string | yes | |
Idempotency-Key | header | string | no | Unique key for safe write retries within 24h |
Request body (optional)
| Field | Type | Required | Description |
|---|---|---|---|
reason | string | no | |
dry_run | boolean | no |
curl -X POST "https://api.mubit.ai/api/v1/tasks/$TASK_ID/train" \
-H "Authorization: Bearer $MUBIT_MANAGEMENT_KEY" \
-H "Idempotency-Key: $IDEMPOTENCY_KEY" \
-H "Content-Type: application/json" \
-d '{"reason":"Retrain with updated customer support guidelines"}'Response 202: Asynchronous job accepted
| Field | Type | Required | Description |
|---|---|---|---|
job | Job | yes |
{
"job": {
"id": "job_019283",
"type": "export",
"status": "queued",
"created_at": "2026-10-26T12:00:00Z"
}
}| Status | Meaning |
|---|---|
400 | Bad request (validation, invalid_cursor, out_of_bounds) |
401 | Unauthenticated (missing, invalid, or expired token) |
403 | Forbidden (role_required, role_ceiling, project_scoped, forbidden, or a key that isn't a management key) |
404 | Not found |
409 | Conflict (idempotency_conflict, state_conflict) |
500 | Internal server error |
Get job status
GET /api/v1/jobs/{job_id}
Reads one training job by the id Start training returned: its status and its times. type is training. The status is queued, running, succeeded, failed or canceled. A failed job carries an error. A job of another organization is 404.
Role: read or higher.
| Name | In | Type | Required | Description |
|---|---|---|---|---|
job_id | path | string | yes |
curl "https://api.mubit.ai/api/v1/jobs/$JOB_ID" \
-H "Authorization: Bearer $MUBIT_MANAGEMENT_KEY"Response 200: Job status
| Field | Type | Required | Description |
|---|---|---|---|
id | string, nullable | yes | Null while the job has no id yet (a training run whose dataset is still being built) |
type | string | yes | The kind of job: training for a training run |
status | string: preparing, queued, running, succeeded, failed, canceled | yes | |
created_at | string (date-time) | yes | |
started_at | string (date-time), nullable | no | |
finished_at | string (date-time), nullable | no | |
progress | object | no | |
result | object, nullable | no | |
error | object, nullable | no | Present for a failed job: the code training_failed and a message |
{
"id": "ftjob_019283",
"type": "training",
"status": "running",
"created_at": "2026-10-26T11:55:00Z",
"started_at": "2026-10-26T11:55:05Z",
"finished_at": null,
"result": null,
"error": null
}| Status | Meaning |
|---|---|
401 | Unauthenticated (missing, invalid, or expired token) |
403 | Forbidden (role_required, role_ceiling, project_scoped, forbidden, or a key that isn't a management key) |
404 | Not found |
500 | Internal server error |
503 | Service unavailable (unavailable). Retry after the Retry-After seconds. |