# Models

## The ErrorResponse object

```json
{"openapi":"3.0.3","info":{"title":"Ango Hub API v2","version":"2.0.0"},"components":{"schemas":{"ErrorResponse":{"type":"object","properties":{"status":{"type":"string","enum":["fail","error"]},"message":{"type":"string"}}}}}}
```

## The MessageResponse object

```json
{"openapi":"3.0.3","info":{"title":"Ango Hub API v2","version":"2.0.0"},"components":{"schemas":{"MessageResponse":{"type":"object","properties":{"status":{"type":"string"},"data":{"type":"object","properties":{"message":{"type":"string"}}}}}}}}
```

## The ProjectListItem object

```json
{"openapi":"3.0.3","info":{"title":"Ango Hub API v2","version":"2.0.0"},"components":{"schemas":{"ProjectListItem":{"type":"object","properties":{"_id":{"type":"string"},"name":{"type":"string"},"description":{"type":"string"},"organization":{"type":"string"},"createdAt":{"type":"string","format":"date-time"}}}}}}
```

## The Project object

```json
{"openapi":"3.0.3","info":{"title":"Ango Hub API v2","version":"2.0.0"},"components":{"schemas":{"Project":{"type":"object","properties":{"_id":{"type":"string"},"name":{"type":"string"},"description":{"type":"string"},"type":{"type":"string","enum":["ango","pct","iframe"],"default":"ango"},"owner":{"type":"string","description":"Owner email"},"organization":{"type":"string","description":"Organization ID"},"categorySchema":{"$ref":"#/components/schemas/CategorySchema"},"stages":{"type":"array","items":{"$ref":"#/components/schemas/Stage"}},"assignedTo":{"type":"array","items":{"$ref":"#/components/schemas/Assignee"}},"batches":{"type":"array","items":{"$ref":"#/components/schemas/Batch"}},"queueVersion":{"type":"number"},"assetCount":{"type":"integer"},"benchmarkEnabled":{"type":"boolean"},"benchmarkRatio":{"type":"number"},"instructions":{"type":"string","description":"Instructions URL"},"ocrLanguage":{"type":"string"},"idleTimeout":{"type":"number","description":"Idle timeout in seconds"},"projectPlugins":{"type":"object"},"pluginPresets":{"type":"array","items":{"type":"object"}},"errorCodesEnabled":{"type":"boolean"},"errorSchema":{"type":"object"},"exportStorageId":{"type":"string"},"exportStorageBucket":{"type":"string"},"exportStoragePath":{"type":"string"},"exportStorageEnabled":{"type":"boolean"},"taskSkipEnabled":{"type":"boolean"},"unassignSkippedTask":{"type":"boolean"},"gcSyncEnabled":{"type":"boolean"},"deleted":{"type":"boolean"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"CategorySchema":{"type":"object","description":"Label configuration schema that defines the annotation tools, classifications, and relations for a project.\nThis schema determines what annotation types are available to users and how they can label assets.\n\n**Note:** Schema structure varies between Ango and PCT projects.\n- Ango projects: Use standard annotation tools (bounding-box, polygon, etc.)\n- PCT projects: Use PCT tool type with markingTools array and nested classifications with PCT-specific fields\n","properties":{"tools":{"type":"array","description":"Array of annotation tools (bounding box, polygon, segmentation, etc.)","items":{"$ref":"#/components/schemas/Tool"}},"classifications":{"type":"array","description":"Array of classification questions (radio, checkbox, dropdown, text, etc.)","items":{"$ref":"#/components/schemas/Classification"}},"relations":{"type":"array","description":"Array of relation types that can connect annotations","items":{"$ref":"#/components/schemas/Relation"}}}},"Tool":{"type":"object","description":"Annotation tool configuration","required":["schemaId","title","tool"],"properties":{"schemaId":{"type":"string","description":"Unique identifier for this tool"},"title":{"type":"string","description":"Display name for the tool"},"tool":{"type":"string","description":"Type of annotation tool","enum":["bounding-box","polygon","polyline","point","rotated-bounding-box","segmentation","brush","medical-brush","ner","pdf","pct","angle"]},"required":{"type":"boolean","description":"Whether this annotation is required","default":false},"color":{"type":"string","description":"Hex color code for this annotation class","pattern":"^#[0-9A-Fa-f]{6}$"},"shortcutKey":{"type":"string","description":"Keyboard shortcut for quick selection"},"classifications":{"type":"array","description":"Nested classifications specific to this tool","items":{"$ref":"#/components/schemas/Classification"}},"multiple":{"type":"boolean","description":"Allow creating multiple instances of this annotation","default":false},"exportName":{"type":"string","description":"(PCT only) Name used when exporting data (for organizing exported annotations)"},"displayName":{"type":"string","description":"(PCT only) Display name shown in the annotation interface"},"abbreviatedName":{"type":"string","description":"(PCT only) Abbreviated name for compact UI views"},"markingTools":{"type":"array","description":"(PCT only) List of marking tools enabled for this PCT tool.\nAvailable marking tools: polygon, polygon2d, polyline, polyline2d, cuboid, rectangle\n","items":{"type":"string","enum":["polygon","polygon2d","polyline","polyline2d","cuboid","rectangle"]}},"truncate":{"type":"boolean","description":"(PCT only) Enable truncation for this tool","default":false},"presetCuboidDimensions":{"type":"boolean","description":"(PCT only) Enable preset cuboid dimensions","default":false},"cuboidLength":{"type":"string","description":"(PCT only) Preset cuboid length value (stored as string)"},"cuboidWidth":{"type":"string","description":"(PCT only) Preset cuboid width value (stored as string)"},"cuboidHeight":{"type":"string","description":"(PCT only) Preset cuboid height value (stored as string)"},"keypointWithVerticalLine":{"type":"boolean","description":"(PCT only) Enable keypoint with vertical line feature","default":false},"edgeLengthConstraint":{"type":"string","description":"(PCT only) Minimum edge length constraint (stored as string)"},"hasInstance":{"type":"boolean","description":"(PCT only) Enable instance tracking for this tool","default":false}}},"Classification":{"type":"object","description":"Classification question configuration","required":["schemaId","title","tool"],"properties":{"schemaId":{"type":"string","description":"Unique identifier for this classification"},"title":{"type":"string","description":"Question or label text"},"tool":{"type":"string","description":"Type of classification input (same as 'type')","enum":["radio","checkbox","single-dropdown","multi-dropdown","tree-dropdown","single-tree-dropdown","text","boolean"]},"color":{"type":"string","description":"Hex color code for this classification","pattern":"^#[0-9A-Fa-f]{6}$"},"required":{"type":"boolean","description":"Whether answering this classification is required","default":false},"shortcutKey":{"type":"string","description":"Keyboard shortcut key"},"columnField":{"type":"boolean","description":"Whether to show in column view","default":false},"frameSpecific":{"type":"boolean","description":"Whether classification is frame-specific (for videos)","default":false},"showDropdown":{"type":"boolean","description":"Whether to show as dropdown in UI","default":false},"richText":{"type":"boolean","description":"Whether to enable rich text input (for text type)","default":false},"regex":{"type":"string","nullable":true,"description":"Regular expression for text validation (for text type)"},"parentOptionId":{"type":"string","nullable":true,"description":"Parent option ID for nested classifications"},"options":{"type":"array","description":"Available options (not used for text type)","items":{"$ref":"#/components/schemas/ClassificationOption"}},"treeOptions":{"type":"array","description":"Tree-structured options (for tree-dropdown types)","items":{"type":"object"}},"classifications":{"type":"array","description":"Nested child classifications","items":{"$ref":"#/components/schemas/Classification"}},"multiple":{"type":"boolean","description":"Allow multiple selections","default":false},"parentToolType":{"type":"string","description":"(PCT only) Parent tool type this classification belongs to"},"parentToolId":{"type":"string","description":"(PCT only) Parent tool schemaId this classification is associated with"},"attributeLevel":{"type":"string","description":"(PCT only) Level at which this attribute applies","enum":["Class Level","Instance Level"]},"defaultValue":{"description":"Default value for this classification (type varies based on classification tool type)","oneOf":[{"type":"boolean"},{"type":"string"},{"type":"number"}]},"exportName":{"type":"string","description":"(PCT only) Name used when exporting data"},"displayName":{"type":"string","description":"(PCT only) Display name shown in the annotation interface"},"abbreviatedName":{"type":"string","description":"(PCT only) Abbreviated name for compact UI views"},"attributeMode":{"type":"string","description":"(PCT only) Attribute mode determining how values persist across frames.\n- Time Varying: Value can change per frame\n- Constant: Single value for entire sequence\n- Sensor Specific: Different values per sensor\n","enum":["Time Varying","Constant","Sensor Specific"]},"associatedMarkingTool":{"type":"array","description":"(PCT only) Marking tools this classification is associated with.\nThis classification will only be available when using these marking tools.\n","items":{"type":"string","enum":["polygon","polygon2d","polyline","polyline2d","cuboid","rectangle"]}}}},"ClassificationOption":{"type":"object","description":"Option for a classification question","required":["schemaId","value"],"properties":{"schemaId":{"type":"string","description":"Unique identifier for this option"},"value":{"type":"string","description":"Display text and internal value for this option"},"label":{"type":"string","description":"Alternative display text (deprecated, use 'value')"},"children":{"type":"array","description":"Nested classifications that appear when this option is selected","items":{"$ref":"#/components/schemas/Classification"}}}},"Relation":{"type":"object","description":"Relation type that can connect two annotations.\n\n**Relation Types:**\n- `one-to-one`: Direct connection between two annotations (Ango only)\n- `group`: Groups multiple annotations together (Ango only)\n- `one-to-many`: Parent-child hierarchical relationship (PCT only)\n\n**Note:** PCT projects support additional fields like `parentTool` and `childTools` for one-to-many relations.\n","required":["schemaId","title","tool"],"properties":{"schemaId":{"type":"string","description":"Unique identifier for this relation"},"title":{"type":"string","description":"Display name for the relation"},"tool":{"type":"string","description":"Type of relation tool:\n- `one-to-one`: Direct 1:1 connection between annotations (Ango only)\n- `group`: Non-directional grouping of multiple annotations (Ango only)\n- `one-to-many`: Hierarchical parent-child relationship (PCT only)\n","enum":["one-to-one","group","one-to-many"]},"color":{"type":"string","description":"Hex color code for this relation","pattern":"^#[0-9A-Fa-f]{6}$"},"required":{"type":"boolean","description":"Whether this relation must be used in annotations","default":false},"classifications":{"type":"array","description":"Nested classification questions attached to this relation.\nAllows adding metadata or attributes to the relationship itself.\n","default":[]},"multiple":{"type":"boolean","description":"Whether multiple instances of this relation can be created","default":false},"shortcutKey":{"type":"string","description":"Keyboard shortcut to quickly create this relation"},"parentTool":{"type":"string","description":"(PCT only) For one-to-many relations, specifies the schemaId of the parent tool.\nOnly applicable when `tool: \"one-to-many\"`.\n"},"childTools":{"type":"array","description":"(PCT only) For one-to-many relations, specifies the schemaIds of allowed child tools.\nOnly applicable when `tool: \"one-to-many\"`.\n","items":{"type":"string"}}}},"Stage":{"type":"object","description":"Workflow stage configuration. Different stage types have different properties.\n- Label: Manual annotation stage\n- Review: QA/review stage\n- Logic: Conditional routing stage\n- Plugin: ML model integration stage\n- Webhook: External API callback stage\n- Consensus: Multi-annotator agreement stage\n- Hold: Pause stage\n- Start: Entry point (auto-forwards)\n- Complete: Terminal success stage\n- Archive: Terminal archive stage\n","required":["id","type"],"properties":{"id":{"type":"string","description":"Unique identifier for this stage"},"name":{"type":"string","description":"Display name for this stage"},"type":{"type":"string","description":"Type of stage","enum":["Label","Review","Logic","Plugin","Webhook","Consensus","Hold","Start","Complete","Archive"]},"next":{"type":"array","items":{"type":"string"},"description":"Array of next stage IDs (for Logic stages, order matters)"},"position":{"type":"object","description":"Position in workflow diagram UI","properties":{"x":{"type":"number"},"y":{"type":"number"}}},"assignedTo":{"type":"array","description":"Users assigned to work on this stage (Label/Review stages)","items":{"type":"string"}},"rememberAssignee":{"type":"boolean","description":"Auto-assign to previous stage's user (sticky assignment)","default":false},"logic":{"$ref":"#/components/schemas/LogicConfig","description":"Logic routing configuration (Logic stages only)"},"pluginId":{"type":"string","description":"Plugin ID to execute (Plugin stages only)"},"pluginConfig":{"type":"object","description":"Plugin-specific configuration (Plugin stages only)"},"webhook":{"$ref":"#/components/schemas/WebhookConfig","description":"Webhook configuration (Webhook stages only)"},"consensusConfig":{"$ref":"#/components/schemas/ConsensusConfig","description":"Consensus configuration (Consensus stages only)"},"readOnly":{"type":"boolean","description":"Whether this stage is read-only (users can view but not edit)","default":false},"preventRequeue":{"type":"boolean","description":"Prevent tasks from being requeued to this stage","default":false},"autoForward":{"type":"boolean","description":"Automatically advance to next stage without user action","default":true},"consensusId":{"type":"string","description":"Links stage to a consensus stage (used in consensus workflows)"},"consensusDynamic":{"type":"boolean","description":"Dynamic vs static consensus stage","default":false}}},"LogicConfig":{"type":"object","description":"Logic stage routing configuration. Routes tasks based on conditions.\nConditions are evaluated in order, first match wins.\n","properties":{"type":{"type":"string","description":"Type of logic routing","enum":["AnnotationType","Annotator","RandomSample","Duration","Batch","IssueErrorCode"]},"value":{"type":"object","description":"Default value (usually empty)"},"conditions":{"type":"array","description":"Array of routing conditions","items":{"$ref":"#/components/schemas/LogicCondition"}}}},"LogicCondition":{"type":"object","description":"Individual routing condition for Logic stages","properties":{"type":{"type":"string","description":"Type of condition","enum":["AnnotationType","Annotator","RandomSample","Duration","Batch","IssueErrorCode"]},"value":{"type":"object","description":"Condition-specific value","properties":{"tools":{"type":"array","description":"Tool filters (AnnotationType logic)","items":{"type":"object","properties":{"filter":{"type":"array","items":{"type":"string"},"description":"Annotation filters:\n- exists___<schemaId>: Annotation must exist\n- not-exist___<schemaId>: Annotation must NOT exist\n"}}}},"emails":{"type":"array","description":"User emails (Annotator logic)","items":{"type":"string"}},"sampleRate":{"type":"number","description":"Sample rate 0-1 (RandomSample logic)","minimum":0,"maximum":1},"duration":{"type":"number","description":"Duration in milliseconds (Duration logic)"},"operator":{"type":"string","description":"Comparison operator for Duration","enum":["lt","gt","eq"]},"batches":{"type":"array","description":"Batch names (Batch logic)","items":{"type":"string"}}}},"index":{"type":"number","description":"Index of next stage in parent's next array"}}},"WebhookConfig":{"type":"object","description":"Webhook configuration for external API integration","required":["url"],"properties":{"url":{"type":"string","format":"uri","description":"Webhook endpoint URL"},"method":{"type":"string","description":"HTTP method","enum":["POST","PUT"],"default":"POST"},"authType":{"type":"string","description":"Authentication type","enum":["no_auth","secret","bearer_token"],"default":"no_auth"},"secret":{"type":"string","description":"Secret for HMAC signature (authType=secret)"},"token":{"type":"string","description":"Bearer token (authType=bearer_token)"},"timeout":{"type":"number","description":"Timeout in milliseconds","default":30000},"retryCount":{"type":"number","description":"Number of retry attempts","default":3}}},"ConsensusConfig":{"type":"object","description":"Consensus configuration for multi-annotator agreement","properties":{"version":{"type":"number","description":"Consensus algorithm version (1 or 2, v2 recommended)","enum":[1,2],"default":2},"threshold":{"type":"number","description":"Minimum agreement score (0-1) required to pass","minimum":0,"maximum":1},"adjudicationMethod":{"type":"string","description":"Method for resolving disagreements","enum":["majority","union","intersection","first"],"default":"majority"},"dynamicConsensus":{"type":"boolean","description":"Add more copies if threshold not met","default":false},"minCopies":{"type":"number","description":"Minimum number of consensus copies","minimum":2,"default":2},"maxCopies":{"type":"number","description":"Maximum number of consensus copies (dynamic consensus)","default":5}}},"Assignee":{"type":"object","properties":{"assignee":{"type":"string","description":"User email"},"role":{"type":"string","enum":["Manager","Labeler","Reviewer","Lead"]}}},"Batch":{"type":"object","required":["name"],"properties":{"_id":{"type":"string","description":"Batch ID (auto-generated if not provided)"},"name":{"type":"string","description":"Batch name"}}}}}}
```

## The ProjectCreateRequest object

````json
{"openapi":"3.0.3","info":{"title":"Ango Hub API v2","version":"2.0.0"},"components":{"schemas":{"ProjectCreateRequest":{"type":"object","required":["name"],"properties":{"name":{"type":"string","minLength":1,"description":"Project name"},"description":{"type":"string","description":"Project description"},"type":{"type":"string","description":"Project type","enum":["ango","pct","iframe"],"default":"ango"},"pctConfig":{"$ref":"#/components/schemas/PctConfig","description":"Point Cloud Tool configuration (required only when type is \"pct\")"}}},"PctConfig":{"type":"object","description":"Configuration specific to Point Cloud Tool (PCT) projects.\nThese settings control how 3D point cloud annotation behaves.\n\nExample:\n```json\n{\n  \"allowOverlapping\": false,\n  \"trackingMultipleSensors\": true,\n  \"segmentationMode\": false\n}\n```\n","properties":{"allowOverlapping":{"type":"boolean","description":"Allow overlapping 3D bounding boxes","default":false},"trackingMultipleSensors":{"type":"boolean","description":"Enable tracking across multiple LiDAR sensors","default":false},"segmentationMode":{"type":"boolean","description":"Enable segmentation mode for point clouds","default":false}}}}}}
````

## The ProjectUpdateRequest object

