Before you start
You need:- Label version history enabled for your projects. Contact your Labelbox team to enable label version history. Versions are recorded from then on: there are none from before it was enabled.
- Permission to read the project’s labels. See Who can read versions.
- For the Python examples, Python SDK version 7.16.0 or later.
What is recorded
A version is recorded for each label at each of these hand-offs:
A review decision on single labels records a version of each label it names. A decision on the whole data row, a rework submit, and a move into a rework step record a version of every label on the data row.
Each version holds the label’s annotations as they were committed by that hand-off, with the feature names in effect then. A reviewer who edits a label and then approves it records two versions:
SAVED, then APPROVED. If the decision is recorded while the reviewer’s save is still being committed, the decision’s version can show the annotations from before that save. The save is then the next version.
What is not recorded
- Autosaves and drafts. Only the hand-offs above record a version. Edits in the editor that were not saved, and skipped data rows, record none.
- Earlier history. Nothing from before label version history was enabled for the project.
- Other changes to labels. Labels imported through the SDK or API, and reviews of tasks outside the label editor, such as external tasks, record no version.
- Very large labels. A label whose annotations take more than 64 MB, or more than 16 MB compressed, is not recorded. Recording never holds up the hand-off: if a version cannot be recorded, the hand-off goes ahead without it.
Who can read versions
You can read the versions of the labels you can read in the project, as for the project’s labels:- Without permission to view other users’ labels, you see only the versions of labels you created.
- In another organization’s project, without permission to view all labels, you see only the versions of labels your organization’s members created.
- Otherwise, you see the versions of all the project’s labels.
Read versions with the Python SDK
List one label’s versions, oldest first:Python
version.label_json holds the annotations at that moment. For a Label you already have, such as one from project.labels(), label.versions() lists the same versions. List the versions of a whole project, filtered by data row, user, or time:
Python
Project.label_versions() takes these parameters, all optional:
Label.versions() and Client.get_label_version() take include_annotations too. Client.get_label_version() returns None when the version does not exist or you cannot read its label.
The SDK raises ValueError, before sending anything, for a page_size outside 1 to 100 or a created_after that is not before created_before. It raises lbox.exceptions.AuthorizationError when you cannot read the project’s labels.
Version fields
Because
label has the same shape as Label.label, you can compare a version with the label as it is now, or with the version before it, using the same code.
Read versions with the GraphQL API
ThelabelVersions query lists a project’s versions, oldest first:
GraphQL
https://api.labelbox.com/graphql with your API key as a bearer token. where takes projectId, which is required, and optionally labelId, dataRowId, createdById, createdAfter (included), and createdBefore (excluded). first is the page size, from 1 to 100, and 100 by default.
To read the next page, send the same query again with after set to the previous page’s nextCursor, until nextCursor is null. A cursor only continues the query it came from: with other filters, another project, or another organization it is refused.
labelVersion(where: { id: "<VERSION_ID>" }) returns one version, or null when it does not exist or you cannot read its label.
Reading recent versions
Versions are listed in the order they were recorded. A version is listed once its hand-off has committed, so a hand-off still committing can appear a moment later with an earliercreatedAt. To read new versions as they come, read up to a time at least a minute in the past with createdBefore, and start the next read from there with createdAfter.
Labelbox MCP server
Through the Labelbox MCP server, an AI assistant can audit a label’s history for you:list_label_versionslists a project’s versions, oldest first, with the same filters as the API:labelId,dataRowId,createdById,createdAfter, andcreatedBefore. It returns the versions’ metadata, not their annotations.get_label_versionreads one version, with a summary of its annotations at that moment: their names and text answers, for up to 200 annotations. It never returns geometry, masks, or the full label. Read those with the SDK or the API.
labelbox://guides/label-history guide shows the assistant how to find a label, page its versions, and compare them. Ask, for example: