> For the complete documentation index, see [llms.txt](https://docs.imerit.net/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.imerit.net/api/docs/assets.md).

# Assets

Asset upload and management

## Get Signed Upload URL

> Generates a signed PUT URL for uploading a file directly to storage. The key is \`{project}/{type}/{name}\`. Manager is required for \`assets\`, \`instructions\`, \`exports\` and \`segmentationModels\`; any project role is enough for \`brushes\`, \`medicalBrushes\`, \`upload-box\` and \`conversation\`. Organization admins pass either way. Fails with 403 once the organization asset quota is exhausted.

```json
{"openapi":"3.0.3","info":{"title":"Ango Hub API v2","version":"2.0.0"},"tags":[{"name":"Assets","description":"Asset upload and management"}],"servers":[{"url":"https://imeritapi.ango.ai/v2","description":"EU Production Server"},{"url":"https://us-api.ango.ai/v2","description":"US Production Server"},{"url":"https://in-api.ango.ai/v2","description":"India Production Server"},{"url":"https://testapi.ango.ai/v2","description":"Test Server"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"apikey","description":"API key for authentication. Format - apikey YOUR_API_KEY"}},"schemas":{"UploadUrlResponse":{"type":"object","properties":{"status":{"type":"string"},"data":{"type":"object","properties":{"uploadUrl":{"type":"string"}}}}},"ErrorResponse":{"type":"object","properties":{"status":{"type":"string","enum":["fail","error"]},"message":{"type":"string"}}}},"responses":{"ForbiddenError":{"description":"Forbidden - insufficient permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"paths":{"/getUploadUrl":{"get":{"tags":["Assets"],"summary":"Get Signed Upload URL","description":"Generates a signed PUT URL for uploading a file directly to storage. The key is `{project}/{type}/{name}`. Manager is required for `assets`, `instructions`, `exports` and `segmentationModels`; any project role is enough for `brushes`, `medicalBrushes`, `upload-box` and `conversation`. Organization admins pass either way. Fails with 403 once the organization asset quota is exhausted.","operationId":"getUploadUrl","parameters":[{"name":"name","in":"query","required":true,"schema":{"type":"string"},"description":"File name with extension"},{"name":"project","in":"query","required":true,"schema":{"type":"string"},"description":"Project ID"},{"name":"type","in":"query","schema":{"type":"string"},"description":"Storage folder for the file: `assets`, `instructions`, `exports`, `segmentationModels`, `brushes`, `medicalBrushes`, `upload-box` or `conversation`. The legacy custom Upload Box form `{projectId}/upload-box` works only together with a custom `bucket` and a `storageId`; there the real project is the first segment of `type` and the `project` parameter is a storage subfolder. Not enforced by the server: omitting it signs a key containing the literal `undefined` and requires the Manager role."},{"name":"storageId","in":"query","schema":{"type":"string"},"description":"Custom storage ID"},{"name":"bucket","in":"query","schema":{"type":"string"},"description":"Custom bucket name"}],"responses":{"200":{"description":"Upload URL generated successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UploadUrlResponse"}}}},"403":{"$ref":"#/components/responses/ForbiddenError"}}}}}}
```

## Get Signed Download URL

> Generates a signed GET URL for an asset URL. When \`storageId\` is given, access to that storage integration is checked. Fails with 403 once the organization asset quota is exhausted.

```json
{"openapi":"3.0.3","info":{"title":"Ango Hub API v2","version":"2.0.0"},"tags":[{"name":"Assets","description":"Asset upload and management"}],"servers":[{"url":"https://imeritapi.ango.ai/v2","description":"EU Production Server"},{"url":"https://us-api.ango.ai/v2","description":"US Production Server"},{"url":"https://in-api.ango.ai/v2","description":"India Production Server"},{"url":"https://testapi.ango.ai/v2","description":"Test Server"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"apikey","description":"API key for authentication. Format - apikey YOUR_API_KEY"}},"schemas":{"SignedUrlResponse":{"type":"object","properties":{"status":{"type":"string"},"data":{"type":"object","properties":{"signedUrl":{"type":"string"}}}}},"ErrorResponse":{"type":"object","properties":{"status":{"type":"string","enum":["fail","error"]},"message":{"type":"string"}}}},"responses":{"ForbiddenError":{"description":"Forbidden - insufficient permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"paths":{"/getSignedUrl":{"get":{"tags":["Assets"],"summary":"Get Signed Download URL","description":"Generates a signed GET URL for an asset URL. When `storageId` is given, access to that storage integration is checked. Fails with 403 once the organization asset quota is exhausted.","operationId":"getSignedUrl","parameters":[{"name":"name","in":"query","required":true,"schema":{"type":"string"},"description":"Full asset URL to sign"},{"name":"storageId","in":"query","schema":{"type":"string"},"description":"Storage integration ID. Omit it for objects in the platform bucket."}],"responses":{"200":{"description":"Signed URL generated successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignedUrlResponse"}}}},"403":{"$ref":"#/components/responses/ForbiddenError"}}}}}}
```

## Import Assets from Cloud

> Imports assets from cloud storage (S3, GCS, Azure) and creates their tasks. The upload status is derived by the server, so PCT assets, videos without width, height and frameTotal, and NRRD series get their task only after preprocessing; for those \`tasksCreated\` is lower than \`assetsCreated\`. A \`storage\` at request level is ignored, put it on each asset.

```json
{"openapi":"3.0.3","info":{"title":"Ango Hub API v2","version":"2.0.0"},"tags":[{"name":"Assets","description":"Asset upload and management"}],"servers":[{"url":"https://imeritapi.ango.ai/v2","description":"EU Production Server"},{"url":"https://us-api.ango.ai/v2","description":"US Production Server"},{"url":"https://in-api.ango.ai/v2","description":"India Production Server"},{"url":"https://testapi.ango.ai/v2","description":"Test Server"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"apikey","description":"API key for authentication. Format - apikey YOUR_API_KEY"}},"parameters":{"ProjectIdParam":{"name":"projectId","in":"path","required":true,"schema":{"type":"string"},"description":"Project ID"}},"schemas":{"CloudImportRequest":{"type":"object","required":["assets"],"properties":{"assets":{"type":"array","items":{"$ref":"#/components/schemas/CloudImportAsset"}},"uploadLocal":{"type":"string","enum":["true","false"],"description":"\"true\" marks the created assets private. Nothing is downloaded, the files stay where they are. Read endpoints return pre-signed URLs when an asset is private, carries a `storage`, or is NRRD, so an asset with a `storage` gets signed URLs either way.","default":"false"},"priority":{"type":"number","minimum":-1000,"maximum":1000,"description":"Task priority for queue ordering (higher values first). Applies to every asset in the request and wins over a per-asset `priority`, including when it is 0.","default":0}}},"CloudImportAsset":{"type":"object","required":["data"],"properties":{"data":{"type":"string","description":"Cloud storage URL or path to the asset.\n- For images/videos: Full URL (e.g., `https://bucket.s3.amazonaws.com/image.jpg`)\n- For PCT (Point Cloud): Folder path in format `bucket-name/folder-path/` (must end with `/`)\n"},"dataset":{"type":"array","items":{"type":"string"},"description":"Alternative to data - array of URLs for multi-file assets (e.g., videos with frames)"},"_id":{"type":"string","description":"Asset ID to create the asset with, as a 24 character hex string. Must be unused and unique within the request; a duplicate inside one request returns 400. `id` is accepted as an alias."},"externalId":{"type":"string","description":"External identifier for the asset. Defaults to `data` when omitted."},"storage":{"type":"string","description":"Storage integration ID (required for accessing private cloud buckets and PCT imports)"},"editorType":{"type":"string","enum":["ango","pct","llm","nrrd","iframe"],"description":"Asset editor type. Determines how the asset is processed and displayed.\n- `ango`: Standard AngoHub editor (default) - supports images, videos, PDFs, and more\n- `pct`: Point Cloud Tool - 3D point cloud annotation (requires folder path in `data`)\n- `llm`: LLM/Chat annotation editor\n- `nrrd`: Medical imaging (DICOM to NRRD conversion)\n- `iframe`: Custom iframe-based editor\n"},"batches":{"type":"array","items":{"type":"string"},"description":"Batch IDs to assign this asset to. Use the `_id` values from the project's `batches` array, not batch names."},"metadata":{"$ref":"#/components/schemas/AssetMetadata"},"overlay":{"type":"array","items":{"oneOf":[{"type":"string"},{"type":"object","properties":{"id":{"type":"string"},"url":{"type":"string"}}}]},"description":"Overlay images, either URLs or `{id, url}` objects"},"contextData":{"type":"object","description":"Additional context data for the asset"},"attachments":{"type":"array","items":{"type":"object","properties":{"type":{"type":"string"},"value":{"type":"string"},"label":{"type":"object"}}},"description":"Extra material shown next to the asset"},"priority":{"type":"number","minimum":-1000,"maximum":1000,"description":"Task priority for this asset, used only when the request-level `priority` is absent. It is keyed by `externalId`, so assets sharing one `externalId` share one priority, and it reaches only the tasks created at import time."},"tools":{"type":"array","items":{"type":"object"},"description":"Pre-label annotation objects (bounding boxes, polygons, and so on). Each object carries the `schemaId` of a tool in the project category schema. Pre-labels are applied only to assets that are ready at import time; an asset queued for preprocessing (a video without `metadata.width`, `metadata.height` and `metadata.frameTotal`, a DICOM series, or a PCT asset) gets its task later and keeps no pre-label."},"objects":{"type":"array","items":{"type":"object"},"description":"Alias for `tools`, read only when `tools` is absent."},"classifications":{"type":"array","items":{"type":"object"},"description":"Pre-label classification answers"},"relations":{"type":"array","items":{"type":"object"},"description":"Pre-label relation objects"},"brushDataUrl":{"type":"string","description":"URL of an uploaded brush mask to pre-label a brush annotation"},"medicalBrushDataUrl":{"type":"string","description":"URL of an uploaded medical brush mask"}}},"AssetMetadata":{"type":"object","description":"Technical asset metadata. Only these fields are stored; any other key is dropped on write. For a video asset, supply width, height and frameTotal to skip server-side preprocessing.","properties":{"width":{"type":"integer"},"height":{"type":"integer"},"size":{"type":"integer"},"frameStep":{"type":"integer"},"frameTotal":{"type":"integer"},"frameRate":{"type":"number"},"numOfPages":{"type":"integer"},"numOfWords":{"type":"integer"},"duration":{"type":"integer","description":"Duration in milliseconds"},"hasVariableFrameRate":{"type":"boolean"}}},"AssetImportResponse":{"type":"object","properties":{"status":{"type":"string"},"data":{"type":"object","properties":{"assets":{"type":"object","properties":{"assetsCreated":{"type":"integer"},"tasksCreated":{"type":"integer"},"preLabelsCount":{"type":"integer"},"validPreLabelsCount":{"type":"integer"}}}}}}},"ErrorResponse":{"type":"object","properties":{"status":{"type":"string","enum":["fail","error"]},"message":{"type":"string"}}}},"responses":{"BadRequestError":{"description":"Bad request - validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"paths":{"/project/{projectId}/cloud":{"post":{"tags":["Assets"],"summary":"Import Assets from Cloud","description":"Imports assets from cloud storage (S3, GCS, Azure) and creates their tasks. The upload status is derived by the server, so PCT assets, videos without width, height and frameTotal, and NRRD series get their task only after preprocessing; for those `tasksCreated` is lower than `assetsCreated`. A `storage` at request level is ignored, put it on each asset.","operationId":"importAssetsFromCloud","parameters":[{"$ref":"#/components/parameters/ProjectIdParam"},{"name":"batches","in":"query","schema":{"type":"string"},"description":"JSON stringified array of batch IDs, applied to every asset in the request that does not carry its own `batches`."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CloudImportRequest"}}}},"responses":{"200":{"description":"Assets imported successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AssetImportResponse"}}}},"400":{"$ref":"#/components/responses/BadRequestError"}}}}}}
```

## Upload Chat Assets

> Creates conversation assets for chat annotation projects. Conversations come from the uploaded file; without a file, \`numberOfConversations\` empty conversations are created. At most 10000 conversations per request. The created assets are always private.

```json
{"openapi":"3.0.3","info":{"title":"Ango Hub API v2","version":"2.0.0"},"tags":[{"name":"Assets","description":"Asset upload and management"}],"servers":[{"url":"https://imeritapi.ango.ai/v2","description":"EU Production Server"},{"url":"https://us-api.ango.ai/v2","description":"US Production Server"},{"url":"https://in-api.ango.ai/v2","description":"India Production Server"},{"url":"https://testapi.ango.ai/v2","description":"Test Server"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"apikey","description":"API key for authentication. Format - apikey YOUR_API_KEY"}},"parameters":{"ProjectIdParam":{"name":"projectId","in":"path","required":true,"schema":{"type":"string"},"description":"Project ID"}},"schemas":{"ChatAssetUploadRequest":{"type":"object","properties":{"file":{"type":"string","format":"binary","description":"JSON file holding the conversations to import"},"storageId":{"type":"string","description":"Storage integration ID. Send an empty value to use the platform bucket."},"bucket":{"type":"string"},"batches":{"type":"string","description":"JSON stringified array of batch IDs, applied to every conversation asset created by this request."},"llmConfig":{"type":"string","description":"LLM configuration JSON"},"numberOfConversations":{"type":"number","description":"How many conversations to create when no file is uploaded"},"namingStrategy":{"type":"string","description":"Accepted for backward compatibility, has no effect"},"priority":{"type":"number"}}},"AssetImportResponse":{"type":"object","properties":{"status":{"type":"string"},"data":{"type":"object","properties":{"assets":{"type":"object","properties":{"assetsCreated":{"type":"integer"},"tasksCreated":{"type":"integer"},"preLabelsCount":{"type":"integer"},"validPreLabelsCount":{"type":"integer"}}}}}}}}},"paths":{"/project/{projectId}/chat":{"post":{"tags":["Assets"],"summary":"Upload Chat Assets","description":"Creates conversation assets for chat annotation projects. Conversations come from the uploaded file; without a file, `numberOfConversations` empty conversations are created. At most 10000 conversations per request. The created assets are always private.","operationId":"uploadChatAssets","parameters":[{"$ref":"#/components/parameters/ProjectIdParam"}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/ChatAssetUploadRequest"}}}},"responses":{"200":{"description":"Chat assets uploaded successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AssetImportResponse"}}}}}}}}}
```

## Get Project Assets

> Retrieves assets for a specific project with optional filtering. Results are always ordered newest first. Without \`page\` and \`limit\` every asset in the project is returned.

```json
{"openapi":"3.0.3","info":{"title":"Ango Hub API v2","version":"2.0.0"},"tags":[{"name":"Assets","description":"Asset upload and management"}],"servers":[{"url":"https://imeritapi.ango.ai/v2","description":"EU Production Server"},{"url":"https://us-api.ango.ai/v2","description":"US Production Server"},{"url":"https://in-api.ango.ai/v2","description":"India Production Server"},{"url":"https://testapi.ango.ai/v2","description":"Test Server"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"apikey","description":"API key for authentication. Format - apikey YOUR_API_KEY"}},"parameters":{"ProjectIdParam":{"name":"projectId","in":"path","required":true,"schema":{"type":"string"},"description":"Project ID"}},"schemas":{"AssetListResponse":{"type":"object","properties":{"status":{"type":"string"},"data":{"type":"object","properties":{"assets":{"type":"array","items":{"$ref":"#/components/schemas/Asset"}},"total":{"type":"integer"}}}}},"Asset":{"type":"object","description":"When an asset is private, carries a `storage`, or is NRRD, and its `data` is a URL, the read endpoints replace `data`, `dataset` and `overlay` with pre-signed URLs and set `head` to a signed HEAD URL. Otherwise `head` equals `data`.","properties":{"_id":{"type":"string"},"id":{"type":"string","description":"Same value as `_id`"},"data":{"type":"string","description":"Asset URL"},"dataset":{"type":"array","items":{"type":"string"}},"overlay":{"type":"array","items":{"oneOf":[{"type":"string"},{"type":"object","properties":{"id":{"type":"string"},"url":{"type":"string"}}}]}},"head":{"type":"string","description":"Signed HEAD URL for the asset, or the same value as `data`"},"project":{"type":"string","description":"Project ID, or the project object when `populate=project` is used"},"organization":{"type":"string"},"storage":{"type":"string","description":"Storage integration ID, null for assets in the platform bucket","nullable":true},"externalId":{"type":"string"},"editorType":{"type":"string","enum":["ango","pct","llm","nrrd","iframe"]},"uploadStatus":{"type":"string","enum":["READY","PCT_WAITING","METADATA_WAITING","PCT_FAILED","METADATA_FAILED"],"description":"An asset is READY once it can be annotated. PCT and preprocessing assets get their task only after the waiting state clears."},"isPrivate":{"type":"boolean"},"isPreLabeled":{"type":"boolean"},"batches":{"type":"array","items":{"type":"string"},"description":"Batch IDs the asset belongs to"},"metadata":{"$ref":"#/components/schemas/AssetMetadata"},"attachments":{"type":"array","items":{"type":"object","properties":{"type":{"type":"string"},"value":{"type":"string"},"label":{"type":"object"}}}},"contextData":{"type":"object"},"labelTasks":{"type":"array","description":"Returned only when populated, as objects carrying `_id`, `id`, `stage` and `assignee`. The project assets list always populates it.","items":{"type":"object","properties":{"_id":{"type":"string"},"id":{"type":"string"},"stage":{"type":"string"},"assignee":{"type":"string"}}}},"deleted":{"type":"boolean","description":"Deleted assets are excluded from responses by default, so this is false"},"preprocessEnqueuedAt":{"type":"string","format":"date-time","description":"When the asset was queued for preprocessing"},"createdAt":{"type":"string","format":"date-time"},"createdBy":{"type":"string"}}},"AssetMetadata":{"type":"object","description":"Technical asset metadata. Only these fields are stored; any other key is dropped on write. For a video asset, supply width, height and frameTotal to skip server-side preprocessing.","properties":{"width":{"type":"integer"},"height":{"type":"integer"},"size":{"type":"integer"},"frameStep":{"type":"integer"},"frameTotal":{"type":"integer"},"frameRate":{"type":"number"},"numOfPages":{"type":"integer"},"numOfWords":{"type":"integer"},"duration":{"type":"integer","description":"Duration in milliseconds"},"hasVariableFrameRate":{"type":"boolean"}}}}},"paths":{"/project/{projectId}/assets":{"get":{"tags":["Assets"],"summary":"Get Project Assets","description":"Retrieves assets for a specific project with optional filtering. Results are always ordered newest first. Without `page` and `limit` every asset in the project is returned.","operationId":"getProjectAssets","parameters":[{"$ref":"#/components/parameters/ProjectIdParam"},{"name":"page","in":"query","schema":{"type":"integer","minimum":1},"description":"Page number (1-indexed). Sets the page size to 10 when `limit` is absent."},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1},"description":"Items per page. Not capped; without it and without `page` no limit is applied."},{"name":"filters","in":"query","schema":{"type":"string"},"description":"JSON stringified filter object, merged into the query"},{"name":"externalId","in":"query","schema":{"type":"string"},"description":"Filter by external ID"},{"name":"batches","in":"query","schema":{"type":"string"},"description":"Filter by batch ID"},{"name":"populate","in":"query","schema":{"type":"string"},"description":"Relation to populate, repeatable. `labelTasks` is always populated. Use `project` to get the project object instead of its ID."},{"name":"fields","in":"query","schema":{"type":"string"},"description":"Comma separated field list. Prefix a field with `-` to exclude it. Inclusion lists have no effect because the server always requests all fields."}],"responses":{"200":{"description":"Assets retrieved successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AssetListResponse"}}}}}}}}}
```

## Delete Assets

> Soft deletes assets. The assets and their tasks, task history and issues are marked deleted, the project asset count is decremented by the number of IDs sent, and the tasks are removed from the work queues.

```json
{"openapi":"3.0.3","info":{"title":"Ango Hub API v2","version":"2.0.0"},"tags":[{"name":"Assets","description":"Asset upload and management"}],"servers":[{"url":"https://imeritapi.ango.ai/v2","description":"EU Production Server"},{"url":"https://us-api.ango.ai/v2","description":"US Production Server"},{"url":"https://in-api.ango.ai/v2","description":"India Production Server"},{"url":"https://testapi.ango.ai/v2","description":"Test Server"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"apikey","description":"API key for authentication. Format - apikey YOUR_API_KEY"}},"parameters":{"ProjectIdParam":{"name":"projectId","in":"path","required":true,"schema":{"type":"string"},"description":"Project ID"}},"schemas":{"BulkDeleteAssetsRequest":{"type":"object","required":["assets"],"properties":{"assets":{"type":"array","items":{"type":"string"}}}},"BulkDeleteResponse":{"type":"object","properties":{"status":{"type":"string"},"data":{"type":"object","properties":{"assets":{"type":"array","description":"The asset IDs from the request, echoed back, including IDs that did not exist","items":{"type":"string"}}}}}}}},"paths":{"/project/{projectId}/assets":{"delete":{"tags":["Assets"],"summary":"Delete Assets","description":"Soft deletes assets. The assets and their tasks, task history and issues are marked deleted, the project asset count is decremented by the number of IDs sent, and the tasks are removed from the work queues.","operationId":"bulkDeleteAssets","parameters":[{"$ref":"#/components/parameters/ProjectIdParam"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BulkDeleteAssetsRequest"}}}},"responses":{"200":{"description":"Assets deleted successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BulkDeleteResponse"}}}}}}}}}
```

## Update Asset

> Updates asset metadata or properties

```json
{"openapi":"3.0.3","info":{"title":"Ango Hub API v2","version":"2.0.0"},"tags":[{"name":"Assets","description":"Asset upload and management"}],"servers":[{"url":"https://imeritapi.ango.ai/v2","description":"EU Production Server"},{"url":"https://us-api.ango.ai/v2","description":"US Production Server"},{"url":"https://in-api.ango.ai/v2","description":"India Production Server"},{"url":"https://testapi.ango.ai/v2","description":"Test Server"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"apikey","description":"API key for authentication. Format - apikey YOUR_API_KEY"}},"schemas":{"AssetUpdateRequest":{"type":"object","description":"The fields below are the supported ones. The endpoint applies the request body to the asset without validation, so any other Asset field is writable as well. The response carries the updated asset with its URLs re-signed.","properties":{"metadata":{"$ref":"#/components/schemas/AssetMetadata"},"contextData":{"type":"object"},"data":{"type":"string"},"overlay":{"type":"array","items":{"oneOf":[{"type":"string"},{"type":"object","properties":{"id":{"type":"string"},"url":{"type":"string"}}}]}},"externalId":{"type":"string"}}},"AssetMetadata":{"type":"object","description":"Technical asset metadata. Only these fields are stored; any other key is dropped on write. For a video asset, supply width, height and frameTotal to skip server-side preprocessing.","properties":{"width":{"type":"integer"},"height":{"type":"integer"},"size":{"type":"integer"},"frameStep":{"type":"integer"},"frameTotal":{"type":"integer"},"frameRate":{"type":"number"},"numOfPages":{"type":"integer"},"numOfWords":{"type":"integer"},"duration":{"type":"integer","description":"Duration in milliseconds"},"hasVariableFrameRate":{"type":"boolean"}}},"AssetResponse":{"type":"object","properties":{"status":{"type":"string"},"data":{"type":"object","properties":{"asset":{"$ref":"#/components/schemas/Asset"}}}}},"Asset":{"type":"object","description":"When an asset is private, carries a `storage`, or is NRRD, and its `data` is a URL, the read endpoints replace `data`, `dataset` and `overlay` with pre-signed URLs and set `head` to a signed HEAD URL. Otherwise `head` equals `data`.","properties":{"_id":{"type":"string"},"id":{"type":"string","description":"Same value as `_id`"},"data":{"type":"string","description":"Asset URL"},"dataset":{"type":"array","items":{"type":"string"}},"overlay":{"type":"array","items":{"oneOf":[{"type":"string"},{"type":"object","properties":{"id":{"type":"string"},"url":{"type":"string"}}}]}},"head":{"type":"string","description":"Signed HEAD URL for the asset, or the same value as `data`"},"project":{"type":"string","description":"Project ID, or the project object when `populate=project` is used"},"organization":{"type":"string"},"storage":{"type":"string","description":"Storage integration ID, null for assets in the platform bucket","nullable":true},"externalId":{"type":"string"},"editorType":{"type":"string","enum":["ango","pct","llm","nrrd","iframe"]},"uploadStatus":{"type":"string","enum":["READY","PCT_WAITING","METADATA_WAITING","PCT_FAILED","METADATA_FAILED"],"description":"An asset is READY once it can be annotated. PCT and preprocessing assets get their task only after the waiting state clears."},"isPrivate":{"type":"boolean"},"isPreLabeled":{"type":"boolean"},"batches":{"type":"array","items":{"type":"string"},"description":"Batch IDs the asset belongs to"},"metadata":{"$ref":"#/components/schemas/AssetMetadata"},"attachments":{"type":"array","items":{"type":"object","properties":{"type":{"type":"string"},"value":{"type":"string"},"label":{"type":"object"}}}},"contextData":{"type":"object"},"labelTasks":{"type":"array","description":"Returned only when populated, as objects carrying `_id`, `id`, `stage` and `assignee`. The project assets list always populates it.","items":{"type":"object","properties":{"_id":{"type":"string"},"id":{"type":"string"},"stage":{"type":"string"},"assignee":{"type":"string"}}}},"deleted":{"type":"boolean","description":"Deleted assets are excluded from responses by default, so this is false"},"preprocessEnqueuedAt":{"type":"string","format":"date-time","description":"When the asset was queued for preprocessing"},"createdAt":{"type":"string","format":"date-time"},"createdBy":{"type":"string"}}}}},"paths":{"/assets/{assetId}":{"post":{"tags":["Assets"],"summary":"Update Asset","description":"Updates asset metadata or properties","operationId":"updateAsset","parameters":[{"name":"assetId","in":"path","required":true,"schema":{"type":"string"},"description":"Asset ID"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AssetUpdateRequest"}}}},"responses":{"200":{"description":"Asset updated successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AssetResponse"}}}}}}}}}
```

## Assign Batches to Assets

> Replaces the batches of existing assets with the given batch IDs. The new batches are also written to the tasks and task history of those assets.

```json
{"openapi":"3.0.3","info":{"title":"Ango Hub API v2","version":"2.0.0"},"tags":[{"name":"Assets","description":"Asset upload and management"}],"servers":[{"url":"https://imeritapi.ango.ai/v2","description":"EU Production Server"},{"url":"https://us-api.ango.ai/v2","description":"US Production Server"},{"url":"https://in-api.ango.ai/v2","description":"India Production Server"},{"url":"https://testapi.ango.ai/v2","description":"Test Server"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"apikey","description":"API key for authentication. Format - apikey YOUR_API_KEY"}},"schemas":{"AssignBatchesRequest":{"type":"object","required":["assets","batches","projectId"],"properties":{"assets":{"type":"array","items":{"type":"string"},"description":"Asset IDs to update"},"batches":{"type":"array","items":{"type":"string"},"description":"Batch IDs to set on the assets. Use the `_id` values from the project's `batches` array, not batch names; an unknown ID fails the whole request with 400."},"projectId":{"type":"string","description":"Project the batches belong to"}}},"AssignBatchesResponse":{"type":"object","properties":{"status":{"type":"string"},"data":{"type":"object","properties":{"assets":{"type":"object","properties":{"count":{"type":"integer","description":"Number of assets updated"},"message":{"type":"string"}}}}}}}}},"paths":{"/assignBatches":{"post":{"tags":["Assets"],"summary":"Assign Batches to Assets","description":"Replaces the batches of existing assets with the given batch IDs. The new batches are also written to the tasks and task history of those assets.","operationId":"assignBatches","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AssignBatchesRequest"}}}},"responses":{"200":{"description":"Batches assigned successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AssignBatchesResponse"}}}}}}}}}
```


---

# 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.imerit.net/api/docs/assets.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.
