> 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/python-sdk/manage-annotation-workflow.md).

# Manage Annotation Workflow

`Project` exposes the annotation-pipeline primitives: list the upload batches, inspect annotation jobs, and create new jobs that assign images to a labeler and a reviewer.

## List image batches

Every uploaded set of images belongs to a batch. List a project's batches:

```python
import roboflow

rf = roboflow.Roboflow(api_key="YOUR_API_KEY")
project = rf.workspace().project("my-detector")

batches = project.get_batches()
for b in batches.get("batches", []):
    print(b["id"], b["name"], b["images"], "images")
```

Get a single batch's details:

```python
batch = project.get_batch("<batch-id>")
print(batch)
```

## List annotation jobs

```python
jobs = project.get_annotation_jobs()
for job in jobs.get("jobs", []):
    print(job["id"], job["name"], job["status"], job["annotated"], "/", job["numImages"])
```

Get a single job:

```python
job = project.get_annotation_job("<job-id>")
print(job)
```

## Create an annotation job

Assign images from a batch to a labeler (and a reviewer, if your workspace has Role-Based Access Control enabled):

```python
job = project.create_annotation_job(
    name="Round 1: indoor frames",
    batch_id="<batch-id>",
    num_images=100,
    labeler_email="labeler@company.com",
    reviewer_email="reviewer@company.com",
)
print(job["id"], job["status"])
```

### Parameters

* `name` (str) - display name for the job.
* `batch_id` (str) - id of the upload batch the images come from.
* `num_images` (int) - how many images from the batch to include in this job.
* `labeler_email` (str) - email of a workspace member who will draw the labels.
* `reviewer_email` (str) - email of a workspace member who will review. If RBAC isn't enabled, set this equal to the labeler.

## Save an annotation programmatically

When you have annotations from another source (an existing CVAT export, a model prediction you want to commit), use [`Project.save_annotation`](/developer/python-sdk/manage-images.md#attach-an-annotation-to-an-existing-image) to attach them directly to an image.

## REST and CLI equivalents

* REST: see [List Image Batches](/developer/rest-api/list-image-batches.md) and [Create and List Annotation Jobs](/developer/rest-api/create-and-list-annotation-jobs.md).
* CLI: see [Manage Annotation Workflow (CLI)](/developer/command-line-interface/manage-annotation-workflow.md).
