Schema and assets
After you can connect, the next step is usually: understand your labels, then work with assets.
Assume you already have a project from Install and connect.
Label schema
Section titled “Label schema”Why schemas matter
Section titled “Why schemas matter”Every annotation and prediction needs a label_id. If you train or predict with the wrong IDs, labels will not match what annotators see in the UI.
Read the schema
Section titled “Read the schema”schema = project.schema.get()
# Convenient normalized classes:classes = schema["definition"]["classes"]# Each class typically includes name, color, options, …
# Raw API rows (include UUIDs you need for label_id):rows = schema["schemas"]for row in rows: print(row["id"], row.get("name"))What this does: fetches the project’s label definitions and returns both a normalized view and the raw list.
Expected output: a dict with project_id, schemas, and definition.classes.
Create label classes
Section titled “Create label classes”created = project.schema.create( definition={ "classes": [ {"name": "person", "color": "#FF5500"}, {"name": "car", "color": "#00AAFF"}, {"name": "bicycle", "color": "#33CC66"}, ] })Why create via SDK: useful for bootstrapping new projects from CI or notebooks. You can also create labels in the web UI under the project’s Labels area.
Project statistics
Section titled “Project statistics”stats = project.get_statistics()# { "total_assets": …, "status_counts": { … } }Useful as a quick health check before training.
List assets
Section titled “List assets”assets = project.assets.list(limit=20, offset=0)
for asset in assets: print(asset.id, asset.status, asset.asset_type)Filter assets
Section titled “Filter assets”assets = project.assets.list( status="APPROVED", is_in_dataset=True, created_after="2026-03-25", # ISO date or datetime string)Common filters supported by the SDK include:
status,asset_type,is_in_datasetassigned_to,assigned_reviewer,for_reviewcreated_after,label_ids,sort,searchhas_annotation,have_comment- Pagination:
limit/offsetorpage/page_size
Get one asset and download it
Section titled “Get one asset and download it”one = project.assets.get("uuid-of-asset")print(one.storage_url, one.metadata)
# Stream bytes to a local pathpath = one.download("photo.jpg")
# Optional: derive a filename from metadata when available# from pathlib import Path# path = one.download(Path("downloads") / one.suggested_filename())What download does: fetches the asset via a presigned URL (a separate HTTP client without your API Authorization header) and writes the file to disk.
Batch download
Section titled “Batch download”results = project.assets.download_batch( output_dir="./downloads", max_workers=4, page_size=50, filter=lambda a: a.status == "APPROVED",)
for item in results: if "error" in item: print("failed", item["asset_id"], item["error"]) else: print("ok", item["asset_id"], item["file_path"])Why batch download: dataset export for local training experiments or QA without clicking through the UI.
Next step
Section titled “Next step”Register models and send predictions: Models and predictions.
