{"openapi":"3.0.0","info":{"title":"mlop API","version":"1.0.0","description":"API for mlop - ML experiment tracking platform"},"servers":[{"url":"https://pluto-api.trainy.ai","description":"API Server"}],"security":[{"bearerAuth":[]}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"API Key","description":"API key obtained from the mlop dashboard"}},"schemas":{"FieldFilterTerm":{"type":"object","properties":{"source":{"type":"string","enum":["config","systemMetadata"]},"key":{"type":"string"},"dataType":{"type":"string","enum":["text","number","date","option"]},"operator":{"type":"string","enum":["contains","does not contain","equals","is","is not","starts with","ends with","regex","is greater than",">","is less than","<","is greater than or equal to",">=","is less than or equal to","<=","is between","is not between","is before","is on or before","is after","is on or after","is any of","is none of","exists","not exists"]},"values":{"type":"array","items":{"nullable":true}}},"required":["source","key","dataType","operator","values"]},"RunFilterGrammar":{"type":"object","properties":{"booleanOperators":{"type":"array","items":{"type":"string","enum":["$and","$or","$not"]}},"leafOperators":{"type":"array","items":{"type":"string","enum":["$eq","$ne","$gt","$gte","$lt","$lte","$in","$nin","$regex"]}},"fields":{"type":"array","items":{"type":"string","enum":["state","status","heartbeat_at","heartbeatAt","created_at","createdAt","updated_at","updatedAt","name","displayName","display_name","tags"]}},"fieldPrefixes":{"type":"array","items":{"type":"string","enum":["config.","systemMetadata.","summaryMetrics.","summary_metrics."]}}},"required":["booleanOperators","leafOperators","fields","fieldPrefixes"]},"CreateRunResponse":{"type":"object","properties":{"runId":{"type":"number","description":"Numeric ID of the created run"},"number":{"type":"number","nullable":true,"description":"Sequential run number within the project (for display IDs)"},"displayId":{"type":"string","nullable":true,"description":"Human-readable display ID (e.g., 'MMP-1')"},"projectName":{"type":"string","description":"Name of the project"},"organizationSlug":{"type":"string","description":"Organization slug"},"url":{"type":"string","description":"URL to view the run"},"resumed":{"type":"boolean","description":"Whether an existing run was resumed (true) or a new run was created (false)"},"forkedFromRunId":{"type":"number","nullable":true,"description":"ID of the parent run this was forked from (null if not forked)"},"forkStep":{"type":"number","nullable":true,"description":"Step at which the fork occurred (null if not forked)"}},"required":["runId","number","displayId","projectName","organizationSlug","url","resumed"]},"Error":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]},"CreateRunRequest":{"type":"object","properties":{"runName":{"type":"string","description":"Name of the run","example":"training-run-1"},"projectName":{"type":"string","description":"Name of the project","example":"my-project"},"externalId":{"type":"string","nullable":true,"minLength":1,"description":"User-provided run ID for multi-node distributed training. If provided and a run with this ID exists, the existing run is returned.","example":"my-ddp-run-2024"},"tags":{"type":"array","nullable":true,"items":{"type":"string"},"maxItems":50,"description":"Tags for the run (max 50)","example":["experiment","v1"]},"loggerSettings":{"type":"string","nullable":true,"description":"Logger settings as JSON string"},"systemMetadata":{"type":"string","nullable":true,"description":"System metadata as JSON string"},"config":{"type":"string","nullable":true,"description":"Run configuration as JSON string","example":"{\"lr\": 0.001}"},"createdAt":{"type":"integer","nullable":true,"minimum":0,"maximum":8640000000000000,"description":"Creation timestamp in epoch milliseconds (backfill/migration)"},"updatedAt":{"type":"integer","nullable":true,"minimum":0,"maximum":8640000000000000,"description":"Update timestamp in epoch milliseconds (backfill/migration)"},"forkRunId":{"type":"number","nullable":true,"description":"ID of the run to fork from. Creates a child run that inherits metrics up to forkStep."},"forkStep":{"type":"number","nullable":true,"description":"Step at which to fork. Required when forkRunId is provided. The child run inherits all metrics up to and including this step."},"inheritConfig":{"type":"boolean","nullable":true,"description":"Whether to inherit config from the parent run (default: true). Only applies when forkRunId is provided."},"inheritTags":{"type":"boolean","nullable":true,"description":"Whether to inherit tags from the parent run (default: false). Only applies when forkRunId is provided."}},"required":["runName","projectName"]},"ResumeRunResponse":{"type":"object","properties":{"runId":{"type":"number","description":"Numeric ID of the resumed run"},"number":{"type":"number","nullable":true,"description":"Sequential run number within the project"},"displayId":{"type":"string","nullable":true,"description":"Human-readable display ID (e.g., 'MMP-1')"},"projectName":{"type":"string","description":"Name of the project"},"organizationSlug":{"type":"string","description":"Organization slug"},"url":{"type":"string","description":"URL to view the run"},"resumed":{"type":"boolean","description":"Always true for this endpoint"}},"required":["runId","number","displayId","projectName","organizationSlug","url","resumed"]},"ResumeRunRequest":{"type":"object","properties":{"runId":{"type":"number","description":"Numeric ID of the run to resume","example":123},"displayId":{"type":"string","description":"Human-readable display ID (e.g., 'MMP-1')","example":"MMP-1"},"externalId":{"type":"string","description":"User-provided external ID","example":"my-training-run-v1"},"projectName":{"type":"string","description":"Project name. Required when using externalId (which is scoped to a project). Optional but recommended with displayId to disambiguate when distinct project names share a run-prefix.","example":"my-project"}}},"Success":{"type":"object","properties":{"success":{"type":"boolean"}},"required":["success"]},"UpdateStatusRequest":{"type":"object","properties":{"runId":{"type":"number","description":"Numeric ID of the run","example":123},"status":{"type":"string","enum":["RUNNING","COMPLETED","FAILED","TERMINATED","CANCELLED"],"description":"New status","example":"COMPLETED"},"statusMetadata":{"type":"string","nullable":true,"description":"Status metadata as JSON string"},"loggerSettings":{"type":"string","nullable":true,"description":"Logger settings to merge"},"statusUpdated":{"type":"integer","nullable":true,"minimum":0,"maximum":8640000000000000,"description":"Status-change timestamp in epoch milliseconds (backfill/migration). When omitted, the server stamps now(). Migration tooling replaying a finished run should pass the run's original finish time so its Duration reflects the historical run length, not time-since-import."}},"required":["runId","status"]},"RunStatusHistoryResponse":{"type":"object","properties":{"runId":{"type":"number"},"events":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"runId":{"type":"number"},"fromStatus":{"type":"string","nullable":true},"toStatus":{"type":"string"},"source":{"type":"string"},"metadata":{"nullable":true},"actorId":{"type":"string","nullable":true},"apiKeyId":{"type":"string","nullable":true},"createdAt":{"type":"string"}},"required":["id","runId","fromStatus","toStatus","source","actorId","apiKeyId","createdAt"]}}},"required":["runId","events"]},"AddLogNameRequest":{"type":"object","properties":{"runId":{"type":"number","description":"Numeric ID of the run"},"logName":{"type":"array","items":{"type":"string"},"description":"Log names to add","example":["train/loss","train/accuracy"]},"logType":{"type":"string","enum":["METRIC","IMAGE","VIDEO","AUDIO","FILE","TEXT","ARTIFACT","HISTOGRAM","TABLE","DATA"],"description":"Type of log","example":"METRIC"}},"required":["runId","logName","logType"]},"UpdateTagsRequest":{"type":"object","properties":{"runId":{"type":"number","description":"Numeric ID of the run"},"tags":{"type":"array","items":{"type":"string"},"maxItems":50,"description":"New tags for the run (max 50)","example":["production","v2"]}},"required":["runId","tags"]},"UpdateNotesRequest":{"type":"object","properties":{"runId":{"type":"number","description":"Numeric ID of the run"},"notes":{"type":"string","nullable":true,"maxLength":1000,"description":"Notes/description for the run (max 1000 chars). Set to null or empty string to clear."}},"required":["runId","notes"]},"UpdateConfigRequest":{"type":"object","properties":{"runId":{"type":"number","description":"Numeric ID of the run"},"config":{"type":"string","description":"Configuration as JSON string","example":"{\"model\": \"resnet50\"}"}},"required":["runId","config"]},"RunListItem":{"type":"array","items":{"type":"object","properties":{"id":{"type":"number","description":"Numeric run ID"},"name":{"type":"string","description":"Run name"},"number":{"type":"number","nullable":true,"description":"Sequential run number within the project"},"displayId":{"type":"string","nullable":true,"description":"Human-readable display ID (e.g., 'MMP-1')"},"projectName":{"type":"string","description":"Name of the project this run belongs to"},"status":{"type":"string","description":"Run status"},"tags":{"type":"array","items":{"type":"string"},"description":"Run tags"},"createdAt":{"type":"string","description":"Creation timestamp"},"_flatConfig":{"type":"object","additionalProperties":{"nullable":true},"description":"Flattened config — only present when includeFieldValues=true"},"_flatSystemMetadata":{"type":"object","additionalProperties":{"nullable":true},"description":"Flattened systemMetadata — only present when includeFieldValues=true"}},"required":["id","name","number","displayId","projectName","status","tags","createdAt"]}},"ListRunsResponse":{"type":"object","properties":{"runs":{"$ref":"#/components/schemas/RunListItem"},"total":{"type":"number","description":"Total count of matching runs"}},"required":["runs","total"]},"CreateModelGraphRequest":{"type":"object","properties":{"runId":{"type":"number","description":"Numeric ID of the run"},"graph":{"type":"object","properties":{"format":{"type":"string"},"nodes":{"type":"object","additionalProperties":{"type":"object","properties":{"type":{"type":"string"},"depth":{"type":"integer"},"order":{"type":"integer"},"label":{"type":"string"},"node_id":{"type":"string"},"node_type":{"type":"string","enum":["MODULE","UNKNOWN","CONTAINER","IO"]},"inst_id":{"type":"string"},"args":{"type":"array","items":{"nullable":true}},"kwargs":{"type":"object","additionalProperties":{"nullable":true}},"params":{"type":"object","additionalProperties":{"type":"array","items":{"type":"number"}}},"edges":{"type":"array","items":{"type":"array","items":{"type":"string"}}}},"required":["type","depth"]}}},"required":["format","nodes"],"description":"Graph data with nodes and edges"}},"required":["runId","graph"]},"ValidateApiKeyResponse":{"type":"object","properties":{"valid":{"type":"boolean"},"organization":{"type":"object","properties":{"id":{"type":"string"},"slug":{"type":"string"}},"required":["id","slug"]},"user":{"type":"object","properties":{"id":{"type":"string"}},"required":["id"]}},"required":["valid","organization","user"]},"RunDetailsResponse":{"type":"object","properties":{"id":{"type":"number"},"name":{"type":"string"},"number":{"type":"number","nullable":true,"description":"Sequential run number within the project"},"displayId":{"type":"string","nullable":true,"description":"Human-readable display ID (e.g., 'MMP-1')"},"status":{"type":"string"},"tags":{"type":"array","items":{"type":"string"}},"config":{"nullable":true},"systemMetadata":{"nullable":true},"loggerSettings":{"nullable":true},"statusMetadata":{"nullable":true},"createdAt":{"type":"string"},"updatedAt":{"type":"string"},"statusUpdated":{"type":"string","nullable":true},"projectName":{"type":"string"},"externalId":{"type":"string","nullable":true},"forkedFromRunId":{"type":"number","nullable":true},"forkStep":{"type":"number","nullable":true},"logNames":{"type":"array","items":{"type":"object","properties":{"logName":{"type":"string"},"logType":{"type":"string"},"logGroup":{"type":"string","nullable":true}},"required":["logName","logType","logGroup"]}}},"required":["id","name","number","displayId","status","tags","createdAt","updatedAt","statusUpdated","projectName","externalId","forkedFromRunId","forkStep","logNames"]},"RunDetailsByDisplayIdResponse":{"type":"object","properties":{"id":{"type":"number"},"name":{"type":"string"},"number":{"type":"number","nullable":true},"displayId":{"type":"string","nullable":true},"status":{"type":"string"},"tags":{"type":"array","items":{"type":"string"}},"config":{"nullable":true},"systemMetadata":{"nullable":true},"loggerSettings":{"nullable":true},"statusMetadata":{"nullable":true},"createdAt":{"type":"string"},"updatedAt":{"type":"string"},"statusUpdated":{"type":"string","nullable":true},"projectName":{"type":"string"},"externalId":{"type":"string","nullable":true},"logNames":{"type":"array","items":{"type":"object","properties":{"logName":{"type":"string"},"logType":{"type":"string"},"logGroup":{"type":"string","nullable":true}},"required":["logName","logType","logGroup"]}}},"required":["id","name","number","displayId","status","tags","createdAt","updatedAt","statusUpdated","projectName","externalId","logNames"]},"QueryLogsResponse":{"type":"object","properties":{"logs":{"type":"array","items":{"type":"object","properties":{"time":{"type":"string"},"logType":{"type":"string"},"lineNumber":{"type":"number"},"message":{"type":"string"},"step":{"type":"number","nullable":true}},"required":["time","logType","lineNumber","message","step"]}},"total":{"type":"number"}},"required":["logs","total"]},"QueryMetricsResponse":{"type":"object","properties":{"metrics":{"type":"array","items":{"type":"object","properties":{"logName":{"type":"string"},"logGroup":{"type":"string"},"time":{"type":"string"},"step":{"type":"number"},"value":{"type":"number"}},"required":["logName","logGroup","time","step","value"]}}},"required":["metrics"]},"QueryRawMetricsResponse":{"type":"object","properties":{"rows":{"type":"array","items":{"type":"object","properties":{"logGroup":{"type":"string"},"step":{"type":"number"},"time":{"type":"string","description":"Server-side write timestamp (ClickHouse DateTime64(3))."},"value":{"type":"number"},"nonFiniteFlags":{"type":"number","description":"Bitmask: bit0=NaN, bit1=+Inf, bit2=-Inf. When non-zero, `value` is 0 and the flag is the source of truth."}},"required":["logGroup","step","time","value","nonFiniteFlags"]}},"truncated":{"type":"boolean","description":"True when the row count hit `limit` and more rows likely exist — narrow stepMin/stepMax to page."}},"required":["rows","truncated"]},"GetFilesResponse":{"type":"object","properties":{"files":{"type":"array","items":{"type":"object","properties":{"fileName":{"type":"string"},"fileType":{"type":"string"},"fileSize":{"type":"number"},"logName":{"type":"string"},"logGroup":{"type":"string"},"time":{"type":"string"},"step":{"type":"number"},"url":{"type":"string"},"caption":{"type":"string","nullable":true}},"required":["fileName","fileType","fileSize","logName","logGroup","time","step","url","caption"]}}},"required":["files"]},"ListProjectsResponse":{"type":"object","properties":{"projects":{"type":"array","items":{"type":"object","properties":{"id":{"type":"number"},"name":{"type":"string"},"createdAt":{"type":"string"},"updatedAt":{"type":"string"},"runCount":{"type":"number"}},"required":["id","name","createdAt","updatedAt","runCount"]}}},"required":["projects"]},"GetStatisticsResponse":{"type":"object","properties":{"runId":{"type":"number"},"runName":{"type":"string"},"projectName":{"type":"string"},"url":{"type":"string","description":"URL to view this run in the UI"},"metrics":{"type":"array","items":{"type":"object","properties":{"logName":{"type":"string"},"logGroup":{"type":"string"},"count":{"type":"number"},"min":{"type":"number"},"max":{"type":"number"},"mean":{"type":"number"},"stddev":{"type":"number"},"last":{"type":"object","properties":{"step":{"type":"number"},"value":{"type":"number"}},"required":["step","value"]}},"required":["logName","logGroup","count","min","max","mean","stddev","last"]}}},"required":["runId","runName","projectName","url","metrics"]},"CompareRunsResponse":{"type":"object","properties":{"projectName":{"type":"string"},"logName":{"type":"string"},"comparisonUrl":{"type":"string","description":"URL to compare these runs in the UI"},"runs":{"type":"array","items":{"type":"object","properties":{"runId":{"type":"number"},"runName":{"type":"string"},"url":{"type":"string","description":"URL to view this run"},"status":{"type":"string"},"config":{"nullable":true},"stats":{"type":"object","nullable":true,"properties":{"count":{"type":"number"},"min":{"type":"number"},"max":{"type":"number"},"mean":{"type":"number"},"final":{"type":"number","description":"Final value (at last step)"}},"required":["count","min","max","mean","final"]}},"required":["runId","runName","url","status","stats"]}}},"required":["projectName","logName","comparisonUrl","runs"]},"ListMetricNamesResponse":{"type":"object","properties":{"projectName":{"type":"string"},"metricNames":{"type":"array","items":{"type":"string"}}},"required":["projectName","metricNames"]},"LeaderboardResponse":{"type":"object","properties":{"projectName":{"type":"string"},"logName":{"type":"string"},"aggregation":{"type":"string"},"direction":{"type":"string"},"runs":{"type":"array","items":{"type":"object","properties":{"rank":{"type":"number","description":"1-based rank position"},"runId":{"type":"number"},"runName":{"type":"string"},"status":{"type":"string"},"url":{"type":"string","description":"URL to view this run in the UI"},"value":{"type":"number","description":"The aggregated metric value used for ranking"},"config":{"nullable":true},"tags":{"type":"array","items":{"type":"string"}},"createdAt":{"type":"string"}},"required":["rank","runId","runName","status","url","value","tags","createdAt"]}},"total":{"type":"number","description":"Total number of runs that have this metric"}},"required":["projectName","logName","aggregation","direction","runs","total"]},"DashboardSectionSummary":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"widgetCount":{"type":"number"},"dynamicPattern":{"type":"string","nullable":true},"childCount":{"type":"number"}},"required":["id","name","widgetCount","dynamicPattern","childCount"]},"DashboardSummary":{"type":"object","properties":{"id":{"type":"string","description":"Dashboard view ID"},"name":{"type":"string","description":"Dashboard name"},"isDefault":{"type":"boolean","description":"Whether this is the project's default dashboard"},"currentVersion":{"type":"integer","minimum":0,"exclusiveMinimum":true,"description":"Latest immutable dashboard version"},"configValid":{"type":"boolean","description":"Whether the stored config matches the current schema"},"sectionCount":{"type":"number","description":"Number of top-level sections"},"widgetCount":{"type":"number","description":"Total widgets across all sections"},"sections":{"type":"array","items":{"$ref":"#/components/schemas/DashboardSectionSummary"},"description":"Per-section summary"},"createdAt":{"type":"string","description":"ISO-8601 creation timestamp"},"updatedAt":{"type":"string","description":"ISO-8601 last-update timestamp"},"createdById":{"type":"string","description":"ID of the user who created the dashboard"},"url":{"type":"string","description":"Deep link to the dashboard in the web UI"}},"required":["id","name","isDefault","currentVersion","configValid","sectionCount","widgetCount","sections","createdAt","updatedAt","createdById","url"]},"ListDashboardsResponse":{"type":"object","properties":{"dashboards":{"type":"array","items":{"$ref":"#/components/schemas/DashboardSummary"}}},"required":["dashboards"]},"DashboardDetailsResponse":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"projectName":{"type":"string"},"isDefault":{"type":"boolean"},"currentVersion":{"type":"integer","minimum":0,"exclusiveMinimum":true},"config":{"type":"object","additionalProperties":{"nullable":true},"description":"Full DashboardViewConfig"},"createdAt":{"type":"string"},"updatedAt":{"type":"string"},"createdById":{"type":"string"},"url":{"type":"string"}},"required":["id","name","projectName","isDefault","currentVersion","config","createdAt","updatedAt","createdById","url"]},"DashboardVersionMetadata":{"type":"object","properties":{"version":{"type":"integer","minimum":0,"exclusiveMinimum":true},"name":{"type":"string"},"source":{"type":"string"},"restoredFromVersion":{"type":"integer","nullable":true,"minimum":0,"exclusiveMinimum":true},"createdAt":{"type":"string"},"createdBy":{"type":"object","nullable":true,"properties":{"id":{"type":"string"},"name":{"type":"string"},"image":{"type":"string","nullable":true}},"required":["id","name","image"]},"isCurrent":{"type":"boolean"}},"required":["version","name","source","restoredFromVersion","createdAt","createdBy","isCurrent"]},"ListDashboardVersionsResponse":{"type":"object","properties":{"currentVersion":{"type":"integer","minimum":0,"exclusiveMinimum":true},"versions":{"type":"array","items":{"$ref":"#/components/schemas/DashboardVersionMetadata"}},"nextCursor":{"type":"integer","nullable":true,"minimum":0,"exclusiveMinimum":true}},"required":["currentVersion","versions","nextCursor"]},"DashboardVersionDetailsResponse":{"allOf":[{"$ref":"#/components/schemas/DashboardVersionMetadata"},{"type":"object","properties":{"config":{"type":"object","additionalProperties":{"nullable":true}}},"required":["config"]}]},"CreateDashboardResponse":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"projectName":{"type":"string"},"isDefault":{"type":"boolean"},"currentVersion":{"type":"integer","minimum":0,"exclusiveMinimum":true},"sectionCount":{"type":"number"},"widgetCount":{"type":"number"},"createdAt":{"type":"string"},"updatedAt":{"type":"string"},"url":{"type":"string"}},"required":["id","name","projectName","isDefault","currentVersion","sectionCount","widgetCount","createdAt","updatedAt","url"]},"CreateDashboardRequest":{"type":"object","properties":{"projectName":{"type":"string","description":"Name of the project","example":"my-project"},"name":{"type":"string","minLength":1,"maxLength":255,"description":"Dashboard name","example":"Training Overview"},"config":{"type":"object","description":"Full dashboard config. Defaults to an empty dashboard when omitted."},"isDefault":{"type":"boolean","default":false,"description":"Make this the project's default dashboard (admins/owners only)"}},"required":["projectName","name"]},"UpdateDashboardResponse":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"projectName":{"type":"string"},"isDefault":{"type":"boolean"},"currentVersion":{"type":"integer","minimum":0,"exclusiveMinimum":true},"sectionCount":{"type":"number"},"widgetCount":{"type":"number"},"updatedAt":{"type":"string"},"url":{"type":"string"}},"required":["id","name","projectName","isDefault","currentVersion","sectionCount","widgetCount","updatedAt","url"]},"UpdateDashboardRequest":{"type":"object","properties":{"viewId":{"type":"string","description":"Dashboard view ID","example":"12"},"name":{"type":"string","minLength":1,"maxLength":255,"description":"New dashboard name"},"config":{"type":"object","description":"Replacement dashboard config (full replace, not a merge)"},"isDefault":{"type":"boolean","description":"Make this the project's default dashboard (admins/owners only)"},"expectedUpdatedAt":{"type":"string","format":"date-time","description":"Optimistic-concurrency guard. When set, the update is rejected with 409 if the dashboard changed after this timestamp."}},"required":["viewId"]},"RestoreDashboardVersionResponse":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"projectName":{"type":"string"},"isDefault":{"type":"boolean"},"currentVersion":{"type":"integer","minimum":0,"exclusiveMinimum":true},"restoredFromVersion":{"type":"integer","minimum":0,"exclusiveMinimum":true},"config":{"type":"object","additionalProperties":{"nullable":true}},"updatedAt":{"type":"string"},"url":{"type":"string"}},"required":["id","name","projectName","isDefault","currentVersion","restoredFromVersion","config","updatedAt","url"]},"RestoreDashboardVersionRequest":{"type":"object","properties":{"viewId":{"type":"string"},"version":{"type":"integer","minimum":0,"exclusiveMinimum":true},"expectedUpdatedAt":{"type":"string","format":"date-time","description":"Optimistic-concurrency guard from the current dashboard details response"}},"required":["viewId","version","expectedUpdatedAt"]}},"parameters":{}},"paths":{"/api/runs/create":{"post":{"tags":["Runs"],"summary":"Create a new run","description":"Creates a new run in the specified project. If the project doesn't exist, it will be created. If externalId is provided and a run with that ID already exists, the existing run is returned (Neptune-style resume for multi-node distributed training).","security":[{"bearerAuth":[]}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRunRequest"}}}},"responses":{"200":{"description":"Run created successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRunResponse"}}}},"400":{"description":"Organization is at limit","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/runs/resume":{"post":{"tags":["Runs"],"summary":"Resume an existing run","description":"Resumes an existing run, setting its status back to RUNNING. Returns the same response format as create. Use this when you want to log additional data (e.g., evaluation metrics) to a previously completed run. Provide exactly one of: runId (numeric), displayId (e.g., 'MMP-1'), or externalId (user-provided).","security":[{"bearerAuth":[]}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResumeRunRequest"}}}},"responses":{"200":{"description":"Run resumed successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResumeRunResponse"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Run not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Display ID is ambiguous across multiple projects; specify projectName","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/runs/status/update":{"post":{"tags":["Runs"],"summary":"Update run status","description":"Updates the status of an existing run (e.g., RUNNING, COMPLETED, FAILED).","security":[{"bearerAuth":[]}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateStatusRequest"}}}},"responses":{"200":{"description":"Status updated successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Success"}}}},"400":{"description":"Invalid JSON in request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Run not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/runs/status/history":{"get":{"tags":["Runs"],"summary":"Get run status transition history","description":"Returns the ordered list of status transition events for a run (oldest first). Includes implicit creation event, API-driven updates, resumes, and backend-driven stale/threshold transitions.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"number","nullable":true,"description":"Numeric run ID"},"required":false,"name":"runId","in":"query"}],"responses":{"200":{"description":"Status history","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RunStatusHistoryResponse"}}}},"404":{"description":"Run not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/runs/logName/add":{"post":{"tags":["Runs"],"summary":"Add log names to a run","description":"Adds new log names (metrics, console logs, etc.) to an existing run.","security":[{"bearerAuth":[]}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AddLogNameRequest"}}}},"responses":{"200":{"description":"Log names added successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Success"}}}},"404":{"description":"Run not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/runs/tags/update":{"post":{"tags":["Runs"],"summary":"Update run tags","description":"Replaces all tags on a run with the provided tags.","security":[{"bearerAuth":[]}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateTagsRequest"}}}},"responses":{"200":{"description":"Tags updated successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Success"}}}},"400":{"description":"Invalid tags (e.g. more than one group:* tag)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Run not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/runs/notes/update":{"post":{"tags":["Runs"],"summary":"Update run notes","description":"Updates the notes/description on a run. Set to null or empty string to clear.","security":[{"bearerAuth":[]}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateNotesRequest"}}}},"responses":{"200":{"description":"Notes updated successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Success"}}}},"404":{"description":"Run not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/runs/config/update":{"post":{"tags":["Runs"],"summary":"Update run config","description":"Merges new configuration with existing run config. New keys override existing keys.","security":[{"bearerAuth":[]}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateConfigRequest"}}}},"responses":{"200":{"description":"Config updated successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Success"}}}},"400":{"description":"Invalid config JSON","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Run not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/runs/list":{"get":{"tags":["Runs"],"summary":"List runs with optional search and tag filtering","description":"Lists runs in a project with optional search using ILIKE substring matching. Supports tag filtering with OR logic (returns runs with ANY of the specified tags).","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","description":"Project name. Required unless `konduktorJob` is provided (which scopes to the org instead).","example":"my-project"},"required":false,"name":"projectName","in":"query"},{"schema":{"type":"string","description":"Search term for run names (substring match)","example":"training"},"required":false,"name":"search","in":"query"},{"schema":{"type":"string","description":"Comma-separated list of tags to filter by (OR logic)","example":"baseline,experiment"},"required":false,"name":"tags","in":"query"},{"schema":{"type":"number","minimum":1,"maximum":200,"default":50,"description":"Maximum number of runs to return","example":50},"required":false,"name":"limit","in":"query"},{"schema":{"type":"string","description":"Anchored prefix match on systemMetadata.konduktor.job_name. Accepts a full Konduktor job ID or a YAML base name (Konduktor appends a 4-char random suffix per launch). When provided, projectName becomes optional (search scopes to the org).","example":"mcp-konduktor-e2e"},"required":false,"name":"konduktorJobPrefix","in":"query"},{"schema":{"type":"boolean","nullable":true,"default":false,"description":"When true, attach _flatConfig and _flatSystemMetadata to each run. Off by default for lean SDK responses.","example":false},"required":false,"name":"includeFieldValues","in":"query"},{"schema":{"type":"string","description":"JSON-encoded array of {source:'config'|'systemMetadata', key:string}. Restricts _flatConfig/_flatSystemMetadata to the listed keys. Empty array = no field values.","example":"[{\"source\":\"config\",\"key\":\"lr\"}]"},"required":false,"name":"visibleColumns","in":"query"},{"schema":{"type":"string","description":"JSON-encoded array of field-filter terms (see the FieldFilterTerm component for the structured shape and the full source/dataType/operator enums). Filters config.*/systemMetadata.* fields via the indexed run_field_values table; terms AND together. Operators (dataType-dependent): contains, does not contain, equals, is, is not, starts with, ends with, regex, is greater than/>, is less than/<, is greater than or equal to/>=, is less than or equal to/<=, is between, is not between, is before, is on or before, is after, is on or after, is any of, is none of, exists, not exists.","example":"[{\"source\":\"config\",\"key\":\"checkpoint.r2_prefix\",\"dataType\":\"text\",\"operator\":\"contains\",\"values\":[\"37a\"]}]"},"required":false,"name":"fieldFilters","in":"query"},{"schema":{"type":"string","description":"Sort field with optional '-' (desc) or '+' (asc) prefix. Built-in: createdAt, updatedAt, name, status (snake_case accepted). heartbeat_at: last time the run logged data (computed on-demand from ClickHouse MAX(time); runs that never logged are excluded from the ordering). Config/sysmeta: config.<key>.value / systemMetadata.<key>.value. Metric: summary_metrics.<name> (LAST value). Default: createdAt desc. Invalid/unknown field → 400. For config/metric/heartbeat sorts the candidate set is capped at 10000 runs.","example":"-config.lr.value"},"required":false,"name":"sort","in":"query"},{"schema":{"type":"number","nullable":true,"minimum":0,"maximum":100000,"description":"Number of runs to skip before returning results (offset pagination). Combine with `limit` to page through results; `total` reports the full match count.","example":0},"required":false,"name":"offset","in":"query"},{"schema":{"type":"string","description":"Comma-separated run statuses to filter by (OR within the list). One or more of: RUNNING, COMPLETED, FAILED, TERMINATED, CANCELLED. Invalid values → 400.","example":"RUNNING,FAILED"},"required":false,"name":"status","in":"query"},{"schema":{"type":"string","format":"date-time","description":"ISO-8601 timestamp; keep only runs whose last logged-data time (heartbeat) is at or after this. Requires projectName.","example":"2026-06-22T00:00:00Z"},"required":false,"name":"heartbeatAfter","in":"query"},{"schema":{"type":"string","format":"date-time","description":"ISO-8601 timestamp; keep only runs whose last logged-data time (heartbeat) is at or before this (i.e. stale). Requires projectName.","example":"2026-06-22T00:00:00Z"},"required":false,"name":"heartbeatBefore","in":"query"},{"schema":{"type":"string","description":"JSON-encoded wandb-style filter query. Supports $and/$or/$not and leaf operators (eq, $ne, $gt/$gte/$lt/$lte, $in/$nin, $regex) over: state/status, heartbeat_at, created_at/updated_at, name, tags, config.<key>, summaryMetrics.<key>.","example":"{\"$or\":[{\"state\":\"running\"},{\"heartbeat_at\":{\"$gte\":\"2026-06-22T00:00:00Z\"}}]}"},"required":false,"name":"filter","in":"query"}],"responses":{"200":{"description":"List of runs","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListRunsResponse"}}}},"400":{"description":"Bad request (e.g. missing both projectName and konduktorJobPrefix)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/runs/modelGraph/create":{"post":{"tags":["Runs"],"summary":"Create model graph","description":"Creates a model graph visualization for a run, including nodes and edges.","security":[{"bearerAuth":[]}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateModelGraphRequest"}}}},"responses":{"200":{"description":"Model graph created successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Success"}}}},"404":{"description":"Run not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/runs/auth/validate":{"get":{"tags":["Auth"],"summary":"Validate API key","description":"Validates the API key and returns organization information. Used by MCP clients to verify credentials.","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"API key is valid","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ValidateApiKeyResponse"}}}},"401":{"description":"Invalid API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/runs/details/{runId}":{"get":{"tags":["Runs"],"summary":"Get full run details","description":"Returns complete run information including config, metadata, tags, status, and available log names.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"number","nullable":true,"description":"Numeric run ID"},"required":false,"name":"runId","in":"path"}],"responses":{"200":{"description":"Run details","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RunDetailsResponse"}}}},"404":{"description":"Run not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/runs/details/by-display-id/{displayId}":{"get":{"tags":["Runs"],"summary":"Get run details by display ID","description":"Resolves a human-readable display ID (e.g., 'MMP-1') to a run and returns its details.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","description":"Display ID in PREFIX-NUMBER format (e.g., 'MMP-1')"},"required":true,"name":"displayId","in":"path"},{"schema":{"type":"string","description":"Name of the project the run belongs to. A display ID's prefix is derived from its project name, so distinct names (e.g. 'monitor_tests' and 'monitor-tests') can collapse to the same prefix and make the display ID ambiguous across projects. Provide this to resolve to the intended project; omit it only when the display ID is known to be unique."},"required":false,"name":"projectName","in":"query"}],"responses":{"200":{"description":"Run details","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RunDetailsByDisplayIdResponse"}}}},"400":{"description":"Invalid display ID format","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Run not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Display ID is ambiguous across multiple projects; specify projectName","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/runs/logs":{"get":{"tags":["Runs"],"summary":"Query console logs from a run","description":"Returns console logs (stdout/stderr) from ClickHouse. Supports filtering by log type and pagination.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"number","nullable":true,"description":"Numeric run ID"},"required":false,"name":"runId","in":"query"},{"schema":{"type":"string","description":"Project name"},"required":true,"name":"projectName","in":"query"},{"schema":{"type":"string","enum":["INFO","ERROR","WARNING","DEBUG","PRINT"],"description":"Filter by log type"},"required":false,"name":"logType","in":"query"},{"schema":{"type":"number","minimum":1,"maximum":10000,"default":1000,"description":"Maximum lines to return"},"required":false,"name":"limit","in":"query"},{"schema":{"type":"number","nullable":true,"minimum":0,"default":0,"description":"Number of lines to skip"},"required":false,"name":"offset","in":"query"}],"responses":{"200":{"description":"Console logs","content":{"application/json":{"schema":{"$ref":"#/components/schemas/QueryLogsResponse"}}}}}}},"/api/runs/metrics":{"get":{"tags":["Runs"],"summary":"Query metrics from a run","description":"Returns time-series metrics from ClickHouse. Supports filtering by metric name, group, and step range. Uses reservoir sampling to limit data points.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"number","nullable":true,"description":"Numeric run ID"},"required":false,"name":"runId","in":"query"},{"schema":{"type":"string","description":"Project name"},"required":true,"name":"projectName","in":"query"},{"schema":{"type":"string","description":"Filter by metric name (e.g., train/loss)"},"required":false,"name":"logName","in":"query"},{"schema":{"type":"string","description":"Filter by metric group (e.g., train)"},"required":false,"name":"logGroup","in":"query"},{"schema":{"type":"number","minimum":1,"maximum":10000,"default":2000,"description":"Maximum data points to return"},"required":false,"name":"limit","in":"query"},{"schema":{"type":"integer","nullable":true,"minimum":0,"description":"Minimum step number (inclusive). Use with stepMax to query a specific range of steps."},"required":false,"name":"stepMin","in":"query"},{"schema":{"type":"integer","nullable":true,"minimum":0,"description":"Maximum step number (inclusive). Use with stepMin to query a specific range of steps."},"required":false,"name":"stepMax","in":"query"}],"responses":{"200":{"description":"Metrics data","content":{"application/json":{"schema":{"$ref":"#/components/schemas/QueryMetricsResponse"}}}}}}},"/api/runs/metrics/raw":{"get":{"tags":["Runs"],"summary":"Query raw (un-deduped) metric writes from a run","description":"Returns every row written to ClickHouse for the given (run, metric), including duplicates from resumes/re-logs, with the original write `time`. Reads from the un-deduped `mlop_metrics` table — no FINAL, no reservoir sampling. Each row carries a `nonFiniteFlags` bitmask (bit0=NaN, bit1=+Inf, bit2=-Inf); when a flag is set, `value` is `0` and the flag is the source of truth. Use `/metrics` for analysis or chart rendering — this endpoint is for audit and cleanup.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"number","nullable":true,"description":"Numeric run ID"},"required":false,"name":"runId","in":"query"},{"schema":{"type":"string","description":"Project name"},"required":true,"name":"projectName","in":"query"},{"schema":{"type":"string","description":"Metric name (e.g., train/loss). Required — scoping every raw scan to a single metric keeps payloads bounded."},"required":true,"name":"logName","in":"query"},{"schema":{"type":"integer","nullable":true,"minimum":0,"description":"Minimum step number (inclusive)."},"required":false,"name":"stepMin","in":"query"},{"schema":{"type":"integer","nullable":true,"minimum":0,"description":"Maximum step number (inclusive)."},"required":false,"name":"stepMax","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":50000,"default":50000,"description":"Maximum rows to return (default and max: 50000). Page by narrowing stepMin/stepMax when more is needed."},"required":false,"name":"limit","in":"query"}],"responses":{"200":{"description":"Raw metric rows","content":{"application/json":{"schema":{"$ref":"#/components/schemas/QueryRawMetricsResponse"}}}}}}},"/api/runs/files":{"get":{"tags":["Runs"],"summary":"Get files and artifacts from a run","description":"Returns file metadata with presigned URLs for downloading. URLs are valid for 5 days.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"number","nullable":true,"description":"Numeric run ID"},"required":false,"name":"runId","in":"query"},{"schema":{"type":"string","description":"Project name"},"required":true,"name":"projectName","in":"query"},{"schema":{"type":"string","description":"Filter by log name"},"required":false,"name":"logName","in":"query"},{"schema":{"type":"string","description":"Filter by log group"},"required":false,"name":"logGroup","in":"query"}],"responses":{"200":{"description":"Files with presigned URLs","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetFilesResponse"}}}}}}},"/api/runs/projects":{"get":{"tags":["Projects"],"summary":"List all projects","description":"Returns all projects in the organization associated with the API key.","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"List of projects","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListProjectsResponse"}}}}}}},"/api/runs/statistics":{"get":{"tags":["Runs"],"summary":"Get statistics for a run's metrics","description":"Returns per-metric aggregates (count, min, max, mean, stddev, last) read from the pre-computed summaries table. Raw, no editorializing — interpretation is the caller's job.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"number","nullable":true,"description":"Numeric run ID"},"required":false,"name":"runId","in":"query"},{"schema":{"type":"string","description":"Project name"},"required":true,"name":"projectName","in":"query"},{"schema":{"type":"string","description":"Filter by specific metric name (e.g., train/loss)"},"required":false,"name":"logName","in":"query"},{"schema":{"type":"string","description":"Filter by metric group (e.g., train)"},"required":false,"name":"logGroup","in":"query"}],"responses":{"200":{"description":"Statistics for metrics","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GetStatisticsResponse"}}}},"404":{"description":"Run not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/runs/compare":{"get":{"tags":["Runs"],"summary":"Compare metrics across multiple runs","description":"Returns per-run aggregates (count, min, max, mean, final) for a single metric across multiple runs, read from the pre-computed summaries table. Raw, no editorializing — interpretation is the caller's job.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","description":"Comma-separated list of run IDs to compare (e.g., '1,2,5')"},"required":true,"name":"runIds","in":"query"},{"schema":{"type":"string","description":"Project name"},"required":true,"name":"projectName","in":"query"},{"schema":{"type":"string","description":"Metric name to compare (e.g., 'train/loss')"},"required":true,"name":"logName","in":"query"}],"responses":{"200":{"description":"Comparison results","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompareRunsResponse"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/runs/metric-names":{"get":{"tags":["Runs"],"summary":"List distinct metric names in a project","description":"Returns distinct metric names from the pre-computed metric summaries table. Useful for discovering available metrics before querying leaderboard or statistics. Optionally filter by a search substring or specific run IDs.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","description":"Project name"},"required":true,"name":"projectName","in":"query"},{"schema":{"type":"string","description":"Substring search to filter metric names (e.g., 'loss')"},"required":false,"name":"search","in":"query"},{"schema":{"type":"string","description":"Comma-separated run IDs to scope the search (e.g., '1,2,5')"},"required":false,"name":"runIds","in":"query"},{"schema":{"type":"number","nullable":true,"default":500,"description":"Maximum number of metric names to return (default: 500)"},"required":false,"name":"limit","in":"query"}],"responses":{"200":{"description":"List of distinct metric names","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListMetricNamesResponse"}}}}}}},"/api/runs/leaderboard":{"get":{"tags":["Runs"],"summary":"Rank runs by a metric","description":"Returns runs ranked by a metric aggregation (MIN, MAX, AVG, LAST, VARIANCE) using pre-computed metric summaries. Much faster than comparing individual runs. Useful for finding the best runs in a project by loss, accuracy, or any other metric.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","description":"Project name"},"required":true,"name":"projectName","in":"query"},{"schema":{"type":"string","description":"Metric name to rank by (e.g., 'train/loss', 'eval/accuracy')"},"required":true,"name":"logName","in":"query"},{"schema":{"type":"string","enum":["MIN","MAX","AVG","LAST","VARIANCE"],"default":"LAST","description":"Aggregation type: MIN, MAX, AVG, LAST, VARIANCE (default: LAST)"},"required":false,"name":"aggregation","in":"query"},{"schema":{"type":"string","enum":["ASC","DESC"],"default":"ASC","description":"Sort direction: ASC (lowest first) or DESC (highest first). Default: ASC"},"required":false,"name":"direction","in":"query"},{"schema":{"type":"number","nullable":true,"default":20,"description":"Number of runs to return (default: 20, max: 100)"},"required":false,"name":"limit","in":"query"},{"schema":{"type":"number","nullable":true,"default":0,"description":"Offset for pagination (default: 0)"},"required":false,"name":"offset","in":"query"}],"responses":{"200":{"description":"Ranked list of runs with metric values","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LeaderboardResponse"}}}}}}},"/api/runs/{runId}":{"get":{"tags":["Runs"],"summary":"Get run by ID","description":"Decodes a SQID-encoded run ID and returns the numeric ID.","parameters":[{"schema":{"type":"string","description":"SQID-encoded run ID"},"required":true,"name":"runId","in":"path"}],"responses":{"200":{"description":"Run ID decoded successfully","content":{"application/json":{"schema":{"type":"object","properties":{"runId":{"type":"number","description":"Numeric run ID"}},"required":["runId"]}}}}}}},"/api/dashboards/list":{"get":{"tags":["Dashboards"],"summary":"List dashboards for a project","description":"Returns dashboard views for a project with per-section summaries but WITHOUT the full widget config. Use /details/{viewId} to fetch a complete config.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","description":"Name of the project","example":"my-project"},"required":true,"name":"projectName","in":"query"}],"responses":{"200":{"description":"Dashboards listed successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListDashboardsResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Project not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/dashboards/details/{viewId}":{"get":{"tags":["Dashboards"],"summary":"Get a dashboard with its full config","description":"Returns a single dashboard view including the complete section/widget configuration.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","description":"Dashboard view ID","example":"12"},"required":true,"name":"viewId","in":"path"}],"responses":{"200":{"description":"Dashboard fetched successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DashboardDetailsResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Dashboard not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Stored config failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/dashboards/details/{viewId}/versions":{"get":{"tags":["Dashboards"],"summary":"List immutable dashboard versions","description":"Returns newest-first version metadata without the full dashboard config.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string"},"required":true,"name":"viewId","in":"path"},{"schema":{"type":"integer","minimum":1,"maximum":100,"default":50},"required":false,"name":"limit","in":"query"},{"schema":{"type":"integer","minimum":0,"exclusiveMinimum":true},"required":false,"name":"beforeVersion","in":"query"}],"responses":{"200":{"description":"Dashboard versions listed successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListDashboardVersionsResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Dashboard not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/dashboards/details/{viewId}/versions/{version}":{"get":{"tags":["Dashboards"],"summary":"Get an immutable dashboard version","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string"},"required":true,"name":"viewId","in":"path"},{"schema":{"type":"integer","minimum":0,"exclusiveMinimum":true},"required":true,"name":"version","in":"path"}],"responses":{"200":{"description":"Dashboard version fetched successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DashboardVersionDetailsResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Dashboard or version not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Stored config failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/dashboards/create":{"post":{"tags":["Dashboards"],"summary":"Create a dashboard","description":"Creates a new dashboard view in a project. Names are unique per project. Only org admins/owners may set isDefault.","security":[{"bearerAuth":[]}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDashboardRequest"}}}},"responses":{"200":{"description":"Dashboard created successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDashboardResponse"}}}},"400":{"description":"Invalid request body or dashboard config","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Project not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"A dashboard with this name already exists","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/dashboards/update":{"post":{"tags":["Dashboards"],"summary":"Update a dashboard","description":"Updates a dashboard's name, config, and/or default flag. Only the creator or an org admin/owner may modify a dashboard. A provided config REPLACES the stored one.","security":[{"bearerAuth":[]}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateDashboardRequest"}}}},"responses":{"200":{"description":"Dashboard updated successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateDashboardResponse"}}}},"400":{"description":"Invalid request body or dashboard config","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Dashboard not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Name conflict, or the dashboard changed since expectedUpdatedAt","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Stored config failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/dashboards/restore":{"post":{"tags":["Dashboards"],"summary":"Restore a historical dashboard version","description":"Copies a historical name/config snapshot into the dashboard and appends a new immutable head version.","security":[{"bearerAuth":[]}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RestoreDashboardVersionRequest"}}}},"responses":{"200":{"description":"Dashboard version restored as a new current version","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RestoreDashboardVersionResponse"}}}},"400":{"description":"The selected version is already current","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Dashboard or version not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Name conflict or stale expectedUpdatedAt","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Stored version config failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}}}