````json
{"openapi":"3.0.3","info":{"title":"Ango Hub API v2","version":"2.0.0"},"components":{"schemas":{"ProjectUpdateRequest":{"type":"object","properties":{"name":{"type":"string","minLength":1},"description":{"type":"string"},"categorySchema":{"$ref":"#/components/schemas/CategorySchema"},"stages":{"type":"array","items":{"$ref":"#/components/schemas/Stage"}},"batches":{"type":"array","items":{"$ref":"#/components/schemas/Batch"}},"benchmarkEnabled":{"type":"boolean"},"benchmarkRatio":{"type":"number"},"instructions":{"type":"string"},"ocrLanguage":{"type":"string"},"idleTimeout":{"type":"number"},"projectPlugins":{"type":"object"},"pluginPresets":{"type":"array","items":{"type":"object"}},"errorCodesEnabled":{"type":"boolean"},"errorSchema":{"type":"object"},"exportStorageId":{"type":"string"},"exportStorageBucket":{"type":"string"},"exportStoragePath":{"type":"string"},"exportStorageEnabled":{"type":"boolean"},"taskSkipEnabled":{"type":"boolean"},"unassignSkippedTask":{"type":"boolean"},"gcSyncEnabled":{"type":"boolean"},"pctConfig":{"$ref":"#/components/schemas/PctConfig","description":"Point Cloud Tool configuration (only for pct project type)"},"deleted":{"type":"boolean"}}},"CategorySchema":{"type":"object","description":"Label configuration schema that defines the annotation tools, classifications, and relations for a project.\nThis schema determines what annotation types are available to users and how they can label assets.\n\n**Note:** Schema structure varies between Ango and PCT projects.\n- Ango projects: Use standard annotation tools (bounding-box, polygon, etc.)\n- PCT projects: Use PCT tool type with markingTools array and nested classifications with PCT-specific fields\n","properties":{"tools":{"type":"array","description":"Array of annotation tools (bounding box, polygon, segmentation, etc.)","items":{"$ref":"#/components/schemas/Tool"}},"classifications":{"type":"array","description":"Array of classification questions (radio, checkbox, dropdown, text, etc.)","items":{"$ref":"#/components/schemas/Classification"}},"relations":{"type":"array","description":"Array of relation types that can connect annotations","items":{"$ref":"#/components/schemas/Relation"}}}},"Tool":{"type":"object","description":"Annotation tool configuration","required":["schemaId","title","tool"],"properties":{"schemaId":{"type":"string","description":"Unique identifier for this tool"},"title":{"type":"string","description":"Display name for the tool"},"tool":{"type":"string","description":"Type of annotation tool","enum":["bounding-box","polygon","polyline","point","rotated-bounding-box","segmentation","brush","medical-brush","ner","pdf","pct","angle"]},"required":{"type":"boolean","description":"Whether this annotation is required","default":false},"color":{"type":"string","description":"Hex color code for this annotation class","pattern":"^#[0-9A-Fa-f]{6}$"},"shortcutKey":{"type":"string","description":"Keyboard shortcut for quick selection"},"classifications":{"type":"array","description":"Nested classifications specific to this tool","items":{"$ref":"#/components/schemas/Classification"}},"multiple":{"type":"boolean","description":"Allow creating multiple instances of this annotation","default":false},"exportName":{"type":"string","description":"(PCT only) Name used when exporting data (for organizing exported annotations)"},"displayName":{"type":"string","description":"(PCT only) Display name shown in the annotation interface"},"abbreviatedName":{"type":"string","description":"(PCT only) Abbreviated name for compact UI views"},"markingTools":{"type":"array","description":"(PCT only) List of marking tools enabled for this PCT tool.\nAvailable marking tools: polygon, polygon2d, polyline, polyline2d, cuboid, rectangle\n","items":{"type":"string","enum":["polygon","polygon2d","polyline","polyline2d","cuboid","rectangle"]}},"truncate":{"type":"boolean","description":"(PCT only) Enable truncation for this tool","default":false},"presetCuboidDimensions":{"type":"boolean","description":"(PCT only) Enable preset cuboid dimensions","default":false},"cuboidLength":{"type":"string","description":"(PCT only) Preset cuboid length value (stored as string)"},"cuboidWidth":{"type":"string","description":"(PCT only) Preset cuboid width value (stored as string)"},"cuboidHeight":{"type":"string","description":"(PCT only) Preset cuboid height value (stored as string)"},"keypointWithVerticalLine":{"type":"boolean","description":"(PCT only) Enable keypoint with vertical line feature","default":false},"edgeLengthConstraint":{"type":"string","description":"(PCT only) Minimum edge length constraint (stored as string)"},"hasInstance":{"type":"boolean","description":"(PCT only) Enable instance tracking for this tool","default":false}}},"Classification":{"type":"object","description":"Classification question configuration","required":["schemaId","title","tool"],"properties":{"schemaId":{"type":"string","description":"Unique identifier for this classification"},"title":{"type":"string","description":"Question or label text"},"tool":{"type":"string","description":"Type of classification input (same as 'type')","enum":["radio","checkbox","single-dropdown","multi-dropdown","tree-dropdown","single-tree-dropdown","text","boolean"]},"color":{"type":"string","description":"Hex color code for this classification","pattern":"^#[0-9A-Fa-f]{6}$"},"required":{"type":"boolean","description":"Whether answering this classification is required","default":false},"shortcutKey":{"type":"string","description":"Keyboard shortcut key"},"columnField":{"type":"boolean","description":"Whether to show in column view","default":false},"frameSpecific":{"type":"boolean","description":"Whether classification is frame-specific (for videos)","default":false},"showDropdown":{"type":"boolean","description":"Whether to show as dropdown in UI","default":false},"richText":{"type":"boolean","description":"Whether to enable rich text input (for text type)","default":false},"regex":{"type":"string","nullable":true,"description":"Regular expression for text validation (for text type)"},"parentOptionId":{"type":"string","nullable":true,"description":"Parent option ID for nested classifications"},"options":{"type":"array","description":"Available options (not used for text type)","items":{"$ref":"#/components/schemas/ClassificationOption"}},"treeOptions":{"type":"array","description":"Tree-structured options (for tree-dropdown types)","items":{"type":"object"}},"classifications":{"type":"array","description":"Nested child classifications","items":{"$ref":"#/components/schemas/Classification"}},"multiple":{"type":"boolean","description":"Allow multiple selections","default":false},"parentToolType":{"type":"string","description":"(PCT only) Parent tool type this classification belongs to"},"parentToolId":{"type":"string","description":"(PCT only) Parent tool schemaId this classification is associated with"},"attributeLevel":{"type":"string","description":"(PCT only) Level at which this attribute applies","enum":["Class Level","Instance Level"]},"defaultValue":{"description":"Default value for this classification (type varies based on classification tool type)","oneOf":[{"type":"boolean"},{"type":"string"},{"type":"number"}]},"exportName":{"type":"string","description":"(PCT only) Name used when exporting data"},"displayName":{"type":"string","description":"(PCT only) Display name shown in the annotation interface"},"abbreviatedName":{"type":"string","description":"(PCT only) Abbreviated name for compact UI views"},"attributeMode":{"type":"string","description":"(PCT only) Attribute mode determining how values persist across frames.\n- Time Varying: Value can change per frame\n- Constant: Single value for entire sequence\n- Sensor Specific: Different values per sensor\n","enum":["Time Varying","Constant","Sensor Specific"]},"associatedMarkingTool":{"type":"array","description":"(PCT only) Marking tools this classification is associated with.\nThis classification will only be available when using these marking tools.\n","items":{"type":"string","enum":["polygon","polygon2d","polyline","polyline2d","cuboid","rectangle"]}}}},"ClassificationOption":{"type":"object","description":"Option for a classification question","required":["schemaId","value"],"properties":{"schemaId":{"type":"string","description":"Unique identifier for this option"},"value":{"type":"string","description":"Display text and internal value for this option"},"label":{"type":"string","description":"Alternative display text (deprecated, use 'value')"},"children":{"type":"array","description":"Nested classifications that appear when this option is selected","items":{"$ref":"#/components/schemas/Classification"}}}},"Relation":{"type":"object","description":"Relation type that can connect two annotations.\n\n**Relation Types:**\n- `one-to-one`: Direct connection between two annotations (Ango only)\n- `group`: Groups multiple annotations together (Ango only)\n- `one-to-many`: Parent-child hierarchical relationship (PCT only)\n\n**Note:** PCT projects support additional fields like `parentTool` and `childTools` for one-to-many relations.\n","required":["schemaId","title","tool"],"properties":{"schemaId":{"type":"string","description":"Unique identifier for this relation"},"title":{"type":"string","description":"Display name for the relation"},"tool":{"type":"string","description":"Type of relation tool:\n- `one-to-one`: Direct 1:1 connection between annotations (Ango only)\n- `group`: Non-directional grouping of multiple annotations (Ango only)\n- `one-to-many`: Hierarchical parent-child relationship (PCT only)\n","enum":["one-to-one","group","one-to-many"]},"color":{"type":"string","description":"Hex color code for this relation","pattern":"^#[0-9A-Fa-f]{6}$"},"required":{"type":"boolean","description":"Whether this relation must be used in annotations","default":false},"classifications":{"type":"array","description":"Nested classification questions attached to this relation.\nAllows adding metadata or attributes to the relationship itself.\n","default":[]},"multiple":{"type":"boolean","description":"Whether multiple instances of this relation can be created","default":false},"shortcutKey":{"type":"string","description":"Keyboard shortcut to quickly create this relation"},"parentTool":{"type":"string","description":"(PCT only) For one-to-many relations, specifies the schemaId of the parent tool.\nOnly applicable when `tool: \"one-to-many\"`.\n"},"childTools":{"type":"array","description":"(PCT only) For one-to-many relations, specifies the schemaIds of allowed child tools.\nOnly applicable when `tool: \"one-to-many\"`.\n","items":{"type":"string"}}}},"Stage":{"type":"object","description":"Workflow stage configuration. Different stage types have different properties.\n- Label: Manual annotation stage\n- Review: QA/review stage\n- Logic: Conditional routing stage\n- Plugin: ML model integration stage\n- Webhook: External API callback stage\n- Consensus: Multi-annotator agreement stage\n- Hold: Pause stage\n- Start: Entry point (auto-forwards)\n- Complete: Terminal success stage\n- Archive: Terminal archive stage\n","required":["id","type"],"properties":{"id":{"type":"string","description":"Unique identifier for this stage"},"name":{"type":"string","description":"Display name for this stage"},"type":{"type":"string","description":"Type of stage","enum":["Label","Review","Logic","Plugin","Webhook","Consensus","Hold","Start","Complete","Archive"]},"next":{"type":"array","items":{"type":"string"},"description":"Array of next stage IDs (for Logic stages, order matters)"},"position":{"type":"object","description":"Position in workflow diagram UI","properties":{"x":{"type":"number"},"y":{"type":"number"}}},"assignedTo":{"type":"array","description":"Users assigned to work on this stage (Label/Review stages)","items":{"type":"string"}},"rememberAssignee":{"type":"boolean","description":"Auto-assign to previous stage's user (sticky assignment)","default":false},"logic":{"$ref":"#/components/schemas/LogicConfig","description":"Logic routing configuration (Logic stages only)"},"pluginId":{"type":"string","description":"Plugin ID to execute (Plugin stages only)"},"pluginConfig":{"type":"object","description":"Plugin-specific configuration (Plugin stages only)"},"webhook":{"$ref":"#/components/schemas/WebhookConfig","description":"Webhook configuration (Webhook stages only)"},"consensusConfig":{"$ref":"#/components/schemas/ConsensusConfig","description":"Consensus configuration (Consensus stages only)"},"readOnly":{"type":"boolean","description":"Whether this stage is read-only (users can view but not edit)","default":false},"preventRequeue":{"type":"boolean","description":"Prevent tasks from being requeued to this stage","default":false},"autoForward":{"type":"boolean","description":"Automatically advance to next stage without user action","default":true},"consensusId":{"type":"string","description":"Links stage to a consensus stage (used in consensus workflows)"},"consensusDynamic":{"type":"boolean","description":"Dynamic vs static consensus stage","default":false}}},"LogicConfig":{"type":"object","description":"Logic stage routing configuration. Routes tasks based on conditions.\nConditions are evaluated in order, first match wins.\n","properties":{"type":{"type":"string","description":"Type of logic routing","enum":["AnnotationType","Annotator","RandomSample","Duration","Batch","IssueErrorCode"]},"value":{"type":"object","description":"Default value (usually empty)"},"conditions":{"type":"array","description":"Array of routing conditions","items":{"$ref":"#/components/schemas/LogicCondition"}}}},"LogicCondition":{"type":"object","description":"Individual routing condition for Logic stages","properties":{"type":{"type":"string","description":"Type of condition","enum":["AnnotationType","Annotator","RandomSample","Duration","Batch","IssueErrorCode"]},"value":{"type":"object","description":"Condition-specific value","properties":{"tools":{"type":"array","description":"Tool filters (AnnotationType logic)","items":{"type":"object","properties":{"filter":{"type":"array","items":{"type":"string"},"description":"Annotation filters:\n- exists___<schemaId>: Annotation must exist\n- not-exist___<schemaId>: Annotation must NOT exist\n"}}}},"emails":{"type":"array","description":"User emails (Annotator logic)","items":{"type":"string"}},"sampleRate":{"type":"number","description":"Sample rate 0-1 (RandomSample logic)","minimum":0,"maximum":1},"duration":{"type":"number","description":"Duration in milliseconds (Duration logic)"},"operator":{"type":"string","description":"Comparison operator for Duration","enum":["lt","gt","eq"]},"batches":{"type":"array","description":"Batch names (Batch logic)","items":{"type":"string"}}}},"index":{"type":"number","description":"Index of next stage in parent's next array"}}},"WebhookConfig":{"type":"object","description":"Webhook configuration for external API integration","required":["url"],"properties":{"url":{"type":"string","format":"uri","description":"Webhook endpoint URL"},"method":{"type":"string","description":"HTTP method","enum":["POST","PUT"],"default":"POST"},"authType":{"type":"string","description":"Authentication type","enum":["no_auth","secret","bearer_token"],"default":"no_auth"},"secret":{"type":"string","description":"Secret for HMAC signature (authType=secret)"},"token":{"type":"string","description":"Bearer token (authType=bearer_token)"},"timeout":{"type":"number","description":"Timeout in milliseconds","default":30000},"retryCount":{"type":"number","description":"Number of retry attempts","default":3}}},"ConsensusConfig":{"type":"object","description":"Consensus configuration for multi-annotator agreement","properties":{"version":{"type":"number","description":"Consensus algorithm version (1 or 2, v2 recommended)","enum":[1,2],"default":2},"threshold":{"type":"number","description":"Minimum agreement score (0-1) required to pass","minimum":0,"maximum":1},"adjudicationMethod":{"type":"string","description":"Method for resolving disagreements","enum":["majority","union","intersection","first"],"default":"majority"},"dynamicConsensus":{"type":"boolean","description":"Add more copies if threshold not met","default":false},"minCopies":{"type":"number","description":"Minimum number of consensus copies","minimum":2,"default":2},"maxCopies":{"type":"number","description":"Maximum number of consensus copies (dynamic consensus)","default":5}}},"Batch":{"type":"object","required":["name"],"properties":{"_id":{"type":"string","description":"Batch ID (auto-generated if not provided)"},"name":{"type":"string","description":"Batch name"}}},"PctConfig":{"type":"object","description":"Configuration specific to Point Cloud Tool (PCT) projects.\nThese settings control how 3D point cloud annotation behaves.\n\nExample:\n```json\n{\n  \"allowOverlapping\": false,\n  \"trackingMultipleSensors\": true,\n  \"segmentationMode\": false\n}\n```\n","properties":{"allowOverlapping":{"type":"boolean","description":"Allow overlapping 3D bounding boxes","default":false},"trackingMultipleSensors":{"type":"boolean","description":"Enable tracking across multiple LiDAR sensors","default":false},"segmentationMode":{"type":"boolean","description":"Enable segmentation mode for point clouds","default":false}}}}}}
````

## The ProjectListResponse object

```json
{"openapi":"3.0.3","info":{"title":"Ango Hub API v2","version":"2.0.0"},"components":{"schemas":{"ProjectListResponse":{"type":"object","properties":{"status":{"type":"string"},"data":{"type":"object","properties":{"projects":{"type":"array","items":{"$ref":"#/components/schemas/ProjectListItem"}},"total":{"type":"integer"}}}}},"ProjectListItem":{"type":"object","properties":{"_id":{"type":"string"},"name":{"type":"string"},"description":{"type":"string"},"organization":{"type":"string"},"createdAt":{"type":"string","format":"date-time"}}}}}}
```

## The ProjectResponse object

