Skip to main content
All notable API changes will be documented in this file. The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.

[Unreleased] - 2026-03-06

Added

  • workloadMetadata on POST /api/v1/tracesets/upload-url: TracesetUploadUrlRequest now documents workloadMetadata, which the endpoint already accepted. It is stored on the traceset as given, up to 65,536 bytes when serialized, and must be a JSON object. It declares the traceset’s rank count, either as shape.rankCount or as parallelism degrees (dp, tp, sp, ep, pp, multiplied together, with an absent degree counting as 1); the traceset reports that count as rankCountDerived, and attaching it to a configuration uses it. The Python client’s TracesetUploadUrlRequest gains workload_metadata, and central-cli traceset upload gains --workload-metadata <PATH>, a JSON file that the command requires.
  • Simple simulation endpoint: POST /api/v1/simple/simulations — submit a collective-operation workload (AllReduce, Broadcast, etc.) with a single request. The platform handles topology derivation, traceset synthesis, and simulation launch automatically.
  • Topology constraints: topologyConstraints object on SimpleSimulationRequest with switchRadix (enum: 64x800G, 128x400G, 256x200G) and subscriptionRatio (enum: 1:1, 2:1, 3:1, 4:1). Enables arbitrary rank counts by deriving a valid 2-tier CLOS topology from hardware constraints.
  • Chakra mapping files: a mapping-file resource that pins each Chakra logical rank to a server, and optionally declares scale-up groups and their fabric parameters. Upload a file once, attach it to a simulation configuration, and every simulation created from that configuration is launched with it. Without one, placement is unchanged: rank i runs on the i-th Chakra-capable server. A simulation with a mapping file runs to completion on a traceset you upload. A simulation on one of the platform’s own Chakra tracesets fails before the simulator starts until an update to the platform’s simulation hosts is in service. The platform does not generate mapping files: you write or generate the file and upload it, and Scala provides a mapping file toolkit, a generator script with sample configs, on request (see Generate a mapping file in Chakra Mapping Files). A mapping file attaches behind an uploaded traceset only when that traceset has a rank count, which it reports as rankCountDerived. For a new upload that rank count is the one its workload metadata declares, as shape.rankCount or as parallelism degrees (dp, tp, sp, ep, pp). Behind a traceset with no rank count, the mapping-file attach, like the traceset attach, answers 422 UNPROCESSABLE_ENTITY, which retrying does not change (see Current limitations in Chakra Mapping Files). Eight new operations, all tagged mapping-files: The stored file is the simulator’s own text format, byte for byte, with a 64 MB per-file limit and no per-workspace quota. MappingFileSummary carries id, name, workspaceId, sizeBytes, rankCount, scaleUpGroupCount, hasScaleUp and createdAt; MappingFileDetails adds description, hash, etag and duplicateOfExisting. New error.code values: MAPPING_FILE_INVALID, MAPPING_FILE_HASH_COLLISION, MAPPING_FILE_DELETED, MAPPING_REQUIRES_TRACESET, MAPPING_REQUIRES_CHAKRA_APP, MAPPING_RANK_COUNT_MISMATCH, MAPPING_PARAMS_LOCKED, TRACESET_CONFLICTS_WITH_MAPPING and MAPPING_FILE_DELETED_REFERENCE, plus MAPPING_FILE_MISSING and MAPPING_PARAMS_INCONSISTENT on 500 platform faults. See Chakra Mapping Files for the file format and the full flow.
  • activeMappingFile on ConfigurationDetails: names the attached mapping file as { "id", "name", "deleted" }, or is null. deleted is resolved when the configuration is read, so a configuration that still refers to a deleted file reports it as deleted. Only attach and detach set it: a configuration update whose body carries activeMappingFile returns 400. Attach requires at least one Chakra application (422 MAPPING_REQUIRES_CHAKRA_APP), an attached traceset (409 MAPPING_REQUIRES_TRACESET) that has a rank count (422 UNPROCESSABLE_ENTITY otherwise, not resolved by retrying), a mapping file in the configuration’s workspace that has not been deleted (404 otherwise), and equal rank counts (422 MAPPING_RANK_COUNT_MISMATCH, naming both counts). While a file is attached, a configuration update, an application-parameter update or an application create that would change UseMapping or MappingFileName returns 422 MAPPING_PARAMS_LOCKED, and a traceset with a different rank count returns 409 TRACESET_CONFLICTS_WITH_MAPPING on traceset attach and on configuration update.
  • appliedMappingFile on SimulationDetails: names the mapping file the simulation was created with, as { "id", "name", "deleted" }, and is absent for a configuration with no mapping file. It keeps naming the file after a delete, with deleted reading true; deleting a mapping file never changes a simulation already created. POST /api/v1/simulations from a configuration whose attached mapping file has been deleted returns 409 MAPPING_FILE_DELETED_REFERENCE, naming the file. A mapped run never falls back to in-order placement: a file that cannot be delivered to the simulator fails the simulation. When the platform rejects the file while staging it, the failureReason reads Mapping file <name> (<id>) could not be delivered, with a long <name> possibly shortened to end in … and the id always in full; a failure not attributed to the mapping file reports a general failure reason.

