> 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/import-export.md).

# Import/Export

Bulk data import and export

## Import Attachments

> Sets the attachments of existing assets. Each item matches assets of the project by \`externalId\`, or by \`data\` when \`externalId\` is absent, and every matching asset has its whole \`attachments\` array replaced with the one in that item. A matcher may hit more than one asset. At most 10000 items per request and 1000 attachments per item.

```json
{"openapi":"3.0.3","info":{"title":"Ango Hub API v2","version":"2.0.0"},"tags":[{"name":"Import/Export","description":"Bulk data import and export"}],"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":{"ImportAttachmentsRequest":{"type":"object","required":["project","attachments"],"properties":{"project":{"type":"string","description":"Project whose assets are updated"},"attachments":{"type":"array","minItems":1,"maxItems":10000,"description":"One entry per asset matcher","items":{"type":"object","required":["attachments"],"anyOf":[{"required":["externalId"]},{"required":["data"]}],"properties":{"externalId":{"type":"string","description":"Asset external ID to match. Must be a non-empty string. Takes precedence over `data`."},"data":{"type":"string","description":"Asset URL to match, used when `externalId` is absent"},"attachments":{"type":"array","maxItems":1000,"description":"Replaces the matched assets' attachments","items":{"type":"object","properties":{"type":{"type":"string"},"value":{"type":"string"},"label":{"type":"object"}}}}}}}}},"ImportAttachmentsResponse":{"type":"object","properties":{"status":{"type":"string"},"data":{"type":"object","properties":{"project":{"type":"object","properties":{"importCount":{"type":"integer","description":"Number of assets actually modified across all items. An asset whose attachments already equal the submitted array is not counted."}}}}}}},"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"}}}},"UnauthorizedError":{"description":"Unauthorized - invalid or missing API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"ForbiddenError":{"description":"Forbidden - insufficient permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"NotFoundError":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"paths":{"/attachments":{"post":{"tags":["Import/Export"],"summary":"Import Attachments","description":"Sets the attachments of existing assets. Each item matches assets of the project by `externalId`, or by `data` when `externalId` is absent, and every matching asset has its whole `attachments` array replaced with the one in that item. A matcher may hit more than one asset. At most 10000 items per request and 1000 attachments per item.","operationId":"importAttachments","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ImportAttachmentsRequest"}}}},"responses":{"200":{"description":"Attachments imported successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ImportAttachmentsResponse"}}}},"400":{"$ref":"#/components/responses/BadRequestError"},"401":{"$ref":"#/components/responses/UnauthorizedError"},"403":{"$ref":"#/components/responses/ForbiddenError"},"404":{"$ref":"#/components/responses/NotFoundError"}}}}}}
```

## Import Labels

> Writes pre-labels onto existing tasks. Items are matched against the task \`externalId\`. When an item carries no \`externalId\`, \`data\` is used, matching tasks whose \`externalId\` is that URL or the hash derived from it for assets uploaded without an explicit \`externalId\`. Only tasks still in the Start stage of the project are updated, and an item that produces an empty answer is not written; both cases are skipped silently and reflected in the returned counts. Sending no \`project\` in the body returns 200 with an empty data object.

```json
{"openapi":"3.0.3","info":{"title":"Ango Hub API v2","version":"2.0.0"},"tags":[{"name":"Import/Export","description":"Bulk data import and export"}],"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":{"ImportLabelsRequest":{"type":"object","required":["project","jsonContent"],"properties":{"project":{"type":"string"},"jsonContent":{"type":"array","description":"Pre-label items. The annotation payload sits at the top level of each item, in the same shape the export produces.","items":{"type":"object","properties":{"externalId":{"type":"string","description":"Task external ID to match. Takes precedence over `data`."},"data":{"type":"string","description":"Asset URL, used when `externalId` is absent. It only matches assets that were uploaded without an explicit `externalId`."},"tools":{"type":"array","items":{"type":"object"},"description":"Annotation objects. Read only when `objects` is absent."},"objects":{"type":"array","items":{"type":"object"},"description":"Annotation objects. Takes precedence over `tools` on this endpoint."},"classifications":{"type":"array","items":{"type":"object"}},"relations":{"type":"array","items":{"type":"object"}},"brushDataUrl":{"type":"string","description":"URL of an uploaded brush mask"},"medicalBrushDataUrl":{"type":"string","description":"URL of an uploaded NRRD medical brush mask, ignored when it is not an NRRD URL"}}}}}},"ImportLabelsResponse":{"type":"object","properties":{"status":{"type":"string"},"data":{"type":"object","properties":{"project":{"type":"string","description":"Message of the form \"<labeled> / <sent> tasks are labeled.\". When the two numbers differ it is followed by a hint that the tasks must be in the Start stage and the external IDs must match."}}}}},"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"}}}},"UnauthorizedError":{"description":"Unauthorized - invalid or missing API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"ForbiddenError":{"description":"Forbidden - insufficient permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"NotFoundError":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"paths":{"/import/labels":{"post":{"tags":["Import/Export"],"summary":"Import Labels","description":"Writes pre-labels onto existing tasks. Items are matched against the task `externalId`. When an item carries no `externalId`, `data` is used, matching tasks whose `externalId` is that URL or the hash derived from it for assets uploaded without an explicit `externalId`. Only tasks still in the Start stage of the project are updated, and an item that produces an empty answer is not written; both cases are skipped silently and reflected in the returned counts. Sending no `project` in the body returns 200 with an empty data object.","operationId":"importLabels","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ImportLabelsRequest"}}}},"responses":{"200":{"description":"Labels imported successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ImportLabelsResponse"}}}},"400":{"$ref":"#/components/responses/BadRequestError"},"401":{"$ref":"#/components/responses/UnauthorizedError"},"403":{"$ref":"#/components/responses/ForbiddenError"},"404":{"$ref":"#/components/responses/NotFoundError"}}}}}}
```

## Export Tasks

> Builds the export and returns a link to it. The call is synchronous: it blocks until the archive is built and uploaded, so a large project can take minutes. The same operation is also served at \`/exportV3\`. Every run is recorded in the project's export history, and the caller is notified in the app when it finishes unless \`doNotNotify\` is true. Any query parameter not listed below is parsed as JSON and applied as a filter on the exported tasks.

```json
{"openapi":"3.0.3","info":{"title":"Ango Hub API v2","version":"2.0.0"},"tags":[{"name":"Import/Export","description":"Bulk data import and export"}],"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":{"ExportResponse":{"type":"object","properties":{"status":{"type":"string"},"data":{"type":"object","properties":{"exportPath":{"type":"string","description":"Pre-signed link to the export archive, a zip containing the export files. The link is valid for 24 hours. The same object is kept in the project's export history, which re-signs it on read, so an expired link can be refreshed there."}}}}},"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"}}}},"UnauthorizedError":{"description":"Unauthorized - invalid or missing API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"ForbiddenError":{"description":"Forbidden - insufficient permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"NotFoundError":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"paths":{"/export":{"get":{"tags":["Import/Export"],"summary":"Export Tasks","description":"Builds the export and returns a link to it. The call is synchronous: it blocks until the archive is built and uploaded, so a large project can take minutes. The same operation is also served at `/exportV3`. Every run is recorded in the project's export history, and the caller is notified in the app when it finishes unless `doNotNotify` is true. Any query parameter not listed below is parsed as JSON and applied as a filter on the exported tasks.","operationId":"exportTasks","parameters":[{"name":"project","in":"query","required":true,"schema":{"type":"string"},"description":"Project ID"},{"name":"format","in":"query","schema":{"type":"string","enum":["json","split","ndjson"],"default":"json"},"description":"Export format"},{"name":"type","in":"query","schema":{"type":"string","enum":["task","issue"],"default":"task"},"description":"Export type (task or issue)"},{"name":"stage","in":"query","schema":{"type":"string"},"description":"Filter by stage, as a JSON array string. Values are workflow stage IDs, or one of the fixed stages `Start`, `Complete` and `Archive`."},{"name":"batches","in":"query","schema":{"type":"string"},"description":"Filter by batch, as a JSON array string of batch IDs taken from the project's `batches` array. A task matches when it carries any of them."},{"name":"sendEmail","in":"query","schema":{"type":"string","enum":["true","false"],"default":"false"},"description":"Send export download link via email"},{"name":"doNotNotify","in":"query","schema":{"type":"string","enum":["true","false"],"default":"false"},"description":"Do not send notifications about export"},{"name":"includeMetadata","in":"query","schema":{"type":"string","enum":["true","false"],"default":"false"},"description":"Include asset metadata in export"},{"name":"includeHistory","in":"query","schema":{"type":"string","enum":["true","false"],"default":"false"},"description":"Include task history (all state changes)"},{"name":"includeOnlyKeyFrames","in":"query","schema":{"type":"string","enum":["true","false"],"default":"false"},"description":"Include only key frames for video annotations"},{"name":"includeIdleBlurDurations","in":"query","schema":{"type":"string","enum":["true","false"],"default":"false"},"description":"Include idle and blur duration statistics"},{"name":"split","in":"query","schema":{"type":"string","enum":["true","false"],"default":"false"},"description":"Write one file per task. Overrides `format` with `split`."},{"name":"taskTypes","in":"query","schema":{"type":"string"},"description":"JSON array string of task types to include: `default`, `consensus` or `benchmark`. Defaults to `[\"default\"]`, which also covers tasks stored without a type."},{"name":"sendEmailOnFailure","in":"query","schema":{"type":"string","enum":["true","false"],"default":"false"},"description":"Email the caller when the export fails"},{"name":"includeSegmentationPoints","in":"query","schema":{"type":"string","enum":["true","false"]},"description":"Accepted for backward compatibility, ignored by the server"},{"name":"updatedAt","in":"query","schema":{"type":"string"},"description":"Filter by update date (JSON object, e.g., {\"$gt\":\"2020-08-19T07:37:15.000000Z\",\"$lt\":\"2020-08-26T07:37:15.000000Z\"})"},{"name":"createdAt","in":"query","schema":{"type":"string"},"description":"Filter by creation date (JSON object, e.g., {\"$gt\":\"2020-07-27T07:37:15.000000Z\",\"$lt\":\"2020-08-26T07:37:15.000000Z\"})"},{"name":"filters","in":"query","schema":{"type":"string"},"description":"MongoDB-style filter object for advanced task filtering (JSON string).\nSupports any MongoDB query operators on task fields.\nCommon use cases:\n- Filter by task IDs: {\"_id\": {\"$in\": [\"taskId1\", \"taskId2\"]}}\n- Filter by assignee: {\"assignee\": \"user@example.com\"}\n- Filter by external ID: {\"externalId\": {\"$regex\": \"^prefix_\"}}\n"}],"responses":{"200":{"description":"Export prepared successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExportResponse"}}}},"400":{"$ref":"#/components/responses/BadRequestError"},"401":{"$ref":"#/components/responses/UnauthorizedError"},"403":{"$ref":"#/components/responses/ForbiddenError"},"404":{"$ref":"#/components/responses/NotFoundError"}}}}}}
```

## Export Tasks (V3)

> Alias of \`/export\`. The router mounts both paths on the same handler, so the parameters, the response and the required role are identical. It exists for older clients; new integrations should call \`/export\`.

```json
{"openapi":"3.0.3","info":{"title":"Ango Hub API v2","version":"2.0.0"},"tags":[{"name":"Import/Export","description":"Bulk data import and export"}],"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":{"ExportResponse":{"type":"object","properties":{"status":{"type":"string"},"data":{"type":"object","properties":{"exportPath":{"type":"string","description":"Pre-signed link to the export archive, a zip containing the export files. The link is valid for 24 hours. The same object is kept in the project's export history, which re-signs it on read, so an expired link can be refreshed there."}}}}},"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"}}}},"UnauthorizedError":{"description":"Unauthorized - invalid or missing API key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"ForbiddenError":{"description":"Forbidden - insufficient permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"NotFoundError":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"paths":{"/exportV3":{"get":{"tags":["Import/Export"],"summary":"Export Tasks (V3)","description":"Alias of `/export`. The router mounts both paths on the same handler, so the parameters, the response and the required role are identical. It exists for older clients; new integrations should call `/export`.","operationId":"exportTasksV3","parameters":[{"name":"project","in":"query","required":true,"schema":{"type":"string"},"description":"Project ID"},{"name":"format","in":"query","schema":{"type":"string","enum":["json","split","ndjson"],"default":"json"},"description":"Export format"},{"name":"type","in":"query","schema":{"type":"string","enum":["task","issue"],"default":"task"},"description":"Export type (task or issue)"},{"name":"stage","in":"query","schema":{"type":"string"},"description":"Filter by stage, as a JSON array string. Values are workflow stage IDs, or one of the fixed stages `Start`, `Complete` and `Archive`."},{"name":"batches","in":"query","schema":{"type":"string"},"description":"Filter by batch, as a JSON array string of batch IDs taken from the project's `batches` array. A task matches when it carries any of them."},{"name":"sendEmail","in":"query","schema":{"type":"string","enum":["true","false"],"default":"false"},"description":"Send export download link via email"},{"name":"doNotNotify","in":"query","schema":{"type":"string","enum":["true","false"],"default":"false"},"description":"Do not send notifications about export"},{"name":"includeMetadata","in":"query","schema":{"type":"string","enum":["true","false"],"default":"false"},"description":"Include asset metadata in export"},{"name":"includeHistory","in":"query","schema":{"type":"string","enum":["true","false"],"default":"false"},"description":"Include task history (all state changes)"},{"name":"includeOnlyKeyFrames","in":"query","schema":{"type":"string","enum":["true","false"],"default":"false"},"description":"Include only key frames for video annotations"},{"name":"includeIdleBlurDurations","in":"query","schema":{"type":"string","enum":["true","false"],"default":"false"},"description":"Include idle and blur duration statistics"},{"name":"split","in":"query","schema":{"type":"string","enum":["true","false"],"default":"false"},"description":"Write one file per task. Overrides `format` with `split`."},{"name":"taskTypes","in":"query","schema":{"type":"string"},"description":"JSON array string of task types to include: `default`, `consensus` or `benchmark`. Defaults to `[\"default\"]`, which also covers tasks stored without a type."},{"name":"sendEmailOnFailure","in":"query","schema":{"type":"string","enum":["true","false"],"default":"false"},"description":"Email the caller when the export fails"},{"name":"includeSegmentationPoints","in":"query","schema":{"type":"string","enum":["true","false"]},"description":"Accepted for backward compatibility, ignored by the server"},{"name":"updatedAt","in":"query","schema":{"type":"string"},"description":"Filter by update date (JSON object, e.g., {\"$gt\":\"2020-08-19T07:37:15.000000Z\",\"$lt\":\"2020-08-26T07:37:15.000000Z\"})"},{"name":"createdAt","in":"query","schema":{"type":"string"},"description":"Filter by creation date (JSON object, e.g., {\"$gt\":\"2020-07-27T07:37:15.000000Z\",\"$lt\":\"2020-08-26T07:37:15.000000Z\"})"},{"name":"filters","in":"query","schema":{"type":"string"},"description":"MongoDB-style filter object for advanced task filtering (JSON string).\nSupports any MongoDB query operators on task fields.\nCommon use cases:\n- Filter by task IDs: {\"_id\": {\"$in\": [\"taskId1\", \"taskId2\"]}}\n- Filter by assignee: {\"assignee\": \"user@example.com\"}\n- Filter by external ID: {\"externalId\": {\"$regex\": \"^prefix_\"}}\n"}],"responses":{"200":{"description":"Export prepared successfully","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExportResponse"}}}},"400":{"$ref":"#/components/responses/BadRequestError"},"401":{"$ref":"#/components/responses/UnauthorizedError"},"403":{"$ref":"#/components/responses/ForbiddenError"},"404":{"$ref":"#/components/responses/NotFoundError"}}}}}}
```


---

# 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 by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.imerit.net/api/docs/import-export.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

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.