```json
{"openapi":"3.0.3","info":{"title":"Ango Hub API v2","version":"2.0.0"},"components":{"schemas":{"ProjectResponse":{"type":"object","properties":{"status":{"type":"string"},"data":{"type":"object","properties":{"project":{"$ref":"#/components/schemas/Project"}}}}},"Project":{"type":"object","properties":{"_id":{"type":"string"},"name":{"type":"string"},"description":{"type":"string"},"type":{"type":"string","enum":["ango","pct","iframe"],"default":"ango"},"owner":{"type":"string","description":"Owner email"},"organization":{"type":"string","description":"Organization ID"},"categorySchema":{"$ref":"#/components/schemas/CategorySchema"},"stages":{"type":"array","items":{"$ref":"#/components/schemas/Stage"}},"assignedTo":{"type":"array","items":{"$ref":"#/components/schemas/Assignee"}},"batches":{"type":"array","items":{"$ref":"#/components/schemas/Batch"}},"queueVersion":{"type":"number"},"assetCount":{"type":"integer"},"benchmarkEnabled":{"type":"boolean"},"benchmarkRatio":{"type":"number"},"instructions":{"type":"string","description":"Instructions URL"},"ocrLanguage":{"type":"string"},"idleTimeout":{"type":"number","description":"Idle timeout in seconds"},"projectPlugins":{"type":"object"},"pluginPresets":{"type":"array","items":{"type":"object"}},"errorCodesEnabled":{"type":"boolean"},"errorSchema":{"type":"object"},"exportStorageId":{"type":"string"},"exportStorageBucket":{"type":"string"},"exportStoragePath":{"type":"string"},"exportStorageEnabled":{"type":"boolean"},"taskSkipEnabled":{"type":"boolean"},"unassignSkippedTask":{"type":"boolean"},"gcSyncEnabled":{"type":"boolean"},"deleted":{"type":"boolean"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"CategorySchema":{"type":"object","description":"Label configuration schema that defines the annotation tools, classifications, and relations for a project.\nThis schema determines what annotation types are available to users and how they can label assets.\n\n**Note:** Schema structure varies between Ango and PCT projects.\n- Ango projects: Use standard annotation tools (bounding-box, polygon, etc.)\n- PCT projects: Use PCT tool type with markingTools array and nested classifications with PCT-specific fields\n","properties":{"tools":{"type":"array","description":"Array of annotation tools (bounding box, polygon, segmentation, etc.)","items":{"$ref":"#/components/schemas/Tool"}},"classifications":{"type":"array","description":"Array of classification questions (radio, checkbox, dropdown, text, etc.)","items":{"$ref":"#/components/schemas/Classification"}},"relations":{"type":"array","description":"Array of relation types that can connect annotations","items":{"$ref":"#/components/schemas/Relation"}}}},"Tool":{"type":"object","description":"Annotation tool configuration","required":["schemaId","title","tool"],"properties":{"schemaId":{"type":"string","description":"Unique identifier for this tool"},"title":{"type":"string","description":"Display name for the tool"},"tool":{"type":"string","description":"Type of annotation tool","enum":["bounding-box","polygon","polyline","point","rotated-bounding-box","segmentation","brush","medical-brush","ner","pdf","pct","angle"]},"required":{"type":"boolean","description":"Whether this annotation is required","default":false},"color":{"type":"string","description":"Hex color code for this annotation class","pattern":"^#[0-9A-Fa-f]{6}$"},"shortcutKey":{"type":"string","description":"Keyboard shortcut for quick selection"},"classifications":{"type":"array","description":"Nested classifications specific to this tool","items":{"$ref":"#/components/schemas/Classification"}},"multiple":{"type":"boolean","description":"Allow creating multiple instances of this annotation","default":false},"exportName":{"type":"string","description":"(PCT only) Name used when exporting data (for organizing exported annotations)"},"displayName":{"type":"string","description":"(PCT only) Display name shown in the annotation interface"},"abbreviatedName":{"type":"string","description":"(PCT only) Abbreviated name for compact UI views"},"markingTools":{"type":"array","description":"(PCT only) List of marking tools enabled for this PCT tool.\nAvailable marking tools: polygon, polygon2d, polyline, polyline2d, cuboid, rectangle\n","items":{"type":"string","enum":["polygon","polygon2d","polyline","polyline2d","cuboid","rectangle"]}},"truncate":{"type":"boolean","description":"(PCT only) Enable truncation for this tool","default":false},"presetCuboidDimensions":{"type":"boolean","description":"(PCT only) Enable preset cuboid dimensions","default":false},"cuboidLength":{"type":"string","description":"(PCT only) Preset cuboid length value (stored as string)"},"cuboidWidth":{"type":"string","description":"(PCT only) Preset cuboid width value (stored as string)"},"cuboidHeight":{"type":"string","description":"(PCT only) Preset cuboid height value (stored as string)"},"keypointWithVerticalLine":{"type":"boolean","description":"(PCT only) Enable keypoint with vertical line feature","default":false},"edgeLengthConstraint":{"type":"string","description":"(PCT only) Minimum edge length constraint (stored as string)"},"hasInstance":{"type":"boolean","description":"(PCT only) Enable instance tracking for this tool","default":false}}},"Classification":{"type":"object","description":"Classification question configuration","required":["schemaId","title","tool"],"properties":{"schemaId":{"type":"string","description":"Unique identifier for this classification"},"title":{"type":"string","description":"Question or label text"},"tool":{"type":"string","description":"Type of classification input (same as 'type')","enum":["radio","checkbox","single-dropdown","multi-dropdown","tree-dropdown","single-tree-dropdown","text","boolean"]},"color":{"type":"string","description":"Hex color code for this classification","pattern":"^#[0-9A-Fa-f]{6}$"},"required":{"type":"boolean","description":"Whether answering this classification is required","default":false},"shortcutKey":{"type":"string","description":"Keyboard shortcut key"},"columnField":{"type":"boolean","description":"Whether to show in column view","default":false},"frameSpecific":{"type":"boolean","description":"Whether classification is frame-specific (for videos)","default":false},"showDropdown":{"type":"boolean","description":"Whether to show as dropdown in UI","default":false},"richText":{"type":"boolean","description":"Whether to enable rich text input (for text type)","default":false},"regex":{"type":"string","nullable":true,"description":"Regular expression for text validation (for text type)"},"parentOptionId":{"type":"string","nullable":true,"description":"Parent option ID for nested classifications"},"options":{"type":"array","description":"Available options (not used for text type)","items":{"$ref":"#/components/schemas/ClassificationOption"}},"treeOptions":{"type":"array","description":"Tree-structured options (for tree-dropdown types)","items":{"type":"object"}},"classifications":{"type":"array","description":"Nested child classifications","items":{"$ref":"#/components/schemas/Classification"}},"multiple":{"type":"boolean","description":"Allow multiple selections","default":false},"parentToolType":{"type":"string","description":"(PCT only) Parent tool type this classification belongs to"},"parentToolId":{"type":"string","description":"(PCT only) Parent tool schemaId this classification is associated with"},"attributeLevel":{"type":"string","description":"(PCT only) Level at which this attribute applies","enum":["Class Level","Instance Level"]},"defaultValue":{"description":"Default value for this classification (type varies based on classification tool type)","oneOf":[{"type":"boolean"},{"type":"string"},{"type":"number"}]},"exportName":{"type":"string","description":"(PCT only) Name used when exporting data"},"displayName":{"type":"string","description":"(PCT only) Display name shown in the annotation interface"},"abbreviatedName":{"type":"string","description":"(PCT only) Abbreviated name for compact UI views"},"attributeMode":{"type":"string","description":"(PCT only) Attribute mode determining how values persist across frames.\n- Time Varying: Value can change per frame\n- Constant: Single value for entire sequence\n- Sensor Specific: Different values per sensor\n","enum":["Time Varying","Constant","Sensor Specific"]},"associatedMarkingTool":{"type":"array","description":"(PCT only) Marking tools this classification is associated with.\nThis classification will only be available when using these marking tools.\n","items":{"type":"string","enum":["polygon","polygon2d","polyline","polyline2d","cuboid","rectangle"]}}}},"ClassificationOption":{"type":"object","description":"Option for a classification question","required":["schemaId","value"],"properties":{"schemaId":{"type":"string","description":"Unique identifier for this option"},"value":{"type":"string","description":"Display text and internal value for this option"},"label":{"type":"string","description":"Alternative display text (deprecated, use 'value')"},"children":{"type":"array","description":"Nested classifications that appear when this option is selected","items":{"$ref":"#/components/schemas/Classification"}}}},"Relation":{"type":"object","description":"Relation type that can connect two annotations.\n\n**Relation Types:**\n- `one-to-one`: Direct connection between two annotations (Ango only)\n- `group`: Groups multiple annotations together (Ango only)\n- `one-to-many`: Parent-child hierarchical relationship (PCT only)\n\n**Note:** PCT projects support additional fields like `parentTool` and `childTools` for one-to-many relations.\n","required":["schemaId","title","tool"],"properties":{"schemaId":{"type":"string","description":"Unique identifier for this relation"},"title":{"type":"string","description":"Display name for the relation"},"tool":{"type":"string","description":"Type of relation tool:\n- `one-to-one`: Direct 1:1 connection between annotations (Ango only)\n- `group`: Non-directional grouping of multiple annotations (Ango only)\n- `one-to-many`: Hierarchical parent-child relationship (PCT only)\n","enum":["one-to-one","group","one-to-many"]},"color":{"type":"string","description":"Hex color code for this relation","pattern":"^#[0-9A-Fa-f]{6}$"},"required":{"type":"boolean","description":"Whether this relation must be used in annotations","default":false},"classifications":{"type":"array","description":"Nested classification questions attached to this relation.\nAllows adding metadata or attributes to the relationship itself.\n","default":[]},"multiple":{"type":"boolean","description":"Whether multiple instances of this relation can be created","default":false},"shortcutKey":{"type":"string","description":"Keyboard shortcut to quickly create this relation"},"parentTool":{"type":"string","description":"(PCT only) For one-to-many relations, specifies the schemaId of the parent tool.\nOnly applicable when `tool: \"one-to-many\"`.\n"},"childTools":{"type":"array","description":"(PCT only) For one-to-many relations, specifies the schemaIds of allowed child tools.\nOnly applicable when `tool: \"one-to-many\"`.\n","items":{"type":"string"}}}},"Stage":{"type":"object","description":"Workflow stage configuration. Different stage types have different properties.\n- Label: Manual annotation stage\n- Review: QA/review stage\n- Logic: Conditional routing stage\n- Plugin: ML model integration stage\n- Webhook: External API callback stage\n- Consensus: Multi-annotator agreement stage\n- Hold: Pause stage\n- Start: Entry point (auto-forwards)\n- Complete: Terminal success stage\n- Archive: Terminal archive stage\n","required":["id","type"],"properties":{"id":{"type":"string","description":"Unique identifier for this stage"},"name":{"type":"string","description":"Display name for this stage"},"type":{"type":"string","description":"Type of stage","enum":["Label","Review","Logic","Plugin","Webhook","Consensus","Hold","Start","Complete","Archive"]},"next":{"type":"array","items":{"type":"string"},"description":"Array of next stage IDs (for Logic stages, order matters)"},"position":{"type":"object","description":"Position in workflow diagram UI","properties":{"x":{"type":"number"},"y":{"type":"number"}}},"assignedTo":{"type":"array","description":"Users assigned to work on this stage (Label/Review stages)","items":{"type":"string"}},"rememberAssignee":{"type":"boolean","description":"Auto-assign to previous stage's user (sticky assignment)","default":false},"logic":{"$ref":"#/components/schemas/LogicConfig","description":"Logic routing configuration (Logic stages only)"},"pluginId":{"type":"string","description":"Plugin ID to execute (Plugin stages only)"},"pluginConfig":{"type":"object","description":"Plugin-specific configuration (Plugin stages only)"},"webhook":{"$ref":"#/components/schemas/WebhookConfig","description":"Webhook configuration (Webhook stages only)"},"consensusConfig":{"$ref":"#/components/schemas/ConsensusConfig","description":"Consensus configuration (Consensus stages only)"},"readOnly":{"type":"boolean","description":"Whether this stage is read-only (users can view but not edit)","default":false},"preventRequeue":{"type":"boolean","description":"Prevent tasks from being requeued to this stage","default":false},"autoForward":{"type":"boolean","description":"Automatically advance to next stage without user action","default":true},"consensusId":{"type":"string","description":"Links stage to a consensus stage (used in consensus workflows)"},"consensusDynamic":{"type":"boolean","description":"Dynamic vs static consensus stage","default":false}}},"LogicConfig":{"type":"object","description":"Logic stage routing configuration. Routes tasks based on conditions.\nConditions are evaluated in order, first match wins.\n","properties":{"type":{"type":"string","description":"Type of logic routing","enum":["AnnotationType","Annotator","RandomSample","Duration","Batch","IssueErrorCode"]},"value":{"type":"object","description":"Default value (usually empty)"},"conditions":{"type":"array","description":"Array of routing conditions","items":{"$ref":"#/components/schemas/LogicCondition"}}}},"LogicCondition":{"type":"object","description":"Individual routing condition for Logic stages","properties":{"type":{"type":"string","description":"Type of condition","enum":["AnnotationType","Annotator","RandomSample","Duration","Batch","IssueErrorCode"]},"value":{"type":"object","description":"Condition-specific value","properties":{"tools":{"type":"array","description":"Tool filters (AnnotationType logic)","items":{"type":"object","properties":{"filter":{"type":"array","items":{"type":"string"},"description":"Annotation filters:\n- exists___<schemaId>: Annotation must exist\n- not-exist___<schemaId>: Annotation must NOT exist\n"}}}},"emails":{"type":"array","description":"User emails (Annotator logic)","items":{"type":"string"}},"sampleRate":{"type":"number","description":"Sample rate 0-1 (RandomSample logic)","minimum":0,"maximum":1},"duration":{"type":"number","description":"Duration in milliseconds (Duration logic)"},"operator":{"type":"string","description":"Comparison operator for Duration","enum":["lt","gt","eq"]},"batches":{"type":"array","description":"Batch names (Batch logic)","items":{"type":"string"}}}},"index":{"type":"number","description":"Index of next stage in parent's next array"}}},"WebhookConfig":{"type":"object","description":"Webhook configuration for external API integration","required":["url"],"properties":{"url":{"type":"string","format":"uri","description":"Webhook endpoint URL"},"method":{"type":"string","description":"HTTP method","enum":["POST","PUT"],"default":"POST"},"authType":{"type":"string","description":"Authentication type","enum":["no_auth","secret","bearer_token"],"default":"no_auth"},"secret":{"type":"string","description":"Secret for HMAC signature (authType=secret)"},"token":{"type":"string","description":"Bearer token (authType=bearer_token)"},"timeout":{"type":"number","description":"Timeout in milliseconds","default":30000},"retryCount":{"type":"number","description":"Number of retry attempts","default":3}}},"ConsensusConfig":{"type":"object","description":"Consensus configuration for multi-annotator agreement","properties":{"version":{"type":"number","description":"Consensus algorithm version (1 or 2, v2 recommended)","enum":[1,2],"default":2},"threshold":{"type":"number","description":"Minimum agreement score (0-1) required to pass","minimum":0,"maximum":1},"adjudicationMethod":{"type":"string","description":"Method for resolving disagreements","enum":["majority","union","intersection","first"],"default":"majority"},"dynamicConsensus":{"type":"boolean","description":"Add more copies if threshold not met","default":false},"minCopies":{"type":"number","description":"Minimum number of consensus copies","minimum":2,"default":2},"maxCopies":{"type":"number","description":"Maximum number of consensus copies (dynamic consensus)","default":5}}},"Assignee":{"type":"object","properties":{"assignee":{"type":"string","description":"User email"},"role":{"type":"string","enum":["Manager","Labeler","Reviewer","Lead"]}}},"Batch":{"type":"object","required":["name"],"properties":{"_id":{"type":"string","description":"Batch ID (auto-generated if not provided)"},"name":{"type":"string","description":"Batch name"}}}}}}
```

## The WorkflowUpdateRequest object

```json
{"openapi":"3.0.3","info":{"title":"Ango Hub API v2","version":"2.0.0"},"components":{"schemas":{"WorkflowUpdateRequest":{"type":"object","description":"Request body for updating project workflow stages","required":["stages"],"properties":{"stages":{"type":"array","description":"Complete array of workflow stages for the project","items":{"$ref":"#/components/schemas/Stage"},"minItems":3}}},"Stage":{"type":"object","description":"Workflow stage configuration. Different stage types have different properties.\n- Label: Manual annotation stage\n- Review: QA/review stage\n- Logic: Conditional routing stage\n- Plugin: ML model integration stage\n- Webhook: External API callback stage\n- Consensus: Multi-annotator agreement stage\n- Hold: Pause stage\n- Start: Entry point (auto-forwards)\n- Complete: Terminal success stage\n- Archive: Terminal archive stage\n","required":["id","type"],"properties":{"id":{"type":"string","description":"Unique identifier for this stage"},"name":{"type":"string","description":"Display name for this stage"},"type":{"type":"string","description":"Type of stage","enum":["Label","Review","Logic","Plugin","Webhook","Consensus","Hold","Start","Complete","Archive"]},"next":{"type":"array","items":{"type":"string"},"description":"Array of next stage IDs (for Logic stages, order matters)"},"position":{"type":"object","description":"Position in workflow diagram UI","properties":{"x":{"type":"number"},"y":{"type":"number"}}},"assignedTo":{"type":"array","description":"Users assigned to work on this stage (Label/Review stages)","items":{"type":"string"}},"rememberAssignee":{"type":"boolean","description":"Auto-assign to previous stage's user (sticky assignment)","default":false},"logic":{"$ref":"#/components/schemas/LogicConfig","description":"Logic routing configuration (Logic stages only)"},"pluginId":{"type":"string","description":"Plugin ID to execute (Plugin stages only)"},"pluginConfig":{"type":"object","description":"Plugin-specific configuration (Plugin stages only)"},"webhook":{"$ref":"#/components/schemas/WebhookConfig","description":"Webhook configuration (Webhook stages only)"},"consensusConfig":{"$ref":"#/components/schemas/ConsensusConfig","description":"Consensus configuration (Consensus stages only)"},"readOnly":{"type":"boolean","description":"Whether this stage is read-only (users can view but not edit)","default":false},"preventRequeue":{"type":"boolean","description":"Prevent tasks from being requeued to this stage","default":false},"autoForward":{"type":"boolean","description":"Automatically advance to next stage without user action","default":true},"consensusId":{"type":"string","description":"Links stage to a consensus stage (used in consensus workflows)"},"consensusDynamic":{"type":"boolean","description":"Dynamic vs static consensus stage","default":false}}},"LogicConfig":{"type":"object","description":"Logic stage routing configuration. Routes tasks based on conditions.\nConditions are evaluated in order, first match wins.\n","properties":{"type":{"type":"string","description":"Type of logic routing","enum":["AnnotationType","Annotator","RandomSample","Duration","Batch","IssueErrorCode"]},"value":{"type":"object","description":"Default value (usually empty)"},"conditions":{"type":"array","description":"Array of routing conditions","items":{"$ref":"#/components/schemas/LogicCondition"}}}},"LogicCondition":{"type":"object","description":"Individual routing condition for Logic stages","properties":{"type":{"type":"string","description":"Type of condition","enum":["AnnotationType","Annotator","RandomSample","Duration","Batch","IssueErrorCode"]},"value":{"type":"object","description":"Condition-specific value","properties":{"tools":{"type":"array","description":"Tool filters (AnnotationType logic)","items":{"type":"object","properties":{"filter":{"type":"array","items":{"type":"string"},"description":"Annotation filters:\n- exists___<schemaId>: Annotation must exist\n- not-exist___<schemaId>: Annotation must NOT exist\n"}}}},"emails":{"type":"array","description":"User emails (Annotator logic)","items":{"type":"string"}},"sampleRate":{"type":"number","description":"Sample rate 0-1 (RandomSample logic)","minimum":0,"maximum":1},"duration":{"type":"number","description":"Duration in milliseconds (Duration logic)"},"operator":{"type":"string","description":"Comparison operator for Duration","enum":["lt","gt","eq"]},"batches":{"type":"array","description":"Batch names (Batch logic)","items":{"type":"string"}}}},"index":{"type":"number","description":"Index of next stage in parent's next array"}}},"WebhookConfig":{"type":"object","description":"Webhook configuration for external API integration","required":["url"],"properties":{"url":{"type":"string","format":"uri","description":"Webhook endpoint URL"},"method":{"type":"string","description":"HTTP method","enum":["POST","PUT"],"default":"POST"},"authType":{"type":"string","description":"Authentication type","enum":["no_auth","secret","bearer_token"],"default":"no_auth"},"secret":{"type":"string","description":"Secret for HMAC signature (authType=secret)"},"token":{"type":"string","description":"Bearer token (authType=bearer_token)"},"timeout":{"type":"number","description":"Timeout in milliseconds","default":30000},"retryCount":{"type":"number","description":"Number of retry attempts","default":3}}},"ConsensusConfig":{"type":"object","description":"Consensus configuration for multi-annotator agreement","properties":{"version":{"type":"number","description":"Consensus algorithm version (1 or 2, v2 recommended)","enum":[1,2],"default":2},"threshold":{"type":"number","description":"Minimum agreement score (0-1) required to pass","minimum":0,"maximum":1},"adjudicationMethod":{"type":"string","description":"Method for resolving disagreements","enum":["majority","union","intersection","first"],"default":"majority"},"dynamicConsensus":{"type":"boolean","description":"Add more copies if threshold not met","default":false},"minCopies":{"type":"number","description":"Minimum number of consensus copies","minimum":2,"default":2},"maxCopies":{"type":"number","description":"Maximum number of consensus copies (dynamic consensus)","default":5}}}}}}
```

## The CategorySchemaUpdateRequest object

```json
{"openapi":"3.0.3","info":{"title":"Ango Hub API v2","version":"2.0.0"},"components":{"schemas":{"CategorySchemaUpdateRequest":{"type":"object","description":"Request body for updating project category schema (annotation tools and classifications)","required":["categorySchema"],"properties":{"categorySchema":{"$ref":"#/components/schemas/CategorySchema"}}},"CategorySchema":{"type":"object","description":"Label configuration schema that defines the annotation tools, classifications, and relations for a project.\nThis schema determines what annotation types are available to users and how they can label assets.\n\n**Note:** Schema structure varies between Ango and PCT projects.\n- Ango projects: Use standard annotation tools (bounding-box, polygon, etc.)\n- PCT projects: Use PCT tool type with markingTools array and nested classifications with PCT-specific fields\n","properties":{"tools":{"type":"array","description":"Array of annotation tools (bounding box, polygon, segmentation, etc.)","items":{"$ref":"#/components/schemas/Tool"}},"classifications":{"type":"array","description":"Array of classification questions (radio, checkbox, dropdown, text, etc.)","items":{"$ref":"#/components/schemas/Classification"}},"relations":{"type":"array","description":"Array of relation types that can connect annotations","items":{"$ref":"#/components/schemas/Relation"}}}},"Tool":{"type":"object","description":"Annotation tool configuration","required":["schemaId","title","tool"],"properties":{"schemaId":{"type":"string","description":"Unique identifier for this tool"},"title":{"type":"string","description":"Display name for the tool"},"tool":{"type":"string","description":"Type of annotation tool","enum":["bounding-box","polygon","polyline","point","rotated-bounding-box","segmentation","brush","medical-brush","ner","pdf","pct","angle"]},"required":{"type":"boolean","description":"Whether this annotation is required","default":false},"color":{"type":"string","description":"Hex color code for this annotation class","pattern":"^#[0-9A-Fa-f]{6}$"},"shortcutKey":{"type":"string","description":"Keyboard shortcut for quick selection"},"classifications":{"type":"array","description":"Nested classifications specific to this tool","items":{"$ref":"#/components/schemas/Classification"}},"multiple":{"type":"boolean","description":"Allow creating multiple instances of this annotation","default":false},"exportName":{"type":"string","description":"(PCT only) Name used when exporting data (for organizing exported annotations)"},"displayName":{"type":"string","description":"(PCT only) Display name shown in the annotation interface"},"abbreviatedName":{"type":"string","description":"(PCT only) Abbreviated name for compact UI views"},"markingTools":{"type":"array","description":"(PCT only) List of marking tools enabled for this PCT tool.\nAvailable marking tools: polygon, polygon2d, polyline, polyline2d, cuboid, rectangle\n","items":{"type":"string","enum":["polygon","polygon2d","polyline","polyline2d","cuboid","rectangle"]}},"truncate":{"type":"boolean","description":"(PCT only) Enable truncation for this tool","default":false},"presetCuboidDimensions":{"type":"boolean","description":"(PCT only) Enable preset cuboid dimensions","default":false},"cuboidLength":{"type":"string","description":"(PCT only) Preset cuboid length value (stored as string)"},"cuboidWidth":{"type":"string","description":"(PCT only) Preset cuboid width value (stored as string)"},"cuboidHeight":{"type":"string","description":"(PCT only) Preset cuboid height value (stored as string)"},"keypointWithVerticalLine":{"type":"boolean","description":"(PCT only) Enable keypoint with vertical line feature","default":false},"edgeLengthConstraint":{"type":"string","description":"(PCT only) Minimum edge length constraint (stored as string)"},"hasInstance":{"type":"boolean","description":"(PCT only) Enable instance tracking for this tool","default":false}}},"Classification":{"type":"object","description":"Classification question configuration","required":["schemaId","title","tool"],"properties":{"schemaId":{"type":"string","description":"Unique identifier for this classification"},"title":{"type":"string","description":"Question or label text"},"tool":{"type":"string","description":"Type of classification input (same as 'type')","enum":["radio","checkbox","single-dropdown","multi-dropdown","tree-dropdown","single-tree-dropdown","text","boolean"]},"color":{"type":"string","description":"Hex color code for this classification","pattern":"^#[0-9A-Fa-f]{6}$"},"required":{"type":"boolean","description":"Whether answering this classification is required","default":false},"shortcutKey":{"type":"string","description":"Keyboard shortcut key"},"columnField":{"type":"boolean","description":"Whether to show in column view","default":false},"frameSpecific":{"type":"boolean","description":"Whether classification is frame-specific (for videos)","default":false},"showDropdown":{"type":"boolean","description":"Whether to show as dropdown in UI","default":false},"richText":{"type":"boolean","description":"Whether to enable rich text input (for text type)","default":false},"regex":{"type":"string","nullable":true,"description":"Regular expression for text validation (for text type)"},"parentOptionId":{"type":"string","nullable":true,"description":"Parent option ID for nested classifications"},"options":{"type":"array","description":"Available options (not used for text type)","items":{"$ref":"#/components/schemas/ClassificationOption"}},"treeOptions":{"type":"array","description":"Tree-structured options (for tree-dropdown types)","items":{"type":"object"}},"classifications":{"type":"array","description":"Nested child classifications","items":{"$ref":"#/components/schemas/Classification"}},"multiple":{"type":"boolean","description":"Allow multiple selections","default":false},"parentToolType":{"type":"string","description":"(PCT only) Parent tool type this classification belongs to"},"parentToolId":{"type":"string","description":"(PCT only) Parent tool schemaId this classification is associated with"},"attributeLevel":{"type":"string","description":"(PCT only) Level at which this attribute applies","enum":["Class Level","Instance Level"]},"defaultValue":{"description":"Default value for this classification (type varies based on classification tool type)","oneOf":[{"type":"boolean"},{"type":"string"},{"type":"number"}]},"exportName":{"type":"string","description":"(PCT only) Name used when exporting data"},"displayName":{"type":"string","description":"(PCT only) Display name shown in the annotation interface"},"abbreviatedName":{"type":"string","description":"(PCT only) Abbreviated name for compact UI views"},"attributeMode":{"type":"string","description":"(PCT only) Attribute mode determining how values persist across frames.\n- Time Varying: Value can change per frame\n- Constant: Single value for entire sequence\n- Sensor Specific: Different values per sensor\n","enum":["Time Varying","Constant","Sensor Specific"]},"associatedMarkingTool":{"type":"array","description":"(PCT only) Marking tools this classification is associated with.\nThis classification will only be available when using these marking tools.\n","items":{"type":"string","enum":["polygon","polygon2d","polyline","polyline2d","cuboid","rectangle"]}}}},"ClassificationOption":{"type":"object","description":"Option for a classification question","required":["schemaId","value"],"properties":{"schemaId":{"type":"string","description":"Unique identifier for this option"},"value":{"type":"string","description":"Display text and internal value for this option"},"label":{"type":"string","description":"Alternative display text (deprecated, use 'value')"},"children":{"type":"array","description":"Nested classifications that appear when this option is selected","items":{"$ref":"#/components/schemas/Classification"}}}},"Relation":{"type":"object","description":"Relation type that can connect two annotations.\n\n**Relation Types:**\n- `one-to-one`: Direct connection between two annotations (Ango only)\n- `group`: Groups multiple annotations together (Ango only)\n- `one-to-many`: Parent-child hierarchical relationship (PCT only)\n\n**Note:** PCT projects support additional fields like `parentTool` and `childTools` for one-to-many relations.\n","required":["schemaId","title","tool"],"properties":{"schemaId":{"type":"string","description":"Unique identifier for this relation"},"title":{"type":"string","description":"Display name for the relation"},"tool":{"type":"string","description":"Type of relation tool:\n- `one-to-one`: Direct 1:1 connection between annotations (Ango only)\n- `group`: Non-directional grouping of multiple annotations (Ango only)\n- `one-to-many`: Hierarchical parent-child relationship (PCT only)\n","enum":["one-to-one","group","one-to-many"]},"color":{"type":"string","description":"Hex color code for this relation","pattern":"^#[0-9A-Fa-f]{6}$"},"required":{"type":"boolean","description":"Whether this relation must be used in annotations","default":false},"classifications":{"type":"array","description":"Nested classification questions attached to this relation.\nAllows adding metadata or attributes to the relationship itself.\n","default":[]},"multiple":{"type":"boolean","description":"Whether multiple instances of this relation can be created","default":false},"shortcutKey":{"type":"string","description":"Keyboard shortcut to quickly create this relation"},"parentTool":{"type":"string","description":"(PCT only) For one-to-many relations, specifies the schemaId of the parent tool.\nOnly applicable when `tool: \"one-to-many\"`.\n"},"childTools":{"type":"array","description":"(PCT only) For one-to-many relations, specifies the schemaIds of allowed child tools.\nOnly applicable when `tool: \"one-to-many\"`.\n","items":{"type":"string"}}}}}}}
```

## The LabelValidationUpdateRequest object

```json
{"openapi":"3.0.3","info":{"title":"Ango Hub API v2","version":"2.0.0"},"components":{"schemas":{"LabelValidationUpdateRequest":{"type":"object","description":"Request body for updating project label validation configuration.\nSupports custom validation functions (JavaScript for Ango, Python for PCT) and external API validation.\n","properties":{"validationFunction":{"type":"string","description":"Custom validation function as a string.\n- For Ango projects: JavaScript function that receives `answers` object\n- For PCT projects: Python function that receives `answers` dict\n- Must return array/list of error objects with: objectId, message, preventSubmission\n"},"customValidationEnabled":{"type":"boolean","description":"Enable/disable custom validation function execution"},"submissionPrevent":{"type":"boolean","description":"Globally prevent task submission when validation fails (optional)"},"externalValidation":{"$ref":"#/components/schemas/ExternalValidation"}}},"ExternalValidation":{"type":"object","description":"Configuration for external API-based validation","properties":{"enabled":{"type":"boolean","description":"Enable external validation API calls","default":false},"apiUrl":{"type":"string","description":"URL of external validation API endpoint","default":""},"singleFrame":{"type":"boolean","description":"For video projects - validate only a single frame","default":false},"specificFrame":{"type":"boolean","description":"For video projects - validate specific frame(s)","default":false},"frameNumbers":{"type":"string","description":"Frame number(s) to validate for video projects","default":""}}}}}}
```

## The ExternalValidation object

```json
{"openapi":"3.0.3","info":{"title":"Ango Hub API v2","version":"2.0.0"},"components":{"schemas":{"ExternalValidation":{"type":"object","description":"Configuration for external API-based validation","properties":{"enabled":{"type":"boolean","description":"Enable external validation API calls","default":false},"apiUrl":{"type":"string","description":"URL of external validation API endpoint","default":""},"singleFrame":{"type":"boolean","description":"For video projects - validate only a single frame","default":false},"specificFrame":{"type":"boolean","description":"For video projects - validate specific frame(s)","default":false},"frameNumbers":{"type":"string","description":"Frame number(s) to validate for video projects","default":""}}}}}}
```

## The CategorySchema object

```json
{"openapi":"3.0.3","info":{"title":"Ango Hub API v2","version":"2.0.0"},"components":{"schemas":{"CategorySchema":{"type":"object","description":"Label configuration schema that defines the annotation tools, classifications, and relations for a project.\nThis schema determines what annotation types are available to users and how they can label assets.\n\n**Note:** Schema structure varies between Ango and PCT projects.\n- Ango projects: Use standard annotation tools (bounding-box, polygon, etc.)\n- PCT projects: Use PCT tool type with markingTools array and nested classifications with PCT-specific fields\n","properties":{"tools":{"type":"array","description":"Array of annotation tools (bounding box, polygon, segmentation, etc.)","items":{"$ref":"#/components/schemas/Tool"}},"classifications":{"type":"array","description":"Array of classification questions (radio, checkbox, dropdown, text, etc.)","items":{"$ref":"#/components/schemas/Classification"}},"relations":{"type":"array","description":"Array of relation types that can connect annotations","items":{"$ref":"#/components/schemas/Relation"}}}},"Tool":{"type":"object","description":"Annotation tool configuration","required":["schemaId","title","tool"],"properties":{"schemaId":{"type":"string","description":"Unique identifier for this tool"},"title":{"type":"string","description":"Display name for the tool"},"tool":{"type":"string","description":"Type of annotation tool","enum":["bounding-box","polygon","polyline","point","rotated-bounding-box","segmentation","brush","medical-brush","ner","pdf","pct","angle"]},"required":{"type":"boolean","description":"Whether this annotation is required","default":false},"color":{"type":"string","description":"Hex color code for this annotation class","pattern":"^#[0-9A-Fa-f]{6}$"},"shortcutKey":{"type":"string","description":"Keyboard shortcut for quick selection"},"classifications":{"type":"array","description":"Nested classifications specific to this tool","items":{"$ref":"#/components/schemas/Classification"}},"multiple":{"type":"boolean","description":"Allow creating multiple instances of this annotation","default":false},"exportName":{"type":"string","description":"(PCT only) Name used when exporting data (for organizing exported annotations)"},"displayName":{"type":"string","description":"(PCT only) Display name shown in the annotation interface"},"abbreviatedName":{"type":"string","description":"(PCT only) Abbreviated name for compact UI views"},"markingTools":{"type":"array","description":"(PCT only) List of marking tools enabled for this PCT tool.\nAvailable marking tools: polygon, polygon2d, polyline, polyline2d, cuboid, rectangle\n","items":{"type":"string","enum":["polygon","polygon2d","polyline","polyline2d","cuboid","rectangle"]}},"truncate":{"type":"boolean","description":"(PCT only) Enable truncation for this tool","default":false},"presetCuboidDimensions":{"type":"boolean","description":"(PCT only) Enable preset cuboid dimensions","default":false},"cuboidLength":{"type":"string","description":"(PCT only) Preset cuboid length value (stored as string)"},"cuboidWidth":{"type":"string","description":"(PCT only) Preset cuboid width value (stored as string)"},"cuboidHeight":{"type":"string","description":"(PCT only) Preset cuboid height value (stored as string)"},"keypointWithVerticalLine":{"type":"boolean","description":"(PCT only) Enable keypoint with vertical line feature","default":false},"edgeLengthConstraint":{"type":"string","description":"(PCT only) Minimum edge length constraint (stored as string)"},"hasInstance":{"type":"boolean","description":"(PCT only) Enable instance tracking for this tool","default":false}}},"Classification":{"type":"object","description":"Classification question configuration","required":["schemaId","title","tool"],"properties":{"schemaId":{"type":"string","description":"Unique identifier for this classification"},"title":{"type":"string","description":"Question or label text"},"tool":{"type":"string","description":"Type of classification input (same as 'type')","enum":["radio","checkbox","single-dropdown","multi-dropdown","tree-dropdown","single-tree-dropdown","text","boolean"]},"color":{"type":"string","description":"Hex color code for this classification","pattern":"^#[0-9A-Fa-f]{6}$"},"required":{"type":"boolean","description":"Whether answering this classification is required","default":false},"shortcutKey":{"type":"string","description":"Keyboard shortcut key"},"columnField":{"type":"boolean","description":"Whether to show in column view","default":false},"frameSpecific":{"type":"boolean","description":"Whether classification is frame-specific (for videos)","default":false},"showDropdown":{"type":"boolean","description":"Whether to show as dropdown in UI","default":false},"richText":{"type":"boolean","description":"Whether to enable rich text input (for text type)","default":false},"regex":{"type":"string","nullable":true,"description":"Regular expression for text validation (for text type)"},"parentOptionId":{"type":"string","nullable":true,"description":"Parent option ID for nested classifications"},"options":{"type":"array","description":"Available options (not used for text type)","items":{"$ref":"#/components/schemas/ClassificationOption"}},"treeOptions":{"type":"array","description":"Tree-structured options (for tree-dropdown types)","items":{"type":"object"}},"classifications":{"type":"array","description":"Nested child classifications","items":{"$ref":"#/components/schemas/Classification"}},"multiple":{"type":"boolean","description":"Allow multiple selections","default":false},"parentToolType":{"type":"string","description":"(PCT only) Parent tool type this classification belongs to"},"parentToolId":{"type":"string","description":"(PCT only) Parent tool schemaId this classification is associated with"},"attributeLevel":{"type":"string","description":"(PCT only) Level at which this attribute applies","enum":["Class Level","Instance Level"]},"defaultValue":{"description":"Default value for this classification (type varies based on classification tool type)","oneOf":[{"type":"boolean"},{"type":"string"},{"type":"number"}]},"exportName":{"type":"string","description":"(PCT only) Name used when exporting data"},"displayName":{"type":"string","description":"(PCT only) Display name shown in the annotation interface"},"abbreviatedName":{"type":"string","description":"(PCT only) Abbreviated name for compact UI views"},"attributeMode":{"type":"string","description":"(PCT only) Attribute mode determining how values persist across frames.\n- Time Varying: Value can change per frame\n- Constant: Single value for entire sequence\n- Sensor Specific: Different values per sensor\n","enum":["Time Varying","Constant","Sensor Specific"]},"associatedMarkingTool":{"type":"array","description":"(PCT only) Marking tools this classification is associated with.\nThis classification will only be available when using these marking tools.\n","items":{"type":"string","enum":["polygon","polygon2d","polyline","polyline2d","cuboid","rectangle"]}}}},"ClassificationOption":{"type":"object","description":"Option for a classification question","required":["schemaId","value"],"properties":{"schemaId":{"type":"string","description":"Unique identifier for this option"},"value":{"type":"string","description":"Display text and internal value for this option"},"label":{"type":"string","description":"Alternative display text (deprecated, use 'value')"},"children":{"type":"array","description":"Nested classifications that appear when this option is selected","items":{"$ref":"#/components/schemas/Classification"}}}},"Relation":{"type":"object","description":"Relation type that can connect two annotations.\n\n**Relation Types:**\n- `one-to-one`: Direct connection between two annotations (Ango only)\n- `group`: Groups multiple annotations together (Ango only)\n- `one-to-many`: Parent-child hierarchical relationship (PCT only)\n\n**Note:** PCT projects support additional fields like `parentTool` and `childTools` for one-to-many relations.\n","required":["schemaId","title","tool"],"properties":{"schemaId":{"type":"string","description":"Unique identifier for this relation"},"title":{"type":"string","description":"Display name for the relation"},"tool":{"type":"string","description":"Type of relation tool:\n- `one-to-one`: Direct 1:1 connection between annotations (Ango only)\n- `group`: Non-directional grouping of multiple annotations (Ango only)\n- `one-to-many`: Hierarchical parent-child relationship (PCT only)\n","enum":["one-to-one","group","one-to-many"]},"color":{"type":"string","description":"Hex color code for this relation","pattern":"^#[0-9A-Fa-f]{6}$"},"required":{"type":"boolean","description":"Whether this relation must be used in annotations","default":false},"classifications":{"type":"array","description":"Nested classification questions attached to this relation.\nAllows adding metadata or attributes to the relationship itself.\n","default":[]},"multiple":{"type":"boolean","description":"Whether multiple instances of this relation can be created","default":false},"shortcutKey":{"type":"string","description":"Keyboard shortcut to quickly create this relation"},"parentTool":{"type":"string","description":"(PCT only) For one-to-many relations, specifies the schemaId of the parent tool.\nOnly applicable when `tool: \"one-to-many\"`.\n"},"childTools":{"type":"array","description":"(PCT only) For one-to-many relations, specifies the schemaIds of allowed child tools.\nOnly applicable when `tool: \"one-to-many\"`.\n","items":{"type":"string"}}}}}}}
```

## The CategorySchemaPCTExample object

```json
{"openapi":"3.0.3","info":{"title":"Ango Hub API v2","version":"2.0.0"},"components":{"schemas":{"CategorySchemaPCTExample":{"type":"object","description":"Example category schema for a PCT (Point Cloud Tool) project.\nShows complete PCT tool configuration with all available fields including marking tools,\ncuboid presets, and nested classifications with PCT-specific attributes.\n"}}}}
```

## The Tool object

```json
{"openapi":"3.0.3","info":{"title":"Ango Hub API v2","version":"2.0.0"},"components":{"schemas":{"Tool":{"type":"object","description":"Annotation tool configuration","required":["schemaId","title","tool"],"properties":{"schemaId":{"type":"string","description":"Unique identifier for this tool"},"title":{"type":"string","description":"Display name for the tool"},"tool":{"type":"string","description":"Type of annotation tool","enum":["bounding-box","polygon","polyline","point","rotated-bounding-box","segmentation","brush","medical-brush","ner","pdf","pct","angle"]},"required":{"type":"boolean","description":"Whether this annotation is required","default":false},"color":{"type":"string","description":"Hex color code for this annotation class","pattern":"^#[0-9A-Fa-f]{6}$"},"shortcutKey":{"type":"string","description":"Keyboard shortcut for quick selection"},"classifications":{"type":"array","description":"Nested classifications specific to this tool","items":{"$ref":"#/components/schemas/Classification"}},"multiple":{"type":"boolean","description":"Allow creating multiple instances of this annotation","default":false},"exportName":{"type":"string","description":"(PCT only) Name used when exporting data (for organizing exported annotations)"},"displayName":{"type":"string","description":"(PCT only) Display name shown in the annotation interface"},"abbreviatedName":{"type":"string","description":"(PCT only) Abbreviated name for compact UI views"},"markingTools":{"type":"array","description":"(PCT only) List of marking tools enabled for this PCT tool.\nAvailable marking tools: polygon, polygon2d, polyline, polyline2d, cuboid, rectangle\n","items":{"type":"string","enum":["polygon","polygon2d","polyline","polyline2d","cuboid","rectangle"]}},"truncate":{"type":"boolean","description":"(PCT only) Enable truncation for this tool","default":false},"presetCuboidDimensions":{"type":"boolean","description":"(PCT only) Enable preset cuboid dimensions","default":false},"cuboidLength":{"type":"string","description":"(PCT only) Preset cuboid length value (stored as string)"},"cuboidWidth":{"type":"string","description":"(PCT only) Preset cuboid width value (stored as string)"},"cuboidHeight":{"type":"string","description":"(PCT only) Preset cuboid height value (stored as string)"},"keypointWithVerticalLine":{"type":"boolean","description":"(PCT only) Enable keypoint with vertical line feature","default":false},"edgeLengthConstraint":{"type":"string","description":"(PCT only) Minimum edge length constraint (stored as string)"},"hasInstance":{"type":"boolean","description":"(PCT only) Enable instance tracking for this tool","default":false}}},"Classification":{"type":"object","description":"Classification question configuration","required":["schemaId","title","tool"],"properties":{"schemaId":{"type":"string","description":"Unique identifier for this classification"},"title":{"type":"string","description":"Question or label text"},"tool":{"type":"string","description":"Type of classification input (same as 'type')","enum":["radio","checkbox","single-dropdown","multi-dropdown","tree-dropdown","single-tree-dropdown","text","boolean"]},"color":{"type":"string","description":"Hex color code for this classification","pattern":"^#[0-9A-Fa-f]{6}$"},"required":{"type":"boolean","description":"Whether answering this classification is required","default":false},"shortcutKey":{"type":"string","description":"Keyboard shortcut key"},"columnField":{"type":"boolean","description":"Whether to show in column view","default":false},"frameSpecific":{"type":"boolean","description":"Whether classification is frame-specific (for videos)","default":false},"showDropdown":{"type":"boolean","description":"Whether to show as dropdown in UI","default":false},"richText":{"type":"boolean","description":"Whether to enable rich text input (for text type)","default":false},"regex":{"type":"string","nullable":true,"description":"Regular expression for text validation (for text type)"},"parentOptionId":{"type":"string","nullable":true,"description":"Parent option ID for nested classifications"},"options":{"type":"array","description":"Available options (not used for text type)","items":{"$ref":"#/components/schemas/ClassificationOption"}},"treeOptions":{"type":"array","description":"Tree-structured options (for tree-dropdown types)","items":{"type":"object"}},"classifications":{"type":"array","description":"Nested child classifications","items":{"$ref":"#/components/schemas/Classification"}},"multiple":{"type":"boolean","description":"Allow multiple selections","default":false},"parentToolType":{"type":"string","description":"(PCT only) Parent tool type this classification belongs to"},"parentToolId":{"type":"string","description":"(PCT only) Parent tool schemaId this classification is associated with"},"attributeLevel":{"type":"string","description":"(PCT only) Level at which this attribute applies","enum":["Class Level","Instance Level"]},"defaultValue":{"description":"Default value for this classification (type varies based on classification tool type)","oneOf":[{"type":"boolean"},{"type":"string"},{"type":"number"}]},"exportName":{"type":"string","description":"(PCT only) Name used when exporting data"},"displayName":{"type":"string","description":"(PCT only) Display name shown in the annotation interface"},"abbreviatedName":{"type":"string","description":"(PCT only) Abbreviated name for compact UI views"},"attributeMode":{"type":"string","description":"(PCT only) Attribute mode determining how values persist across frames.\n- Time Varying: Value can change per frame\n- Constant: Single value for entire sequence\n- Sensor Specific: Different values per sensor\n","enum":["Time Varying","Constant","Sensor Specific"]},"associatedMarkingTool":{"type":"array","description":"(PCT only) Marking tools this classification is associated with.\nThis classification will only be available when using these marking tools.\n","items":{"type":"string","enum":["polygon","polygon2d","polyline","polyline2d","cuboid","rectangle"]}}}},"ClassificationOption":{"type":"object","description":"Option for a classification question","required":["schemaId","value"],"properties":{"schemaId":{"type":"string","description":"Unique identifier for this option"},"value":{"type":"string","description":"Display text and internal value for this option"},"label":{"type":"string","description":"Alternative display text (deprecated, use 'value')"},"children":{"type":"array","description":"Nested classifications that appear when this option is selected","items":{"$ref":"#/components/schemas/Classification"}}}}}}}
```

## The Classification object

```json
{"openapi":"3.0.3","info":{"title":"Ango Hub API v2","version":"2.0.0"},"components":{"schemas":{"Classification":{"type":"object","description":"Classification question configuration","required":["schemaId","title","tool"],"properties":{"schemaId":{"type":"string","description":"Unique identifier for this classification"},"title":{"type":"string","description":"Question or label text"},"tool":{"type":"string","description":"Type of classification input (same as 'type')","enum":["radio","checkbox","single-dropdown","multi-dropdown","tree-dropdown","single-tree-dropdown","text","boolean"]},"color":{"type":"string","description":"Hex color code for this classification","pattern":"^#[0-9A-Fa-f]{6}$"},"required":{"type":"boolean","description":"Whether answering this classification is required","default":false},"shortcutKey":{"type":"string","description":"Keyboard shortcut key"},"columnField":{"type":"boolean","description":"Whether to show in column view","default":false},"frameSpecific":{"type":"boolean","description":"Whether classification is frame-specific (for videos)","default":false},"showDropdown":{"type":"boolean","description":"Whether to show as dropdown in UI","default":false},"richText":{"type":"boolean","description":"Whether to enable rich text input (for text type)","default":false},"regex":{"type":"string","nullable":true,"description":"Regular expression for text validation (for text type)"},"parentOptionId":{"type":"string","nullable":true,"description":"Parent option ID for nested classifications"},"options":{"type":"array","description":"Available options (not used for text type)","items":{"$ref":"#/components/schemas/ClassificationOption"}},"treeOptions":{"type":"array","description":"Tree-structured options (for tree-dropdown types)","items":{"type":"object"}},"classifications":{"type":"array","description":"Nested child classifications","items":{"$ref":"#/components/schemas/Classification"}},"multiple":{"type":"boolean","description":"Allow multiple selections","default":false},"parentToolType":{"type":"string","description":"(PCT only) Parent tool type this classification belongs to"},"parentToolId":{"type":"string","description":"(PCT only) Parent tool schemaId this classification is associated with"},"attributeLevel":{"type":"string","description":"(PCT only) Level at which this attribute applies","enum":["Class Level","Instance Level"]},"defaultValue":{"description":"Default value for this classification (type varies based on classification tool type)","oneOf":[{"type":"boolean"},{"type":"string"},{"type":"number"}]},"exportName":{"type":"string","description":"(PCT only) Name used when exporting data"},"displayName":{"type":"string","description":"(PCT only) Display name shown in the annotation interface"},"abbreviatedName":{"type":"string","description":"(PCT only) Abbreviated name for compact UI views"},"attributeMode":{"type":"string","description":"(PCT only) Attribute mode determining how values persist across frames.\n- Time Varying: Value can change per frame\n- Constant: Single value for entire sequence\n- Sensor Specific: Different values per sensor\n","enum":["Time Varying","Constant","Sensor Specific"]},"associatedMarkingTool":{"type":"array","description":"(PCT only) Marking tools this classification is associated with.\nThis classification will only be available when using these marking tools.\n","items":{"type":"string","enum":["polygon","polygon2d","polyline","polyline2d","cuboid","rectangle"]}}}},"ClassificationOption":{"type":"object","description":"Option for a classification question","required":["schemaId","value"],"properties":{"schemaId":{"type":"string","description":"Unique identifier for this option"},"value":{"type":"string","description":"Display text and internal value for this option"},"label":{"type":"string","description":"Alternative display text (deprecated, use 'value')"},"children":{"type":"array","description":"Nested classifications that appear when this option is selected","items":{"$ref":"#/components/schemas/Classification"}}}}}}}
```

## The ClassificationOption object

```json
{"openapi":"3.0.3","info":{"title":"Ango Hub API v2","version":"2.0.0"},"components":{"schemas":{"ClassificationOption":{"type":"object","description":"Option for a classification question","required":["schemaId","value"],"properties":{"schemaId":{"type":"string","description":"Unique identifier for this option"},"value":{"type":"string","description":"Display text and internal value for this option"},"label":{"type":"string","description":"Alternative display text (deprecated, use 'value')"},"children":{"type":"array","description":"Nested classifications that appear when this option is selected","items":{"$ref":"#/components/schemas/Classification"}}}},"Classification":{"type":"object","description":"Classification question configuration","required":["schemaId","title","tool"],"properties":{"schemaId":{"type":"string","description":"Unique identifier for this classification"},"title":{"type":"string","description":"Question or label text"},"tool":{"type":"string","description":"Type of classification input (same as 'type')","enum":["radio","checkbox","single-dropdown","multi-dropdown","tree-dropdown","single-tree-dropdown","text","boolean"]},"color":{"type":"string","description":"Hex color code for this classification","pattern":"^#[0-9A-Fa-f]{6}$"},"required":{"type":"boolean","description":"Whether answering this classification is required","default":false},"shortcutKey":{"type":"string","description":"Keyboard shortcut key"},"columnField":{"type":"boolean","description":"Whether to show in column view","default":false},"frameSpecific":{"type":"boolean","description":"Whether classification is frame-specific (for videos)","default":false},"showDropdown":{"type":"boolean","description":"Whether to show as dropdown in UI","default":false},"richText":{"type":"boolean","description":"Whether to enable rich text input (for text type)","default":false},"regex":{"type":"string","nullable":true,"description":"Regular expression for text validation (for text type)"},"parentOptionId":{"type":"string","nullable":true,"description":"Parent option ID for nested classifications"},"options":{"type":"array","description":"Available options (not used for text type)","items":{"$ref":"#/components/schemas/ClassificationOption"}},"treeOptions":{"type":"array","description":"Tree-structured options (for tree-dropdown types)","items":{"type":"object"}},"classifications":{"type":"array","description":"Nested child classifications","items":{"$ref":"#/components/schemas/Classification"}},"multiple":{"type":"boolean","description":"Allow multiple selections","default":false},"parentToolType":{"type":"string","description":"(PCT only) Parent tool type this classification belongs to"},"parentToolId":{"type":"string","description":"(PCT only) Parent tool schemaId this classification is associated with"},"attributeLevel":{"type":"string","description":"(PCT only) Level at which this attribute applies","enum":["Class Level","Instance Level"]},"defaultValue":{"description":"Default value for this classification (type varies based on classification tool type)","oneOf":[{"type":"boolean"},{"type":"string"},{"type":"number"}]},"exportName":{"type":"string","description":"(PCT only) Name used when exporting data"},"displayName":{"type":"string","description":"(PCT only) Display name shown in the annotation interface"},"abbreviatedName":{"type":"string","description":"(PCT only) Abbreviated name for compact UI views"},"attributeMode":{"type":"string","description":"(PCT only) Attribute mode determining how values persist across frames.\n- Time Varying: Value can change per frame\n- Constant: Single value for entire sequence\n- Sensor Specific: Different values per sensor\n","enum":["Time Varying","Constant","Sensor Specific"]},"associatedMarkingTool":{"type":"array","description":"(PCT only) Marking tools this classification is associated with.\nThis classification will only be available when using these marking tools.\n","items":{"type":"string","enum":["polygon","polygon2d","polyline","polyline2d","cuboid","rectangle"]}}}}}}}
```

## The Relation object

```json
{"openapi":"3.0.3","info":{"title":"Ango Hub API v2","version":"2.0.0"},"components":{"schemas":{"Relation":{"type":"object","description":"Relation type that can connect two annotations.\n\n**Relation Types:**\n- `one-to-one`: Direct connection between two annotations (Ango only)\n- `group`: Groups multiple annotations together (Ango only)\n- `one-to-many`: Parent-child hierarchical relationship (PCT only)\n\n**Note:** PCT projects support additional fields like `parentTool` and `childTools` for one-to-many relations.\n","required":["schemaId","title","tool"],"properties":{"schemaId":{"type":"string","description":"Unique identifier for this relation"},"title":{"type":"string","description":"Display name for the relation"},"tool":{"type":"string","description":"Type of relation tool:\n- `one-to-one`: Direct 1:1 connection between annotations (Ango only)\n- `group`: Non-directional grouping of multiple annotations (Ango only)\n- `one-to-many`: Hierarchical parent-child relationship (PCT only)\n","enum":["one-to-one","group","one-to-many"]},"color":{"type":"string","description":"Hex color code for this relation","pattern":"^#[0-9A-Fa-f]{6}$"},"required":{"type":"boolean","description":"Whether this relation must be used in annotations","default":false},"classifications":{"type":"array","description":"Nested classification questions attached to this relation.\nAllows adding metadata or attributes to the relationship itself.\n","default":[]},"multiple":{"type":"boolean","description":"Whether multiple instances of this relation can be created","default":false},"shortcutKey":{"type":"string","description":"Keyboard shortcut to quickly create this relation"},"parentTool":{"type":"string","description":"(PCT only) For one-to-many relations, specifies the schemaId of the parent tool.\nOnly applicable when `tool: \"one-to-many\"`.\n"},"childTools":{"type":"array","description":"(PCT only) For one-to-many relations, specifies the schemaIds of allowed child tools.\nOnly applicable when `tool: \"one-to-many\"`.\n","items":{"type":"string"}}}}}}}
```

## The PctConfig object

````json
{"openapi":"3.0.3","info":{"title":"Ango Hub API v2","version":"2.0.0"},"components":{"schemas":{"PctConfig":{"type":"object","description":"Configuration specific to Point Cloud Tool (PCT) projects.\nThese settings control how 3D point cloud annotation behaves.\n\nExample:\n```json\n{\n  \"allowOverlapping\": false,\n  \"trackingMultipleSensors\": true,\n  \"segmentationMode\": false\n}\n```\n","properties":{"allowOverlapping":{"type":"boolean","description":"Allow overlapping 3D bounding boxes","default":false},"trackingMultipleSensors":{"type":"boolean","description":"Enable tracking across multiple LiDAR sensors","default":false},"segmentationMode":{"type":"boolean","description":"Enable segmentation mode for point clouds","default":false}}}}}}
````