Fixed

  • Simulation results endpoints: Removed non-functional workspace ownership check that blocked all users from accessing results. DefaultWorkspace.owner = 'system' caused verify_workspace_access to reject every real user. Endpoints now correctly return results for any authenticated user. Affected: GET /simulations/{id}/results, GET /simulations/{id}/results/download-url, GET /simulations/{id}/results/data.

Changed

  • BREAKING for generated clients: SimulationResults, the GET /api/v1/simulations/{sim_id}/results response, no longer declares summary or dashboardUrl. The endpoint never returned either, so responses are unchanged. A client regenerated from this spec no longer has the two fields; to migrate, delete reads of them, which always found them absent. ResultsSummary leaves the published spec, because no operation refers to it.
  • Upload’s workloadMetadata documents its rank-count members: TracesetUploadUrlRequest.workloadMetadata now refers to UploadWorkloadMetadata, which describes shape.rankCount and the parallelism degrees dp, tp, sp, ep and pp through WorkloadShape and WorkloadParallelism. Every member is optional, and other members are still accepted and returned as given. This is a documentation change: requests and responses are unchanged, and upload validates only the rank-count members it already validated. WorkloadMetadata, the stored object on responses, stays a free-form object. TracesetResponse.workloadMetadata no longer says it is present only after promotion: it returns the metadata given at upload, or at the traceset’s latest applied promotion that carried metadata. A new Workload Metadata page describes the rank-count rules and the descriptive members.
  • Upload part URLs carry their size and real expiry: POST /api/v1/tracesets/upload-url and POST /api/v1/mapping-files/upload-url presign each part URL for one hour (was 15 minutes). PartUploadUrl gains size, the number of bytes to PUT for that part; every part but the last is the server’s part size, and a mapping file’s part may be shorter, since its sizeBytes is an upper bound. The part URLs’ expiry is now reported as partUrlsExpireAt, on each FileUploadUrls entry and on MappingFileUploadUrlResponse. expiresAt is unchanged: it is the 24-hour upload session lifetime, which it always was, not the URLs’ expiry. A URL can stop working before partUrlsExpireAt if the platform’s signing credentials expire first. central-cli traceset upload now uploads files over 2 MiB whole: it sent at most 2 MiB per part.
  • BREAKING: GET /api/v1/models reports the Pod and Rack topology container models as type: "pod" and type: "rack". They were reported as "switch". ModelType gains rack and pod, the values GET /api/v1/models/{model_id} already reports for these models, and type=rack and type=pod become valid filters on the list (the server already accepted them). A client generated from an earlier spec with a closed ModelType enum fails to parse a list response that contains these models; to migrate, regenerate or upgrade the client.
  • BREAKING: POST /api/v1/tracesets/upload-url requires an upload with primary files to declare its rank count in workloadMetadata, as shape.rankCount or as parallelism degrees (dp, tp, sp, ep, pp). Without one it returns 400 VALIDATION_ERROR naming both forms, before any upload URL is issued. It also returns 400 for a declaration it cannot accept, naming the field: a shape.rankCount or degree that is not a whole number of at least 1, a shape.rankCount that differs from the parallelism product (naming both), a count above 2,147,483,647, or a workloadMetadata, shape or parallelism that is neither an object nor null. An upload of supporting files only needs no declaration. To migrate: add workloadMetadata declaring the rank count to every upload of trace files; with central-cli, pass --workload-metadata <PATH>.
  • POST /api/v1/tracesets/upload-url/complete reports the traceset ready for every completed upload, including one with new files, which previously reported processing. Every file of the upload reports metadataStatus complete. A traceset uploaded with exactly one primary file that declares N ranks reports that file’s rankRange as 0 to N−1.
  • Traceset promotion (the Python client’s promote_traceset) returns 422 UNPROCESSABLE_ENTITY when the new workloadMetadata would change the rank count the traceset declared at upload, naming both counts. A declared rank count cannot be changed after upload: for a traceset that carries one, the new workloadMetadata must declare the same count, and metadata that declares none differs from it.
  • BREAKING: min and max in a component schema (ParameterValueSchema, returned by GET /api/v1/components/{id}) are now ParameterBound objects instead of numbers. A numeric type’s bound is {"value": 1}. A dimensional type’s (datarate, timeval, bytes, queuesize) bound carries its unit, such as {"value": 10, "unit": "us"}, which can differ from the unit of the parameter’s value. A dimensional bound of 0 is {"value": 0} with no unit. A model’s bound that the platform cannot read is left out of the schema. To migrate: read min.value and min.unit where you read min.
  • BREAKING: GET /api/v1/simulations now accepts only a single field:direction pair in sort (for example created_at:desc). A compound sort such as status:asc,created_at:desc returns 400; it previously returned 200 but could not be paginated correctly past the first page. A next cursor replayed with a different sort than the one that produced it also returns 400 instead of a wrong page. To migrate: send one sort field, and when you change sort, restart pagination without next.
  • Presigned URL expiry reduced: Simulation result download URLs (GET /simulations/{id}/results and GET /simulations/{id}/results/download-url) now expire after 15 minutes (900 s) instead of the previous 60 minutes (3600 s). This is a defense-in-depth hardening to limit exposure if a URL leaks. Clients that fetch a presigned URL and consume it after a delay greater than 15 minutes will receive an HTTP 403 from S3. The expiresAt field in the download-url response reflects the actual expiry. No known consumers cache presigned URLs beyond this window.
  • BREAKING: SimpleWorkload.ranks changed from integer enum ([64, 128, 256, 512, 1024, 4096]) to integer with minimum: 1. Without topologyConstraints, the server still restricts to the 6 reference values. With topologyConstraints, any positive value satisfying the constraint solver is accepted.
  • BREAKING: TracesetFile renamed to FileResponse in the Python client. Adds required field metadata_status. Update imports: from python_client.models import FileResponse (was TracesetFile).
  • BREAKING: ContainerDefinition.type_ and AllowedTypesResponse.container_type now use ContainerType instead of ComponentType in the Python client. Both are str enums with identical string values, so equality comparisons by value still work. Update isinstance checks if used.
  • BREAKING: DlrmMetadata, TraceMetadata, and TraceMetadataWorkloadType removed from the Python client. These types are no longer part of the API surface. Remove any imports that reference them.
  • Traceset listing scope widened: GET /api/v1/tracesets?workspaceId=X now returns all non-deleted tracesets visible to the workspace, including promoted tracesets with scope tenant or public. Previously, only workspace-scoped tracesets were returned. This ensures promoted tracesets remain visible after promotion.
  • TrafficType output consolidation: API responses now return "chakra" where "coordinated" was previously emitted for the trafficType field. Input is backward-compatible: both "chakra" and "coordinated" are accepted via serde alias. This reflects the A5 schema migration consolidating Coordinated into Chakra.
  • BREAKING: PATCH /api/v1/configurations/{config_id}/traceset now requires the traceset to have a positive rank count before attaching. The endpoint previously accepted any valid traceset regardless of library state; it now enforces that the rank count is present and positive (required to populate NumOfChakraFiles in the Chakra workload model). Two new error responses are returned when the traceset’s rank count is missing or invalid: Migration: Both responses are permanent for that traceset and do not resolve on retry. This endpoint first answered a traceset with no rank count with a retry-safe 409 Conflict; see the next entry.
  • BREAKING: a traceset with no rank count is now answered 422 Unprocessable Entity (UNPROCESSABLE_ENTITY) in place of the retry-safe 409 Conflict (CONFLICT), by PATCH /api/v1/configurations/{config_id}/traceset, by PATCH /api/v1/configurations/{config_id}/mapping-file, and by PATCH /api/v1/configurations/{config_id} when a mapping file is attached and the body carries activeTraceset. The 409 said to retry after metadata extraction completed, but a traceset you upload never gained a rank count that way, so the retry never succeeded. The 422 names the traceset and does not resolve on retry. Migration: Stop retrying the request on this response. A client that retries on 409 CONFLICT for these operations should treat the 422 as permanent for that traceset.

