> For the complete documentation index, see [llms.txt](https://docs.m-xr.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.m-xr.com/marso-studio-api/models.md).

# Models

## The EpochMillis object

```json
{"openapi":"3.1.0","info":{"title":"Marso Studio API","version":"0.0.1"},"components":{"schemas":{"EpochMillis":{"type":"integer","format":"int64","description":"Time represented as milliseconds since the Unix epoch.\n"}}}}
```

## The NullableEpochMillis object

```json
{"openapi":"3.1.0","info":{"title":"Marso Studio API","version":"0.0.1"},"components":{"schemas":{"NullableEpochMillis":{"type":["integer","null"],"format":"int64","description":"Time represented as milliseconds since the Unix epoch, or `null` when the\nfield has not been set.\n"}}}}
```

## The SubscriptionPlanCode object

```json
{"openapi":"3.1.0","info":{"title":"Marso Studio API","version":"0.0.1"},"components":{"schemas":{"SubscriptionPlanCode":{"type":"string","pattern":"^plan_[A-Za-z0-9]{7,64}$","description":"Opaque and immutable code for a subscription plan. Use the plan\ncatalogue for its current display name. The code must start with\n`plan_`, followed by 7 to 64 ASCII letters or digits.\n"}}}}
```

## The SubscriptionPlanClass object

```json
{"openapi":"3.1.0","info":{"title":"Marso Studio API","version":"0.0.1"},"components":{"schemas":{"SubscriptionPlanClass":{"type":"string","description":"Stable class of a subscription plan.\n\nPossible enum values:\n- `free`: the Free plan class.\n- `creator`: the Creator plan class.\n- `artist_pro`: the Artist Pro plan class.\n- `studio`: the Studio plan class.\n- `enterprise`: the Enterprise plan class.\n","enum":["free","creator","artist_pro","studio","enterprise"]}}}}
```

## The SubscriptionFeature object

```json
{"openapi":"3.1.0","info":{"title":"Marso Studio API","version":"0.0.1"},"components":{"schemas":{"SubscriptionFeature":{"type":"string","description":"Product capability available to the account.\n\nPossible enum values:\n- `commercial_license`: commercial-use rights.\n- `api_pbr`: PBR generation through the Public Platform API.\n- `api_asset_download`: asset downloads through the Public Platform API.\n- `custom_polycount`: custom polygon counts for 3D generation.\n- `image_edit`: image editing.\n- `multiview`: multiview generation.\n","enum":["commercial_license","api_pbr","api_asset_download","custom_polycount","image_edit","multiview"]}}}}
```

## The PlanFeatureRequiredErrorDetails object

```json
{"openapi":"3.1.0","info":{"title":"Marso Studio API","version":"0.0.1"},"components":{"schemas":{"PlanFeatureRequiredErrorDetails":{"type":"object","required":["feature","upgrade_plan_codes"],"description":"The missing feature and the active plans that provide it.","properties":{"feature":{"$ref":"#/components/schemas/SubscriptionFeature"},"upgrade_plan_codes":{"type":"array","description":"Active plans available for purchase that provide the missing\nfeature. The array uses plan class and opaque code order.\n","items":{"$ref":"#/components/schemas/SubscriptionPlanCode"}}}},"SubscriptionFeature":{"type":"string","description":"Product capability available to the account.\n\nPossible enum values:\n- `commercial_license`: commercial-use rights.\n- `api_pbr`: PBR generation through the Public Platform API.\n- `api_asset_download`: asset downloads through the Public Platform API.\n- `custom_polycount`: custom polygon counts for 3D generation.\n- `image_edit`: image editing.\n- `multiview`: multiview generation.\n","enum":["commercial_license","api_pbr","api_asset_download","custom_polycount","image_edit","multiview"]},"SubscriptionPlanCode":{"type":"string","pattern":"^plan_[A-Za-z0-9]{7,64}$","description":"Opaque and immutable code for a subscription plan. Use the plan\ncatalogue for its current display name. The code must start with\n`plan_`, followed by 7 to 64 ASCII letters or digits.\n"}}}}
```

## The PlanFeatureRequiredError object

```json
{"openapi":"3.1.0","info":{"title":"Marso Studio API","version":"0.0.1"},"components":{"schemas":{"PlanFeatureRequiredError":{"type":"object","required":["error"],"description":"The error envelope for a missing subscription feature.","properties":{"error":{"type":"object","required":["code","message","details"],"description":"The missing-feature error body.","properties":{"code":{"type":"string","const":"PLAN_FEATURE_REQUIRED","description":"Stable error code for a missing subscription feature."},"message":{"type":"string","description":"Human-readable description of the error."},"details":{"$ref":"#/components/schemas/PlanFeatureRequiredErrorDetails"}}}}},"PlanFeatureRequiredErrorDetails":{"type":"object","required":["feature","upgrade_plan_codes"],"description":"The missing feature and the active plans that provide it.","properties":{"feature":{"$ref":"#/components/schemas/SubscriptionFeature"},"upgrade_plan_codes":{"type":"array","description":"Active plans available for purchase that provide the missing\nfeature. The array uses plan class and opaque code order.\n","items":{"$ref":"#/components/schemas/SubscriptionPlanCode"}}}},"SubscriptionFeature":{"type":"string","description":"Product capability available to the account.\n\nPossible enum values:\n- `commercial_license`: commercial-use rights.\n- `api_pbr`: PBR generation through the Public Platform API.\n- `api_asset_download`: asset downloads through the Public Platform API.\n- `custom_polycount`: custom polygon counts for 3D generation.\n- `image_edit`: image editing.\n- `multiview`: multiview generation.\n","enum":["commercial_license","api_pbr","api_asset_download","custom_polycount","image_edit","multiview"]},"SubscriptionPlanCode":{"type":"string","pattern":"^plan_[A-Za-z0-9]{7,64}$","description":"Opaque and immutable code for a subscription plan. Use the plan\ncatalogue for its current display name. The code must start with\n`plan_`, followed by 7 to 64 ASCII letters or digits.\n"}}}}
```

## The ErrorCode object

```json
{"openapi":"3.1.0","info":{"title":"Marso Studio API","version":"0.0.1"},"components":{"schemas":{"ErrorCode":{"type":"string","description":"Machine-readable error code. The enum enumerates every code that can be\nreturned by this API, including infrastructure-level 5xx codes, so\ngenerated clients can decode any `error.code` they receive.\n\nPossible enum values:\n- `INVALID_REQUEST`: the request body or a query parameter failed validation.\n- `MALFORMED_UUID`: a path parameter that should be a UUID is not one.\n- `UNAUTHORIZED`: the request could not be authenticated.\n- `API_KEY_MISSING`: no API key was supplied.\n- `API_KEY_INVALID`: the supplied API key does not match any known key.\n- `API_KEY_REVOKED`: the supplied API key has been revoked.\n- `PLAN_FEATURE_REQUIRED`: the account plan does not include a required feature.\n- `INSUFFICIENT_CREDITS`: the account does not have enough credits for this request.\n- `QUOTA_EXCEEDED`: a usage quota for the account has been exceeded.\n- `FILE_TOO_LARGE`: an uploaded or referenced file exceeds the allowed size.\n- `INVALID_CONTENT_TYPE`: a file's content type does not match its declared or expected type.\n- `UNSUPPORTED_ASSET_FORMAT`: a file's extension is not one of the supported asset formats.\n- `FORMAT_NOT_AVAILABLE`: the requested downloadable format does not exist for this asset.\n- `ASSET_NOT_FOUND`: the asset does not exist or does not belong to the account.\n- `ASSET_IN_USE`: the asset is referenced by an active execution and cannot be deleted.\n- `BATCH_TOO_LARGE`: the batch contains more items than the endpoint allows.\n- `CONCURRENT_EXECUTION_LIMIT_EXCEEDED`: the account has reached its limit on simultaneous submissions.\n- `PBR_FAILURE_CAP_EXCEEDED`: the account has too many recent failed PBR runs; new submissions are temporarily blocked.\n- `EXECUTION_NOT_FOUND`: the execution or batch does not exist or does not belong to the account.\n- `EXECUTION_IN_PROGRESS`: the request conflicts with an execution that is still running.\n- `RATE_LIMITED`: the API key's rate limit was exceeded.\n- `SERVICE_UNAVAILABLE`: a dependent service is temporarily unavailable; retry later.\n- `MAINTENANCE_MODE`: the API is temporarily unavailable for maintenance.\n- `INTERNAL_SERVER_ERROR`: an unexpected server error occurred.\n- `WORKFLOW_CREATION_FAILED`: the platform could not start the underlying workflow.\n- `WORKFLOW_API_ERROR`: the platform's workflow system returned an unexpected error.\n","enum":["INVALID_REQUEST","MALFORMED_UUID","UNAUTHORIZED","API_KEY_MISSING","API_KEY_INVALID","API_KEY_REVOKED","PLAN_FEATURE_REQUIRED","INSUFFICIENT_CREDITS","QUOTA_EXCEEDED","FILE_TOO_LARGE","INVALID_CONTENT_TYPE","UNSUPPORTED_ASSET_FORMAT","FORMAT_NOT_AVAILABLE","ASSET_NOT_FOUND","ASSET_IN_USE","BATCH_TOO_LARGE","CONCURRENT_EXECUTION_LIMIT_EXCEEDED","PBR_FAILURE_CAP_EXCEEDED","EXECUTION_NOT_FOUND","EXECUTION_IN_PROGRESS","RATE_LIMITED","SERVICE_UNAVAILABLE","MAINTENANCE_MODE","INTERNAL_SERVER_ERROR","WORKFLOW_CREATION_FAILED","WORKFLOW_API_ERROR"]}}}}
```

## The ErrorBody object

```json
{"openapi":"3.1.0","info":{"title":"Marso Studio API","version":"0.0.1"},"components":{"schemas":{"ErrorBody":{"type":"object","description":"The body of an error response. The `code` is a stable value clients can\nbranch on; the `message` is a human-readable explanation.\n","required":["code","message"],"properties":{"code":{"$ref":"#/components/schemas/ErrorCode"},"message":{"type":"string","description":"Human-readable description of the error.\n"},"details":{"type":["object","null"],"description":"Additional structured information about the error, or `null` if no\nextra details are available.\n","additionalProperties":true}}},"ErrorCode":{"type":"string","description":"Machine-readable error code. The enum enumerates every code that can be\nreturned by this API, including infrastructure-level 5xx codes, so\ngenerated clients can decode any `error.code` they receive.\n\nPossible enum values:\n- `INVALID_REQUEST`: the request body or a query parameter failed validation.\n- `MALFORMED_UUID`: a path parameter that should be a UUID is not one.\n- `UNAUTHORIZED`: the request could not be authenticated.\n- `API_KEY_MISSING`: no API key was supplied.\n- `API_KEY_INVALID`: the supplied API key does not match any known key.\n- `API_KEY_REVOKED`: the supplied API key has been revoked.\n- `PLAN_FEATURE_REQUIRED`: the account plan does not include a required feature.\n- `INSUFFICIENT_CREDITS`: the account does not have enough credits for this request.\n- `QUOTA_EXCEEDED`: a usage quota for the account has been exceeded.\n- `FILE_TOO_LARGE`: an uploaded or referenced file exceeds the allowed size.\n- `INVALID_CONTENT_TYPE`: a file's content type does not match its declared or expected type.\n- `UNSUPPORTED_ASSET_FORMAT`: a file's extension is not one of the supported asset formats.\n- `FORMAT_NOT_AVAILABLE`: the requested downloadable format does not exist for this asset.\n- `ASSET_NOT_FOUND`: the asset does not exist or does not belong to the account.\n- `ASSET_IN_USE`: the asset is referenced by an active execution and cannot be deleted.\n- `BATCH_TOO_LARGE`: the batch contains more items than the endpoint allows.\n- `CONCURRENT_EXECUTION_LIMIT_EXCEEDED`: the account has reached its limit on simultaneous submissions.\n- `PBR_FAILURE_CAP_EXCEEDED`: the account has too many recent failed PBR runs; new submissions are temporarily blocked.\n- `EXECUTION_NOT_FOUND`: the execution or batch does not exist or does not belong to the account.\n- `EXECUTION_IN_PROGRESS`: the request conflicts with an execution that is still running.\n- `RATE_LIMITED`: the API key's rate limit was exceeded.\n- `SERVICE_UNAVAILABLE`: a dependent service is temporarily unavailable; retry later.\n- `MAINTENANCE_MODE`: the API is temporarily unavailable for maintenance.\n- `INTERNAL_SERVER_ERROR`: an unexpected server error occurred.\n- `WORKFLOW_CREATION_FAILED`: the platform could not start the underlying workflow.\n- `WORKFLOW_API_ERROR`: the platform's workflow system returned an unexpected error.\n","enum":["INVALID_REQUEST","MALFORMED_UUID","UNAUTHORIZED","API_KEY_MISSING","API_KEY_INVALID","API_KEY_REVOKED","PLAN_FEATURE_REQUIRED","INSUFFICIENT_CREDITS","QUOTA_EXCEEDED","FILE_TOO_LARGE","INVALID_CONTENT_TYPE","UNSUPPORTED_ASSET_FORMAT","FORMAT_NOT_AVAILABLE","ASSET_NOT_FOUND","ASSET_IN_USE","BATCH_TOO_LARGE","CONCURRENT_EXECUTION_LIMIT_EXCEEDED","PBR_FAILURE_CAP_EXCEEDED","EXECUTION_NOT_FOUND","EXECUTION_IN_PROGRESS","RATE_LIMITED","SERVICE_UNAVAILABLE","MAINTENANCE_MODE","INTERNAL_SERVER_ERROR","WORKFLOW_CREATION_FAILED","WORKFLOW_API_ERROR"]}}}}
```

## The Error object

```json
{"openapi":"3.1.0","info":{"title":"Marso Studio API","version":"0.0.1"},"components":{"schemas":{"Error":{"type":"object","required":["error"],"description":"Canonical error envelope. The error payload is nested under the `error`\nkey.\n","properties":{"error":{"$ref":"#/components/schemas/ErrorBody"}}},"ErrorBody":{"type":"object","description":"The body of an error response. The `code` is a stable value clients can\nbranch on; the `message` is a human-readable explanation.\n","required":["code","message"],"properties":{"code":{"$ref":"#/components/schemas/ErrorCode"},"message":{"type":"string","description":"Human-readable description of the error.\n"},"details":{"type":["object","null"],"description":"Additional structured information about the error, or `null` if no\nextra details are available.\n","additionalProperties":true}}},"ErrorCode":{"type":"string","description":"Machine-readable error code. The enum enumerates every code that can be\nreturned by this API, including infrastructure-level 5xx codes, so\ngenerated clients can decode any `error.code` they receive.\n\nPossible enum values:\n- `INVALID_REQUEST`: the request body or a query parameter failed validation.\n- `MALFORMED_UUID`: a path parameter that should be a UUID is not one.\n- `UNAUTHORIZED`: the request could not be authenticated.\n- `API_KEY_MISSING`: no API key was supplied.\n- `API_KEY_INVALID`: the supplied API key does not match any known key.\n- `API_KEY_REVOKED`: the supplied API key has been revoked.\n- `PLAN_FEATURE_REQUIRED`: the account plan does not include a required feature.\n- `INSUFFICIENT_CREDITS`: the account does not have enough credits for this request.\n- `QUOTA_EXCEEDED`: a usage quota for the account has been exceeded.\n- `FILE_TOO_LARGE`: an uploaded or referenced file exceeds the allowed size.\n- `INVALID_CONTENT_TYPE`: a file's content type does not match its declared or expected type.\n- `UNSUPPORTED_ASSET_FORMAT`: a file's extension is not one of the supported asset formats.\n- `FORMAT_NOT_AVAILABLE`: the requested downloadable format does not exist for this asset.\n- `ASSET_NOT_FOUND`: the asset does not exist or does not belong to the account.\n- `ASSET_IN_USE`: the asset is referenced by an active execution and cannot be deleted.\n- `BATCH_TOO_LARGE`: the batch contains more items than the endpoint allows.\n- `CONCURRENT_EXECUTION_LIMIT_EXCEEDED`: the account has reached its limit on simultaneous submissions.\n- `PBR_FAILURE_CAP_EXCEEDED`: the account has too many recent failed PBR runs; new submissions are temporarily blocked.\n- `EXECUTION_NOT_FOUND`: the execution or batch does not exist or does not belong to the account.\n- `EXECUTION_IN_PROGRESS`: the request conflicts with an execution that is still running.\n- `RATE_LIMITED`: the API key's rate limit was exceeded.\n- `SERVICE_UNAVAILABLE`: a dependent service is temporarily unavailable; retry later.\n- `MAINTENANCE_MODE`: the API is temporarily unavailable for maintenance.\n- `INTERNAL_SERVER_ERROR`: an unexpected server error occurred.\n- `WORKFLOW_CREATION_FAILED`: the platform could not start the underlying workflow.\n- `WORKFLOW_API_ERROR`: the platform's workflow system returned an unexpected error.\n","enum":["INVALID_REQUEST","MALFORMED_UUID","UNAUTHORIZED","API_KEY_MISSING","API_KEY_INVALID","API_KEY_REVOKED","PLAN_FEATURE_REQUIRED","INSUFFICIENT_CREDITS","QUOTA_EXCEEDED","FILE_TOO_LARGE","INVALID_CONTENT_TYPE","UNSUPPORTED_ASSET_FORMAT","FORMAT_NOT_AVAILABLE","ASSET_NOT_FOUND","ASSET_IN_USE","BATCH_TOO_LARGE","CONCURRENT_EXECUTION_LIMIT_EXCEEDED","PBR_FAILURE_CAP_EXCEEDED","EXECUTION_NOT_FOUND","EXECUTION_IN_PROGRESS","RATE_LIMITED","SERVICE_UNAVAILABLE","MAINTENANCE_MODE","INTERNAL_SERVER_ERROR","WORKFLOW_CREATION_FAILED","WORKFLOW_API_ERROR"]}}}}
```

## The ExecutionStatus object

```json
{"openapi":"3.1.0","info":{"title":"Marso Studio API","version":"0.0.1"},"components":{"schemas":{"ExecutionStatus":{"type":"string","description":"Status of a single item within a batch.\n\nPossible enum values:\n- `QUEUED`: the item is waiting to start.\n- `RUNNING`: the item is being processed.\n- `SUCCEEDED`: the item completed successfully.\n- `PARTIAL_SUCCEEDED`: the item completed but some optional outputs are\n  missing.\n- `FAILED`: the item failed. See the `error` field for details.\n","enum":["QUEUED","RUNNING","SUCCEEDED","PARTIAL_SUCCEEDED","FAILED"]}}}}
```

## The ExecutionErrorBody object

```json
{"openapi":"3.1.0","info":{"title":"Marso Studio API","version":"0.0.1"},"components":{"schemas":{"ExecutionErrorBody":{"type":"object","description":"Failure detail for a failed batch item. The `code` is a stable,\nmachine-readable class drawn from a closed enum so clients can branch on\nthe failure kind. The `message` carries human-readable detail. Only\n`VALIDATION_FAILED` is permanent; do not retry the same input. The other\ncodes are generally retryable.\n","required":["code","message"],"properties":{"code":{"type":"string","enum":["VALIDATION_FAILED","PIPELINE_ERROR","TIMEOUT","INTERNAL"],"description":"Machine-readable class of the failure.\n\nPossible enum values:\n- `VALIDATION_FAILED`: the input is unsuitable or invalid. This is a\n  permanent failure; retrying the same input will not succeed.\n- `PIPELINE_ERROR`: the PBR pipeline attempted the item but failed.\n  Generally retryable.\n- `TIMEOUT`: the item exceeded its time budget. Generally retryable.\n- `INTERNAL`: an internal orchestration fault. Generally retryable.\n"},"message":{"type":"string","description":"Human-readable explanation of the failure.\n"}}}}}}
```

## The BatchUploadRequest object

```json
{"openapi":"3.1.0","info":{"title":"Marso Studio API","version":"0.0.1"},"components":{"schemas":{"BatchUploadRequest":{"type":"object","required":["files"],"description":"Request body for `POST /batch/uploads`. Describe 5 to 200 files you want to\nupload; the response returns a presigned upload URL for each one.\n","properties":{"files":{"type":"array","minItems":5,"maxItems":200,"description":"The files to upload. Must contain between 5 and 200 items.\n","items":{"$ref":"#/components/schemas/BatchUploadFileRequest"}}}},"BatchUploadFileRequest":{"type":"object","required":["filename","size_bytes"],"description":"Metadata for a single file in a batch upload request.\n","properties":{"filename":{"type":"string","description":"The file name. The extension determines the asset type and must be in\nthe allowed list. Allowed extensions: `.usd` and `.glb` for\nmeshes; `.jpg`, `.jpeg`, and `.png` for images.\n"},"content_type":{"type":"string","description":"The file's content type. Optional; inferred from the extension when\nomitted. When provided, it must match the extension's allowed\ncontent type.\n"},"size_bytes":{"type":"integer","format":"int64","description":"The exact byte length of the file. Used as the upload's\n`Content-Length` and enforced as a hard size cap. Allowed byte limits\nvary by format; images are additionally validated to be\n4096×4096 pixels or smaller after upload.\n"}}}}}}
```

## The BatchUploadFileRequest object

```json
{"openapi":"3.1.0","info":{"title":"Marso Studio API","version":"0.0.1"},"components":{"schemas":{"BatchUploadFileRequest":{"type":"object","required":["filename","size_bytes"],"description":"Metadata for a single file in a batch upload request.\n","properties":{"filename":{"type":"string","description":"The file name. The extension determines the asset type and must be in\nthe allowed list. Allowed extensions: `.usd` and `.glb` for\nmeshes; `.jpg`, `.jpeg`, and `.png` for images.\n"},"content_type":{"type":"string","description":"The file's content type. Optional; inferred from the extension when\nomitted. When provided, it must match the extension's allowed\ncontent type.\n"},"size_bytes":{"type":"integer","format":"int64","description":"The exact byte length of the file. Used as the upload's\n`Content-Length` and enforced as a hard size cap. Allowed byte limits\nvary by format; images are additionally validated to be\n4096×4096 pixels or smaller after upload.\n"}}}}}}
```

## The BatchUploadResponse object

```json
{"openapi":"3.1.0","info":{"title":"Marso Studio API","version":"0.0.1"},"components":{"schemas":{"BatchUploadResponse":{"type":"object","required":["files"],"description":"Response from `POST /batch/uploads`. Contains the upload batch ID and the\npresigned upload URL for each file.\n","properties":{"upload_batch_id":{"type":"string","description":"The ID that groups the created pending assets. Poll\n`GET /batch/uploads/{upload_batch_id}` for aggregate readiness. May be\nabsent if the grouping could not be recorded; in that case, fall back\nto polling each asset individually.\n"},"files":{"type":"array","description":"Presigned upload URLs and asset IDs, index-aligned with the request.\n","items":{"$ref":"#/components/schemas/BatchUploadFileResponse"}}}},"BatchUploadFileResponse":{"type":"object","required":["asset_id","upload_url"],"description":"Presigned upload URL and metadata for one file in a batch upload response.\n","properties":{"asset_id":{"type":"string","description":"The ID of the pending asset created for this file.\n"},"upload_url":{"type":"string","format":"uri","description":"Presigned S3 PUT URL. Upload the raw file bytes to this URL using the\nheaders provided in `headers`.\n"},"headers":{"type":"object","additionalProperties":{"type":"string"},"description":"Every header the client must send verbatim with the PUT request. This\nincludes `Content-Type`, `Content-Length`, and any `x-amz-meta-*`\nmetadata headers. All headers are bound into the signature, so omitting\nor altering any of them causes S3 to reject the upload.\n"}}}}}}
```

## The BatchUploadState object

```json
{"openapi":"3.1.0","info":{"title":"Marso Studio API","version":"0.0.1"},"components":{"schemas":{"BatchUploadState":{"type":"string","description":"Aggregate state of an upload batch.\n\nPossible enum values:\n- `UPLOADING`: at least one file is still being validated.\n- `COMPLETED`: every file in the batch is `ready`.\n- `PARTIALLY_COMPLETED`: the batch has a mix of `ready` and `rejected`\n  files; this is a terminal state.\n- `FAILED`: every file in the batch was rejected.\n","enum":["UPLOADING","COMPLETED","PARTIALLY_COMPLETED","FAILED"]}}}}
```

## The BatchUploadStatusResponse object

```json
{"openapi":"3.1.0","info":{"title":"Marso Studio API","version":"0.0.1"},"components":{"schemas":{"BatchUploadStatusResponse":{"type":"object","required":["state","files","created_at"],"description":"Response from `GET /batch/uploads/{upload_batch_id}`. Contains the\naggregate state of the batch and the validation status of each file.\n","properties":{"state":{"$ref":"#/components/schemas/BatchUploadState"},"files":{"type":"array","description":"Per-file validation status, index-aligned with the upload request.\n","items":{"$ref":"#/components/schemas/BatchUploadStatusFile"}},"created_at":{"$ref":"#/components/schemas/EpochMillis"},"completed_at":{"$ref":"#/components/schemas/NullableEpochMillis"}}},"BatchUploadState":{"type":"string","description":"Aggregate state of an upload batch.\n\nPossible enum values:\n- `UPLOADING`: at least one file is still being validated.\n- `COMPLETED`: every file in the batch is `ready`.\n- `PARTIALLY_COMPLETED`: the batch has a mix of `ready` and `rejected`\n  files; this is a terminal state.\n- `FAILED`: every file in the batch was rejected.\n","enum":["UPLOADING","COMPLETED","PARTIALLY_COMPLETED","FAILED"]},"BatchUploadStatusFile":{"type":"object","required":["file_name","status"],"description":"Validation status of one file in an upload batch.\n","properties":{"file_name":{"type":"string","description":"The file name as provided in the upload request.\n"},"status":{"type":"string","enum":["pending","ready","rejected"],"description":"The validation status of this file.\n\nPossible enum values:\n- `pending`: the file has not been validated yet.\n- `ready`: the file passed validation and can be used for PBR generation.\n- `rejected`: the file failed validation. The file must be re-uploaded.\n"}}},"EpochMillis":{"type":"integer","format":"int64","description":"Time represented as milliseconds since the Unix epoch.\n"},"NullableEpochMillis":{"type":["integer","null"],"format":"int64","description":"Time represented as milliseconds since the Unix epoch, or `null` when the\nfield has not been set.\n"}}}}
```

## The BatchUploadStatusFile object

```json
{"openapi":"3.1.0","info":{"title":"Marso Studio API","version":"0.0.1"},"components":{"schemas":{"BatchUploadStatusFile":{"type":"object","required":["file_name","status"],"description":"Validation status of one file in an upload batch.\n","properties":{"file_name":{"type":"string","description":"The file name as provided in the upload request.\n"},"status":{"type":"string","enum":["pending","ready","rejected"],"description":"The validation status of this file.\n\nPossible enum values:\n- `pending`: the file has not been validated yet.\n- `ready`: the file passed validation and can be used for PBR generation.\n- `rejected`: the file failed validation. The file must be re-uploaded.\n"}}}}}}
```

## The BatchUploadFileResponse object

```json
{"openapi":"3.1.0","info":{"title":"Marso Studio API","version":"0.0.1"},"components":{"schemas":{"BatchUploadFileResponse":{"type":"object","required":["asset_id","upload_url"],"description":"Presigned upload URL and metadata for one file in a batch upload response.\n","properties":{"asset_id":{"type":"string","description":"The ID of the pending asset created for this file.\n"},"upload_url":{"type":"string","format":"uri","description":"Presigned S3 PUT URL. Upload the raw file bytes to this URL using the\nheaders provided in `headers`.\n"},"headers":{"type":"object","additionalProperties":{"type":"string"},"description":"Every header the client must send verbatim with the PUT request. This\nincludes `Content-Type`, `Content-Length`, and any `x-amz-meta-*`\nmetadata headers. All headers are bound into the signature, so omitting\nor altering any of them causes S3 to reject the upload.\n"}}}}}}
```

## The BatchUploadErrorResponse object

```json
{"openapi":"3.1.0","info":{"title":"Marso Studio API","version":"0.0.1"},"components":{"schemas":{"BatchUploadErrorResponse":{"type":"object","required":["errors"],"description":"Returned when one or more files in an upload request fail validation.\nLists every failed file so you can fix them all at once. The batch\nis all-or-nothing: if any file fails, nothing is created.\n","properties":{"errors":{"type":"array","description":"Per-file validation failures.\n","items":{"$ref":"#/components/schemas/BatchUploadFileError"}}}},"BatchUploadFileError":{"type":"object","required":["index","filename","code","message"],"description":"One validation failure from a `POST /batch/uploads` request.\n","properties":{"index":{"type":"integer","description":"Zero-based position of the file in the upload request.\n"},"filename":{"type":"string","description":"The offending file name. Empty if the fault was a missing file name.\n"},"code":{"type":"string","description":"Machine-readable reason for the rejection. Possible values include\n`UNSUPPORTED_ASSET_FORMAT`, `INVALID_CONTENT_TYPE`, `FILE_TOO_LARGE`,\nand `INVALID_REQUEST`.\n"},"message":{"type":"string","description":"Human-readable explanation of why this file was rejected.\n"}}}}}}
```

## The BatchUploadFileError object

```json
{"openapi":"3.1.0","info":{"title":"Marso Studio API","version":"0.0.1"},"components":{"schemas":{"BatchUploadFileError":{"type":"object","required":["index","filename","code","message"],"description":"One validation failure from a `POST /batch/uploads` request.\n","properties":{"index":{"type":"integer","description":"Zero-based position of the file in the upload request.\n"},"filename":{"type":"string","description":"The offending file name. Empty if the fault was a missing file name.\n"},"code":{"type":"string","description":"Machine-readable reason for the rejection. Possible values include\n`UNSUPPORTED_ASSET_FORMAT`, `INVALID_CONTENT_TYPE`, `FILE_TOO_LARGE`,\nand `INVALID_REQUEST`.\n"},"message":{"type":"string","description":"Human-readable explanation of why this file was rejected.\n"}}}}}}
```

## The CreatePBRMeshBatchRequest object

```json
{"openapi":"3.1.0","info":{"title":"Marso Studio API","version":"0.0.1"},"components":{"schemas":{"CreatePBRMeshBatchRequest":{"type":"object","required":["asset_ids"],"description":"Request body for `POST /batch/pbr/mesh`. Submit one or more ready mesh\nassets for 3D mesh to PBR generation.\n","properties":{"asset_ids":{"type":"array","minItems":1,"maxItems":200,"items":{"type":"string","format":"uuid"},"description":"IDs of the `ready` mesh assets to process. These assets must have been\nuploaded via `POST /batch/uploads` and must currently be in the `ready`\nstate.\n"},"options":{"$ref":"#/components/schemas/PublicPBRMeshOptions"}}},"PublicPBRMeshOptions":{"type":"object","additionalProperties":false,"description":"Tuning options for a mesh PBR run. Every field is optional, and an\nomitted field uses the system default.\n\nThis is the image options plus `output_2d`, the 1 mesh-only option. It\nneeds a stage the image pipeline skips, so it appears on the mesh\nendpoints only. An image endpoint rejects it.\n\n**Every mesh result carries a USDZ.** The export is no longer an\noption. `output_3d` is gone, and a request that carries it gets a\n`400`. The pipeline always packages `material.usdz` for a mesh run,\nand the result lists it beside the texture maps.\n\nThis object rejects a field it does not declare, the same way\n`PublicPBRImageOptions` rejects one. Issue #2175 removed the same 6\noptions from both, and it removed `output_3d` from this object alone.\n\n4 of the 6 changed a mesh result before the removal. A mesh run now uses\nthe deployed value for each: 16 views, the `quality` solver profile, the\n`coverage` blend mode, and a bake at 4096. The PBR options reference\nholds the per-option detail. Delete these fields from your request body,\nbecause the endpoint now rejects them.\n","properties":{"detail_transfer":{"$ref":"#/components/schemas/PublicPBRDetailTransfer"},"output_2d":{"$ref":"#/components/schemas/PublicPBROutput2D"}}},"PublicPBRDetailTransfer":{"type":"object","additionalProperties":false,"description":"Settings for detail transfer during PBR generation.\n\nThis object lost `magnitude_only`. The pipeline tunes that value for\neach texture pass, so 1 value you send could only flatten the tuning.\n","properties":{"enabled":{"type":["boolean","null"],"default":true,"description":"Whether detail transfer is enabled. An omitted field, and an\nexplicit `null`, both leave the stage on.\n"}}},"PublicPBROutput2D":{"type":"object","additionalProperties":false,"description":"Container for 2D output options. All fields are optional; omitted fields\nuse system defaults.\n\nThis object lost `video`. The pipeline holds no video stage and no\nturntable stage.\n","properties":{"orm":{"$ref":"#/components/schemas/PublicPBROutput2DORM"}}},"PublicPBROutput2DORM":{"type":"object","additionalProperties":false,"description":"Settings for an occlusion/roughness/metallic (ORM) combined 2D output\nmap.\n\n**No result carries the ORM map yet.** The 2 mesh endpoints accept the\noption today, and the pipeline stage that packs the map is still in\nbuild. The option never fails a run, and it changes no result until that\nstage ships.\n","properties":{"enabled":{"type":["boolean","null"],"default":false,"description":"Whether to generate the ORM map. An omitted field, and an explicit\n`null`, both leave the map off.\nNo result carries the map yet, as the object description states.\n"},"channel_order":{"type":"string","enum":["ORM","RMO","MRO"],"default":"ORM","description":"Channel order for the combined map. An omitted field packs the\nchannels in the `ORM` order.\n\nPossible enum values:\n- `ORM`: occlusion, roughness, metallic.\n- `RMO`: roughness, metallic, occlusion.\n- `MRO`: metallic, roughness, occlusion.\n"}}}}}}
```

## The CreatePBRImageBatchRequest object

```json
{"openapi":"3.1.0","info":{"title":"Marso Studio API","version":"0.0.1"},"components":{"schemas":{"CreatePBRImageBatchRequest":{"type":"object","required":["asset_ids"],"description":"Request body for `POST /batch/pbr/image`. It has the same shape as\n`CreatePBRMeshBatchRequest`, except for the options. The image path\ntakes no `output_2d`, because that option needs a stage the image\npipeline skips.\n","properties":{"asset_ids":{"type":"array","minItems":1,"maxItems":200,"items":{"type":"string","format":"uuid"},"description":"IDs of the `ready` image assets to process. These assets must have\nbeen uploaded via `POST /batch/uploads` and must currently be in the\n`ready` state.\n"},"options":{"$ref":"#/components/schemas/PublicPBRImageOptions"}}},"PublicPBRImageOptions":{"type":"object","additionalProperties":false,"description":"Tuning options for an image PBR run. Every field is optional, and an\nomitted field uses the system default.\n\nThe image pipeline runs inference only. It reaches neither the 3D\ncontainer stage nor the packed 2D map stage, so `output_2d` appears on\nthe mesh endpoints only, and no image result carries a USDZ.\n`detail_transfer` is the whole surface here.\n\nThis object rejects a field it does not declare. Issue #2175 removed\n`pbr_mode`, `blend_mode`, `coverage`, `texture`,\n`detail_transfer.magnitude_only` and `output_2d.video`. A request that\nstill carries 1 of them gets a 400, and the message names the field.\nDelete them from your request body. The PBR options reference states\nwhat each removal changed.\n","properties":{"detail_transfer":{"$ref":"#/components/schemas/PublicPBRDetailTransfer"}}},"PublicPBRDetailTransfer":{"type":"object","additionalProperties":false,"description":"Settings for detail transfer during PBR generation.\n\nThis object lost `magnitude_only`. The pipeline tunes that value for\neach texture pass, so 1 value you send could only flatten the tuning.\n","properties":{"enabled":{"type":["boolean","null"],"default":true,"description":"Whether detail transfer is enabled. An omitted field, and an\nexplicit `null`, both leave the stage on.\n"}}}}}}
```

## The BatchStatus object

```json
{"openapi":"3.1.0","info":{"title":"Marso Studio API","version":"0.0.1"},"components":{"schemas":{"BatchStatus":{"type":"string","description":"Aggregate status of a PBR batch.\n\nPossible enum values:\n- `QUEUED`: the batch is waiting to start.\n- `RUNNING`: at least one item is being processed.\n- `COMPLETED`: every item succeeded.\n- `PARTIALLY_COMPLETED`: the batch finished with a mix of successes and\n  failures.\n- `FAILED`: every item failed.\n","enum":["QUEUED","RUNNING","COMPLETED","PARTIALLY_COMPLETED","FAILED"]}}}}
```

## The BatchCountsBody object

```json
{"openapi":"3.1.0","info":{"title":"Marso Studio API","version":"0.0.1"},"components":{"schemas":{"BatchCountsBody":{"type":"object","required":["total","completed","failed","pending"],"description":"Count of items in a batch, grouped by status.\n","properties":{"total":{"type":"integer","description":"Total number of items in the batch.\n"},"completed":{"type":"integer","description":"Number of items that have reached a terminal state, whether they\nsucceeded or failed.\n"},"failed":{"type":"integer","description":"Number of items that failed.\n"},"pending":{"type":"integer","description":"Number of items that are still queued or running.\n"}}}}}}
```

## The BatchItemBody object

```json
{"openapi":"3.1.0","info":{"title":"Marso Studio API","version":"0.0.1"},"components":{"schemas":{"BatchItemBody":{"type":"object","required":["execution_id","status","created_at"],"description":"One item's result within a batch. `asset_id` is the source asset you\nsubmitted, so a failed item is always traceable to its input.\n`pbr_material_assets` maps each `\"<slot>/<pass>\"` to its generated texture\nasset and a ready-to-use `download_url`, so you can pull every result\ndirectly from the poll response. `thumbnail_url` is a preview image,\nalways present on a succeeded mesh item, and best-effort on a succeeded\nimage item (an image item may finish without one). `error` is set only\non failed items.\n","properties":{"execution_id":{"type":"string","description":"Unique identifier of the execution for this item.\n"},"asset_id":{"type":"string","description":"ID of the source asset that was submitted for this item.\n"},"status":{"$ref":"#/components/schemas/ExecutionStatus"},"thumbnail_url":{"type":"string","format":"uri","description":"URL of a preview image. Always present on a succeeded mesh item;\nbest-effort on a succeeded image item.\n"},"thumbnail_url_expires_at":{"$ref":"#/components/schemas/EpochMillis"},"pbr_material_assets":{"type":"object","description":"Map from `\"<slot>/<pass>\"` to the generated texture asset. Only\npresent on succeeded items.\n","additionalProperties":{"$ref":"#/components/schemas/BatchMaterialAssetBody"}},"error":{"$ref":"#/components/schemas/ExecutionErrorBody"},"created_at":{"$ref":"#/components/schemas/EpochMillis"}}},"ExecutionStatus":{"type":"string","description":"Status of a single item within a batch.\n\nPossible enum values:\n- `QUEUED`: the item is waiting to start.\n- `RUNNING`: the item is being processed.\n- `SUCCEEDED`: the item completed successfully.\n- `PARTIAL_SUCCEEDED`: the item completed but some optional outputs are\n  missing.\n- `FAILED`: the item failed. See the `error` field for details.\n","enum":["QUEUED","RUNNING","SUCCEEDED","PARTIAL_SUCCEEDED","FAILED"]},"EpochMillis":{"type":"integer","format":"int64","description":"Time represented as milliseconds since the Unix epoch.\n"},"BatchMaterialAssetBody":{"type":"object","required":["asset_id"],"description":"One generated PBR result asset within a batch item. `download_url` is a\nready-to-use link that expires at `expires_at`.\n","properties":{"asset_id":{"type":"string","description":"ID of the generated asset.\n"},"download_url":{"type":"string","format":"uri","description":"Presigned URL for downloading the generated asset. Valid until\n`expires_at`.\n"},"expires_at":{"$ref":"#/components/schemas/EpochMillis"}}},"ExecutionErrorBody":{"type":"object","description":"Failure detail for a failed batch item. The `code` is a stable,\nmachine-readable class drawn from a closed enum so clients can branch on\nthe failure kind. The `message` carries human-readable detail. Only\n`VALIDATION_FAILED` is permanent; do not retry the same input. The other\ncodes are generally retryable.\n","required":["code","message"],"properties":{"code":{"type":"string","enum":["VALIDATION_FAILED","PIPELINE_ERROR","TIMEOUT","INTERNAL"],"description":"Machine-readable class of the failure.\n\nPossible enum values:\n- `VALIDATION_FAILED`: the input is unsuitable or invalid. This is a\n  permanent failure; retrying the same input will not succeed.\n- `PIPELINE_ERROR`: the PBR pipeline attempted the item but failed.\n  Generally retryable.\n- `TIMEOUT`: the item exceeded its time budget. Generally retryable.\n- `INTERNAL`: an internal orchestration fault. Generally retryable.\n"},"message":{"type":"string","description":"Human-readable explanation of the failure.\n"}}}}}}
```

## The BatchMaterialAssetBody object

```json
{"openapi":"3.1.0","info":{"title":"Marso Studio API","version":"0.0.1"},"components":{"schemas":{"BatchMaterialAssetBody":{"type":"object","required":["asset_id"],"description":"One generated PBR result asset within a batch item. `download_url` is a\nready-to-use link that expires at `expires_at`.\n","properties":{"asset_id":{"type":"string","description":"ID of the generated asset.\n"},"download_url":{"type":"string","format":"uri","description":"Presigned URL for downloading the generated asset. Valid until\n`expires_at`.\n"},"expires_at":{"$ref":"#/components/schemas/EpochMillis"}}},"EpochMillis":{"type":"integer","format":"int64","description":"Time represented as milliseconds since the Unix epoch.\n"}}}}
```

## The BatchResponse object

```json
{"openapi":"3.1.0","info":{"title":"Marso Studio API","version":"0.0.1"},"components":{"schemas":{"BatchResponse":{"type":"object","required":["batch_id","status","request_counts","created_at","items"],"description":"Body returned by `POST /batch/pbr/*` (202) and `GET /batch/{batch_id}`\n(200). On submission `items` is empty; poll the batch to populate it.\n`completed_at` is set once the batch reaches a terminal status; `failed_at`\nis set only when that terminal status is `FAILED`.\n","properties":{"batch_id":{"type":"string","description":"Unique identifier of the batch.\n"},"status":{"$ref":"#/components/schemas/BatchStatus"},"request_counts":{"$ref":"#/components/schemas/BatchCountsBody"},"created_at":{"$ref":"#/components/schemas/EpochMillis"},"completed_at":{"$ref":"#/components/schemas/NullableEpochMillis"},"failed_at":{"$ref":"#/components/schemas/NullableEpochMillis"},"items":{"type":"array","description":"Settled results for each item. Empty until at least one item has\nfinished.\n","items":{"$ref":"#/components/schemas/BatchItemBody"}}}},"BatchStatus":{"type":"string","description":"Aggregate status of a PBR batch.\n\nPossible enum values:\n- `QUEUED`: the batch is waiting to start.\n- `RUNNING`: at least one item is being processed.\n- `COMPLETED`: every item succeeded.\n- `PARTIALLY_COMPLETED`: the batch finished with a mix of successes and\n  failures.\n- `FAILED`: every item failed.\n","enum":["QUEUED","RUNNING","COMPLETED","PARTIALLY_COMPLETED","FAILED"]},"BatchCountsBody":{"type":"object","required":["total","completed","failed","pending"],"description":"Count of items in a batch, grouped by status.\n","properties":{"total":{"type":"integer","description":"Total number of items in the batch.\n"},"completed":{"type":"integer","description":"Number of items that have reached a terminal state, whether they\nsucceeded or failed.\n"},"failed":{"type":"integer","description":"Number of items that failed.\n"},"pending":{"type":"integer","description":"Number of items that are still queued or running.\n"}}},"EpochMillis":{"type":"integer","format":"int64","description":"Time represented as milliseconds since the Unix epoch.\n"},"NullableEpochMillis":{"type":["integer","null"],"format":"int64","description":"Time represented as milliseconds since the Unix epoch, or `null` when the\nfield has not been set.\n"},"BatchItemBody":{"type":"object","required":["execution_id","status","created_at"],"description":"One item's result within a batch. `asset_id` is the source asset you\nsubmitted, so a failed item is always traceable to its input.\n`pbr_material_assets` maps each `\"<slot>/<pass>\"` to its generated texture\nasset and a ready-to-use `download_url`, so you can pull every result\ndirectly from the poll response. `thumbnail_url` is a preview image,\nalways present on a succeeded mesh item, and best-effort on a succeeded\nimage item (an image item may finish without one). `error` is set only\non failed items.\n","properties":{"execution_id":{"type":"string","description":"Unique identifier of the execution for this item.\n"},"asset_id":{"type":"string","description":"ID of the source asset that was submitted for this item.\n"},"status":{"$ref":"#/components/schemas/ExecutionStatus"},"thumbnail_url":{"type":"string","format":"uri","description":"URL of a preview image. Always present on a succeeded mesh item;\nbest-effort on a succeeded image item.\n"},"thumbnail_url_expires_at":{"$ref":"#/components/schemas/EpochMillis"},"pbr_material_assets":{"type":"object","description":"Map from `\"<slot>/<pass>\"` to the generated texture asset. Only\npresent on succeeded items.\n","additionalProperties":{"$ref":"#/components/schemas/BatchMaterialAssetBody"}},"error":{"$ref":"#/components/schemas/ExecutionErrorBody"},"created_at":{"$ref":"#/components/schemas/EpochMillis"}}},"ExecutionStatus":{"type":"string","description":"Status of a single item within a batch.\n\nPossible enum values:\n- `QUEUED`: the item is waiting to start.\n- `RUNNING`: the item is being processed.\n- `SUCCEEDED`: the item completed successfully.\n- `PARTIAL_SUCCEEDED`: the item completed but some optional outputs are\n  missing.\n- `FAILED`: the item failed. See the `error` field for details.\n","enum":["QUEUED","RUNNING","SUCCEEDED","PARTIAL_SUCCEEDED","FAILED"]},"BatchMaterialAssetBody":{"type":"object","required":["asset_id"],"description":"One generated PBR result asset within a batch item. `download_url` is a\nready-to-use link that expires at `expires_at`.\n","properties":{"asset_id":{"type":"string","description":"ID of the generated asset.\n"},"download_url":{"type":"string","format":"uri","description":"Presigned URL for downloading the generated asset. Valid until\n`expires_at`.\n"},"expires_at":{"$ref":"#/components/schemas/EpochMillis"}}},"ExecutionErrorBody":{"type":"object","description":"Failure detail for a failed batch item. The `code` is a stable,\nmachine-readable class drawn from a closed enum so clients can branch on\nthe failure kind. The `message` carries human-readable detail. Only\n`VALIDATION_FAILED` is permanent; do not retry the same input. The other\ncodes are generally retryable.\n","required":["code","message"],"properties":{"code":{"type":"string","enum":["VALIDATION_FAILED","PIPELINE_ERROR","TIMEOUT","INTERNAL"],"description":"Machine-readable class of the failure.\n\nPossible enum values:\n- `VALIDATION_FAILED`: the input is unsuitable or invalid. This is a\n  permanent failure; retrying the same input will not succeed.\n- `PIPELINE_ERROR`: the PBR pipeline attempted the item but failed.\n  Generally retryable.\n- `TIMEOUT`: the item exceeded its time budget. Generally retryable.\n- `INTERNAL`: an internal orchestration fault. Generally retryable.\n"},"message":{"type":"string","description":"Human-readable explanation of the failure.\n"}}}}}}
```

## The BatchSummaryBody object

```json
{"openapi":"3.1.0","info":{"title":"Marso Studio API","version":"0.0.1"},"components":{"schemas":{"BatchSummaryBody":{"type":"object","required":["batch_id","status","request_counts","created_at"],"description":"One row in `GET /batch`. Contains a batch's summary without per-item\nresults.\n","properties":{"batch_id":{"type":"string","description":"Unique identifier of the batch.\n"},"status":{"$ref":"#/components/schemas/BatchStatus"},"request_counts":{"$ref":"#/components/schemas/BatchCountsBody"},"created_at":{"$ref":"#/components/schemas/EpochMillis"},"completed_at":{"$ref":"#/components/schemas/NullableEpochMillis"},"failed_at":{"$ref":"#/components/schemas/NullableEpochMillis"}}},"BatchStatus":{"type":"string","description":"Aggregate status of a PBR batch.\n\nPossible enum values:\n- `QUEUED`: the batch is waiting to start.\n- `RUNNING`: at least one item is being processed.\n- `COMPLETED`: every item succeeded.\n- `PARTIALLY_COMPLETED`: the batch finished with a mix of successes and\n  failures.\n- `FAILED`: every item failed.\n","enum":["QUEUED","RUNNING","COMPLETED","PARTIALLY_COMPLETED","FAILED"]},"BatchCountsBody":{"type":"object","required":["total","completed","failed","pending"],"description":"Count of items in a batch, grouped by status.\n","properties":{"total":{"type":"integer","description":"Total number of items in the batch.\n"},"completed":{"type":"integer","description":"Number of items that have reached a terminal state, whether they\nsucceeded or failed.\n"},"failed":{"type":"integer","description":"Number of items that failed.\n"},"pending":{"type":"integer","description":"Number of items that are still queued or running.\n"}}},"EpochMillis":{"type":"integer","format":"int64","description":"Time represented as milliseconds since the Unix epoch.\n"},"NullableEpochMillis":{"type":["integer","null"],"format":"int64","description":"Time represented as milliseconds since the Unix epoch, or `null` when the\nfield has not been set.\n"}}}}
```

## The BatchListResponse object

```json
{"openapi":"3.1.0","info":{"title":"Marso Studio API","version":"0.0.1"},"components":{"schemas":{"BatchListResponse":{"type":"object","required":["batches"],"description":"Response from `GET /batch`. A paginated list of batch summaries.\n","properties":{"batches":{"type":"array","description":"Batch summaries, newest first.\n","items":{"$ref":"#/components/schemas/BatchSummaryBody"}},"next_cursor":{"type":"string","description":"Opaque cursor for the next page. Absent or empty when the result set\nis exhausted.\n"}}},"BatchSummaryBody":{"type":"object","required":["batch_id","status","request_counts","created_at"],"description":"One row in `GET /batch`. Contains a batch's summary without per-item\nresults.\n","properties":{"batch_id":{"type":"string","description":"Unique identifier of the batch.\n"},"status":{"$ref":"#/components/schemas/BatchStatus"},"request_counts":{"$ref":"#/components/schemas/BatchCountsBody"},"created_at":{"$ref":"#/components/schemas/EpochMillis"},"completed_at":{"$ref":"#/components/schemas/NullableEpochMillis"},"failed_at":{"$ref":"#/components/schemas/NullableEpochMillis"}}},"BatchStatus":{"type":"string","description":"Aggregate status of a PBR batch.\n\nPossible enum values:\n- `QUEUED`: the batch is waiting to start.\n- `RUNNING`: at least one item is being processed.\n- `COMPLETED`: every item succeeded.\n- `PARTIALLY_COMPLETED`: the batch finished with a mix of successes and\n  failures.\n- `FAILED`: every item failed.\n","enum":["QUEUED","RUNNING","COMPLETED","PARTIALLY_COMPLETED","FAILED"]},"BatchCountsBody":{"type":"object","required":["total","completed","failed","pending"],"description":"Count of items in a batch, grouped by status.\n","properties":{"total":{"type":"integer","description":"Total number of items in the batch.\n"},"completed":{"type":"integer","description":"Number of items that have reached a terminal state, whether they\nsucceeded or failed.\n"},"failed":{"type":"integer","description":"Number of items that failed.\n"},"pending":{"type":"integer","description":"Number of items that are still queued or running.\n"}}},"EpochMillis":{"type":"integer","format":"int64","description":"Time represented as milliseconds since the Unix epoch.\n"},"NullableEpochMillis":{"type":["integer","null"],"format":"int64","description":"Time represented as milliseconds since the Unix epoch, or `null` when the\nfield has not been set.\n"}}}}
```

## The UploadRequest object

```json
{"openapi":"3.1.0","info":{"title":"Marso Studio API","version":"0.0.1"},"components":{"schemas":{"UploadRequest":{"type":"object","required":["filename","size_bytes"],"description":"Request body for `POST /uploads`. Describes the one file you want to\nupload.\n","properties":{"filename":{"type":"string","description":"The name of the file, including its extension. The extension selects\nthe asset type and must be one of `.usd`, `.glb`, `.jpg`, `.jpeg`, or\n`.png`.\n"},"content_type":{"type":"string","description":"The MIME type of the file. Optional: it is inferred from the file\nextension when omitted. When present it must match the extension.\n"},"size_bytes":{"type":"integer","format":"int64","description":"The exact size of the file in bytes. It is signed into the upload URL\nas `Content-Length`, so the bytes you PUT must match it exactly. Must\nbe at least 1, and no more than 5 MB for an image or 100 MB for a mesh.\n"}}}}}}
```

## The UploadResponse object

```json
{"openapi":"3.1.0","info":{"title":"Marso Studio API","version":"0.0.1"},"components":{"schemas":{"UploadResponse":{"type":"object","required":["asset_id","upload_url"],"description":"Presigned upload URL and metadata returned by `POST /uploads`. There is no\nupload batch ID: a single upload is polled with\n`GET /uploads/{asset_id}`.\n","properties":{"asset_id":{"type":"string","description":"The ID of the pending asset created for this file. Use it to poll the\nupload and, once the status is `ready`, to submit the asset for PBR\ngeneration.\n"},"upload_url":{"type":"string","format":"uri","description":"Presigned S3 PUT URL. Upload the raw file bytes to this URL using the\nheaders provided in `headers`.\n"},"headers":{"type":"object","additionalProperties":{"type":"string"},"description":"Every header you must send verbatim with the PUT request. This includes\n`Content-Type`, `Content-Length`, and any `x-amz-meta-*` metadata\nheaders. All headers are bound into the signature, so omitting or\naltering any of them causes S3 to reject the upload.\n"}}}}}}
```

## The UploadStatusResponse object

```json
{"openapi":"3.1.0","info":{"title":"Marso Studio API","version":"0.0.1"},"components":{"schemas":{"UploadStatusResponse":{"type":"object","required":["asset_id","file_name","status","created_at"],"description":"The validation status of one file uploaded with `POST /uploads`.\n","properties":{"asset_id":{"type":"string","description":"The ID of the asset created for this file.\n"},"file_name":{"type":"string","description":"The file name as provided in the upload request.\n"},"status":{"type":"string","enum":["pending","ready","rejected"],"description":"The validation status of this file.\n\nPossible enum values:\n- `pending`: the file has not been validated yet.\n- `ready`: the file passed validation and can be used for PBR generation.\n- `rejected`: the file failed validation. The file must be uploaded again.\n"},"created_at":{"$ref":"#/components/schemas/EpochMillis"}}},"EpochMillis":{"type":"integer","format":"int64","description":"Time represented as milliseconds since the Unix epoch.\n"}}}}
```

## The CreatePBRMeshExecutionRequest object

```json
{"openapi":"3.1.0","info":{"title":"Marso Studio API","version":"0.0.1"},"components":{"schemas":{"CreatePBRMeshExecutionRequest":{"type":"object","required":["asset_id"],"description":"Request body for `POST /pbr/execute/mesh`. Submit one ready mesh asset\nfor PBR generation.\n","properties":{"asset_id":{"type":"string","format":"uuid","description":"The ID of the mesh asset to process. Upload it with `POST /uploads`\nor `POST /batch/uploads` first. Its status must be `ready`.\n"},"options":{"$ref":"#/components/schemas/PublicPBRMeshOptions"}}},"PublicPBRMeshOptions":{"type":"object","additionalProperties":false,"description":"Tuning options for a mesh PBR run. Every field is optional, and an\nomitted field uses the system default.\n\nThis is the image options plus `output_2d`, the 1 mesh-only option. It\nneeds a stage the image pipeline skips, so it appears on the mesh\nendpoints only. An image endpoint rejects it.\n\n**Every mesh result carries a USDZ.** The export is no longer an\noption. `output_3d` is gone, and a request that carries it gets a\n`400`. The pipeline always packages `material.usdz` for a mesh run,\nand the result lists it beside the texture maps.\n\nThis object rejects a field it does not declare, the same way\n`PublicPBRImageOptions` rejects one. Issue #2175 removed the same 6\noptions from both, and it removed `output_3d` from this object alone.\n\n4 of the 6 changed a mesh result before the removal. A mesh run now uses\nthe deployed value for each: 16 views, the `quality` solver profile, the\n`coverage` blend mode, and a bake at 4096. The PBR options reference\nholds the per-option detail. Delete these fields from your request body,\nbecause the endpoint now rejects them.\n","properties":{"detail_transfer":{"$ref":"#/components/schemas/PublicPBRDetailTransfer"},"output_2d":{"$ref":"#/components/schemas/PublicPBROutput2D"}}},"PublicPBRDetailTransfer":{"type":"object","additionalProperties":false,"description":"Settings for detail transfer during PBR generation.\n\nThis object lost `magnitude_only`. The pipeline tunes that value for\neach texture pass, so 1 value you send could only flatten the tuning.\n","properties":{"enabled":{"type":["boolean","null"],"default":true,"description":"Whether detail transfer is enabled. An omitted field, and an\nexplicit `null`, both leave the stage on.\n"}}},"PublicPBROutput2D":{"type":"object","additionalProperties":false,"description":"Container for 2D output options. All fields are optional; omitted fields\nuse system defaults.\n\nThis object lost `video`. The pipeline holds no video stage and no\nturntable stage.\n","properties":{"orm":{"$ref":"#/components/schemas/PublicPBROutput2DORM"}}},"PublicPBROutput2DORM":{"type":"object","additionalProperties":false,"description":"Settings for an occlusion/roughness/metallic (ORM) combined 2D output\nmap.\n\n**No result carries the ORM map yet.** The 2 mesh endpoints accept the\noption today, and the pipeline stage that packs the map is still in\nbuild. The option never fails a run, and it changes no result until that\nstage ships.\n","properties":{"enabled":{"type":["boolean","null"],"default":false,"description":"Whether to generate the ORM map. An omitted field, and an explicit\n`null`, both leave the map off.\nNo result carries the map yet, as the object description states.\n"},"channel_order":{"type":"string","enum":["ORM","RMO","MRO"],"default":"ORM","description":"Channel order for the combined map. An omitted field packs the\nchannels in the `ORM` order.\n\nPossible enum values:\n- `ORM`: occlusion, roughness, metallic.\n- `RMO`: roughness, metallic, occlusion.\n- `MRO`: metallic, roughness, occlusion.\n"}}}}}}
```

## The CreatePBRImageExecutionRequest object

```json
{"openapi":"3.1.0","info":{"title":"Marso Studio API","version":"0.0.1"},"components":{"schemas":{"CreatePBRImageExecutionRequest":{"type":"object","required":["asset_id"],"description":"Request body for `POST /pbr/execute/image`. Submit one ready image asset\nfor PBR generation. It has the same shape as\n`CreatePBRMeshExecutionRequest`, except for the options. The image path\ntakes no `output_2d`, because that option needs a stage the image\npipeline skips.\n","properties":{"asset_id":{"type":"string","format":"uuid","description":"The ID of the image asset to process. Upload it with\n`POST /uploads` or `POST /batch/uploads` first. Its status must be\n`ready`.\n"},"options":{"$ref":"#/components/schemas/PublicPBRImageOptions"}}},"PublicPBRImageOptions":{"type":"object","additionalProperties":false,"description":"Tuning options for an image PBR run. Every field is optional, and an\nomitted field uses the system default.\n\nThe image pipeline runs inference only. It reaches neither the 3D\ncontainer stage nor the packed 2D map stage, so `output_2d` appears on\nthe mesh endpoints only, and no image result carries a USDZ.\n`detail_transfer` is the whole surface here.\n\nThis object rejects a field it does not declare. Issue #2175 removed\n`pbr_mode`, `blend_mode`, `coverage`, `texture`,\n`detail_transfer.magnitude_only` and `output_2d.video`. A request that\nstill carries 1 of them gets a 400, and the message names the field.\nDelete them from your request body. The PBR options reference states\nwhat each removal changed.\n","properties":{"detail_transfer":{"$ref":"#/components/schemas/PublicPBRDetailTransfer"}}},"PublicPBRDetailTransfer":{"type":"object","additionalProperties":false,"description":"Settings for detail transfer during PBR generation.\n\nThis object lost `magnitude_only`. The pipeline tunes that value for\neach texture pass, so 1 value you send could only flatten the tuning.\n","properties":{"enabled":{"type":["boolean","null"],"default":true,"description":"Whether detail transfer is enabled. An omitted field, and an\nexplicit `null`, both leave the stage on.\n"}}}}}}
```

## The PBRExecutionResponse object

```json
{"openapi":"3.1.0","info":{"title":"Marso Studio API","version":"0.0.1"},"components":{"schemas":{"PBRExecutionResponse":{"type":"object","required":["execution_id","status","created_at"],"description":"Body returned by `POST /pbr/execute/*` (202) and\n`GET /pbr/executions/{execution_id}` (200). It describes one execution and\nis not a batch envelope: there is no batch ID, no counts, and no items\narray.\n\nOn submission every result field is empty, because nothing has finished\nyet. `asset_id` is the source asset you submitted, so a failed execution is\nalways traceable to its input. `pbr_material_assets` maps each\n`\"<slot>/<pass>\"` to its generated texture asset and a ready-to-use\n`download_url`. `thumbnail_url` is a preview image, always present on a\nsucceeded mesh execution, and best-effort on a succeeded image execution.\n`error` is set only when the execution failed.\n","properties":{"execution_id":{"type":"string","description":"Unique identifier of the execution. Poll it at\n`GET /pbr/executions/{execution_id}`.\n"},"asset_id":{"type":"string","description":"The ID of the source asset that was submitted.\n"},"status":{"$ref":"#/components/schemas/ExecutionStatus"},"thumbnail_url":{"type":"string","format":"uri","description":"URL of a preview image. Always present on a succeeded mesh execution;\nbest-effort on a succeeded image execution.\n"},"thumbnail_url_expires_at":{"$ref":"#/components/schemas/EpochMillis"},"pbr_material_assets":{"type":"object","description":"Map from `\"<slot>/<pass>\"` to the generated texture asset. Only present\non a succeeded execution.\n","additionalProperties":{"$ref":"#/components/schemas/BatchMaterialAssetBody"}},"error":{"$ref":"#/components/schemas/ExecutionErrorBody"},"created_at":{"$ref":"#/components/schemas/EpochMillis"},"completed_at":{"$ref":"#/components/schemas/NullableEpochMillis"}}},"ExecutionStatus":{"type":"string","description":"Status of a single item within a batch.\n\nPossible enum values:\n- `QUEUED`: the item is waiting to start.\n- `RUNNING`: the item is being processed.\n- `SUCCEEDED`: the item completed successfully.\n- `PARTIAL_SUCCEEDED`: the item completed but some optional outputs are\n  missing.\n- `FAILED`: the item failed. See the `error` field for details.\n","enum":["QUEUED","RUNNING","SUCCEEDED","PARTIAL_SUCCEEDED","FAILED"]},"EpochMillis":{"type":"integer","format":"int64","description":"Time represented as milliseconds since the Unix epoch.\n"},"BatchMaterialAssetBody":{"type":"object","required":["asset_id"],"description":"One generated PBR result asset within a batch item. `download_url` is a\nready-to-use link that expires at `expires_at`.\n","properties":{"asset_id":{"type":"string","description":"ID of the generated asset.\n"},"download_url":{"type":"string","format":"uri","description":"Presigned URL for downloading the generated asset. Valid until\n`expires_at`.\n"},"expires_at":{"$ref":"#/components/schemas/EpochMillis"}}},"ExecutionErrorBody":{"type":"object","description":"Failure detail for a failed batch item. The `code` is a stable,\nmachine-readable class drawn from a closed enum so clients can branch on\nthe failure kind. The `message` carries human-readable detail. Only\n`VALIDATION_FAILED` is permanent; do not retry the same input. The other\ncodes are generally retryable.\n","required":["code","message"],"properties":{"code":{"type":"string","enum":["VALIDATION_FAILED","PIPELINE_ERROR","TIMEOUT","INTERNAL"],"description":"Machine-readable class of the failure.\n\nPossible enum values:\n- `VALIDATION_FAILED`: the input is unsuitable or invalid. This is a\n  permanent failure; retrying the same input will not succeed.\n- `PIPELINE_ERROR`: the PBR pipeline attempted the item but failed.\n  Generally retryable.\n- `TIMEOUT`: the item exceeded its time budget. Generally retryable.\n- `INTERNAL`: an internal orchestration fault. Generally retryable.\n"},"message":{"type":"string","description":"Human-readable explanation of the failure.\n"}}},"NullableEpochMillis":{"type":["integer","null"],"format":"int64","description":"Time represented as milliseconds since the Unix epoch, or `null` when the\nfield has not been set.\n"}}}}
```

## The PublicGroupedAssetItem object

```json
{"openapi":"3.1.0","info":{"title":"Marso Studio API","version":"0.0.1"},"components":{"schemas":{"PublicGroupedAssetItem":{"type":"object","required":["id","name","model_version"],"description":"One PBR asset in a grouped listing.\n","properties":{"id":{"type":"string","description":"Identifier of the PBR asset. Pass this to `POST /assets/download` to get\ndownload URLs for the 3D model and all of its texture maps.\n"},"name":{"type":"string","description":"The display name from the asset library. If the library has no stored\nname, this is the source file name without its extension.\n"},"file_name":{"type":"string","description":"File name of the SOURCE 3D MODEL this PBR asset was generated from.\n"},"thumbnail_url":{"type":"string","format":"uri","description":"Presigned URL for the PBR asset's thumbnail. Valid for about 1 minute.\n"},"thumbnail_url_expires_at":{"$ref":"#/components/schemas/EpochMillis"},"model_version":{"type":"string","description":"The img2mat model that produced this PBR asset, for example\n`M-XR I2M v1.2`. A PBR asset created before the platform recorded the\nmodel reports `M-XR I2M v1.0`, the first release. Always present.\n"}}},"EpochMillis":{"type":"integer","format":"int64","description":"Time represented as milliseconds since the Unix epoch.\n"}}}}
```

## The PublicAssetGroupItem object

```json
{"openapi":"3.1.0","info":{"title":"Marso Studio API","version":"0.0.1"},"components":{"schemas":{"PublicAssetGroupItem":{"type":"object","required":["group_id","assets"],"description":"One project and the PBR assets it produced.\n","properties":{"group_id":{"type":"string","description":"Identifier of the project.\n"},"name":{"type":"string","description":"Name of the project.\n"},"thumbnail_url":{"type":"string","format":"uri","description":"Presigned URL for the project's thumbnail. Valid for about 1 minute.\nAbsent when the project has no thumbnail resolved yet.\n"},"thumbnail_url_expires_at":{"$ref":"#/components/schemas/EpochMillis"},"assets":{"type":"array","description":"The project's PBR assets. This list is complete: every asset the project\nholds is included, however long the derivation history behind it.\n","items":{"$ref":"#/components/schemas/PublicGroupedAssetItem"}}}},"EpochMillis":{"type":"integer","format":"int64","description":"Time represented as milliseconds since the Unix epoch.\n"},"PublicGroupedAssetItem":{"type":"object","required":["id","name","model_version"],"description":"One PBR asset in a grouped listing.\n","properties":{"id":{"type":"string","description":"Identifier of the PBR asset. Pass this to `POST /assets/download` to get\ndownload URLs for the 3D model and all of its texture maps.\n"},"name":{"type":"string","description":"The display name from the asset library. If the library has no stored\nname, this is the source file name without its extension.\n"},"file_name":{"type":"string","description":"File name of the SOURCE 3D MODEL this PBR asset was generated from.\n"},"thumbnail_url":{"type":"string","format":"uri","description":"Presigned URL for the PBR asset's thumbnail. Valid for about 1 minute.\n"},"thumbnail_url_expires_at":{"$ref":"#/components/schemas/EpochMillis"},"model_version":{"type":"string","description":"The img2mat model that produced this PBR asset, for example\n`M-XR I2M v1.2`. A PBR asset created before the platform recorded the\nmodel reports `M-XR I2M v1.0`, the first release. Always present.\n"}}}}}}
```

## The PublicPagination object

```json
{"openapi":"3.1.0","info":{"title":"Marso Studio API","version":"0.0.1"},"components":{"schemas":{"PublicPagination":{"type":"object","required":["has_more"],"description":"Cursor pagination envelope.\n","properties":{"next_cursor":{"type":"string","description":"Opaque cursor for the next page. Absent when the result set is\nexhausted. Echo it back verbatim as `cursor`.\n"},"has_more":{"type":"boolean","description":"Whether another page follows. Always agrees with the presence of\n`next_cursor`.\n"}}}}}}
```

## The PublicGroupedAssetListResponse object

```json
{"openapi":"3.1.0","info":{"title":"Marso Studio API","version":"0.0.1"},"components":{"schemas":{"PublicGroupedAssetListResponse":{"type":"object","required":["group_by","data","pagination"],"description":"Response from `GET /assets`: your PBR assets grouped by the project that\nproduced them, then the ones belonging to no project.\n\n`data` and `ungrouped_assets` form ONE ordered sequence under a single\ncursor. Every group first, then the ungrouped assets. Just follow\n`pagination.next_cursor` until `has_more` is false.\n\nA cursor is a position in that one sequence, and what it points at differs\neither side of the boundary between the two parts. Treat it as opaque and\nshort-lived: echo the one you were just given, and start a fresh traversal\nrather than storing a cursor and replaying it later.\n","properties":{"group_by":{"type":"string","enum":["projects"],"description":"How the response is grouped, echoing the request.\n"},"data":{"type":"array","description":"Project groups, newest project first.\n","items":{"$ref":"#/components/schemas/PublicAssetGroupItem"}},"ungrouped_assets":{"type":"array","description":"PBR assets that belong to no project, which is where every asset\ncreated through this API arrives. Absent while the response is still\npaging through groups.\n","items":{"$ref":"#/components/schemas/PublicGroupedAssetItem"}},"errors":{"type":"array","description":"Entries on this page that could be served only partially. The entry itself is\nstill returned, in `data` or `ungrouped_assets`, with the affected field empty.\nAbsent when everything on the page resolved.\n\nThis exists so a partial result is visible rather than silent. An entry whose\nthumbnail URL could not be signed arrives with an empty `thumbnail_url` and a\nrow here, which is what lets you tell \"this material has no preview\" from \"we\ncould not give you its preview\". One such entry never costs you the page.\n","items":{"$ref":"#/components/schemas/PublicAssetErrorItem"}},"pagination":{"$ref":"#/components/schemas/PublicPagination"}}},"PublicAssetGroupItem":{"type":"object","required":["group_id","assets"],"description":"One project and the PBR assets it produced.\n","properties":{"group_id":{"type":"string","description":"Identifier of the project.\n"},"name":{"type":"string","description":"Name of the project.\n"},"thumbnail_url":{"type":"string","format":"uri","description":"Presigned URL for the project's thumbnail. Valid for about 1 minute.\nAbsent when the project has no thumbnail resolved yet.\n"},"thumbnail_url_expires_at":{"$ref":"#/components/schemas/EpochMillis"},"assets":{"type":"array","description":"The project's PBR assets. This list is complete: every asset the project\nholds is included, however long the derivation history behind it.\n","items":{"$ref":"#/components/schemas/PublicGroupedAssetItem"}}}},"EpochMillis":{"type":"integer","format":"int64","description":"Time represented as milliseconds since the Unix epoch.\n"},"PublicGroupedAssetItem":{"type":"object","required":["id","name","model_version"],"description":"One PBR asset in a grouped listing.\n","properties":{"id":{"type":"string","description":"Identifier of the PBR asset. Pass this to `POST /assets/download` to get\ndownload URLs for the 3D model and all of its texture maps.\n"},"name":{"type":"string","description":"The display name from the asset library. If the library has no stored\nname, this is the source file name without its extension.\n"},"file_name":{"type":"string","description":"File name of the SOURCE 3D MODEL this PBR asset was generated from.\n"},"thumbnail_url":{"type":"string","format":"uri","description":"Presigned URL for the PBR asset's thumbnail. Valid for about 1 minute.\n"},"thumbnail_url_expires_at":{"$ref":"#/components/schemas/EpochMillis"},"model_version":{"type":"string","description":"The img2mat model that produced this PBR asset, for example\n`M-XR I2M v1.2`. A PBR asset created before the platform recorded the\nmodel reports `M-XR I2M v1.0`, the first release. Always present.\n"}}},"PublicAssetErrorItem":{"type":"object","required":["asset_id","code","message"],"description":"One entry a listing could serve only partially.\n","properties":{"asset_id":{"type":"string","description":"The ID of the entry this error belongs to. It matches the `id` of an entry in\nthe same response, so the two can be joined.\n"},"file_name":{"type":"string","description":"That entry's file name, so the error is legible without looking the ID up.\nAbsent only when the entry carries no name of its own.\n"},"code":{"type":"string","enum":["THUMBNAIL_URL_UNAVAILABLE"],"description":"Possible enum values:\n\n`THUMBNAIL_URL_UNAVAILABLE`: the entry's thumbnail URL could not be signed.\nThe entry is present with an empty `thumbnail_url`, and everything else about\nit is complete. Worth retrying.\n"},"message":{"type":"string","description":"Human-readable explanation.\n"}}},"PublicPagination":{"type":"object","required":["has_more"],"description":"Cursor pagination envelope.\n","properties":{"next_cursor":{"type":"string","description":"Opaque cursor for the next page. Absent when the result set is\nexhausted. Echo it back verbatim as `cursor`.\n"},"has_more":{"type":"boolean","description":"Whether another page follows. Always agrees with the presence of\n`next_cursor`.\n"}}}}}}
```

## The PublicAssetErrorItem object

```json
{"openapi":"3.1.0","info":{"title":"Marso Studio API","version":"0.0.1"},"components":{"schemas":{"PublicAssetErrorItem":{"type":"object","required":["asset_id","code","message"],"description":"One entry a listing could serve only partially.\n","properties":{"asset_id":{"type":"string","description":"The ID of the entry this error belongs to. It matches the `id` of an entry in\nthe same response, so the two can be joined.\n"},"file_name":{"type":"string","description":"That entry's file name, so the error is legible without looking the ID up.\nAbsent only when the entry carries no name of its own.\n"},"code":{"type":"string","enum":["THUMBNAIL_URL_UNAVAILABLE"],"description":"Possible enum values:\n\n`THUMBNAIL_URL_UNAVAILABLE`: the entry's thumbnail URL could not be signed.\nThe entry is present with an empty `thumbnail_url`, and everything else about\nit is complete. Worth retrying.\n"},"message":{"type":"string","description":"Human-readable explanation.\n"}}}}}}
```

## The PublicAssetBulkDownloadRequest object

```json
{"openapi":"3.1.0","info":{"title":"Marso Studio API","version":"0.0.1"},"components":{"schemas":{"PublicAssetBulkDownloadRequest":{"type":"object","required":["asset_ids"],"description":"Request body for `POST /assets/download`. The asset IDs you want download\nURLs for.\n","properties":{"asset_ids":{"type":"array","minItems":1,"maxItems":100,"description":"Asset IDs to mint download URLs for. Repeated IDs collapse to a single\nentry. Every ID must be a well-formed asset ID. One malformed value\nrejects the whole request.\n","items":{"type":"string","format":"uuid"}}}}}}}
```

## The PublicAssetBulkDownloadFile object

```json
{"openapi":"3.1.0","info":{"title":"Marso Studio API","version":"0.0.1"},"components":{"schemas":{"PublicAssetBulkDownloadFile":{"type":"object","required":["asset_id","role","download_url","expires_at"],"description":"One downloadable object within a resolved entry.\n","properties":{"asset_id":{"type":"string","description":"Unique identifier of this file's asset.\n"},"role":{"type":"string","enum":["source","texture","usdz","asset"],"description":"The part this file plays in its entry. A role never tells you the file's\nkind; read the sibling `type` field for that.\n\nPossible enum values:\n- `source`: the asset the PBR material was generated from: a 3D mesh for\n  a mesh batch, an image for an image batch.\n- `texture`: a PBR map. The `pass` field names which one.\n- `usdz`: the USDZ variant of the model.\n- `asset`: a plain (non-PBR) asset, which yields exactly one file.\n"},"pass":{"type":"string","description":"For `texture` files, which PBR map this is (for example `albedo`,\n`metallic`, `roughness`, `normal`).\n"},"type":{"type":"string","description":"Physical type of this file's asset.\n"},"size_bytes":{"type":"integer","format":"int64","description":"Size of this file in bytes.\n"},"download_url":{"type":"string","format":"uri","description":"Presigned URL for downloading this file. Valid for about 2 minutes.\n"},"expires_at":{"$ref":"#/components/schemas/EpochMillis"}}},"EpochMillis":{"type":"integer","format":"int64","description":"Time represented as milliseconds since the Unix epoch.\n"}}}}
```

## The PublicAssetBulkDownloadItem object

```json
{"openapi":"3.1.0","info":{"title":"Marso Studio API","version":"0.0.1"},"components":{"schemas":{"PublicAssetBulkDownloadItem":{"type":"object","required":["asset_id","files"],"description":"One resolved asset ID and every file it resolves to. A PBR material\nresolves to its 3D model plus all of its texture maps (and its USDZ where\none exists), so one request collects a whole material rather than one\nrequest per file. A plain asset resolves to a single file.\n","properties":{"asset_id":{"type":"string","description":"The submitted asset ID this entry belongs to.\n"},"type":{"type":"string","description":"Type of the requested asset.\n"},"file_name":{"type":"string","description":"Name for the entry. For a PBR material this is the source 3D model's\nfile name.\n"},"files":{"type":"array","minItems":1,"description":"Every downloadable file for this entry, each with its own presigned\nURL. Never empty. An ID that resolves to no file is reported in\n`errors` instead.\n","items":{"$ref":"#/components/schemas/PublicAssetBulkDownloadFile"}}}},"PublicAssetBulkDownloadFile":{"type":"object","required":["asset_id","role","download_url","expires_at"],"description":"One downloadable object within a resolved entry.\n","properties":{"asset_id":{"type":"string","description":"Unique identifier of this file's asset.\n"},"role":{"type":"string","enum":["source","texture","usdz","asset"],"description":"The part this file plays in its entry. A role never tells you the file's\nkind; read the sibling `type` field for that.\n\nPossible enum values:\n- `source`: the asset the PBR material was generated from: a 3D mesh for\n  a mesh batch, an image for an image batch.\n- `texture`: a PBR map. The `pass` field names which one.\n- `usdz`: the USDZ variant of the model.\n- `asset`: a plain (non-PBR) asset, which yields exactly one file.\n"},"pass":{"type":"string","description":"For `texture` files, which PBR map this is (for example `albedo`,\n`metallic`, `roughness`, `normal`).\n"},"type":{"type":"string","description":"Physical type of this file's asset.\n"},"size_bytes":{"type":"integer","format":"int64","description":"Size of this file in bytes.\n"},"download_url":{"type":"string","format":"uri","description":"Presigned URL for downloading this file. Valid for about 2 minutes.\n"},"expires_at":{"$ref":"#/components/schemas/EpochMillis"}}},"EpochMillis":{"type":"integer","format":"int64","description":"Time represented as milliseconds since the Unix epoch.\n"}}}}
```

## The PublicAssetBulkDownloadError object

```json
{"openapi":"3.1.0","info":{"title":"Marso Studio API","version":"0.0.1"},"components":{"schemas":{"PublicAssetBulkDownloadError":{"type":"object","required":["asset_id","code","message"],"description":"One asset ID that produced no download URL.\n","properties":{"asset_id":{"type":"string","description":"The submitted asset ID this failure belongs to.\n"},"file_name":{"type":"string","description":"The asset's own file name, so the failure is legible without looking the ID\nup. Present when the asset resolved far enough to have a name, and absent\nfor `ASSET_NOT_FOUND`, where nothing was resolved.\n"},"code":{"type":"string","enum":["ASSET_NOT_FOUND","DOWNLOAD_URL_UNAVAILABLE"],"description":"`ASSET_NOT_FOUND`: no such asset, or it belongs to another account.\nThe two are reported identically on purpose.\n`DOWNLOAD_URL_UNAVAILABLE`: the asset is yours but a URL could not be\nminted for it this time. Worth retrying.\n"},"message":{"type":"string","description":"Human-readable explanation.\n"}}}}}}
```

## The PublicAssetBulkDownloadResponse object

```json
{"openapi":"3.1.0","info":{"title":"Marso Studio API","version":"0.0.1"},"components":{"schemas":{"PublicAssetBulkDownloadResponse":{"type":"object","required":["assets","errors"],"description":"Response from `POST /assets/download`. Together `assets` and `errors`\naccount for every distinct asset ID submitted.\n","properties":{"assets":{"type":"array","description":"Resolved assets with download URLs, in the order the IDs were\nsubmitted (after duplicates are collapsed).\n","items":{"$ref":"#/components/schemas/PublicAssetBulkDownloadItem"}},"errors":{"type":"array","description":"One entry per submitted ID that could not be resolved. Empty when\nevery ID resolved.\n","items":{"$ref":"#/components/schemas/PublicAssetBulkDownloadError"}}}},"PublicAssetBulkDownloadItem":{"type":"object","required":["asset_id","files"],"description":"One resolved asset ID and every file it resolves to. A PBR material\nresolves to its 3D model plus all of its texture maps (and its USDZ where\none exists), so one request collects a whole material rather than one\nrequest per file. A plain asset resolves to a single file.\n","properties":{"asset_id":{"type":"string","description":"The submitted asset ID this entry belongs to.\n"},"type":{"type":"string","description":"Type of the requested asset.\n"},"file_name":{"type":"string","description":"Name for the entry. For a PBR material this is the source 3D model's\nfile name.\n"},"files":{"type":"array","minItems":1,"description":"Every downloadable file for this entry, each with its own presigned\nURL. Never empty. An ID that resolves to no file is reported in\n`errors` instead.\n","items":{"$ref":"#/components/schemas/PublicAssetBulkDownloadFile"}}}},"PublicAssetBulkDownloadFile":{"type":"object","required":["asset_id","role","download_url","expires_at"],"description":"One downloadable object within a resolved entry.\n","properties":{"asset_id":{"type":"string","description":"Unique identifier of this file's asset.\n"},"role":{"type":"string","enum":["source","texture","usdz","asset"],"description":"The part this file plays in its entry. A role never tells you the file's\nkind; read the sibling `type` field for that.\n\nPossible enum values:\n- `source`: the asset the PBR material was generated from: a 3D mesh for\n  a mesh batch, an image for an image batch.\n- `texture`: a PBR map. The `pass` field names which one.\n- `usdz`: the USDZ variant of the model.\n- `asset`: a plain (non-PBR) asset, which yields exactly one file.\n"},"pass":{"type":"string","description":"For `texture` files, which PBR map this is (for example `albedo`,\n`metallic`, `roughness`, `normal`).\n"},"type":{"type":"string","description":"Physical type of this file's asset.\n"},"size_bytes":{"type":"integer","format":"int64","description":"Size of this file in bytes.\n"},"download_url":{"type":"string","format":"uri","description":"Presigned URL for downloading this file. Valid for about 2 minutes.\n"},"expires_at":{"$ref":"#/components/schemas/EpochMillis"}}},"EpochMillis":{"type":"integer","format":"int64","description":"Time represented as milliseconds since the Unix epoch.\n"},"PublicAssetBulkDownloadError":{"type":"object","required":["asset_id","code","message"],"description":"One asset ID that produced no download URL.\n","properties":{"asset_id":{"type":"string","description":"The submitted asset ID this failure belongs to.\n"},"file_name":{"type":"string","description":"The asset's own file name, so the failure is legible without looking the ID\nup. Present when the asset resolved far enough to have a name, and absent\nfor `ASSET_NOT_FOUND`, where nothing was resolved.\n"},"code":{"type":"string","enum":["ASSET_NOT_FOUND","DOWNLOAD_URL_UNAVAILABLE"],"description":"`ASSET_NOT_FOUND`: no such asset, or it belongs to another account.\nThe two are reported identically on purpose.\n`DOWNLOAD_URL_UNAVAILABLE`: the asset is yours but a URL could not be\nminted for it this time. Worth retrying.\n"},"message":{"type":"string","description":"Human-readable explanation.\n"}}}}}}
```

## The PublicAssetDetailResponse object

```json
{"openapi":"3.1.0","info":{"title":"Marso Studio API","version":"0.0.1"},"components":{"schemas":{"PublicAssetDetailResponse":{"type":"object","required":["asset_id","name","type","size_bytes","created_at","download_url","expires_at"],"description":"Response from `GET /assets/{asset_id}` for a regular asset. Contains the\nasset metadata and a presigned download URL.\n","properties":{"asset_id":{"type":"string","description":"Unique identifier of the asset.\n"},"name":{"type":"string","description":"The display name from the asset library. If the library has no stored\nname, this is the file name without its extension.\n"},"type":{"type":"string","description":"Physical type of the asset.\n"},"size_bytes":{"type":"integer","format":"int64","description":"Size of the asset in bytes.\n"},"created_at":{"$ref":"#/components/schemas/EpochMillis"},"download_url":{"type":"string","format":"uri","description":"Presigned URL for downloading the asset. Valid for about 1 minute.\n"},"expires_at":{"$ref":"#/components/schemas/EpochMillis"}}},"EpochMillis":{"type":"integer","format":"int64","description":"Time represented as milliseconds since the Unix epoch.\n"}}}}
```

## The PublicPBRMaterialAsset object

```json
{"openapi":"3.1.0","info":{"title":"Marso Studio API","version":"0.0.1"},"components":{"schemas":{"PublicPBRMaterialAsset":{"type":"object","required":["asset_id","download_url","expires_at"],"description":"One component of a PBR material result: the asset it was generated from, a\ntexture map, or a USDZ bundle. The component is itself an asset with a\npresigned download URL.\n","properties":{"asset_id":{"type":"string","description":"Unique identifier of the component asset.\n"},"type":{"type":"string","description":"Physical type of the component asset.\n"},"download_url":{"type":"string","format":"uri","description":"Presigned URL for downloading the component. Valid until `expires_at`.\n"},"expires_at":{"$ref":"#/components/schemas/EpochMillis"}}},"EpochMillis":{"type":"integer","format":"int64","description":"Time represented as milliseconds since the Unix epoch.\n"}}}}
```

## The PublicPBRMaterialInfo object

```json
{"openapi":"3.1.0","info":{"title":"Marso Studio API","version":"0.0.1"},"components":{"schemas":{"PublicPBRMaterialInfo":{"type":"object","required":["slot_name","gltf_material_index"],"description":"Metadata about the material within a PBR material result.\n","properties":{"slot_name":{"type":"string","description":"The material slot name in the source asset. `default` for a\nsingle-material mesh and for every image-sourced material.\n"},"display_name":{"type":"string","description":"Human-readable name of the material.\n"},"gltf_material_index":{"type":["integer","null"],"description":"Zero-based glTF material index. `null` for legacy single-material\nresults.\n"}}}}}}
```

## The PublicPBRMaterialDetailResponse object

```json
{"openapi":"3.1.0","info":{"title":"Marso Studio API","version":"0.0.1"},"components":{"schemas":{"PublicPBRMaterialDetailResponse":{"type":"object","required":["asset_id","name","type","created_at","url","source_execution_id","model_version","material","source","textures"],"description":"Response from `GET /assets/{asset_id}` for a PBR material asset.\nContains the material metadata, the asset the material was generated from,\nand the generated texture components.\n","properties":{"asset_id":{"type":"string","description":"Unique identifier of the PBR material asset.\n"},"name":{"type":"string","description":"The display name from the asset library. If the library has no stored\nname, this is the source file name without its extension.\n"},"type":{"type":"string","enum":["PBR_MATERIAL"],"description":"Always `PBR_MATERIAL` for this response type.\n"},"created_at":{"$ref":"#/components/schemas/EpochMillis"},"url":{"type":"string","format":"uri","description":"Presigned URL for downloading the main PBR material asset.\n"},"thumbnail_url":{"type":"string","format":"uri","description":"Presigned URL for a thumbnail preview of the result, if available.\n"},"thumbnail_url_expires_at":{"$ref":"#/components/schemas/EpochMillis"},"source_execution_id":{"type":"string","description":"ID of the execution that produced this PBR material result.\n"},"model_version":{"type":"string","description":"The img2mat model that produced this PBR asset, for example\n`M-XR I2M v1.2`. A PBR asset created before the platform recorded the\nmodel reports `M-XR I2M v1.0`, the first release. Always present, and\nthe same value `GET /assets` reports for this asset.\n"},"material":{"$ref":"#/components/schemas/PublicPBRMaterialInfo"},"source":{"allOf":[{"$ref":"#/components/schemas/PublicPBRMaterialAsset"}],"description":"The asset this PBR material was generated from: a 3D mesh for a mesh\nbatch, an image for an image batch. Read its `type` rather than assuming\nthe material came from a mesh.\n"},"textures":{"type":"object","description":"Map from texture map name to the generated texture asset.\n","additionalProperties":{"$ref":"#/components/schemas/PublicPBRMaterialAsset"}},"usdz":{"$ref":"#/components/schemas/PublicPBRMaterialAsset"},"available_formats":{"type":"array","description":"Additional downloadable formats available for this PBR material\nresult. Currently only `usdz` is returned, and only if the result\nproduced a USDZ component.\n","items":{"type":"string","enum":["usdz"]}}}},"EpochMillis":{"type":"integer","format":"int64","description":"Time represented as milliseconds since the Unix epoch.\n"},"PublicPBRMaterialInfo":{"type":"object","required":["slot_name","gltf_material_index"],"description":"Metadata about the material within a PBR material result.\n","properties":{"slot_name":{"type":"string","description":"The material slot name in the source asset. `default` for a\nsingle-material mesh and for every image-sourced material.\n"},"display_name":{"type":"string","description":"Human-readable name of the material.\n"},"gltf_material_index":{"type":["integer","null"],"description":"Zero-based glTF material index. `null` for legacy single-material\nresults.\n"}}},"PublicPBRMaterialAsset":{"type":"object","required":["asset_id","download_url","expires_at"],"description":"One component of a PBR material result: the asset it was generated from, a\ntexture map, or a USDZ bundle. The component is itself an asset with a\npresigned download URL.\n","properties":{"asset_id":{"type":"string","description":"Unique identifier of the component asset.\n"},"type":{"type":"string","description":"Physical type of the component asset.\n"},"download_url":{"type":"string","format":"uri","description":"Presigned URL for downloading the component. Valid until `expires_at`.\n"},"expires_at":{"$ref":"#/components/schemas/EpochMillis"}}}}}}
```

## The PublicAssetDeleteResponse object

```json
{"openapi":"3.1.0","info":{"title":"Marso Studio API","version":"0.0.1"},"components":{"schemas":{"PublicAssetDeleteResponse":{"type":"object","required":["asset_id","deleted"],"description":"Response from `DELETE /assets/{asset_id}`.\n","properties":{"asset_id":{"type":"string","description":"Unique identifier of the asset that was deleted.\n"},"deleted":{"type":"boolean","description":"Whether the asset was deleted. If the asset was already deleted or\ndid not exist, this may be `false`.\n"}}}}}}
```

## The PublicPBRDetailTransfer object

```json
{"openapi":"3.1.0","info":{"title":"Marso Studio API","version":"0.0.1"},"components":{"schemas":{"PublicPBRDetailTransfer":{"type":"object","additionalProperties":false,"description":"Settings for detail transfer during PBR generation.\n\nThis object lost `magnitude_only`. The pipeline tunes that value for\neach texture pass, so 1 value you send could only flatten the tuning.\n","properties":{"enabled":{"type":["boolean","null"],"default":true,"description":"Whether detail transfer is enabled. An omitted field, and an\nexplicit `null`, both leave the stage on.\n"}}}}}}
```

## The PublicPBROutput2DORM object

```json
{"openapi":"3.1.0","info":{"title":"Marso Studio API","version":"0.0.1"},"components":{"schemas":{"PublicPBROutput2DORM":{"type":"object","additionalProperties":false,"description":"Settings for an occlusion/roughness/metallic (ORM) combined 2D output\nmap.\n\n**No result carries the ORM map yet.** The 2 mesh endpoints accept the\noption today, and the pipeline stage that packs the map is still in\nbuild. The option never fails a run, and it changes no result until that\nstage ships.\n","properties":{"enabled":{"type":["boolean","null"],"default":false,"description":"Whether to generate the ORM map. An omitted field, and an explicit\n`null`, both leave the map off.\nNo result carries the map yet, as the object description states.\n"},"channel_order":{"type":"string","enum":["ORM","RMO","MRO"],"default":"ORM","description":"Channel order for the combined map. An omitted field packs the\nchannels in the `ORM` order.\n\nPossible enum values:\n- `ORM`: occlusion, roughness, metallic.\n- `RMO`: roughness, metallic, occlusion.\n- `MRO`: metallic, roughness, occlusion.\n"}}}}}}
```

## The PublicPBROutput2D object

```json
{"openapi":"3.1.0","info":{"title":"Marso Studio API","version":"0.0.1"},"components":{"schemas":{"PublicPBROutput2D":{"type":"object","additionalProperties":false,"description":"Container for 2D output options. All fields are optional; omitted fields\nuse system defaults.\n\nThis object lost `video`. The pipeline holds no video stage and no\nturntable stage.\n","properties":{"orm":{"$ref":"#/components/schemas/PublicPBROutput2DORM"}}},"PublicPBROutput2DORM":{"type":"object","additionalProperties":false,"description":"Settings for an occlusion/roughness/metallic (ORM) combined 2D output\nmap.\n\n**No result carries the ORM map yet.** The 2 mesh endpoints accept the\noption today, and the pipeline stage that packs the map is still in\nbuild. The option never fails a run, and it changes no result until that\nstage ships.\n","properties":{"enabled":{"type":["boolean","null"],"default":false,"description":"Whether to generate the ORM map. An omitted field, and an explicit\n`null`, both leave the map off.\nNo result carries the map yet, as the object description states.\n"},"channel_order":{"type":"string","enum":["ORM","RMO","MRO"],"default":"ORM","description":"Channel order for the combined map. An omitted field packs the\nchannels in the `ORM` order.\n\nPossible enum values:\n- `ORM`: occlusion, roughness, metallic.\n- `RMO`: roughness, metallic, occlusion.\n- `MRO`: metallic, roughness, occlusion.\n"}}}}}}
```

## The PublicPBRImageOptions object

```json
{"openapi":"3.1.0","info":{"title":"Marso Studio API","version":"0.0.1"},"components":{"schemas":{"PublicPBRImageOptions":{"type":"object","additionalProperties":false,"description":"Tuning options for an image PBR run. Every field is optional, and an\nomitted field uses the system default.\n\nThe image pipeline runs inference only. It reaches neither the 3D\ncontainer stage nor the packed 2D map stage, so `output_2d` appears on\nthe mesh endpoints only, and no image result carries a USDZ.\n`detail_transfer` is the whole surface here.\n\nThis object rejects a field it does not declare. Issue #2175 removed\n`pbr_mode`, `blend_mode`, `coverage`, `texture`,\n`detail_transfer.magnitude_only` and `output_2d.video`. A request that\nstill carries 1 of them gets a 400, and the message names the field.\nDelete them from your request body. The PBR options reference states\nwhat each removal changed.\n","properties":{"detail_transfer":{"$ref":"#/components/schemas/PublicPBRDetailTransfer"}}},"PublicPBRDetailTransfer":{"type":"object","additionalProperties":false,"description":"Settings for detail transfer during PBR generation.\n\nThis object lost `magnitude_only`. The pipeline tunes that value for\neach texture pass, so 1 value you send could only flatten the tuning.\n","properties":{"enabled":{"type":["boolean","null"],"default":true,"description":"Whether detail transfer is enabled. An omitted field, and an\nexplicit `null`, both leave the stage on.\n"}}}}}}
```

## The PublicPBRMeshOptions object

```json
{"openapi":"3.1.0","info":{"title":"Marso Studio API","version":"0.0.1"},"components":{"schemas":{"PublicPBRMeshOptions":{"type":"object","additionalProperties":false,"description":"Tuning options for a mesh PBR run. Every field is optional, and an\nomitted field uses the system default.\n\nThis is the image options plus `output_2d`, the 1 mesh-only option. It\nneeds a stage the image pipeline skips, so it appears on the mesh\nendpoints only. An image endpoint rejects it.\n\n**Every mesh result carries a USDZ.** The export is no longer an\noption. `output_3d` is gone, and a request that carries it gets a\n`400`. The pipeline always packages `material.usdz` for a mesh run,\nand the result lists it beside the texture maps.\n\nThis object rejects a field it does not declare, the same way\n`PublicPBRImageOptions` rejects one. Issue #2175 removed the same 6\noptions from both, and it removed `output_3d` from this object alone.\n\n4 of the 6 changed a mesh result before the removal. A mesh run now uses\nthe deployed value for each: 16 views, the `quality` solver profile, the\n`coverage` blend mode, and a bake at 4096. The PBR options reference\nholds the per-option detail. Delete these fields from your request body,\nbecause the endpoint now rejects them.\n","properties":{"detail_transfer":{"$ref":"#/components/schemas/PublicPBRDetailTransfer"},"output_2d":{"$ref":"#/components/schemas/PublicPBROutput2D"}}},"PublicPBRDetailTransfer":{"type":"object","additionalProperties":false,"description":"Settings for detail transfer during PBR generation.\n\nThis object lost `magnitude_only`. The pipeline tunes that value for\neach texture pass, so 1 value you send could only flatten the tuning.\n","properties":{"enabled":{"type":["boolean","null"],"default":true,"description":"Whether detail transfer is enabled. An omitted field, and an\nexplicit `null`, both leave the stage on.\n"}}},"PublicPBROutput2D":{"type":"object","additionalProperties":false,"description":"Container for 2D output options. All fields are optional; omitted fields\nuse system defaults.\n\nThis object lost `video`. The pipeline holds no video stage and no\nturntable stage.\n","properties":{"orm":{"$ref":"#/components/schemas/PublicPBROutput2DORM"}}},"PublicPBROutput2DORM":{"type":"object","additionalProperties":false,"description":"Settings for an occlusion/roughness/metallic (ORM) combined 2D output\nmap.\n\n**No result carries the ORM map yet.** The 2 mesh endpoints accept the\noption today, and the pipeline stage that packs the map is still in\nbuild. The option never fails a run, and it changes no result until that\nstage ships.\n","properties":{"enabled":{"type":["boolean","null"],"default":false,"description":"Whether to generate the ORM map. An omitted field, and an explicit\n`null`, both leave the map off.\nNo result carries the map yet, as the object description states.\n"},"channel_order":{"type":"string","enum":["ORM","RMO","MRO"],"default":"ORM","description":"Channel order for the combined map. An omitted field packs the\nchannels in the `ORM` order.\n\nPossible enum values:\n- `ORM`: occlusion, roughness, metallic.\n- `RMO`: roughness, metallic, occlusion.\n- `MRO`: metallic, roughness, occlusion.\n"}}}}}}
```

## The AccountAPIKeyMeta object

```json
{"openapi":"3.1.0","info":{"title":"Marso Studio API","version":"0.0.1"},"components":{"schemas":{"AccountAPIKeyMeta":{"type":"object","required":["prefix","label","created_at"],"description":"Metadata about the API key used to authenticate the request.\n","properties":{"prefix":{"type":"string","description":"Recognizable prefix of the API key, formed as `mxr_live_` followed by\nthe first 7 entropy characters. This lets you identify the key without\nexposing the full secret.\n"},"label":{"type":"string","description":"Human-readable label given to the key in the dashboard.\n"},"created_at":{"$ref":"#/components/schemas/EpochMillis"},"last_used_at":{"$ref":"#/components/schemas/NullableEpochMillis"}}},"EpochMillis":{"type":"integer","format":"int64","description":"Time represented as milliseconds since the Unix epoch.\n"},"NullableEpochMillis":{"type":["integer","null"],"format":"int64","description":"Time represented as milliseconds since the Unix epoch, or `null` when the\nfield has not been set.\n"}}}}
```

## The AccountMeResponse object

```json
{"openapi":"3.1.0","info":{"title":"Marso Studio API","version":"0.0.1"},"components":{"schemas":{"AccountMeResponse":{"type":"object","required":["user_id","plan_tier","effective_features","api_key"],"description":"Response from `GET /account/me`. Contains the account's identity and the\nAPI key used to authenticate the request.\n","properties":{"user_id":{"type":"string","description":"Unique identifier of the account.\n"},"email":{"type":"string","description":"Email address associated with the account.\n"},"plan_tier":{"type":"string","description":"Legacy compatibility tier. This value stays `free` for all accounts.\n"},"subscription_plan_code":{"$ref":"#/components/schemas/SubscriptionPlanCode","description":"Opaque code for the personal subscription plan."},"subscription_plan_class":{"$ref":"#/components/schemas/SubscriptionPlanClass","description":"Stable class of the personal subscription plan."},"organization_seat_plan_code":{"$ref":"#/components/schemas/SubscriptionPlanCode","description":"Opaque code for the assigned Organization seat plan."},"organization_seat_plan_class":{"$ref":"#/components/schemas/SubscriptionPlanClass","description":"Stable class of the assigned Organization seat plan."},"effective_features":{"type":"array","description":"Sorted union of features from the personal plan and an assigned\nOrganization seat. The array is empty when subscriptions are off.\n","items":{"$ref":"#/components/schemas/SubscriptionFeature"}},"api_key":{"$ref":"#/components/schemas/AccountAPIKeyMeta"}}},"SubscriptionPlanCode":{"type":"string","pattern":"^plan_[A-Za-z0-9]{7,64}$","description":"Opaque and immutable code for a subscription plan. Use the plan\ncatalogue for its current display name. The code must start with\n`plan_`, followed by 7 to 64 ASCII letters or digits.\n"},"SubscriptionPlanClass":{"type":"string","description":"Stable class of a subscription plan.\n\nPossible enum values:\n- `free`: the Free plan class.\n- `creator`: the Creator plan class.\n- `artist_pro`: the Artist Pro plan class.\n- `studio`: the Studio plan class.\n- `enterprise`: the Enterprise plan class.\n","enum":["free","creator","artist_pro","studio","enterprise"]},"SubscriptionFeature":{"type":"string","description":"Product capability available to the account.\n\nPossible enum values:\n- `commercial_license`: commercial-use rights.\n- `api_pbr`: PBR generation through the Public Platform API.\n- `api_asset_download`: asset downloads through the Public Platform API.\n- `custom_polycount`: custom polygon counts for 3D generation.\n- `image_edit`: image editing.\n- `multiview`: multiview generation.\n","enum":["commercial_license","api_pbr","api_asset_download","custom_polycount","image_edit","multiview"]},"AccountAPIKeyMeta":{"type":"object","required":["prefix","label","created_at"],"description":"Metadata about the API key used to authenticate the request.\n","properties":{"prefix":{"type":"string","description":"Recognizable prefix of the API key, formed as `mxr_live_` followed by\nthe first 7 entropy characters. This lets you identify the key without\nexposing the full secret.\n"},"label":{"type":"string","description":"Human-readable label given to the key in the dashboard.\n"},"created_at":{"$ref":"#/components/schemas/EpochMillis"},"last_used_at":{"$ref":"#/components/schemas/NullableEpochMillis"}}},"EpochMillis":{"type":"integer","format":"int64","description":"Time represented as milliseconds since the Unix epoch.\n"},"NullableEpochMillis":{"type":["integer","null"],"format":"int64","description":"Time represented as milliseconds since the Unix epoch, or `null` when the\nfield has not been set.\n"}}}}
```

## The AccountCreditsResponse object

```json
{"openapi":"3.1.0","info":{"title":"Marso Studio API","version":"0.0.1"},"components":{"schemas":{"AccountCreditsResponse":{"type":"object","required":["total_credits","daily_free_credits","paid_credits","billing_source","organization_member"],"description":"Response from `GET /account/credits`. Contains the account's personal\ncredit balance. Organization pool balances are not exposed.\n","properties":{"total_credits":{"type":"integer","format":"int64","description":"Sum of personal daily-free and paid credits. Does not include any\norganization pool balance.\n"},"daily_free_credits":{"type":"integer","format":"int64","description":"Remaining personal daily-free credits.\n"},"paid_credits":{"type":"integer","format":"int64","description":"Remaining personal paid credits.\n"},"billing_source":{"type":"string","enum":["personal","organization"],"description":"Preferred billing source for the account.\n\nPossible enum values:\n- `personal`: charges are applied to the account's personal credits.\n- `organization`: charges are applied to the account's organization\n  credits, if available.\n"},"organization_member":{"type":"boolean","description":"Whether the account belongs to an organization. No organization\nidentity or pool balance is exposed in this response.\n"}}}}}}
```

## The AccountUsageBucket object

```json
{"openapi":"3.1.0","info":{"title":"Marso Studio API","version":"0.0.1"},"components":{"schemas":{"AccountUsageBucket":{"type":"object","required":["date","credits"],"description":"One UTC day of credit usage.\n","properties":{"date":{"type":"string","description":"UTC day as an RFC 3339 date string.\n"},"credits":{"type":"integer","format":"int64","description":"Total credits consumed on that day.\n"}}}}}}
```

## The AccountUsageResponse object

```json
{"openapi":"3.1.0","info":{"title":"Marso Studio API","version":"0.0.1"},"components":{"schemas":{"AccountUsageResponse":{"type":"object","required":["total_credits","buckets"],"description":"Response from `GET /account/usage`. Contains credit consumption over the\nrequested time range, grouped by UTC day.\n","properties":{"total_credits":{"type":"integer","format":"int64","description":"Total credits consumed across all days in the requested window.\n"},"buckets":{"type":"array","description":"Per-day credit usage, sorted chronologically.\n","items":{"$ref":"#/components/schemas/AccountUsageBucket"}}}},"AccountUsageBucket":{"type":"object","required":["date","credits"],"description":"One UTC day of credit usage.\n","properties":{"date":{"type":"string","description":"UTC day as an RFC 3339 date string.\n"},"credits":{"type":"integer","format":"int64","description":"Total credits consumed on that day.\n"}}}}}}
```

## The PricingExecutionCosts object

```json
{"openapi":"3.1.0","info":{"title":"Marso Studio API","version":"0.0.1"},"components":{"schemas":{"PricingExecutionCosts":{"type":"object","required":["api_mesh_pbr","api_image_pbr","api_mesh_batch_item","api_image_batch_item"],"additionalProperties":false,"description":"The credit price of one unit of each PBR generation action. Every price is\na whole number of credits and is never negative.\n","properties":{"api_mesh_pbr":{"type":"integer","format":"int64","minimum":0,"description":"Credits charged for one 3D mesh to PBR submit through\n`POST /pbr/execute/mesh`.\n"},"api_image_pbr":{"type":"integer","format":"int64","minimum":0,"description":"Credits charged for one image to PBR submit through\n`POST /pbr/execute/image`.\n"},"api_mesh_batch_item":{"type":"integer","format":"int64","minimum":0,"description":"Credits charged for each item of a 3D mesh to PBR batch submitted\nthrough `POST /batch/pbr/mesh`. Multiply by the number of items for\nthe price of the whole batch.\n"},"api_image_batch_item":{"type":"integer","format":"int64","minimum":0,"description":"Credits charged for each item of an image to PBR batch submitted\nthrough `POST /batch/pbr/image`. Multiply by the number of items for\nthe price of the whole batch.\n"}}}}}}
```

## The PricingResponse object

```json
{"openapi":"3.1.0","info":{"title":"Marso Studio API","version":"0.0.1"},"components":{"schemas":{"PricingResponse":{"type":"object","required":["pricing_catalogue_id","execution_costs"],"description":"Response from `GET /pricing`. Contains the PBR credit prices that apply to\nthe account associated with the API key.\n","properties":{"pricing_catalogue_id":{"type":"string","description":"ID of the pricing catalogue the prices came from, for example\n`standard-v3`. Quote this value when you report a question about a\ncharge.\n"},"execution_costs":{"$ref":"#/components/schemas/PricingExecutionCosts","description":"The credit price of each PBR generation action."}}},"PricingExecutionCosts":{"type":"object","required":["api_mesh_pbr","api_image_pbr","api_mesh_batch_item","api_image_batch_item"],"additionalProperties":false,"description":"The credit price of one unit of each PBR generation action. Every price is\na whole number of credits and is never negative.\n","properties":{"api_mesh_pbr":{"type":"integer","format":"int64","minimum":0,"description":"Credits charged for one 3D mesh to PBR submit through\n`POST /pbr/execute/mesh`.\n"},"api_image_pbr":{"type":"integer","format":"int64","minimum":0,"description":"Credits charged for one image to PBR submit through\n`POST /pbr/execute/image`.\n"},"api_mesh_batch_item":{"type":"integer","format":"int64","minimum":0,"description":"Credits charged for each item of a 3D mesh to PBR batch submitted\nthrough `POST /batch/pbr/mesh`. Multiply by the number of items for\nthe price of the whole batch.\n"},"api_image_batch_item":{"type":"integer","format":"int64","minimum":0,"description":"Credits charged for each item of an image to PBR batch submitted\nthrough `POST /batch/pbr/image`. Multiply by the number of items for\nthe price of the whole batch.\n"}}}}}}
```

## The AddonLatestResponse object

```json
{"openapi":"3.1.0","info":{"title":"Marso Studio API","version":"0.0.1"},"components":{"schemas":{"AddonLatestResponse":{"type":"object","required":["version","display_name"],"description":"The response body for `GET /addons`.","properties":{"version":{"type":"string","description":"The latest published version of the addon, for example `2.0.1`.\n"},"display_name":{"type":"string","description":"The name to show a user for the addon, for example\n`Marso for Blender`.\n"}}}}}}
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.m-xr.com/marso-studio-api/models.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
