> For the complete documentation index, see [llms.txt](https://docs.roboflow.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.roboflow.com/developer/rest-api/project-deploy-api.md).

# Project Deploy API

The Project Deploy API lets you read and configure a project's deployment state: which model is deployed, whether Active Learning is enabled, and how collected images are filtered and managed.

These endpoints live on the main API host at `https://api.roboflow.com`. All requests require an `api_key` passed as a query parameter or in the request body.

## Get Project Deploy State

<mark style="color:green;">`GET`</mark> `/:workspace/:project/deploy`

Returns the project's deployment configuration, including the selected model, deployability status, workflow, and Active Learning state.

Required scope: `project:read`

```bash
curl "https://api.roboflow.com/my-workspace/my-project/deploy?api_key=$ROBOFLOW_API_KEY"
```

**Response**

```json
{
  "project": {
    "id": "abc123",
    "url": "my-project",
    "name": "My Project",
    "owner": "my-workspace-id",
    "type": "object-detection",
    "classes": ["cat", "dog"],
    "multilabel": false
  },
  "workflow": {
    "id": "wf_xyz",
    "name": "My Project Base Workflow",
    "url": "my-project-base-workflow",
    "workspaceUrl": "my-workspace",
    "inferencePath": "/infer/workflows/my-workspace/my-project-base-workflow"
  },
  "model": {
    "kind": "pretrained",
    "modelId": "rfdetr-medium"
  },
  "deployability": {
    "status": "deployable",
    "reason": null,
    "modelWasConfigured": false,
    "selectedModelId": "rfdetr-medium",
    "selectionReason": null
  },
  "activeLearning": {
    "enabled": false,
    "collectionLimits": {},
    "filters": []
  },
  "baseWorkflowWasCreated": false
}
```

`model` is `null` when no model has been configured. `deployability.status` is `"not_deployable"` when the workflow cannot serve inference (for example, when no model is set and none can be auto-selected).

## Update Deployed Model

<mark style="color:green;">`POST`</mark> `/:workspace/:project/deploy/model`

Set or change the model used by the project's deployment workflow.

Required scope: `project:update`

**Body** (JSON)

The `model` field accepts three shapes:

**By model ID:**

```json
{
  "api_key": "YOUR_API_KEY",
  "model": {
    "type": "model_id",
    "modelId": "rfdetr-medium"
  }
}
```

**SAM3 template (zero-shot segmentation):**

```json
{
  "api_key": "YOUR_API_KEY",
  "model": {
    "type": "sam3",
    "classes": ["cat", "dog"]
  }
}
```

**CLIP template (zero-shot classification):**

```json
{
  "api_key": "YOUR_API_KEY",
  "model": {
    "type": "clip",
    "classes": ["cat", "dog"]
  }
}
```

```bash
curl -X POST "https://api.roboflow.com/my-workspace/my-project/deploy/model" \
  -H "Content-Type: application/json" \
  -d '{
    "api_key": "'$ROBOFLOW_API_KEY'",
    "model": { "type": "model_id", "modelId": "rfdetr-medium" }
  }'
```

**Response:** Same shape as [Get Project Deploy State](#get-project-deploy-state), reflecting the updated model and deployability status.

Returns `400` if the `model` field is missing or does not match one of the accepted shapes.

## Get Active Learning Configuration

<mark style="color:green;">`GET`</mark> `/:workspace/:project/deploy/active-learning`

Returns the project's Active Learning state: whether it is enabled, collection limits, and filters.

Required scope: `project:read`

```bash
curl "https://api.roboflow.com/my-workspace/my-project/deploy/active-learning?api_key=$ROBOFLOW_API_KEY"
```

**Response**

```json
{
  "project": { ... },
  "workflow": { ... },
  "model": { ... },
  "deployability": { ... },
  "activeLearning": {
    "enabled": false,
    "collectionLimits": {},
    "filters": []
  }
}
```

Same shape as [Get Project Deploy State](#get-project-deploy-state) except the `baseWorkflowWasCreated` field is omitted.

## Enable Active Learning

<mark style="color:green;">`POST`</mark> `/:workspace/:project/deploy/active-learning/enable`

Enables Active Learning on the project. If no model is configured, the service attempts to auto-select one. Returns `400` if the workflow is not deployable (for example, no model can be selected).

Required scope: `project:update`

```bash
curl -X POST "https://api.roboflow.com/my-workspace/my-project/deploy/active-learning/enable" \
  -H "Content-Type: application/json" \
  -d '{ "api_key": "'$ROBOFLOW_API_KEY'" }'
```

**Response:** Same shape as [Get Active Learning Configuration](#get-active-learning-configuration), with `activeLearning.enabled` set to `true`.

## Disable Active Learning

<mark style="color:green;">`POST`</mark> `/:workspace/:project/deploy/active-learning/disable`

Disables Active Learning on the project.

Required scope: `project:update`

```bash
curl -X POST "https://api.roboflow.com/my-workspace/my-project/deploy/active-learning/disable" \
  -H "Content-Type: application/json" \
  -d '{ "api_key": "'$ROBOFLOW_API_KEY'" }'
```

**Response:** Same shape as [Get Active Learning Configuration](#get-active-learning-configuration), with `activeLearning.enabled` set to `false`.

## Update Active Learning Configuration

<mark style="color:green;">`POST`</mark> `/:workspace/:project/deploy/active-learning/configuration`

Updates collection limits and, optionally, filters for Active Learning.

Required scope: `project:update`

**Body** (JSON)

<table><thead><tr><th width="200">Name</th><th width="120">Type</th><th>Description</th><th data-type="checkbox">Required</th></tr></thead><tbody><tr><td><code>api_key</code></td><td>string</td><td>Workspace API key.</td><td>true</td></tr><tr><td><code>collectionLimits</code></td><td>object</td><td>Collection limits configuration (see below).</td><td>true</td></tr><tr><td><code>filters</code></td><td>array</td><td>Array of filter objects. Omit to leave existing filters unchanged.</td><td>false</td></tr></tbody></table>

**Collection limits fields:**

<table><thead><tr><th width="280">Name</th><th width="120">Type</th><th>Description</th><th data-type="checkbox">Required</th></tr></thead><tbody><tr><td><code>dataPercentage</code></td><td>number</td><td>Percentage of inferences to collect (0-100).</td><td>true</td></tr><tr><td><code>minutelyUsageLimit</code></td><td>integer</td><td>Max images collected per minute (0 for unlimited).</td><td>true</td></tr><tr><td><code>hourlyUsageLimit</code></td><td>integer</td><td>Max images collected per hour.</td><td>true</td></tr><tr><td><code>dailyUsageLimit</code></td><td>integer</td><td>Max images collected per day.</td><td>true</td></tr><tr><td><code>labelingBatchesRecreationFrequency</code></td><td>string</td><td>How often new review batches are created: <code>"never"</code>, <code>"daily"</code>, <code>"weekly"</code>, or <code>"monthly"</code>.</td><td>true</td></tr><tr><td><code>usageQuotaName</code></td><td>string</td><td>Quota identifier (non-empty string).</td><td>true</td></tr><tr><td><code>imageCompressionLevel</code></td><td>integer</td><td>JPEG quality (1-100).</td><td>false</td></tr><tr><td><code>maxImageHeight</code></td><td>integer</td><td>Resize collected images to this max height.</td><td>false</td></tr><tr><td><code>maxImageWidth</code></td><td>integer</td><td>Resize collected images to this max width.</td><td>false</td></tr><tr><td><code>registrationTags</code></td><td>array</td><td>Tags to attach to collected images.</td><td>false</td></tr><tr><td><code>persistPredictions</code></td><td>boolean</td><td>Whether to store model predictions alongside collected images.</td><td>false</td></tr></tbody></table>

**Filter types:**

Each filter object has a `type` field. Two filter types are supported:

*Class confidence filter* - collects images where predictions for specific classes fall within a confidence range:

```json
{
  "type": "classConfidence",
  "classFilterMode": "any",
  "classes": ["cat"],
  "confidenceLowerBound": 0.2,
  "confidenceUpperBound": 0.8
}
```

`classFilterMode` can be `"any"` (any class matches), `"in"` (only listed classes), or `"out"` (all classes except listed).

*Detection size filter* - collects images where detection bounding boxes fall within a size range:

```json
{
  "type": "detectionSize",
  "sizeLowerPercentage": 5,
  "sizeUpperPercentage": 50
}
```

**Example request:**

```bash
curl -X POST "https://api.roboflow.com/my-workspace/my-project/deploy/active-learning/configuration" \
  -H "Content-Type: application/json" \
  -d '{
    "api_key": "'$ROBOFLOW_API_KEY'",
    "collectionLimits": {
      "dataPercentage": 50,
      "minutelyUsageLimit": 10,
      "hourlyUsageLimit": 100,
      "dailyUsageLimit": 1000,
      "labelingBatchesRecreationFrequency": "daily",
      "usageQuotaName": "default"
    },
    "filters": [
      {
        "type": "classConfidence",
        "classFilterMode": "any",
        "classes": ["cat"],
        "confidenceLowerBound": 0.2,
        "confidenceUpperBound": 0.8
      }
    ]
  }'
```

**Response:** Same shape as [Get Active Learning Configuration](#get-active-learning-configuration).

Returns `400` with validation details if `collectionLimits` or `filters` are malformed.

## List Active Learning Images

<mark style="color:green;">`GET`</mark> `/:workspace/:project/deploy/active-learning/images`

Lists images in the Active Learning review queue with pagination, filtering, and sorting.

Required scope: `project:read`

**Query parameters**

<table><thead><tr><th width="180">Name</th><th width="120">Type</th><th>Description</th><th data-type="checkbox">Required</th></tr></thead><tbody><tr><td><code>api_key</code></td><td>string</td><td>Workspace API key.</td><td>true</td></tr><tr><td><code>page</code></td><td>integer</td><td>Page number (default: 1).</td><td>false</td></tr><tr><td><code>pageSize</code></td><td>integer</td><td>Items per page.</td><td>false</td></tr><tr><td><code>search</code></td><td>string</td><td>Free text search.</td><td>false</td></tr><tr><td><code>reviewer</code></td><td>string</td><td>Filter by reviewer email, or <code>"unassigned"</code>.</td><td>false</td></tr><tr><td><code>status</code></td><td>string</td><td><code>"all"</code>, <code>"not_started"</code>, or <code>"in_progress"</code>.</td><td>false</td></tr><tr><td><code>sortBy</code></td><td>string</td><td><code>"created"</code>, <code>"images"</code>, or <code>"progress"</code>.</td><td>false</td></tr><tr><td><code>sortDirection</code></td><td>string</td><td><code>"asc"</code> or <code>"desc"</code>.</td><td>false</td></tr></tbody></table>

```bash
curl "https://api.roboflow.com/my-workspace/my-project/deploy/active-learning/images?api_key=$ROBOFLOW_API_KEY&page=1&pageSize=20"
```

**Response**

```json
{
  "activeLearningImages": {
    "totalImagesReadyForReview": 42,
    "reviewQueuePage": {
      "page": 1,
      "pageSize": 20,
      "totalItems": 42,
      "totalPages": 3,
      "items": [
        { "type": "batch", "id": "active_learning_2026-06-18" }
      ],
      "search": "",
      "status": "all",
      "sortBy": "created",
      "sortDirection": "desc",
      "reviewer": ""
    }
  }
}
```

## Legacy Endpoints

The previous Active Learning endpoints at `/:workspace/:project/active_learning` (GET and POST) are deprecated. They now return `Deprecation: true` and `Link` headers pointing to the new `deploy/active-learning` namespace. Migrate to the endpoints documented above.