[Previous Unreleased] - 2024-12-23

Changed

  • BREAKING: Pagination.limit renamed to Pagination.count in API responses
    • Affected: All paginated list endpoints
    • Before: {"limit": 10, "hasMore": true, "cursor": "..."}
    • After: {"count": 10, "hasMore": true, "cursor": "..."}
    • Semantic change: count represents the actual number of items returned (may be less than requested limit)
    • Note: Query parameter ?limit=N remains unchanged; only the response field name changed
    • Migration: Update client code to read count instead of limit from pagination responses
  • BREAKING: ParameterDefinition.default type changed from JSON value to string
    • Affected: GET /api/v1/models/{id}, GET /api/v1/components/{id}
    • Before: {"default": 100} or {"default": true}
    • After: {"default": "100"} or {"default": "true"}
    • Migration: Parse the string value according to the parameter’s type field
  • BREAKING: ComponentDeclaration.model format changed to use standardized model reference
    • Affected: GET /api/v1/templates/{id}, GET /api/v1/configurations/{id}, GET /api/v1/configurations/{id}/versions/{v}, POST /api/v1/templates/{id}/clone
    • Before: {"model": "ScalaSwitch:3.2.1", "name": "spine-1"} (model in internal format, name user-defined)
    • After: {"model": "scala-switch-v3.2.1", "name": "spine-1"} (model standardized to API format, name remains user-manageable)
    • Format: Model field is standardized to API format (scala-switch-v{version})
    • Name field: Remains user-manageable and unchanged from input
    • Benefit: Model field can be parsed to extract model reference for use with GET /api/v1/models/{model_id}
    • Migration: Update any code that parses or displays component model fields
  • BREAKING: Only referenced components are returned in configuration responses
    • Affected: GET /api/v1/templates/{id}, GET /api/v1/configurations/{id}, POST /api/v1/templates/{id}/clone
    • Before: All components declared in the configuration were returned, including unused ones
    • After: Only components referenced in topology.components, topology.containers, or containers[].components are returned
    • Rationale: Reduces response size and focuses on components actually used in the topology
    • Migration: If your code relies on seeing all declared components, use the stored configuration data directly
  • Template cloning preserves original data format
    • Affected: POST /api/v1/templates/{id}/clone
    • Change: Cloned configurations now preserve the original template’s data format (legacy or new format)
    • Before: Template data was transformed to new format during cloning
    • After: Template data format is preserved, only metadata fields (version, workspaceId, name, status, parent_config_id) are updated
    • Benefit: Maintains compatibility with existing templates and allows format-specific handling

Removed

  • BREAKING: Removed fields from ParameterDefinition:
    • componentType - was used for nested component type references
    • model - was used for model references within parameters
    • parameters - was used for nested parameter definitions
    • Migration: These fields were not widely used. If you relied on nested parameter structures, contact the API team for migration guidance.

Added

  • Model Metadata Enrichment: Templates API now fetches model metadata from model_version
    • Affected: GET /api/v1/templates/{id}
    • Components are enriched with parameter schemas and type information from the database
    • When a component references a model (e.g., ScalaSwitch:4.0.0), the API looks up the model in model_version and includes the full parameter schema
    • Benefit: Clients receive complete model metadata without needing separate API calls to /api/v1/models/{model_id}
  • Parameter Extraction: Extended parameter extraction to include coordinator-level parameters
    • Application models now expose parameters from Coordinators, ModelProfiles, and TrafficPattern sections
    • Parameters include group information (e.g., Delay.CoordinatorAttributes)