Manage Workflows

List, retrieve, create, and update the Workflows in a workspace through the REST API and Python SDK.

About

Roboflow Workflows are visual computer-vision pipelines you build in the web app and deploy as a hosted endpoint. This page covers the management surface - listing, retrieving, creating, and updating the Workflows in a workspace - through the REST API and Python SDK. To run a Workflow against an image or video stream, see the Workflows runtime docs.

HTTP API

Roboflow Workflows are visual computer-vision pipelines you can build in the web app and deploy as a hosted endpoint. The REST API exposes the management surface; for executing a workflow against an image or video stream, see Run a Model on an Image and the Workflows runtime docs.

api_key may be passed as a query parameter or in the request body. Required scopes are noted on each endpoint.

Project Base Workflows

Each Project has a base Workflow that backs its hosted model endpoint. Use these Project-scoped operations to read that Workflow or select the model used by its model step.

Get a Project Base Workflow

GET /:workspace/:project/deploy

Required scope: project:read

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

If the Project does not have a base Workflow, this request creates one. The response identifies the Project, its base Workflow, the selected model, its deployability, and its Active Learning state:

{
  "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": {
    "id": "rfdetr-medium",
    "kind": "pretrained",
    "displayName": "RF-DETR Medium",
    "modelId": "rfdetr-medium"
  },
  "deployability": {
    "status": "deployable",
    "modelWasConfigured": false,
    "selectedModelId": null,
    "selectionReason": null
  },
  "activeLearning": {
    "enabled": false,
    "collectionLimits": {
      "dataPercentage": 100,
      "minutelyUsageLimit": 10,
      "hourlyUsageLimit": 100,
      "dailyUsageLimit": 1000,
      "labelingBatchesRecreationFrequency": "daily",
      "usageQuotaName": "upload_quota_active_learning",
      "imageCompressionLevel": 95,
      "maxImageHeight": 1080,
      "maxImageWidth": 1920,
      "persistPredictions": true
    },
    "filters": []
  },
  "baseWorkflowWasCreated": false
}

model is null when no model is configured. deployability.status is "not_deployable" when the Workflow cannot serve inference. baseWorkflowWasCreated tells you whether this request created the base Workflow.

Select a Project Base Workflow Model

POST /:workspace/:project/deploy/model

Required scope: project:update

Set model.type to "model_id", "sam3", or "clip":

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"
    }
  }'

For "model_id", modelId is required. displayName and taskType are optional. For "sam3" and "clip", provide a non-empty classes array instead of modelId:

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

The response has the same shape as Get a Project Base Workflow. A 400 response means the model value is missing or invalid.

To enable data collection, set collection limits, or list images in the review queue, use the Active Learning HTTP API.

List Workflows

GET /:workspace/workflows

Lists all workflows in the workspace.

Query

NameTypeDescriptionRequired
api_keystringAPI key for the workspace.true

Example Request

curl "https://api.roboflow.com/my-workspace/workflows?api_key=$ROBOFLOW_API_KEY"

Response

{
  "workflows": [
    {
      "id": "wf_abc123",
      "name": "Slow webhooks",
      "url": "slow-webhooks",
      "createdAt": "2026-04-12T17:05:33.000Z"
    }
  ],
  "status": "ok"
}

Required scope: workflow:read.

Get a Workflow

GET /:workspace/workflows/:workflowUrl

Returns the workflow's specification, metadata, and (for non-public workflows) authorization status.

curl "https://api.roboflow.com/my-workspace/workflows/slow-webhooks?api_key=$ROBOFLOW_API_KEY"

Public workflows can be accessed without an api_key. Private workflows require the workflow:read scope.

List Workflow Versions

GET /:workspace/workflows/:workflowUrl/versions

curl "https://api.roboflow.com/my-workspace/workflows/slow-webhooks/versions?api_key=$ROBOFLOW_API_KEY"

Returns the versioned snapshots of the workflow specification.

Create a Workflow

POST /:workspace/createWorkflow