## The Stage object

```json
{"openapi":"3.0.3","info":{"title":"Ango Hub API v2","version":"2.0.0"},"components":{"schemas":{"Stage":{"type":"object","description":"Workflow stage configuration. Different stage types have different properties.\n- Label: Manual annotation stage\n- Review: QA/review stage\n- Logic: Conditional routing stage\n- Plugin: ML model integration stage\n- Webhook: External API callback stage\n- Consensus: Multi-annotator agreement stage\n- Hold: Pause stage\n- Start: Entry point (auto-forwards)\n- Complete: Terminal success stage\n- Archive: Terminal archive stage\n","required":["id","type"],"properties":{"id":{"type":"string","description":"Unique identifier for this stage"},"name":{"type":"string","description":"Display name for this stage"},"type":{"type":"string","description":"Type of stage","enum":["Label","Review","Logic","Plugin","Webhook","Consensus","Hold","Start","Complete","Archive"]},"next":{"type":"array","items":{"type":"string"},"description":"Array of next stage IDs (for Logic stages, order matters)"},"position":{"type":"object","description":"Position in workflow diagram UI","properties":{"x":{"type":"number"},"y":{"type":"number"}}},"assignedTo":{"type":"array","description":"Users assigned to work on this stage (Label/Review stages)","items":{"type":"string"}},"rememberAssignee":{"type":"boolean","description":"Auto-assign to previous stage's user (sticky assignment)","default":false},"logic":{"$ref":"#/components/schemas/LogicConfig","description":"Logic routing configuration (Logic stages only)"},"pluginId":{"type":"string","description":"Plugin ID to execute (Plugin stages only)"},"pluginConfig":{"type":"object","description":"Plugin-specific configuration (Plugin stages only)"},"webhook":{"$ref":"#/components/schemas/WebhookConfig","description":"Webhook configuration (Webhook stages only)"},"consensusConfig":{"$ref":"#/components/schemas/ConsensusConfig","description":"Consensus configuration (Consensus stages only)"},"readOnly":{"type":"boolean","description":"Whether this stage is read-only (users can view but not edit)","default":false},"preventRequeue":{"type":"boolean","description":"Prevent tasks from being requeued to this stage","default":false},"autoForward":{"type":"boolean","description":"Automatically advance to next stage without user action","default":true},"consensusId":{"type":"string","description":"Links stage to a consensus stage (used in consensus workflows)"},"consensusDynamic":{"type":"boolean","description":"Dynamic vs static consensus stage","default":false}}},"LogicConfig":{"type":"object","description":"Logic stage routing configuration. Routes tasks based on conditions.\nConditions are evaluated in order, first match wins.\n","properties":{"type":{"type":"string","description":"Type of logic routing","enum":["AnnotationType","Annotator","RandomSample","Duration","Batch","IssueErrorCode"]},"value":{"type":"object","description":"Default value (usually empty)"},"conditions":{"type":"array","description":"Array of routing conditions","items":{"$ref":"#/components/schemas/LogicCondition"}}}},"LogicCondition":{"type":"object","description":"Individual routing condition for Logic stages","properties":{"type":{"type":"string","description":"Type of condition","enum":["AnnotationType","Annotator","RandomSample","Duration","Batch","IssueErrorCode"]},"value":{"type":"object","description":"Condition-specific value","properties":{"tools":{"type":"array","description":"Tool filters (AnnotationType logic)","items":{"type":"object","properties":{"filter":{"type":"array","items":{"type":"string"},"description":"Annotation filters:\n- exists___<schemaId>: Annotation must exist\n- not-exist___<schemaId>: Annotation must NOT exist\n"}}}},"emails":{"type":"array","description":"User emails (Annotator logic)","items":{"type":"string"}},"sampleRate":{"type":"number","description":"Sample rate 0-1 (RandomSample logic)","minimum":0,"maximum":1},"duration":{"type":"number","description":"Duration in milliseconds (Duration logic)"},"operator":{"type":"string","description":"Comparison operator for Duration","enum":["lt","gt","eq"]},"batches":{"type":"array","description":"Batch names (Batch logic)","items":{"type":"string"}}}},"index":{"type":"number","description":"Index of next stage in parent's next array"}}},"WebhookConfig":{"type":"object","description":"Webhook configuration for external API integration","required":["url"],"properties":{"url":{"type":"string","format":"uri","description":"Webhook endpoint URL"},"method":{"type":"string","description":"HTTP method","enum":["POST","PUT"],"default":"POST"},"authType":{"type":"string","description":"Authentication type","enum":["no_auth","secret","bearer_token"],"default":"no_auth"},"secret":{"type":"string","description":"Secret for HMAC signature (authType=secret)"},"token":{"type":"string","description":"Bearer token (authType=bearer_token)"},"timeout":{"type":"number","description":"Timeout in milliseconds","default":30000},"retryCount":{"type":"number","description":"Number of retry attempts","default":3}}},"ConsensusConfig":{"type":"object","description":"Consensus configuration for multi-annotator agreement","properties":{"version":{"type":"number","description":"Consensus algorithm version (1 or 2, v2 recommended)","enum":[1,2],"default":2},"threshold":{"type":"number","description":"Minimum agreement score (0-1) required to pass","minimum":0,"maximum":1},"adjudicationMethod":{"type":"string","description":"Method for resolving disagreements","enum":["majority","union","intersection","first"],"default":"majority"},"dynamicConsensus":{"type":"boolean","description":"Add more copies if threshold not met","default":false},"minCopies":{"type":"number","description":"Minimum number of consensus copies","minimum":2,"default":2},"maxCopies":{"type":"number","description":"Maximum number of consensus copies (dynamic consensus)","default":5}}}}}}
```

