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 a single dataset. Each call takes a dataset_name plus a list of image IDs and returns a BatchResult with a processed count and per-item failure context. Partial success does not raise. The backend caps each request at 100,000 images.

Every example below shows the Python SDK call and the equivalent raw REST request. The REST examples authenticate with an X-API-Key header; set PICTOGRAPH_API_KEY in your shell to copy-and-run them.

from pictograph import Client
client = Client()  # reads PICTOGRAPH_API_KEY

move

Move images to a different virtual folder within the same dataset. Storage paths are immutable: “move” updates virtual_folder_path; the underlying image bytes don’t move.

ArgTypeDefaultNotes
dataset_namestrrequiredProject name within your org
image_idsSequence[str]requiredImage UUIDs (1 to 100000)
target_folder_pathstr"/"Destination virtual folder
result = client.batch.move(
    dataset_name="my-dataset",
    image_ids=["img-1", "img-2", "img-3"],
    target_folder_path="/sorted/cars",
)
print(result.processed, 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": ["img-1", "img-2", "img-3"],
    "target_folder_path": "/sorted/cars"
  }'

Requires member+ role.

copy

Copy images to a different folder. Server-side copy of the underlying bytes (instant, zero data transfer); new project_images rows point at the copied blobs.

ArgTypeDefaultNotes
dataset_namestrrequired
image_idsSequence[str]required
target_folder_pathstr"/"Destination virtual folder
duplicate_handlingLiteral["rename", "skip", "overwrite"]"rename"How to handle filename collisions
copy_annotationsboolFalseWhen True, copy annotations_json and status too
result = client.batch.copy(
    dataset_name="my-dataset",
    image_ids=["img-1", "img-2"],
    target_folder_path="/cars-copy",
    duplicate_handling="rename",   # collision policy in the destination
    copy_annotations=False,        # destination images start without annotations
)
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": ["img-1", "img-2"],
    "target_folder_path": "/cars-copy",
    "duplicate_handling": "rename",
    "copy_annotations": false
  }'

Requires member+ role.

delete

Soft-archive by default; permanent on request. permanent=True purges the stored bytes plus cached thumbnails. This is irreversible and requires admin+ role.

ArgTypeDefaultNotes
dataset_namestrrequired
image_idsSequence[str]required
permanentboolFalseTrue hard-deletes from storage (admin+)
result = client.batch.delete(
    dataset_name="my-dataset",
    image_ids=["img-1", "img-2", "img-3"],
    permanent=False,                 # archive (recoverable)
)
print(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": ["img-1", "img-2", "img-3"],
    "permanent": false
  }'

update

Update metadata fields on a batch of images. Pass exactly the fields you want to change: None is omitted from the request. Note this is a PATCH, and the fields are nested under updates on the wire.

ArgTypeDefaultNotes
dataset_namestrrequired
image_idsSequence[str]required
statusstr | NoneNone"new", "annotate", "review", "complete"
display_namestr | NoneNoneDisplay override
is_archivedbool | NoneNoneTrue archives; False restores
result = client.batch.update(
    dataset_name="my-dataset",
    image_ids=["img-1", "img-2"],
    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": ["img-1", "img-2"],
    "updates": {"status": "complete", "is_archived": false}
  }'

The SDK raises ValidationError if every field is None (the update would be a no-op). Requires member+ role.

BatchResult

AttributeTypeNotes
successboolWhether the call completed
processedintCount of images the op landed for
failedlist[BatchFailure]{id, reason} per failed image
affected_folderslist[str]Virtual folders touched by the op

Errors

StatusExceptionCause
403ForbiddenErrorpermanent=True requires admin+ role; all writes require member+
404NotFoundErrorDataset missing, or no matching image_id
400 / 422ValidationErrorInvalid field value or empty update

Why batch over loops

Reorganizing 10K images is one round-trip with batch.move() versus 10K with images.update(). Bulk operations are implemented server-side as single statements, not loops.

Copied to clipboard