Headers

NameValue
Content-Typeapplication/json

Body

NameTypeDescriptionRequired
api_keystringWorkspace API key.true
namestringDisplay name.true
urlstringURL slug for the workflow.true
configstringJSON-encoded workflow specification (see note below).true
templatestringJSON-encoded template metadata. Pass "{}" if you don't have one.false

Note on config: the API expects the stored shape {"specification": {...}}. Passing a bare specification works through the SDK adapter, which auto-wraps it; for direct REST calls, wrap it yourself.

Example Request

curl -X POST "https://api.roboflow.com/my-workspace/createWorkflow" \
  -H 'Content-Type: application/json' \
  -d '{"api_key":"'$ROBOFLOW_API_KEY'","name":"My Workflow","url":"my-workflow","config":"{\"specification\":{\"version\":\"1.0\",\"inputs\":[],\"steps\":[],\"outputs\":[]}}"}'

You can also send the same fields as query parameters, but then template is required. Use the body for large specifications, since long URLs get cut off.

curl -X POST "https://api.roboflow.com/my-workspace/createWorkflow" \
  --get \
  --data-urlencode "api_key=$ROBOFLOW_API_KEY" \
  --data-urlencode "name=My Workflow" \
  --data-urlencode "url=my-workflow" \
  --data-urlencode 'config={"specification":{"version":"1.0","inputs":[],"steps":[],"outputs":[]}}' \
  --data-urlencode 'template={}'

Response

{
  "workflows": { "id": "wf_xyz789", "url": "my-workflow" },
  "status": "ok"
}

Required scope: workflow:create.

Update a Workflow

POST /:workspace/updateWorkflow

Headers

NameValue
Content-Typeapplication/json

Body

NameTypeDescriptionRequired
idstringWorkflow's internal ID.true
namestringDisplay name.true
urlstringURL slug.true
configstringJSON-encoded workflow specification (see note on Create).true
curl -X POST "https://api.roboflow.com/my-workspace/updateWorkflow?api_key=$ROBOFLOW_API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{"id":"wf_xyz789","name":"My Workflow","url":"my-workflow","config":"{\"specification\":{\"version\":\"1.0\",\"steps\":[]}}"}'

Required scope: workflow:update.

Fork a Workflow

POST /:workspace/forkWorkflow

Copy a workflow from another workspace into this one.

Body

NameTypeDescriptionRequired
source_workspacestringSlug of the workspace that owns the source workflow.true
source_workflowstringURL slug of the source workflow.true
namestringDisplay name for the fork. Defaults to source name.false
urlstringURL slug for the fork. Auto-generated if omitted.false
curl -X POST "https://api.roboflow.com/my-workspace/forkWorkflow?api_key=$ROBOFLOW_API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{"source_workspace":"other-workspace","source_workflow":"their-workflow","name":"My Fork","url":"my-fork"}'

Required scope: workflow:create.

Generate a Workflow Token

POST /:workspace/workflowToken

Generate a short-lived token suitable for executing a workflow from a public client (e.g. a browser).

curl -X POST "https://api.roboflow.com/my-workspace/workflowToken?api_key=$ROBOFLOW_API_KEY"

Delete (soft-delete) a Workflow

DELETE /:workspace/workflows/:workflowUrl

Moves the workflow to Trash. See Manage Trash for the response shape and restore flow.

Run a Workflow

Workflow execution lives at https://serverless.roboflow.com, not the management API. See Run a Model on an Image and the product docs on deploying a workflow.

Python SDK

Roboflow Workflows are visual computer-vision pipelines. The SDK exposes list / get / create directly on Workspace; update, fork, and delete live in the low-level rfapi adapter.

List workflows

import roboflow

rf = roboflow.Roboflow(api_key="YOUR_API_KEY")
workspace = rf.workspace()

workflows = workspace.list_workflows()
for w in workflows:
    print(w["id"], w["name"], w["url"])

Get a workflow

workflow = workspace.get_workflow("slow-webhooks")
print(workflow["specification"])