## The LogicConfig object

```json
{"openapi":"3.0.3","info":{"title":"Ango Hub API v2","version":"2.0.0"},"components":{"schemas":{"LogicConfig":{"type":"object","description":"Logic stage routing configuration. Routes tasks based on conditions.\nConditions are evaluated in order, first match wins.\n","properties":{"type":{"type":"string","description":"Type of logic routing","enum":["AnnotationType","Annotator","RandomSample","Duration","Batch","IssueErrorCode"]},"value":{"type":"object","description":"Default value (usually empty)"},"conditions":{"type":"array","description":"Array of routing conditions","items":{"$ref":"#/components/schemas/LogicCondition"}}}},"LogicCondition":{"type":"object","description":"Individual routing condition for Logic stages","properties":{"type":{"type":"string","description":"Type of condition","enum":["AnnotationType","Annotator","RandomSample","Duration","Batch","IssueErrorCode"]},"value":{"type":"object","description":"Condition-specific value","properties":{"tools":{"type":"array","description":"Tool filters (AnnotationType logic)","items":{"type":"object","properties":{"filter":{"type":"array","items":{"type":"string"},"description":"Annotation filters:\n- exists___<schemaId>: Annotation must exist\n- not-exist___<schemaId>: Annotation must NOT exist\n"}}}},"emails":{"type":"array","description":"User emails (Annotator logic)","items":{"type":"string"}},"sampleRate":{"type":"number","description":"Sample rate 0-1 (RandomSample logic)","minimum":0,"maximum":1},"duration":{"type":"number","description":"Duration in milliseconds (Duration logic)"},"operator":{"type":"string","description":"Comparison operator for Duration","enum":["lt","gt","eq"]},"batches":{"type":"array","description":"Batch names (Batch logic)","items":{"type":"string"}}}},"index":{"type":"number","description":"Index of next stage in parent's next array"}}}}}}
```

