Sign in Get started

Batch

Bulk move, copy, delete, and update across many images in one round-trip.

View as Markdown

Bulk image operations on one dataset. Every call takes a dataset_name plus a list of image IDs (1 to 10,000) and returns a BatchResult: partial success does not raise. Reorganizing 10,000 images is one round-trip instead of 10,000 single-image calls, and the work runs server-side as single statements rather than a loop.

There is no pictograph CLI group for batch - use the SDK or REST below. SDK source: resources/batch.py. All four operations require member+ role; delete(permanent=True) requires admin+.

move

Move images to a different virtual directory. Directory structure is metadata: the stored image bytes never move. A filename that already exists in the target is auto-suffixed (photo.pngphoto-1.png) and counted in renamed rather than failing the batch.

Source: Batch.move

Arg Type Default Notes
dataset_name str required Dataset name.
image_ids Sequence[str] required Image UUIDs (1 to 10,000)
target_directory_path str "/" Destination virtual directory
result = client.batch.move(
    dataset_name="my-dataset",
    image_ids=["a1b2c3d4-5e6f-4708-9a1b-2c3d4e5f6a7b"],
    target_directory_path="/sorted/cars",
)
print(result.processed, result.renamed, result.failed)
curl -s -X POST "https://api.pictograph.io/api/v1/developer/batch/images/move" \
  -H "X-API-Key: $PICTOGRAPH_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"dataset_name": "my-dataset", "image_ids": ["a1b2c3d4-5e6f-4708-9a1b-2c3d4e5f6a7b"], "target_directory_path": "/sorted/cars"}'

Returns BatchResult

BatchResult · 6 fields
class BatchResult(BaseModel):
    """Outcome of a batch operation."""
    success: bool
    processed: int
    failed: list[BatchFailure] = []
    affected_directories: list[str] = []
    renamed: int = 0
    operation: str | None = None

copy

Copy images to a different directory. The underlying bytes are copied server-side - instant, no data transfer - and new image rows point at the copies.

Source: Batch.copy

Arg Type Default Notes
dataset_name str required Dataset name.
image_ids Sequence[str] required Image ids to act on.
target_directory_path str "/" Destination virtual directory
duplicate_handling "rename" | "skip" | "overwrite" "rename" skip records the source as failed; overwrite deletes the existing image first
copy_annotations bool False When True, copy annotations and status too
result = client.batch.copy(
    dataset_name="my-dataset",
    image_ids=["a1b2c3d4-5e6f-4708-9a1b-2c3d4e5f6a7b"],
    target_directory_path="/cars-copy",
    duplicate_handling="rename",
    copy_annotations=True,
)
print(result.processed, result.failed)
curl -s -X POST "https://api.pictograph.io/api/v1/developer/batch/images/copy" \
  -H "X-API-Key: $PICTOGRAPH_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"dataset_name": "my-dataset", "image_ids": ["a1b2c3d4-5e6f-4708-9a1b-2c3d4e5f6a7b"], "target_directory_path": "/cars-copy", "duplicate_handling": "rename", "copy_annotations": true}'

Returns BatchResult

BatchResult · 6 fields
class BatchResult(BaseModel):
    """Outcome of a batch operation."""
    success: bool
    processed: int
    failed: list[BatchFailure] = []
    affected_directories: list[str] = []
    renamed: int = 0
    operation: str | None = None

delete

Soft-archive by default: images move to the Archive tab and stay in storage, restorable with update(is_archived=False). permanent=True purges the stored bytes plus cached thumbnails, is irreversible, and requires admin+ role. Check result.operation ("archived" or "deleted") to confirm which one happened.

Source: Batch.delete

Arg Type Default Notes
dataset_name str required Dataset name.
image_ids Sequence[str] required Image UUIDs to delete.
permanent bool False When True, hard delete. Requires admin/owner role. Defaults to False (soft archive).
result = client.batch.delete(
    dataset_name="my-dataset",
    image_ids=["a1b2c3d4-5e6f-4708-9a1b-2c3d4e5f6a7b"],
    permanent=False,
)
print(result.operation, result.processed, result.failed)
curl -s -X POST "https://api.pictograph.io/api/v1/developer/batch/images/delete" \
  -H "X-API-Key: $PICTOGRAPH_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"dataset_name": "my-dataset", "image_ids": ["a1b2c3d4-5e6f-4708-9a1b-2c3d4e5f6a7b"], "permanent": false}'

Returns BatchResult

BatchResult · 6 fields
class BatchResult(BaseModel):
    """Outcome of a batch operation."""
    success: bool
    processed: int
    failed: list[BatchFailure] = []
    affected_directories: list[str] = []
    renamed: int = 0
    operation: str | None = None

update

Update metadata on a batch of images. Pass exactly the fields you want to change; None is omitted from the request, and the SDK raises ValueError if every field is None. Note this is a PATCH, and the fields are nested under updates on the wire.

Source: Batch.update

Arg Type Default Notes
dataset_name str required Dataset name.
image_ids Sequence[str] required Image ids to act on.
status str | None None "new", "annotate", "review", "complete"
display_name str | None None Display override; the raw filename is unchanged
is_archived bool | None None True archives, False restores
result = client.batch.update(
    dataset_name="my-dataset",
    image_ids=["a1b2c3d4-5e6f-4708-9a1b-2c3d4e5f6a7b"],
    status="complete",
    is_archived=False,
)
print(result.processed, result.failed)
curl -s -X PATCH "https://api.pictograph.io/api/v1/developer/batch/images/update" \
  -H "X-API-Key: $PICTOGRAPH_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"dataset_name": "my-dataset", "image_ids": ["a1b2c3d4-5e6f-4708-9a1b-2c3d4e5f6a7b"], "updates": {"status": "complete", "is_archived": false}}'

Returns BatchResult

BatchResult · 6 fields
class BatchResult(BaseModel):
    """Outcome of a batch operation."""
    success: bool
    processed: int
    failed: list[BatchFailure] = []
    affected_directories: list[str] = []
    renamed: int = 0
    operation: str | None = None

BatchResult

Attribute Type Notes
success bool Whether the call completed
processed int Count of images the operation landed for
failed list[BatchFailure] {id, reason} per failed image - retry this subset
affected_directories list[str] Virtual directories touched
renamed int Filenames auto-suffixed on move; 0 elsewhere
operation str | None On delete: "archived" or "deleted"

Common errors

Status Exception Cause
403 ForbiddenError permanent=True needs admin+; all writes need member+
404 NotFoundError Dataset missing, or no matching image_id
400 / 422 ValidationError Invalid field value or empty update
Copied to clipboard