---
title: Tasks
description: Annotation tasks and the per-annotator contribution breakdown - who annotated how many images, active editing time, and annotations authored - exportable for audit and billing.
section: API Reference
order: 18.5
---
A task assigns a frozen set of a dataset's images to one or more org members for
annotation or review. This resource is read-only: enumerate the organization's
tasks and export a task's per-annotator contribution breakdown - the same
aggregate the app's task modal shows, so the app and the API never diverge on the
numbers.

The contribution breakdown is what makes annotation work auditable outside the
browser. For each contributor you get the distinct images they worked, their
measured active editing time, the images they last-saved to completion, and the
annotations they authored, plus rollup totals for the whole task.

The feed is scoped to the API key's organization. A task has no unique name (two
tasks can share a title), so it is addressed by its id.

## list

One page of the organization's tasks, newest first.

Source: [`Tasks.list`](https://github.com/pictograph-io/pictograph-sdk/blob/v1.69.67/src/pictograph/resources/tasks.py)

| Arg | Type | Default | Notes |
|---|---|---|---|
| `limit` | `int` | `50` | Page size, maximum 100 |
| `offset` | `int` | `0` | Offset for manual paging |

```python
for task in client.tasks.list(limit=25):
    print(task.title, task.status, f"{task.image_count} images", f"{task.assignee_count} assignees")
```

```bash
pictograph tasks list --limit 25
```

```bash
curl -s "https://api.pictograph.io/api/v1/developer/tasks?limit=25&offset=0" \
  -H "X-API-Key: $PICTOGRAPH_API_KEY"
```

**Returns** `list[Task]`

<details>
<summary><code>Task</code> &middot; 9 fields</summary>

```python
class Task(BaseModel):
    """One annotation task in the organization (list item)."""
    id: str
    dataset_id: str
    dataset: str | None = None
    title: str
    kind: str
    status: str
    created_at: datetime
    image_count: int
    assignee_count: int
```

</details>

## iter

Auto-paging iterator over every task in the organization. Stops on the
server-computed `pagination.has_more` flag, so you never manage offsets by hand.

Source: [`Tasks.iter`](https://github.com/pictograph-io/pictograph-sdk/blob/v1.69.67/src/pictograph/resources/tasks.py)

| Arg | Type | Default | Notes |
|---|---|---|---|
| `page_size` | `int` | `100` | Items per round-trip |
| `max_total` | `int \| None` | `None` | Stop after this many items |

```python
for task in client.tasks.iter(page_size=100):
    print(task.id, task.title)
```

```bash
# The CLI auto-pages with --all.
pictograph tasks list --all --max-total 500
```

```bash
# Page manually with limit + offset until pagination.has_more is false.
curl -s "https://api.pictograph.io/api/v1/developer/tasks?limit=100&offset=100" \
  -H "X-API-Key: $PICTOGRAPH_API_KEY"
```

**Returns** `OffsetPager[Task]`

<details>
<summary><code>Task</code> &middot; 9 fields</summary>

```python
class Task(BaseModel):
    """One annotation task in the organization (list item)."""
    id: str
    dataset_id: str
    dataset: str | None = None
    title: str
    kind: str
    status: str
    created_at: datetime
    image_count: int
    assignee_count: int
```

</details>

## contributions

The per-annotator contribution breakdown for one task: who contributed, how many
images each, active editing time each, and the annotations they authored, against
the task total.

Source: [`Tasks.contributions`](https://github.com/pictograph-io/pictograph-sdk/blob/v1.69.67/src/pictograph/resources/tasks.py)

| Arg | Type | Default | Notes |
|---|---|---|---|
| `task_id` | `str` | required | Task id from `list` |

```python
breakdown = client.tasks.contributions(
    task_id="346b73d3-24d3-45bd-ae95-4da1fa4d9166",
)
print(breakdown.images_complete, "of", breakdown.total_images, "images complete")
for c in breakdown.contributors:
    print(c.full_name, c.images_worked, "images", f"{c.active_minutes:.1f}m", c.annotations_added, "annotations")
```

```bash
pictograph tasks contributions 346b73d3-24d3-45bd-ae95-4da1fa4d9166
```

```bash
curl -s "https://api.pictograph.io/api/v1/developer/tasks/346b73d3-24d3-45bd-ae95-4da1fa4d9166/contributions" \
  -H "X-API-Key: $PICTOGRAPH_API_KEY"
```

**Returns** `TaskContributions`

<details>
<summary><code>TaskContributions</code> &middot; 6 fields</summary>

```python
class TaskContributions(BaseModel):
    """Per-annotator contribution breakdown for a task, with rollup totals."""
    task_id: str
    contributors: list[TaskContribution]
    contributor_count: int
    total_images: int
    images_complete: int
    total_active_seconds: int
```

</details>

`active_seconds` and `images_worked` are exact, from per-image active-time
tracking. `images_completed` and `annotations_added` are last-writer attribution:
they credit the most recent saver of each image, since there is no per-shape
authorship record. Annotation work done before contribution tracking existed
cannot be backfilled, so a pre-instrumentation task reports zeros rather than a
confident wrong number.

## Common errors

| Status | Exception | Cause |
|---|---|---|
| 404 | `NotFoundError` | No task with that id in your organization |
| 429 | `RateLimitError` | Polling faster than your tier's request budget allows |