## The LogicCondition object

```json
{"openapi":"3.0.3","info":{"title":"Ango Hub API v2","version":"2.0.0"},"components":{"schemas":{"LogicCondition":{"type":"object","description":"Individual routing condition for Logic stages","properties":{"type":{"type":"string","description":"Type of condition","enum":["AnnotationType","Annotator","RandomSample","Duration","Batch","IssueErrorCode"]},"value":{"type":"object","description":"Condition-specific value","properties":{"tools":{"type":"array","description":"Tool filters (AnnotationType logic)","items":{"type":"object","properties":{"filter":{"type":"array","items":{"type":"string"},"description":"Annotation filters:\n- exists___<schemaId>: Annotation must exist\n- not-exist___<schemaId>: Annotation must NOT exist\n"}}}},"emails":{"type":"array","description":"User emails (Annotator logic)","items":{"type":"string"}},"sampleRate":{"type":"number","description":"Sample rate 0-1 (RandomSample logic)","minimum":0,"maximum":1},"duration":{"type":"number","description":"Duration in milliseconds (Duration logic)"},"operator":{"type":"string","description":"Comparison operator for Duration","enum":["lt","gt","eq"]},"batches":{"type":"array","description":"Batch names (Batch logic)","items":{"type":"string"}}}},"index":{"type":"number","description":"Index of next stage in parent's next array"}}}}}}
```

## The WebhookConfig object

```json
{"openapi":"3.0.3","info":{"title":"Ango Hub API v2","version":"2.0.0"},"components":{"schemas":{"WebhookConfig":{"type":"object","description":"Webhook configuration for external API integration","required":["url"],"properties":{"url":{"type":"string","format":"uri","description":"Webhook endpoint URL"},"method":{"type":"string","description":"HTTP method","enum":["POST","PUT"],"default":"POST"},"authType":{"type":"string","description":"Authentication type","enum":["no_auth","secret","bearer_token"],"default":"no_auth"},"secret":{"type":"string","description":"Secret for HMAC signature (authType=secret)"},"token":{"type":"string","description":"Bearer token (authType=bearer_token)"},"timeout":{"type":"number","description":"Timeout in milliseconds","default":30000},"retryCount":{"type":"number","description":"Number of retry attempts","default":3}}}}}}
```

## The ConsensusConfig object

```json
{"openapi":"3.0.3","info":{"title":"Ango Hub API v2","version":"2.0.0"},"components":{"schemas":{"ConsensusConfig":{"type":"object","description":"Consensus configuration for multi-annotator agreement","properties":{"version":{"type":"number","description":"Consensus algorithm version (1 or 2, v2 recommended)","enum":[1,2],"default":2},"threshold":{"type":"number","description":"Minimum agreement score (0-1) required to pass","minimum":0,"maximum":1},"adjudicationMethod":{"type":"string","description":"Method for resolving disagreements","enum":["majority","union","intersection","first"],"default":"majority"},"dynamicConsensus":{"type":"boolean","description":"Add more copies if threshold not met","default":false},"minCopies":{"type":"number","description":"Minimum number of consensus copies","minimum":2,"default":2},"maxCopies":{"type":"number","description":"Maximum number of consensus copies (dynamic consensus)","default":5}}}}}}
```

## The Assignee object

```json
{"openapi":"3.0.3","info":{"title":"Ango Hub API v2","version":"2.0.0"},"components":{"schemas":{"Assignee":{"type":"object","properties":{"assignee":{"type":"string","description":"User email"},"role":{"type":"string","enum":["Manager","Labeler","Reviewer","Lead"]}}}}}}
```

## The Batch object

```json
{"openapi":"3.0.3","info":{"title":"Ango Hub API v2","version":"2.0.0"},"components":{"schemas":{"Batch":{"type":"object","required":["name"],"properties":{"_id":{"type":"string","description":"Batch ID (auto-generated if not provided)"},"name":{"type":"string","description":"Batch name"}}}}}}
```

## The AssigneeUpdateRequest object

```json
{"openapi":"3.0.3","info":{"title":"Ango Hub API v2","version":"2.0.0"},"components":{"schemas":{"AssigneeUpdateRequest":{"type":"object","required":["role","assignees"],"properties":{"role":{"type":"string","enum":["Manager","Labeler","Reviewer","Lead"]},"assignees":{"type":"array","items":{"type":"string"},"description":"Array of user emails"},"roleAssignments":{"type":"object","additionalProperties":{"type":"string","enum":["Manager","Labeler","Reviewer","Lead"]},"description":"Optional map of user email to role override. Example - {\"user1@example.com\":\"Reviewer\"}"}}}}}}
```

## The AssetBuilderTemplateRequest object

```json
{"openapi":"3.0.3","info":{"title":"Ango Hub API v2","version":"2.0.0"},"components":{"schemas":{"AssetBuilderTemplateRequest":{"type":"object","required":["name","config"],"properties":{"name":{"type":"string"},"config":{"type":"object"}}}}}}
```

## The AssetBuilderTemplateResponse object

```json
{"openapi":"3.0.3","info":{"title":"Ango Hub API v2","version":"2.0.0"},"components":{"schemas":{"AssetBuilderTemplateResponse":{"type":"object","properties":{"status":{"type":"string"},"data":{"type":"object","properties":{"template":{"type":"object","properties":{"_id":{"type":"string"},"name":{"type":"string"},"config":{"type":"object"}}}}}}}}}}
```

## The PerformanceRequest object

```json
{"openapi":"3.0.3","info":{"title":"Ango Hub API v2","version":"2.0.0"},"components":{"schemas":{"PerformanceRequest":{"type":"object","properties":{"startDate":{"type":"string","format":"date-time"},"endDate":{"type":"string","format":"date-time"},"users":{"type":"array","items":{"type":"string"}}}}}}}
```

## The PerformanceResponse object

```json
{"openapi":"3.0.3","info":{"title":"Ango Hub API v2","version":"2.0.0"},"components":{"schemas":{"PerformanceResponse":{"type":"object","properties":{"status":{"type":"string"},"data":{"type":"object","properties":{"performance":{"type":"object"}}}}}}}}
```

## The BatchUpdateRequest object

```json
{"openapi":"3.0.3","info":{"title":"Ango Hub API v2","version":"2.0.0"},"components":{"schemas":{"BatchUpdateRequest":{"type":"object","required":["batches"],"properties":{"batches":{"type":"array","items":{"$ref":"#/components/schemas/Batch"}}}},"Batch":{"type":"object","required":["name"],"properties":{"_id":{"type":"string","description":"Batch ID (auto-generated if not provided)"},"name":{"type":"string","description":"Batch name"}}}}}}
```

## The LabelTask object

```json
{"openapi":"3.0.3","info":{"title":"Ango Hub API v2","version":"2.0.0"},"components":{"schemas":{"LabelTask":{"type":"object","properties":{"_id":{"type":"string"},"project":{"type":"string"},"asset":{"type":"string"},"stage":{"type":"string"},"status":{"type":"string"},"assignee":{"type":"string"},"externalId":{"type":"string"},"batches":{"type":"array","items":{"type":"string"}},"priority":{"type":"number"},"answer":{"type":"object"},"createdAt":{"type":"string","format":"date-time"},"completedAt":{"type":"string","format":"date-time"},"duration":{"type":"number","description":"Duration in seconds"}}}}}}
```

## The TaskListResponse object

```json
{"openapi":"3.0.3","info":{"title":"Ango Hub API v2","version":"2.0.0"},"components":{"schemas":{"TaskListResponse":{"type":"object","properties":{"status":{"type":"string"},"data":{"type":"object","properties":{"tasks":{"type":"array","items":{"$ref":"#/components/schemas/LabelTask"}},"total":{"type":"integer"}}}}},"LabelTask":{"type":"object","properties":{"_id":{"type":"string"},"project":{"type":"string"},"asset":{"type":"string"},"stage":{"type":"string"},"status":{"type":"string"},"assignee":{"type":"string"},"externalId":{"type":"string"},"batches":{"type":"array","items":{"type":"string"}},"priority":{"type":"number"},"answer":{"type":"object"},"createdAt":{"type":"string","format":"date-time"},"completedAt":{"type":"string","format":"date-time"},"duration":{"type":"number","description":"Duration in seconds"}}}}}}
```

## The TaskResponse object

```json
{"openapi":"3.0.3","info":{"title":"Ango Hub API v2","version":"2.0.0"},"components":{"schemas":{"TaskResponse":{"type":"object","properties":{"status":{"type":"string"},"data":{"type":"object","properties":{"task":{"$ref":"#/components/schemas/LabelTask"}}}}},"LabelTask":{"type":"object","properties":{"_id":{"type":"string"},"project":{"type":"string"},"asset":{"type":"string"},"stage":{"type":"string"},"status":{"type":"string"},"assignee":{"type":"string"},"externalId":{"type":"string"},"batches":{"type":"array","items":{"type":"string"}},"priority":{"type":"number"},"answer":{"type":"object"},"createdAt":{"type":"string","format":"date-time"},"completedAt":{"type":"string","format":"date-time"},"duration":{"type":"number","description":"Duration in seconds"}}}}}}
```

## The TaskFilters object

```json
{"openapi":"3.0.3","info":{"title":"Ango Hub API v2","version":"2.0.0"},"components":{"schemas":{"TaskFilters":{"type":"object","description":"Filter criteria for task operations","properties":{"taskIds":{"type":"array","items":{"type":"string"},"description":"Array of task IDs"},"externalIds":{"type":"array","items":{"type":"string"},"description":"Array of external IDs"},"assetIds":{"type":"array","items":{"type":"string"},"description":"Array of asset IDs"},"fromStageIds":{"type":"array","items":{"type":"string"},"description":"Array of source stage IDs"},"batches":{"type":"array","items":{"type":"string"},"description":"Array of batch IDs"}}}}}}
```

## The RequeueTasksRequest object

```json
{"openapi":"3.0.3","info":{"title":"Ango Hub API v2","version":"2.0.0"},"components":{"schemas":{"RequeueTasksRequest":{"type":"object","required":["toStageId","filters"],"properties":{"toStageId":{"type":"string","description":"Destination stage ID"},"filters":{"$ref":"#/components/schemas/TaskFilters"},"options":{"type":"object","description":"Options for task requeue operation","properties":{"removeAnnotations":{"type":"boolean","description":"Remove existing annotations when requeuing","default":false},"removeAssignee":{"type":"boolean","description":"Remove task assignee when requeuing","default":false},"removeStageHistory":{"type":"boolean","description":"Remove stage history when requeuing","default":false}}}}},"TaskFilters":{"type":"object","description":"Filter criteria for task operations","properties":{"taskIds":{"type":"array","items":{"type":"string"},"description":"Array of task IDs"},"externalIds":{"type":"array","items":{"type":"string"},"description":"Array of external IDs"},"assetIds":{"type":"array","items":{"type":"string"},"description":"Array of asset IDs"},"fromStageIds":{"type":"array","items":{"type":"string"},"description":"Array of source stage IDs"},"batches":{"type":"array","items":{"type":"string"},"description":"Array of batch IDs"}}}}}}
```

## The RequeueResponse object

```json
{"openapi":"3.0.3","info":{"title":"Ango Hub API v2","version":"2.0.0"},"components":{"schemas":{"RequeueResponse":{"type":"object","properties":{"status":{"type":"string"},"data":{"type":"object","properties":{"modifiedCount":{"type":"object","properties":{"modified":{"type":"integer"},"toStageId":{"type":"string"}}}}}}}}}}
```

## The UpdatePriorityRequest object

```json
{"openapi":"3.0.3","info":{"title":"Ango Hub API v2","version":"2.0.0"},"components":{"schemas":{"UpdatePriorityRequest":{"type":"object","required":["priority","filters"],"properties":{"priority":{"type":"number","minimum":-1000,"maximum":1000,"description":"Priority value (-1000 to 1000)"},"filters":{"$ref":"#/components/schemas/TaskFilters"},"options":{"type":"object"}}},"TaskFilters":{"type":"object","description":"Filter criteria for task operations","properties":{"taskIds":{"type":"array","items":{"type":"string"},"description":"Array of task IDs"},"externalIds":{"type":"array","items":{"type":"string"},"description":"Array of external IDs"},"assetIds":{"type":"array","items":{"type":"string"},"description":"Array of asset IDs"},"fromStageIds":{"type":"array","items":{"type":"string"},"description":"Array of source stage IDs"},"batches":{"type":"array","items":{"type":"string"},"description":"Array of batch IDs"}}}}}}
```

## The PriorityUpdateResponse object

```json
{"openapi":"3.0.3","info":{"title":"Ango Hub API v2","version":"2.0.0"},"components":{"schemas":{"PriorityUpdateResponse":{"type":"object","properties":{"status":{"type":"string"},"data":{"type":"object","properties":{"result":{"type":"object","properties":{"modifiedCount":{"type":"integer"},"priority":{"type":"number"}}}}}}}}}}
```

## The TaskAssignRequest object

```json
{"openapi":"3.0.3","info":{"title":"Ango Hub API v2","version":"2.0.0"},"components":{"schemas":{"TaskAssignRequest":{"type":"object","required":["user","project","tasks","stage"],"properties":{"user":{"type":"string","description":"User email to assign to"},"project":{"type":"string","description":"Project ID"},"tasks":{"type":"array","items":{"type":"string"},"description":"Array of task IDs"},"stage":{"type":"string","description":"Stage ID"}}}}}}
```

## The TaskAssignResponse object

```json
{"openapi":"3.0.3","info":{"title":"Ango Hub API v2","version":"2.0.0"},"components":{"schemas":{"TaskAssignResponse":{"type":"object","properties":{"status":{"type":"string"},"data":{"type":"object","properties":{"task":{"type":"object","properties":{"updatedCount":{"type":"integer"},"assignedTasks":{"type":"object","properties":{"count":{"type":"integer"}}},"message":{"type":"string"}}}}}}}}}}
```

## The AnnotateRequest object

```json
{"openapi":"3.0.3","info":{"title":"Ango Hub API v2","version":"2.0.0"},"components":{"schemas":{"AnnotateRequest":{"type":"object","required":["answer"],"properties":{"answer":{"type":"object","description":"Annotation answer object (structure depends on project categorySchema)"}}}}}}
```

## The ReviewRequest object

```json
{"openapi":"3.0.3","info":{"title":"Ango Hub API v2","version":"2.0.0"},"components":{"schemas":{"ReviewRequest":{"type":"object","required":["reviewStatus"],"properties":{"reviewStatus":{"type":"string","enum":["Accepted","Rejected"],"description":"Review decision for the task.\n- `Accepted`: Approve the task and move it to the next stage\n- `Rejected`: Reject the task (typically sends it back for correction)\n"},"answer":{"type":"object","description":"Optional annotation modifications (structure depends on project categorySchema)"},"duration":{"type":"number","description":"Time spent reviewing in seconds"},"idleDuration":{"type":"number","description":"Idle time during review in seconds"},"blurDuration":{"type":"number","description":"Time window was blurred/unfocused in seconds"}}}}}}
```

## The LabelResponse object