The url argument is the workflow's slug (visible in the web app's URL bar) - not its Firestore id.

Create a workflow

workflow = workspace.create_workflow(
    name="My Workflow",
    definition={
        "version": "1.0",
        "inputs": [...],
        "steps": [...],
        "outputs": [...],
    },
)
print(workflow["id"], workflow["url"])

Pass definition=None to create an empty workflow shell that you'll edit in the web app afterwards.

The SDK accepts either a bare specification dict ({"version": ..., "steps": ...}) or a wrapped one ({"specification": {...}}); it normalizes the wrapping for you and strips a UTF-8 BOM if present.

Update a workflow

Workspace doesn't expose update directly - use the low-level adapter:

from roboflow.adapters import rfapi

rfapi.update_workflow(
    api_key="YOUR_API_KEY",
    workspace_url=workspace.url,
    workflow_id=workflow["id"],
    workflow_name="My Workflow",
    workflow_url="my-workflow",
    config={"version": "1.0", "steps": [...]},
)

Fork a workflow

Copy a workflow from another workspace into your own. Useful for adopting a public template:

from roboflow.adapters import rfapi

forked = rfapi.fork_workflow(
    api_key="YOUR_API_KEY",
    workspace_url=workspace.url,
    source_workspace="other-workspace",
    source_workflow="their-workflow",
    name="My Fork",       # optional; defaults to the source name
    url="my-fork",        # optional; defaults to a generated slug
)

List workflow versions

versions = rfapi.list_workflow_versions(
    api_key="YOUR_API_KEY",
    workspace_url=workspace.url,
    workflow_url="my-workflow",
)

Delete (soft-delete) a workflow

rfapi.delete_workflow(api_key="YOUR_API_KEY", workspace_url=workspace.url, workflow_url="my-workflow")

This moves the workflow to the workspace Trash where it remains for 30 days before permanent cleanup. Restore via Workspace.restore_from_trash("workflow", id) - see Delete and Restore.

Run a workflow

Workflow execution lives in the Inference SDK and the Workflows runtime, not the roboflow package. From Python:

from inference_sdk import InferenceHTTPClient

client = InferenceHTTPClient(
    api_url="https://serverless.roboflow.com",
    api_key="YOUR_API_KEY",
)
result = client.run_workflow(
    workspace_name="my-workspace",
    workflow_id="my-workflow",
    images={"image": "photo.jpg"},
)

CLI

You can list, create, update, fork, and version workflows from the command line.

List Workflows

roboflow workflow list
roboflow workflow list --json

Get Workflow Details

roboflow workflow get my-workflow
roboflow workflow get my-workflow --json

Create a Workflow

roboflow workflow create --name "My Workflow"

With a JSON definition file:

roboflow workflow create --name "My Workflow" --definition workflow.json

Options

FlagDescription
--nameWorkflow name (required)
--definitionPath to JSON definition file
--descriptionWorkflow description

Update a Workflow

Update a workflow's definition:

roboflow workflow update my-workflow --definition updated.json

List Workflow Versions

roboflow workflow version list my-workflow
roboflow workflow version list my-workflow --json

Fork a Workflow

Fork a workflow from the current workspace:

roboflow workflow fork my-workflow

Fork from another workspace:

roboflow workflow fork other-workspace/their-workflow

JSON Output

All workflow commands support --json for structured output:

roboflow workflow list --json | jq '.[].name'
roboflow workflow create --name "Test" --json

Exit codes: 0 = success, 1 = error, 2 = auth error, 3 = not found.

MCP Server

Connect your AI agent to the MCP Server and it can build and run Workflows with these tools:

ToolDescription
workflows_listList saved Workflows in the workspace.
workflows_getGet details for a saved Workflow.
workflows_createCreate and save a new Workflow.
workflows_updateUpdate a saved Workflow's name and definition.
workflows_runExecute a saved Workflow on one or more images.
workflows_deleteDelete a saved Workflow, moving it to the workspace Trash.