```json
{"openapi":"3.0.3","info":{"title":"Ango Hub API v2","version":"2.0.0"},"components":{"schemas":{"LabelResponse":{"type":"object","properties":{"status":{"type":"string"},"data":{"type":"object","properties":{"label":{"$ref":"#/components/schemas/LabelTask"}}}}},"LabelTask":{"type":"object","properties":{"_id":{"type":"string"},"project":{"type":"string"},"asset":{"type":"string"},"stage":{"type":"string"},"status":{"type":"string"},"assignee":{"type":"string"},"externalId":{"type":"string"},"batches":{"type":"array","items":{"type":"string"}},"priority":{"type":"number"},"answer":{"type":"object"},"createdAt":{"type":"string","format":"date-time"},"completedAt":{"type":"string","format":"date-time"},"duration":{"type":"number","description":"Duration in seconds"}}}}}}
```

## The TaskHistory object

```json
{"openapi":"3.0.3","info":{"title":"Ango Hub API v2","version":"2.0.0"},"components":{"schemas":{"TaskHistory":{"type":"object","properties":{"_id":{"type":"string"},"task":{"type":"string"},"user":{"type":"string"},"action":{"type":"string"},"answer":{"type":"object"},"createdAt":{"type":"string","format":"date-time"}}}}}}
```

## The TaskHistoryListResponse object

```json
{"openapi":"3.0.3","info":{"title":"Ango Hub API v2","version":"2.0.0"},"components":{"schemas":{"TaskHistoryListResponse":{"type":"object","properties":{"status":{"type":"string"},"data":{"type":"object","properties":{"taskHistory":{"type":"array","items":{"$ref":"#/components/schemas/TaskHistory"}}}}}},"TaskHistory":{"type":"object","properties":{"_id":{"type":"string"},"task":{"type":"string"},"user":{"type":"string"},"action":{"type":"string"},"answer":{"type":"object"},"createdAt":{"type":"string","format":"date-time"}}}}}}
```

## The TaskHistoryResponse object

```json
{"openapi":"3.0.3","info":{"title":"Ango Hub API v2","version":"2.0.0"},"components":{"schemas":{"TaskHistoryResponse":{"type":"object","properties":{"status":{"type":"string"},"data":{"type":"object","properties":{"taskHistory":{"$ref":"#/components/schemas/TaskHistory"}}}}},"TaskHistory":{"type":"object","properties":{"_id":{"type":"string"},"task":{"type":"string"},"user":{"type":"string"},"action":{"type":"string"},"answer":{"type":"object"},"createdAt":{"type":"string","format":"date-time"}}}}}}
```

## The Asset object

```json
{"openapi":"3.0.3","info":{"title":"Ango Hub API v2","version":"2.0.0"},"components":{"schemas":{"Asset":{"type":"object","properties":{"_id":{"type":"string"},"data":{"type":"string","description":"Asset URL"},"dataset":{"type":"array","items":{"type":"string"}},"overlay":{"type":"array","items":{"type":"string"}},"project":{"type":"string"},"organization":{"type":"string"},"externalId":{"type":"string"},"batches":{"type":"array","items":{"type":"string"}},"metadata":{"type":"object"},"contextData":{"type":"object"},"labelTasks":{"type":"array","items":{"type":"string"}},"deleted":{"type":"boolean"},"createdAt":{"type":"string","format":"date-time"},"createdBy":{"type":"string"}}}}}}
```

## The AssetListResponse object

```json
{"openapi":"3.0.3","info":{"title":"Ango Hub API v2","version":"2.0.0"},"components":{"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","properties":{"_id":{"type":"string"},"data":{"type":"string","description":"Asset URL"},"dataset":{"type":"array","items":{"type":"string"}},"overlay":{"type":"array","items":{"type":"string"}},"project":{"type":"string"},"organization":{"type":"string"},"externalId":{"type":"string"},"batches":{"type":"array","items":{"type":"string"}},"metadata":{"type":"object"},"contextData":{"type":"object"},"labelTasks":{"type":"array","items":{"type":"string"}},"deleted":{"type":"boolean"},"createdAt":{"type":"string","format":"date-time"},"createdBy":{"type":"string"}}}}}}
```

## The AssetResponse object

```json
{"openapi":"3.0.3","info":{"title":"Ango Hub API v2","version":"2.0.0"},"components":{"schemas":{"AssetResponse":{"type":"object","properties":{"status":{"type":"string"},"data":{"type":"object","properties":{"asset":{"$ref":"#/components/schemas/Asset"}}}}},"Asset":{"type":"object","properties":{"_id":{"type":"string"},"data":{"type":"string","description":"Asset URL"},"dataset":{"type":"array","items":{"type":"string"}},"overlay":{"type":"array","items":{"type":"string"}},"project":{"type":"string"},"organization":{"type":"string"},"externalId":{"type":"string"},"batches":{"type":"array","items":{"type":"string"}},"metadata":{"type":"object"},"contextData":{"type":"object"},"labelTasks":{"type":"array","items":{"type":"string"}},"deleted":{"type":"boolean"},"createdAt":{"type":"string","format":"date-time"},"createdBy":{"type":"string"}}}}}}
```

## The UploadUrlResponse object

```json
{"openapi":"3.0.3","info":{"title":"Ango Hub API v2","version":"2.0.0"},"components":{"schemas":{"UploadUrlResponse":{"type":"object","properties":{"status":{"type":"string"},"data":{"type":"object","properties":{"uploadUrl":{"type":"string"}}}}}}}}
```

## The SignedUrlResponse object

```json
{"openapi":"3.0.3","info":{"title":"Ango Hub API v2","version":"2.0.0"},"components":{"schemas":{"SignedUrlResponse":{"type":"object","properties":{"status":{"type":"string"},"data":{"type":"object","properties":{"signedUrl":{"type":"string"}}}}}}}}
```

## The CloudImportAsset object

```json
{"openapi":"3.0.3","info":{"title":"Ango Hub API v2","version":"2.0.0"},"components":{"schemas":{"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)"},"externalId":{"type":"string","description":"External identifier for the asset (for reference/tracking)"},"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 names to assign this asset to"},"metadata":{"type":"object","description":"Custom metadata key-value pairs"},"overlay":{"type":"array","items":{"type":"string"},"description":"Overlay image URLs (for image comparison tasks)"},"contextData":{"type":"object","description":"Additional context data for the asset"},"preLabel":{"type":"object","description":"Pre-labeling data (annotations from ML models or previous annotations)","properties":{"tools":{"type":"array","items":{"type":"object"}},"classifications":{"type":"array","items":{"type":"object"}},"relations":{"type":"array","items":{"type":"object"}}}}}}}}}
```

## The CloudImportRequest object

```json
{"openapi":"3.0.3","info":{"title":"Ango Hub API v2","version":"2.0.0"},"components":{"schemas":{"CloudImportRequest":{"type":"object","required":["assets"],"properties":{"assets":{"type":"array","items":{"$ref":"#/components/schemas/CloudImportAsset"}},"uploadLocal":{"type":"string","enum":["true","false"],"description":"Whether to download and store assets locally.\n- \"true\": Download assets from cloud URLs and store locally\n- \"false\": Keep assets in cloud (reference URLs only)\nDefault: \"false\" for cloud imports\n","default":"false"},"priority":{"type":"number","minimum":-1000,"maximum":1000,"description":"Task priority for queue ordering (higher values = higher priority)","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)"},"externalId":{"type":"string","description":"External identifier for the asset (for reference/tracking)"},"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 names to assign this asset to"},"metadata":{"type":"object","description":"Custom metadata key-value pairs"},"overlay":{"type":"array","items":{"type":"string"},"description":"Overlay image URLs (for image comparison tasks)"},"contextData":{"type":"object","description":"Additional context data for the asset"},"preLabel":{"type":"object","description":"Pre-labeling data (annotations from ML models or previous annotations)","properties":{"tools":{"type":"array","items":{"type":"object"}},"classifications":{"type":"array","items":{"type":"object"}},"relations":{"type":"array","items":{"type":"object"}}}}}}}}}
```

## The AssetImportResponse object

```json
{"openapi":"3.0.3","info":{"title":"Ango Hub API v2","version":"2.0.0"},"components":{"schemas":{"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"}}}}}}}}}}
```

## The ChatAssetUploadRequest object

```json
{"openapi":"3.0.3","info":{"title":"Ango Hub API v2","version":"2.0.0"},"components":{"schemas":{"ChatAssetUploadRequest":{"type":"object","properties":{"file":{"type":"string","format":"binary","description":"JSON file with conversations"},"conversations":{"type":"string","description":"JSON stringified conversations array"},"storageId":{"type":"string"},"bucket":{"type":"string"},"batches":{"type":"string","description":"JSON stringified batch names"},"llmConfig":{"type":"string","description":"LLM configuration JSON"},"numberOfConversations":{"type":"number"},"namingStrategy":{"type":"string"},"priority":{"type":"number"}}}}}}
```

## The AssetUpdateRequest object

```json
{"openapi":"3.0.3","info":{"title":"Ango Hub API v2","version":"2.0.0"},"components":{"schemas":{"AssetUpdateRequest":{"type":"object","properties":{"metadata":{"type":"object"},"contextData":{"type":"object"},"data":{"type":"string"},"overlay":{"type":"array","items":{"type":"string"}},"externalId":{"type":"string"}}}}}}
```

## The BulkDeleteAssetsRequest object

```json
{"openapi":"3.0.3","info":{"title":"Ango Hub API v2","version":"2.0.0"},"components":{"schemas":{"BulkDeleteAssetsRequest":{"type":"object","required":["assets"],"properties":{"assets":{"type":"array","items":{"type":"string"}}}}}}}
```

## The BulkDeleteResponse object

```json
{"openapi":"3.0.3","info":{"title":"Ango Hub API v2","version":"2.0.0"},"components":{"schemas":{"BulkDeleteResponse":{"type":"object","properties":{"status":{"type":"string"},"data":{"type":"object","properties":{"deleted":{"type":"integer"},"failed":{"type":"integer"}}}}}}}}
```

## The AssignBatchesRequest object

```json
{"openapi":"3.0.3","info":{"title":"Ango Hub API v2","version":"2.0.0"},"components":{"schemas":{"AssignBatchesRequest":{"type":"object","required":["assetIds","batches"],"properties":{"assetIds":{"type":"array","items":{"type":"string"}},"batches":{"type":"array","items":{"type":"string"}},"mode":{"type":"string","enum":["add","replace"],"default":"add"}}}}}}
```

## The AssignBatchesResponse object

```json
{"openapi":"3.0.3","info":{"title":"Ango Hub API v2","version":"2.0.0"},"components":{"schemas":{"AssignBatchesResponse":{"type":"object","properties":{"status":{"type":"string"},"data":{"type":"object","properties":{"assets":{"type":"object","properties":{"modifiedCount":{"type":"integer"},"batches":{"type":"array","items":{"type":"string"}}}}}}}}}}}
```

## The Issue object

```json
{"openapi":"3.0.3","info":{"title":"Ango Hub API v2","version":"2.0.0"},"components":{"schemas":{"Issue":{"type":"object","properties":{"_id":{"type":"string"},"title":{"type":"string"},"content":{"type":"string"},"project":{"type":"string"},"asset":{"type":"string"},"labelTask":{"type":"string"},"status":{"type":"string","enum":["Open","Resolved","Closed"]},"createdBy":{"type":"string"},"assignee":{"type":"string"},"errorType":{"type":"string"},"errorCode":{"type":"string"},"position":{"type":"string"},"points":{"type":"array","items":{"type":"object"}},"contentMentions":{"type":"array","items":{"type":"object","properties":{"userEmail":{"type":"string"},"userName":{"type":"string"}}}},"comments":{"type":"array","items":{"type":"object","properties":{"_id":{"type":"string"},"content":{"type":"string"},"createdBy":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"contentMentions":{"type":"array","items":{"type":"object","properties":{"userEmail":{"type":"string"},"userName":{"type":"string"}}}}}}},"errorCodes":{"type":"array","items":{"type":"object","properties":{"category":{"type":"string"},"name":{"type":"string"},"key":{"type":"string"}}}},"pctDetails":{"type":"object","description":"PCT-specific issue details containing positional metadata, severity,\nreference source, and optional marker information for navigating to\na point inside a 3D/2D scene.\n","properties":{"attribute":{"type":"string","nullable":true,"description":"Attribute ID from configuration."},"class":{"type":"string","nullable":true,"description":"Class ID from configuration."},"frame":{"type":"integer","description":"Starting frame number of the issue."},"endInputFrame":{"type":"integer","description":"Last frame where the issue persists."},"instance":{"type":"integer","description":"Class instance index."},"severity":{"type":"integer","enum":[2,3,4],"description":"Issue severity: 2=High, 3=Medium, 4=Low"},"referenceIndex":{"type":"integer","description":"-1 for 3D sensor, 0+ for 2D camera sensor index"},"marker":{"type":"object","description":"Marker for navigating to the issue location.","properties":{"type":{"type":"string","enum":["Marker 3D","Marker 2D"]},"value":{"type":"object","properties":{"geometry":{"type":"object","properties":{"position":{"type":"object","properties":{"x":{"type":"number"},"y":{"type":"number"},"z":{"type":"number"}}},"rotation":{"type":"object","properties":{"x":{"type":"number"},"y":{"type":"number"},"z":{"type":"number"}}},"boxSize":{"type":"object","properties":{"x":{"type":"number"},"y":{"type":"number"},"z":{"type":"number"}}}}}}}}}}},"resolvedBy":{"type":"string"},"resolvedAt":{"type":"string","format":"date-time"},"updatedBy":{"type":"string"},"updatedAt":{"type":"string","format":"date-time"},"createdAt":{"type":"string","format":"date-time"}}}}}}
```

## The IssueListResponse object

```json
{"openapi":"3.0.3","info":{"title":"Ango Hub API v2","version":"2.0.0"},"components":{"schemas":{"IssueListResponse":{"type":"object","properties":{"status":{"type":"string"},"data":{"type":"object","properties":{"issue":{"type":"array","items":{"$ref":"#/components/schemas/Issue"}}}}}},"Issue":{"type":"object","properties":{"_id":{"type":"string"},"title":{"type":"string"},"content":{"type":"string"},"project":{"type":"string"},"asset":{"type":"string"},"labelTask":{"type":"string"},"status":{"type":"string","enum":["Open","Resolved","Closed"]},"createdBy":{"type":"string"},"assignee":{"type":"string"},"errorType":{"type":"string"},"errorCode":{"type":"string"},"position":{"type":"string"},"points":{"type":"array","items":{"type":"object"}},"contentMentions":{"type":"array","items":{"type":"object","properties":{"userEmail":{"type":"string"},"userName":{"type":"string"}}}},"comments":{"type":"array","items":{"type":"object","properties":{"_id":{"type":"string"},"content":{"type":"string"},"createdBy":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"contentMentions":{"type":"array","items":{"type":"object","properties":{"userEmail":{"type":"string"},"userName":{"type":"string"}}}}}}},"errorCodes":{"type":"array","items":{"type":"object","properties":{"category":{"type":"string"},"name":{"type":"string"},"key":{"type":"string"}}}},"pctDetails":{"type":"object","description":"PCT-specific issue details containing positional metadata, severity,\nreference source, and optional marker information for navigating to\na point inside a 3D/2D scene.\n","properties":{"attribute":{"type":"string","nullable":true,"description":"Attribute ID from configuration."},"class":{"type":"string","nullable":true,"description":"Class ID from configuration."},"frame":{"type":"integer","description":"Starting frame number of the issue."},"endInputFrame":{"type":"integer","description":"Last frame where the issue persists."},"instance":{"type":"integer","description":"Class instance index."},"severity":{"type":"integer","enum":[2,3,4],"description":"Issue severity: 2=High, 3=Medium, 4=Low"},"referenceIndex":{"type":"integer","description":"-1 for 3D sensor, 0+ for 2D camera sensor index"},"marker":{"type":"object","description":"Marker for navigating to the issue location.","properties":{"type":{"type":"string","enum":["Marker 3D","Marker 2D"]},"value":{"type":"object","properties":{"geometry":{"type":"object","properties":{"position":{"type":"object","properties":{"x":{"type":"number"},"y":{"type":"number"},"z":{"type":"number"}}},"rotation":{"type":"object","properties":{"x":{"type":"number"},"y":{"type":"number"},"z":{"type":"number"}}},"boxSize":{"type":"object","properties":{"x":{"type":"number"},"y":{"type":"number"},"z":{"type":"number"}}}}}}}}}}},"resolvedBy":{"type":"string"},"resolvedAt":{"type":"string","format":"date-time"},"updatedBy":{"type":"string"},"updatedAt":{"type":"string","format":"date-time"},"createdAt":{"type":"string","format":"date-time"}}}}}}
```

## The IssueResponse object

```json
{"openapi":"3.0.3","info":{"title":"Ango Hub API v2","version":"2.0.0"},"components":{"schemas":{"IssueResponse":{"type":"object","properties":{"status":{"type":"string"},"data":{"type":"object","properties":{"issue":{"$ref":"#/components/schemas/Issue"}}}}},"Issue":{"type":"object","properties":{"_id":{"type":"string"},"title":{"type":"string"},"content":{"type":"string"},"project":{"type":"string"},"asset":{"type":"string"},"labelTask":{"type":"string"},"status":{"type":"string","enum":["Open","Resolved","Closed"]},"createdBy":{"type":"string"},"assignee":{"type":"string"},"errorType":{"type":"string"},"errorCode":{"type":"string"},"position":{"type":"string"},"points":{"type":"array","items":{"type":"object"}},"contentMentions":{"type":"array","items":{"type":"object","properties":{"userEmail":{"type":"string"},"userName":{"type":"string"}}}},"comments":{"type":"array","items":{"type":"object","properties":{"_id":{"type":"string"},"content":{"type":"string"},"createdBy":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"contentMentions":{"type":"array","items":{"type":"object","properties":{"userEmail":{"type":"string"},"userName":{"type":"string"}}}}}}},"errorCodes":{"type":"array","items":{"type":"object","properties":{"category":{"type":"string"},"name":{"type":"string"},"key":{"type":"string"}}}},"pctDetails":{"type":"object","description":"PCT-specific issue details containing positional metadata, severity,\nreference source, and optional marker information for navigating to\na point inside a 3D/2D scene.\n","properties":{"attribute":{"type":"string","nullable":true,"description":"Attribute ID from configuration."},"class":{"type":"string","nullable":true,"description":"Class ID from configuration."},"frame":{"type":"integer","description":"Starting frame number of the issue."},"endInputFrame":{"type":"integer","description":"Last frame where the issue persists."},"instance":{"type":"integer","description":"Class instance index."},"severity":{"type":"integer","enum":[2,3,4],"description":"Issue severity: 2=High, 3=Medium, 4=Low"},"referenceIndex":{"type":"integer","description":"-1 for 3D sensor, 0+ for 2D camera sensor index"},"marker":{"type":"object","description":"Marker for navigating to the issue location.","properties":{"type":{"type":"string","enum":["Marker 3D","Marker 2D"]},"value":{"type":"object","properties":{"geometry":{"type":"object","properties":{"position":{"type":"object","properties":{"x":{"type":"number"},"y":{"type":"number"},"z":{"type":"number"}}},"rotation":{"type":"object","properties":{"x":{"type":"number"},"y":{"type":"number"},"z":{"type":"number"}}},"boxSize":{"type":"object","properties":{"x":{"type":"number"},"y":{"type":"number"},"z":{"type":"number"}}}}}}}}}}},"resolvedBy":{"type":"string"},"resolvedAt":{"type":"string","format":"date-time"},"updatedBy":{"type":"string"},"updatedAt":{"type":"string","format":"date-time"},"createdAt":{"type":"string","format":"date-time"}}}}}}
```

## The IssueCreateRequest object

```json
{"openapi":"3.0.3","info":{"title":"Ango Hub API v2","version":"2.0.0"},"components":{"schemas":{"IssueCreateRequest":{"type":"object","required":["labelTask"],"properties":{"labelTask":{"type":"string","description":"Task ID to create issue for"},"title":{"type":"string"},"content":{"type":"string"},"contentMentions":{"type":"array","items":{"type":"object","properties":{"userEmail":{"type":"string"},"userName":{"type":"string"}}}},"position":{"type":"string"},"points":{"type":"array","items":{"type":"object"}},"errorType":{"type":"string"},"errorCode":{"type":"string"},"pctDetails":{"type":"object","description":"PCT-specific issue details containing positional metadata, severity,\nreference source, and optional marker information for navigating to\na point inside a 3D/2D scene.\n","properties":{"attribute":{"type":"string","nullable":true,"description":"Attribute ID from configuration. Can be null or omitted if not assigned."},"class":{"type":"string","nullable":true,"description":"Class ID from configuration. Can be null or omitted if not available."},"frame":{"type":"integer","default":1,"description":"Starting frame number of the issue. Defaults to 1."},"endInputFrame":{"type":"integer","default":1,"description":"Last frame where the issue persists. Defaults to 1."},"instance":{"type":"integer","default":-1,"description":"Class instance index. Defaults to -1."},"severity":{"type":"integer","enum":[2,3,4],"description":"Issue severity: 2=High, 3=Medium, 4=Low"},"referenceIndex":{"type":"integer","default":-1,"description":"-1 for 3D sensor, 0+ for 2D camera sensor index"},"marker":{"type":"object","description":"Optional marker for navigating to the issue location.","properties":{"type":{"type":"string","enum":["Marker 3D","Marker 2D"]},"value":{"type":"object","properties":{"geometry":{"type":"object","properties":{"position":{"type":"object","properties":{"x":{"type":"number"},"y":{"type":"number"},"z":{"type":"number"}}},"rotation":{"type":"object","properties":{"x":{"type":"number"},"y":{"type":"number"},"z":{"type":"number"}}},"boxSize":{"type":"object","properties":{"x":{"type":"number"},"y":{"type":"number"},"z":{"type":"number"}}}}}}}}}}}}}}}}
```

## The IssueUpdateRequest object

```json
{"openapi":"3.0.3","info":{"title":"Ango Hub API v2","version":"2.0.0"},"components":{"schemas":{"IssueUpdateRequest":{"type":"object","description":"Request body for updating an issue. All fields are optional.","properties":{"content":{"type":"string","description":"Updated issue content/description"},"contentMentions":{"type":"array","description":"Users mentioned in the content","items":{"type":"object","properties":{"userEmail":{"type":"string"},"userName":{"type":"string"}}}},"status":{"type":"string","enum":["Open","Resolved"],"description":"Issue status (Open or Resolved)"},"pctDetails":{"type":"object","description":"PCT-specific issue details containing positional metadata, severity,\nreference source, and optional marker information for navigating to\na point inside a 3D/2D scene.\n","properties":{"attribute":{"type":"string","nullable":true,"description":"Attribute ID from configuration. Can be null or omitted if not assigned."},"class":{"type":"string","nullable":true,"description":"Class ID from configuration. Can be null or omitted if not available."},"frame":{"type":"integer","default":1,"description":"Starting frame number of the issue. Defaults to 1."},"endInputFrame":{"type":"integer","default":1,"description":"Last frame where the issue persists. Defaults to 1."},"instance":{"type":"integer","default":-1,"description":"Class instance index. Defaults to -1."},"severity":{"type":"integer","enum":[2,3,4],"description":"Issue severity: 2=High, 3=Medium, 4=Low"},"referenceIndex":{"type":"integer","default":-1,"description":"-1 for 3D sensor, 0+ for 2D camera sensor index"},"marker":{"type":"object","description":"Optional marker for navigating to the issue location.","properties":{"type":{"type":"string","enum":["Marker 3D","Marker 2D"]},"value":{"type":"object","properties":{"geometry":{"type":"object","properties":{"position":{"type":"object","properties":{"x":{"type":"number"},"y":{"type":"number"},"z":{"type":"number"}}},"rotation":{"type":"object","properties":{"x":{"type":"number"},"y":{"type":"number"},"z":{"type":"number"}}},"boxSize":{"type":"object","properties":{"x":{"type":"number"},"y":{"type":"number"},"z":{"type":"number"}}}}}}}}}}},"errorCodes":{"type":"array","description":"Error codes associated with the issue","items":{"type":"object","properties":{"category":{"type":"string"},"name":{"type":"string"},"key":{"type":"string"}}}}}}}}}
```

## The IssueCommentRequest object

```json
{"openapi":"3.0.3","info":{"title":"Ango Hub API v2","version":"2.0.0"},"components":{"schemas":{"IssueCommentRequest":{"type":"object","required":["content"],"properties":{"content":{"type":"string","description":"The comment text content"},"contentMentions":{"type":"array","description":"Users mentioned in the comment","items":{"type":"object","properties":{"userEmail":{"type":"string"},"userName":{"type":"string"}}}}}}}}}
```

## The Storage object

```json
{"openapi":"3.0.3","info":{"title":"Ango Hub API v2","version":"2.0.0"},"components":{"schemas":{"Storage":{"type":"object","properties":{"_id":{"type":"string"},"name":{"type":"string"},"type":{"type":"string","enum":["aws","gcs","azure"]},"bucket":{"type":"string"},"region":{"type":"string"},"organization":{"type":"string"},"createdAt":{"type":"string","format":"date-time"}}}}}}
```

## The StorageListResponse object

```json
{"openapi":"3.0.3","info":{"title":"Ango Hub API v2","version":"2.0.0"},"components":{"schemas":{"StorageListResponse":{"type":"object","properties":{"status":{"type":"string"},"data":{"type":"object","properties":{"storages":{"type":"array","items":{"$ref":"#/components/schemas/Storage"}}}}}},"Storage":{"type":"object","properties":{"_id":{"type":"string"},"name":{"type":"string"},"type":{"type":"string","enum":["aws","gcs","azure"]},"bucket":{"type":"string"},"region":{"type":"string"},"organization":{"type":"string"},"createdAt":{"type":"string","format":"date-time"}}}}}}
```

## The StorageResponse object

```json
{"openapi":"3.0.3","info":{"title":"Ango Hub API v2","version":"2.0.0"},"components":{"schemas":{"StorageResponse":{"type":"object","properties":{"status":{"type":"string"},"data":{"type":"object","properties":{"storage":{"$ref":"#/components/schemas/Storage"}}}}},"Storage":{"type":"object","properties":{"_id":{"type":"string"},"name":{"type":"string"},"type":{"type":"string","enum":["aws","gcs","azure"]},"bucket":{"type":"string"},"region":{"type":"string"},"organization":{"type":"string"},"createdAt":{"type":"string","format":"date-time"}}}}}}
```

## The StorageCreateRequest object

```json
{"openapi":"3.0.3","info":{"title":"Ango Hub API v2","version":"2.0.0"},"components":{"schemas":{"StorageCreateRequest":{"type":"object","required":["name","type","bucket","credentials"],"properties":{"name":{"type":"string"},"type":{"type":"string","enum":["aws","gcs","azure"]},"bucket":{"type":"string"},"region":{"type":"string"},"credentials":{"type":"object","description":"Storage provider credentials"},"privateKey":{"type":"string","description":"Private key (for GCS)"}}}}}}
```

## The StorageFilesResponse object

```json
{"openapi":"3.0.3","info":{"title":"Ango Hub API v2","version":"2.0.0"},"components":{"schemas":{"StorageFilesResponse":{"type":"object","properties":{"status":{"type":"string"},"data":{"type":"object","properties":{"files":{"type":"array","items":{"$ref":"#/components/schemas/StorageFile"}}}}}},"StorageFile":{"type":"object","properties":{"Key":{"type":"string","description":"File path/key in the storage bucket"},"Size":{"type":"integer","description":"File size in bytes"},"LastModified":{"type":"string","format":"date-time","description":"Last modification timestamp"},"ETag":{"type":"string","description":"Entity tag (checksum) for the file"},"SignedUrl":{"type":"string","description":"Pre-signed URL for direct file access (only present when getSignedUrls=true)"}}}}}}
```

## The StorageFile object

```json
{"openapi":"3.0.3","info":{"title":"Ango Hub API v2","version":"2.0.0"},"components":{"schemas":{"StorageFile":{"type":"object","properties":{"Key":{"type":"string","description":"File path/key in the storage bucket"},"Size":{"type":"integer","description":"File size in bytes"},"LastModified":{"type":"string","format":"date-time","description":"Last modification timestamp"},"ETag":{"type":"string","description":"Entity tag (checksum) for the file"},"SignedUrl":{"type":"string","description":"Pre-signed URL for direct file access (only present when getSignedUrls=true)"}}}}}}
```

## The User object

```json
{"openapi":"3.0.3","info":{"title":"Ango Hub API v2","version":"2.0.0"},"components":{"schemas":{"User":{"type":"object","properties":{"_id":{"type":"string"},"email":{"type":"string"},"name":{"type":"string"},"organizationRole":{"type":"string","enum":["Admin","Member","Guest"]},"createdAt":{"type":"string","format":"date-time"}}}}}}
```

## The UserListResponse object

```json
{"openapi":"3.0.3","info":{"title":"Ango Hub API v2","version":"2.0.0"},"components":{"schemas":{"UserListResponse":{"type":"object","properties":{"status":{"type":"string"},"data":{"type":"object","properties":{"users":{"type":"array","items":{"$ref":"#/components/schemas/User"}}}}}},"User":{"type":"object","properties":{"_id":{"type":"string"},"email":{"type":"string"},"name":{"type":"string"},"organizationRole":{"type":"string","enum":["Admin","Member","Guest"]},"createdAt":{"type":"string","format":"date-time"}}}}}}
```

## The BulkUpdateMembersRequest object

```json
{"openapi":"3.0.3","info":{"title":"Ango Hub API v2","version":"2.0.0"},"components":{"schemas":{"BulkUpdateMembersRequest":{"type":"object","required":["users"],"properties":{"users":{"type":"array","items":{"type":"object","required":["email","organizationRole"],"properties":{"email":{"type":"string","format":"email"},"organizationRole":{"type":"string","enum":["Admin","Member","Guest"]}}}}}}}}}
```

## The BulkUpdateResponse object

```json
{"openapi":"3.0.3","info":{"title":"Ango Hub API v2","version":"2.0.0"},"components":{"schemas":{"BulkUpdateResponse":{"type":"object","properties":{"status":{"type":"string"},"data":{"type":"object","properties":{"users":{"type":"object","properties":{"updated":{"type":"integer"},"failed":{"type":"integer"},"results":{"type":"array","items":{"type":"object","properties":{"email":{"type":"string"},"status":{"type":"string"}}}}}}}}}}}}}
```

## The BulkDeleteMembersRequest object

```json
{"openapi":"3.0.3","info":{"title":"Ango Hub API v2","version":"2.0.0"},"components":{"schemas":{"BulkDeleteMembersRequest":{"type":"object","required":["users"],"properties":{"users":{"type":"array","items":{"type":"string","format":"email"}}}}}}}
```

## The Invitation object

```json
{"openapi":"3.0.3","info":{"title":"Ango Hub API v2","version":"2.0.0"},"components":{"schemas":{"Invitation":{"type":"object","properties":{"_id":{"type":"string"},"to":{"type":"string","format":"email"},"organizationRole":{"type":"string","enum":["Admin","Member","Guest"]},"status":{"type":"string","enum":["Pending","Sent","Accepted"]},"createdBy":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"expiresAt":{"type":"string","format":"date-time"}}}}}}
```

## The InviteListResponse object

```json
{"openapi":"3.0.3","info":{"title":"Ango Hub API v2","version":"2.0.0"},"components":{"schemas":{"InviteListResponse":{"type":"object","properties":{"status":{"type":"string"},"data":{"type":"object","properties":{"invites":{"type":"array","items":{"$ref":"#/components/schemas/Invitation"}}}}}},"Invitation":{"type":"object","properties":{"_id":{"type":"string"},"to":{"type":"string","format":"email"},"organizationRole":{"type":"string","enum":["Admin","Member","Guest"]},"status":{"type":"string","enum":["Pending","Sent","Accepted"]},"createdBy":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"expiresAt":{"type":"string","format":"date-time"}}}}}}
```

## The InviteListResponseData object

```json
{"openapi":"3.0.3","info":{"title":"Ango Hub API v2","version":"2.0.0"},"components":{"schemas":{"InviteListResponseData":{"type":"object","properties":{"status":{"type":"string"},"data":{"type":"object","properties":{"invites":{"type":"array","items":{"$ref":"#/components/schemas/Invitation"}}}}}},"Invitation":{"type":"object","properties":{"_id":{"type":"string"},"to":{"type":"string","format":"email"},"organizationRole":{"type":"string","enum":["Admin","Member","Guest"]},"status":{"type":"string","enum":["Pending","Sent","Accepted"]},"createdBy":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"expiresAt":{"type":"string","format":"date-time"}}}}}}
```

## The InvitationRequest object

```json
{"openapi":"3.0.3","info":{"title":"Ango Hub API v2","version":"2.0.0"},"components":{"schemas":{"InvitationRequest":{"type":"object","required":["to","organizationRole"],"properties":{"to":{"type":"array","items":{"type":"string","format":"email"},"minItems":1},"organizationRole":{"type":"string","enum":["Admin","Member","Guest"]},"projectAssignments":{"type":"array","items":{"type":"object","required":["projectId","projectRole"],"properties":{"projectId":{"type":"string"},"projectRole":{"type":"string"}}}},"organizationRoleAssignments":{"type":"object","additionalProperties":{"type":"string"}},"projectRoleAssignments":{"type":"object","additionalProperties":{"type":"string"}}}}}}}
```

## The BulkDeleteInvitesRequest object

```json
{"openapi":"3.0.3","info":{"title":"Ango Hub API v2","version":"2.0.0"},"components":{"schemas":{"BulkDeleteInvitesRequest":{"type":"object","required":["invites"],"properties":{"invites":{"type":"array","items":{"type":"string"}}}}}}}
```

## The ImportAttachmentsRequest object

```json
{"openapi":"3.0.3","info":{"title":"Ango Hub API v2","version":"2.0.0"},"components":{"schemas":{"ImportAttachmentsRequest":{"type":"object","required":["project","attachments"],"properties":{"project":{"type":"string"},"attachments":{"type":"array","items":{"type":"object","required":["attachmentUrl"],"properties":{"assetId":{"type":"string"},"externalId":{"type":"string"},"attachmentUrl":{"type":"string"},"attachmentType":{"type":"string"}}}}}}}}}
```

## The ImportAttachmentsResponse object

```json
{"openapi":"3.0.3","info":{"title":"Ango Hub API v2","version":"2.0.0"},"components":{"schemas":{"ImportAttachmentsResponse":{"type":"object","properties":{"status":{"type":"string"},"data":{"type":"object","properties":{"project":{"type":"object","properties":{"attachmentsImported":{"type":"integer"},"assetsUpdated":{"type":"integer"}}}}}}}}}}
```

## The ImportLabelsRequest object

```json
{"openapi":"3.0.3","info":{"title":"Ango Hub API v2","version":"2.0.0"},"components":{"schemas":{"ImportLabelsRequest":{"type":"object","required":["project","labels"],"properties":{"project":{"type":"string"},"labels":{"type":"array","items":{"type":"object","required":["answer"],"properties":{"assetId":{"type":"string"},"externalId":{"type":"string"},"answer":{"type":"object"},"status":{"type":"string"},"assignee":{"type":"string"}}}}}}}}}
```

## The ImportLabelsResponse object

```json
{"openapi":"3.0.3","info":{"title":"Ango Hub API v2","version":"2.0.0"},"components":{"schemas":{"ImportLabelsResponse":{"type":"object","properties":{"status":{"type":"string"},"data":{"type":"object","properties":{"project":{"type":"string","description":"Success message indicating labeled task count"}}}}}}}}
```

## The ExportResponse object

```json
{"openapi":"3.0.3","info":{"title":"Ango Hub API v2","version":"2.0.0"},"components":{"schemas":{"ExportResponse":{"type":"object","properties":{"status":{"type":"string"},"data":{"type":"object","properties":{"exportPath":{"type":"string"}}}}}}}}
```

## The OverviewResponse object

```json
{"openapi":"3.0.3","info":{"title":"Ango Hub API v2","version":"2.0.0"},"components":{"schemas":{"OverviewResponse":{"type":"object","properties":{"status":{"type":"string"},"data":{"type":"object","properties":{"overview":{"oneOf":[{"type":"object"},{"type":"array"}]}}}}}}}}
```

## The PluginResponseRequest object

```json
{"openapi":"3.0.3","info":{"title":"Ango Hub API v2","version":"2.0.0"},"components":{"schemas":{"PluginResponseRequest":{"type":"object","required":["pluginId","taskId","response","status"],"properties":{"pluginId":{"type":"string"},"taskId":{"type":"string"},"response":{"type":"object"},"status":{"type":"string"}}}}}}
```

## The PluginResponseAck object

```json
{"openapi":"3.0.3","info":{"title":"Ango Hub API v2","version":"2.0.0"},"components":{"schemas":{"PluginResponseAck":{"type":"object","properties":{"status":{"type":"string"},"data":{"type":"object","properties":{"response":{"type":"object","properties":{"received":{"type":"boolean"},"taskId":{"type":"string"}}}}}}}}}}
```

## The PluginLogRequest object

```json
{"openapi":"3.0.3","info":{"title":"Ango Hub API v2","version":"2.0.0"},"components":{"schemas":{"PluginLogRequest":{"type":"object","required":["pluginId","level","message"],"properties":{"pluginId":{"type":"string"},"taskId":{"type":"string"},"level":{"type":"string","enum":["info","warn","error"]},"message":{"type":"string"},"metadata":{"type":"object"}}}}}}
```

## The PluginLogAck object

```json
{"openapi":"3.0.3","info":{"title":"Ango Hub API v2","version":"2.0.0"},"components":{"schemas":{"PluginLogAck":{"type":"object","properties":{"status":{"type":"string"},"data":{"type":"object","properties":{"response":{"type":"object","properties":{"logged":{"type":"boolean"}}}}}}}}}}
```

## The RerunWebhookRequest object

```json
{"openapi":"3.0.3","info":{"title":"Ango Hub API v2","version":"2.0.0"},"components":{"schemas":{"RerunWebhookRequest":{"type":"object","properties":{"stageId":{"type":"string","description":"Stage ID to rerun webhook for"}}}}}}
```

## The WebhookResponse object

```json
{"openapi":"3.0.3","info":{"title":"Ango Hub API v2","version":"2.0.0"},"components":{"schemas":{"WebhookResponse":{"type":"object","properties":{"status":{"type":"string"},"data":{"type":"object","properties":{"webhook":{"type":"object","description":"Webhook rerun result"}}}}}}}}
```
