Sign in Get started

Models

List trained CV models in your organization and download their ONNX weights.

View as Markdown

Models are produced by training runs. The SDK doesn’t insert model rows directly - you train, then read.

Like datasets, models are unique by (organization, name). Every single-model method takes the name positionally or a model_id= keyword - exactly one - and both forms hit the same serializer, so the returned shape is identical. In REST the name goes straight in the path: /api/v1/developer/models/Stop%20Sign%20Detector, and a UUID is accepted in the same position.

Internal storage paths are never returned - fetch weights via download, which mints a short-lived signed URL.

list

Single-page list of models in your organization. Returns the collection envelope with a server-computed total and has_more.

Source: Models.list

Arg Type Default Notes
name str | None None Exact model name; prefer get to fetch one
dataset_name str | None None Restrict to models trained on this dataset
status ModelStatus | None None "training" / "ready" / "failed" / "archived"
model_type ModelType | None None "object_detection" / "instance_segmentation" / "semantic_segmentation" / "keypoint_detection" / "classification"
limit int 50 Server cap: 100
offset int 0 Page offset
models = client.models.list(
    limit=20,
)
for m in models:
    print(m.name, m.architecture, m.status, m.metrics)
pictograph models list --limit 20

The CLI command lists one page and takes no filters; use the SDK or REST for dataset_name / status / model_type / offset.

curl -s "https://api.pictograph.io/api/v1/developer/models/?limit=20" \
  -H "X-API-Key: $PICTOGRAPH_API_KEY"

Returns list[Model]

Model · 17 fields
class Model(BaseModel):
    """A trained computer vision model."""
    id: str
    organization_id: str
    name: str
    description: str | None = None
    model_type: Literal['object_detection', 'semantic_segmentation', 'instance_segmentation', 'classification', 'keypoint_detection']
    architecture: str | None = None
    visibility: Literal['private', 'public']
    status: Literal['training', 'ready', 'failed', 'archived']
    metrics: dict[str, Any] | None = None
    class_mapping: dict[str, Any] | None = None
    training_config: dict[str, Any] | None = None
    version: str = '1.0.0'
    parent_model_id: str | None = None
    forked_from_model_id: str | None = None
    precision: Literal['fp32', 'fp16'] = 'fp32'
    created_at: datetime
    updated_at: datetime

iter

Auto-paging iterator across every model in your organization. Pages are fetched lazily as you consume them, so a large registry never lands in memory at once.

Source: Models.iter

Arg Type Default Notes
dataset_name str | None None Restrict to models trained on this dataset
status ModelStatus | None None Same values as list
model_type ModelType | None None Same values as list
page_size int 50 Rows per underlying request
max_total int | None None Stop after this many models
for m in client.models.iter(page_size=50):
    print(m.id, m.model_type)

There is no CLI command for auto-paging; pictograph models list --limit 100 returns a single page.

# Page manually with limit + offset until fewer than `limit` rows return.
curl -s "https://api.pictograph.io/api/v1/developer/models/?limit=50&offset=0" \
  -H "X-API-Key: $PICTOGRAPH_API_KEY"
# The CLI does not auto-page; this is a single page.
pictograph models list --limit 100

Returns OffsetPager[Model]

Model · 17 fields
class Model(BaseModel):
    """A trained computer vision model."""
    id: str
    organization_id: str
    name: str
    description: str | None = None
    model_type: Literal['object_detection', 'semantic_segmentation', 'instance_segmentation', 'classification', 'keypoint_detection']
    architecture: str | None = None
    visibility: Literal['private', 'public']
    status: Literal['training', 'ready', 'failed', 'archived']
    metrics: dict[str, Any] | None = None
    class_mapping: dict[str, Any] | None = None
    training_config: dict[str, Any] | None = None
    version: str = '1.0.0'
    parent_model_id: str | None = None
    forked_from_model_id: str | None = None
    precision: Literal['fp32', 'fp16'] = 'fp32'
    created_at: datetime
    updated_at: datetime

get

Fetch a single model by name (or model_id= UUID).

Source: Models.get

Arg Type Default Notes
name str | None None Model name. Case-sensitive, unique within the org.
model_id str | None None Model UUID - the keyword alternative to name.
model = client.models.get(
    name="Stop Sign Detector",
)
print(model.architecture, model.metrics, model.class_mapping)
pictograph models get "Stop Sign Detector"
curl -s "https://api.pictograph.io/api/v1/developer/models/Stop%20Sign%20Detector" \
  -H "X-API-Key: $PICTOGRAPH_API_KEY"

Returns Model

Model · 17 fields
class Model(BaseModel):
    """A trained computer vision model."""
    id: str
    organization_id: str
    name: str
    description: str | None = None
    model_type: Literal['object_detection', 'semantic_segmentation', 'instance_segmentation', 'classification', 'keypoint_detection']
    architecture: str | None = None
    visibility: Literal['private', 'public']
    status: Literal['training', 'ready', 'failed', 'archived']
    metrics: dict[str, Any] | None = None
    class_mapping: dict[str, Any] | None = None
    training_config: dict[str, Any] | None = None
    version: str = '1.0.0'
    parent_model_id: str | None = None
    forked_from_model_id: str | None = None
    precision: Literal['fp32', 'fp16'] = 'fp32'
    created_at: datetime
    updated_at: datetime

Inspect metrics (mAP, precision, recall) and class_mapping (index to class name) for inference setup. The same path accepts a UUID, so /api/v1/developer/models/6f1c2f0e-6a1e-4a55-9f3a-2f2d3b4c5d6e resolves the same row.

update

Rename a model, edit its description or readme, set its license, or flip its visibility. Only the fields you pass change. Requires a member+ API key; changing visibility (publishing to Explore) requires admin+. A new_name that collides with another model in your organization is rejected with 400.

Source: Models.update

Arg Type Default Notes
name str | None None The model to update, addressed by name (positional).
model_id str | None None The model to update, addressed by UUID (keyword).
new_name str | None None A new name for the model (the field a rename sets - kept distinct from the name path argument).
description str | None None New description.
readme str | None None New markdown model card.
visibility Literal['private', 'public'] | None None "private" or "public" (admin+).
license_id str | None None A licenses catalog id, or "custom".
license_custom_text str | None None License body when license_id == "custom".
model = client.models.update(
    name="Stop Sign Detector",
    readme="# Stop Sign Detector\n\nTrained on road-signs v2.",
)
print(model.name, model.description)
pictograph models update "Stop Sign Detector" --description "road-signs v2"
curl -s -X PATCH "https://api.pictograph.io/api/v1/developer/models/Stop%20Sign%20Detector" \
  -H "X-API-Key: $PICTOGRAPH_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"readme": "# Stop Sign Detector"}'

Returns Model

Model · 17 fields
class Model(BaseModel):
    """A trained computer vision model."""
    id: str
    organization_id: str
    name: str
    description: str | None = None
    model_type: Literal['object_detection', 'semantic_segmentation', 'instance_segmentation', 'classification', 'keypoint_detection']
    architecture: str | None = None
    visibility: Literal['private', 'public']
    status: Literal['training', 'ready', 'failed', 'archived']
    metrics: dict[str, Any] | None = None
    class_mapping: dict[str, Any] | None = None
    training_config: dict[str, Any] | None = None
    version: str = '1.0.0'
    parent_model_id: str | None = None
    forked_from_model_id: str | None = None
    precision: Literal['fp32', 'fp16'] = 'fp32'
    created_at: datetime
    updated_at: datetime

To rename, the SDK keyword is new_name=, the CLI flag is --name, and the REST body field is name.

download

Stream the weights to a local file. Only status="ready" models are downloadable. format="onnx" (the default) serves the exported ONNX graph; pytorch and safetensors serve the native containers; pte and engine serve the derived ExecuTorch and TensorRT artifacts. A format the model does not publish is refused, never substituted.

Source: Models.download

Arg Type Default Notes
name str | None None Address by name (or pass model_id= instead)
output_path str | Path required Local destination
format "onnx" | "pytorch" | "safetensors" | "pte" | "engine" "onnx" Which artifact to fetch
precision "fp32" | "fp16" | None None Selects the artifact; a precision that was not built is a 404, never a substitution
target str | None None pte lowering backend, or the engine GPU architecture (required for engine)
from pathlib import Path

client.models.download(
    name="Stop Sign Detector",
    output_path=Path("./stop-sign-detector.onnx"),
)
pictograph models download "Stop Sign Detector" --output ./stop-sign-detector.onnx --format onnx

The CLI exposes --format only; use the SDK or REST when you need precision or target.

# Returns {"data": {"download_url": …, "expires_in_minutes": 60, …}}; fetch the weights from it.
curl -s "https://api.pictograph.io/api/v1/developer/models/Stop%20Sign%20Detector/download?format=onnx" \
  -H "X-API-Key: $PICTOGRAPH_API_KEY"

Returns Path

The SDK download is chunked and lands in a sibling .part file renamed atomically on success. Safe for multi-GB models.

fork

Import (fork) a public model into your organization. The model analog of forking a public dataset: the fork references the source model’s weights (no byte copy), so it is downloadable immediately and fast even for large models. The copy’s name is suffixed ("Name (2)") if a model of that name already exists. Requires member, admin, or owner role.

Source: Models.fork

Arg Type Default Notes
organization str required Slug of the organization that owns the source model.
model str required Slug or name of the source public model.
model = client.models.fork(
    organization="acme-vision",
    model="stop-sign-detector",
)
print(model.id, model.visibility, model.forked_from_model_id)
pictograph models fork acme-vision stop-sign-detector
curl -s -X POST "https://api.pictograph.io/api/v1/developer/models/acme-vision/stop-sign-detector/fork" \
  -H "X-API-Key: $PICTOGRAPH_API_KEY"

Model names are unique only within an organization, so all three surfaces address the source by its qualified public name, {organization}/{model} - the same pair the shareable model page uses. This is the one model call that deliberately reaches across organizations, which is why a bare name will not do.

Returns Model

Model · 17 fields
class Model(BaseModel):
    """A trained computer vision model."""
    id: str
    organization_id: str
    name: str
    description: str | None = None
    model_type: Literal['object_detection', 'semantic_segmentation', 'instance_segmentation', 'classification', 'keypoint_detection']
    architecture: str | None = None
    visibility: Literal['private', 'public']
    status: Literal['training', 'ready', 'failed', 'archived']
    metrics: dict[str, Any] | None = None
    class_mapping: dict[str, Any] | None = None
    training_config: dict[str, Any] | None = None
    version: str = '1.0.0'
    parent_model_id: str | None = None
    forked_from_model_id: str | None = None
    precision: Literal['fp32', 'fp16'] = 'fp32'
    created_at: datetime
    updated_at: datetime

delete

Delete a model by name (or model_id= UUID). Requires admin or owner role. The model disappears from the API immediately; its stored weights are reclaimed shortly afterwards.

Source: Models.delete

Arg Type Default Notes
name str | None None Model name (positional). Pass this or model_id.
model_id str | None None Model UUID - the keyword alternative to name.
client.models.delete(
    name="Stop Sign Detector",
)
pictograph models delete "Stop Sign Detector" --yes
curl -s -X DELETE "https://api.pictograph.io/api/v1/developer/models/Stop%20Sign%20Detector" \
  -H "X-API-Key: $PICTOGRAPH_API_KEY"

Returns None

bulk_delete

Delete many models in one atomic, org-scoped, server-side call - never fans out N requests. Idempotent: ids that don’t resolve in your organization are returned in not_found rather than raising. Requires admin or owner role.

Source: Models.bulk_delete

Arg Type Default Notes
model_ids Sequence[str] required Model UUIDs, up to 10,000 per call. Duplicates are ignored; ids that do not resolve in your organization are reported in not_found rather than raising, so a re-run of a completed delete still succeeds.
result = client.models.bulk_delete(
    model_ids=[
        "6f1c2f0e-6a1e-4a55-9f3a-2f2d3b4c5d6e",
        "7a2d3e1b-8c4f-4b66-9e2a-3f4d5c6b7a8e",
    ],
)
print(result.succeeded, result.not_found, result.count)
pictograph models delete \
  6f1c2f0e-6a1e-4a55-9f3a-2f2d3b4c5d6e \
  7a2d3e1b-8c4f-4b66-9e2a-3f4d5c6b7a8e --yes

pictograph models delete takes one model name or several UUIDs; passing more than one issues the same single bulk request.

curl -s -X POST "https://api.pictograph.io/api/v1/developer/models/bulk-delete" \
  -H "X-API-Key: $PICTOGRAPH_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"model_ids": ["6f1c2f0e-6a1e-4a55-9f3a-2f2d3b4c5d6e",
        "7a2d3e1b-8c4f-4b66-9e2a-3f4d5c6b7a8e"]}'

Returns BulkDeleteResult

BulkDeleteResult · 3 fields
class BulkDeleteResult(BaseModel):
    """Result of a server-side bulk delete (one chunked, org-scoped call)."""
    succeeded: list[str] = []
    not_found: list[str] = []
    count: int = 0

The REST response is {"data": {"succeeded": [...], "not_found": [...], "count": N}}.

Status lifecycle

status Meaning
training Training is in progress; download returns an error until ready.
ready Trained successfully; weights downloadable via download().
failed Training stopped with an error. Inspect the source TrainingRun.error_message.
archived Retired. Hidden from list() unless you pass status="archived". Distinct from delete, which removes it.

versions

A model keeps every version it has been trained to. versions lists them with the resolved is_current flag - the owner-promoted pin first, else the newest ready version.

Source: Models.versions

Arg Type Default Notes
name str | None None Model name (positional). Pass this or model_id.
model_id str | None None Model UUID - the keyword alternative to name.
payload = client.models.versions(
    name="Stop Sign Detector",
)
for v in payload.versions:
    print(v.version_number, v.status, v.precision, v.is_current, v.metrics)

There is no CLI command for versions.

curl -s "https://api.pictograph.io/api/v1/developer/models/Stop%20Sign%20Detector/versions" \
  -H "X-API-Key: $PICTOGRAPH_API_KEY"

set_current_version pins which version the model serves everywhere - downloads, deployment provisioning, auto-annotate selection - and the pin survives later retrains, which is what makes rollback real. Pass version_id=None to clear it. Requires admin+.

client.models.set_current_version(
    name="Stop Sign Detector",
    version_id="9d2e4a7b-1c3f-4e58-8a6d-0b1c2d3e4f5a",
)
curl -s -X PATCH "https://api.pictograph.io/api/v1/developer/models/Stop%20Sign%20Detector/current-version" \
  -H "X-API-Key: $PICTOGRAPH_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"version_id": "9d2e4a7b-1c3f-4e58-8a6d-0b1c2d3e4f5a"}'
# No versions command; the SDK and REST expose the version list.
pictograph models get "Stop Sign Detector"

Returns ModelVersionsPayload

ModelVersionsPayload · 4 fields
class ModelVersionsPayload(BaseModel):
    """`models.versions` - the version list plus promote state."""
    versions: list[ModelVersionEntry] = []
    current_version_id: str | None = None
    pinned_version_id: str | None = None
    latest_version_id: str | None = None

files

Every version’s downloadable artifacts in one manifest: weights, the immutable config.json reproducibility artifact, and the generated LICENSE.md and README.md.

Source: Models.files

Arg Type Default Notes
name str | None None Model name (positional). Pass this or model_id.
model_id str | None None Model UUID - the keyword alternative to name.
manifest = client.models.files(
    name="Stop Sign Detector",
)
for f in manifest.files:
    print(f.name, f.runtime, f.precision, f.target_key, f.size_bytes, f.stale)

There is no CLI command for the file manifest.

curl -s "https://api.pictograph.io/api/v1/developer/models/Stop%20Sign%20Detector/files" \
  -H "X-API-Key: $PICTOGRAPH_API_KEY"

download_file pulls a single named file out of a version.

client.models.download_file(
    name="Stop Sign Detector",
    file_name="config.json",
    output_path="./config.json",
)
# No files command; download picks the artifact by --format.
pictograph models download "Stop Sign Detector" -o model.onnx --format onnx

Returns ModelFileManifest

ModelFileManifest · 3 fields
class ModelFileManifest(BaseModel):
    """A model's complete version + file manifest (`models.files`)."""
    versions: list[ModelVersionEntry] = []
    files: list[ModelFileEntry] = []
    pinned_version_id: str | None = None

A file’s stale flag means the toolchain for that runtime has moved on. For onnx and pte that is advisory - they still load. For a TensorRT engine it is blocking: the plan will not deserialize, so rebuild rather than download it.

Inference

Three ways to run a trained model, lightest first.

Hosted test inference

predict runs ONE image on Pictograph’s hosted inference service. It is free on every tier - no compute credits are charged - and needs a member+ key. It shares a daily capacity ceiling with the in-app tester and answers 429 with a Retry-After header when that ceiling is reached.

For batch work use a workflow or a deployment; for offline work, a local runtime below.

Local runtimes

The same trained weights are published in every executable form. All of them return the same task class and the same typed result, so switching runtime is a one-word change. Full guide: Local inference.

from pictograph import get_model, DetectionModel, DetectionResult

model: DetectionModel = get_model(name="Stop Sign Detector", task="object_detection")
result: DetectionResult = model.predict(
    image="street.jpg",
)   # path, URL, bytes, ndarray, PIL
for p in result.predictions:
    print(p.name, round(p.confidence, 3), p.bounding_box)

You select a weight format=; the runtime follows from it. There is no runtime= argument.

format= Artifact Runtime Install
onnx (default) .onnx onnxruntime pip install 'pictograph[inference]'
pytorch .pth pytorch pip install 'pictograph[inference]'
safetensors model.safetensors pytorch pip install 'pictograph[inference]'
pytorch_engine .pte executorch pip install 'pictograph[inference,executorch]'
tensorrt_engine .engine tensorrt pip install 'pictograph[inference,tensorrt]'

The CLI runs the same local path:

pictograph models predict "Stop Sign Detector" street.jpg --confidence 0.4

A client-bound equivalent exists too - client.models.load(...), which takes the same format=. pictograph.load_model(weights, config) is the fully offline twin: no API key, and the runtime is inferred from the weights suffix.

A .engine is not portable. A TensorRT plan is compiled for one GPU architecture, one TensorRT version and one precision, and fails at load anywhere else. get_model(format="tensorrt_engine") therefore defaults to fetching the engine built for your GPU.

Bring your own runtime

Download the artifact and drive it yourself:

import onnxruntime as ort

client.models.download(
    name="Stop Sign Detector",
    output_path="./stop-sign-detector.onnx",
)
session = ort.InferenceSession("./stop-sign-detector.onnx")

For managed batch inference, run the model through a workflow (loads weights per run, no deployment needed), or stand up an always-on deployment.

Evaluation

client.model_evaluations scores a trained detection or instance-segmentation model against an export’s ground truth - per-class and overall precision, recall and F1 plus a confusion matrix - running the inference for you server-side. An export is a curated, defined eval set: its recorded images and class filter control exactly what’s scored, and it aligns evaluation with training (which also runs off exports). Your ground-truth annotations are never modified. For a purely offline scoring pass over predictions you already have, use pictograph.metrics.

# One call: create the run and block until it completes.
ev = client.model_evaluations.evaluate(
    model="Swift Falcon",
    dataset_name="road-signs",
    export_name="v1",
    iou_threshold=0.5,
    confidence_threshold=0.5,
)

print(ev.overall_metrics.precision, ev.overall_metrics.recall, ev.overall_metrics.f1)
for c in ev.per_class_metrics or []:
    print(c.class_name, c.precision, c.recall, c.support)

# The confusion matrix (rows = ground truth, cols = predicted; the last row and
# column are `__background__` for false positives and false negatives).
cm = ev.confusion_matrix
print(cm.labels)
print(cm.grid)

Prefer to start it and poll later? Use the lower-level methods:

ev = client.model_evaluations.create(
    model="Swift Falcon",
    dataset_name="road-signs",
    export_name="v1",
)
ev = client.model_evaluations.wait_for_completion(
    evaluation_id=ev.id,
)
for past in client.model_evaluations.list(model="Swift Falcon"):
    print(past.id, past.status)
client.model_evaluations.cancel(
    evaluation_id=ev.id,
)

Evaluation runs on the trained-model batch-inference path and is billed the same way. An AsyncClient mirror is available at client.model_evaluations too. Only detection and instance-segmentation models are supported; other model types return a ValidationError.

Every method, its arguments, and the REST equivalents are on the Model evaluations page.

download_file

Download ONE manifest artifact by its name (see files).

Source: Models.download_file

Arg Type Default Notes
name str | None None The model, addressed by name (positional).
model_id str | None None The model, addressed by UUID (keyword).
file_name str required The manifest row’s name (e.g. "config.json").
version str | int | None None Which version to take the file from - a version label ("2.0.0"), a version number (2), or a version_id from a prior files call (used as-is, no extra request). None (default) resolves to the model’s current version.
output_path str | Path required Local destination. Parent dirs created.
chunk_size int 8388608 Streaming chunk size (default 8 MB).
progress Callable[[int, int], None] | None None Optional (bytes_so_far, total_bytes) callback for streamed artifacts.
path = client.models.download_file(
    name="Swift Falcon",
    file_name="model.onnx",
    output_path="./model.onnx",
)
print(path)
# No `download-file` command - `download` picks the artifact by --format.
pictograph models download "Stop Sign Detector" -o model.onnx --format onnx
# List the manifest, then fetch the row's signed download_url.
curl -s "https://api.pictograph.io/api/v1/developer/models/Stop%20Sign%20Detector/files" \
  -H "X-API-Key: $PICTOGRAPH_API_KEY"

Returns Path

The local path written. Streamed in chunks into a sibling .part file, renamed atomically on success.

get_by_name

Fetch a model by its name (org-unique) OR its id - whichever you have.

Source: Models.get_by_name

Arg Type Default Notes
model str required Model name or id.
model = client.models.get_by_name(
    model="Swift Falcon",
)
print(model.id, model.model_type, model.status)
# `get` already addresses a model by name.
pictograph models get "Stop Sign Detector"
curl -s "https://api.pictograph.io/api/v1/developer/models/Stop%20Sign%20Detector" \
  -H "X-API-Key: $PICTOGRAPH_API_KEY"

Returns Model

Model · 17 fields
class Model(BaseModel):
    """A trained computer vision model."""
    id: str
    organization_id: str
    name: str
    description: str | None = None
    model_type: Literal['object_detection', 'semantic_segmentation', 'instance_segmentation', 'classification', 'keypoint_detection']
    architecture: str | None = None
    visibility: Literal['private', 'public']
    status: Literal['training', 'ready', 'failed', 'archived']
    metrics: dict[str, Any] | None = None
    class_mapping: dict[str, Any] | None = None
    training_config: dict[str, Any] | None = None
    version: str = '1.0.0'
    parent_model_id: str | None = None
    forked_from_model_id: str | None = None
    precision: Literal['fp32', 'fp16'] = 'fp32'
    created_at: datetime
    updated_at: datetime

load

Load a name for LOCAL inference, using this client’s auth.

Source: Models.load

Arg Type Default Notes
name str required The model to load, by name.
task TaskName | None None Narrows the returned model + result type. None reads the task from the model record.
format WeightFormat 'onnx' Which weights to fetch: onnx, pytorch, safetensors, pytorch_engine or tensorrt_engine. The runtime follows from it.
precision Literal['fp32', 'fp16'] | None None Weight precision to fetch. None takes whatever the model was published at.
target str | None None Which binding to fetch. For tensorrt_engine the GPU architecture (sm75…), defaulting to this machine’s; for pytorch_engine the lowering backend, defaulting to xnnpack.
confidence float 0.5 Minimum score for predict, 0-1.
device Device 'auto' Which hardware to run on: auto (default), cpu, cuda (or cuda:1) or mps. Same values on every format.
cache_dir str | Path | None None Where downloaded artifacts are cached. None uses the SDK’s default cache.
detector = client.models.load(
    name="Swift Falcon",
    format="onnx",
    confidence=0.4,
)
result = detector.predict("photo.jpg")
# `load` returns an in-process model object; download the weights instead.
pictograph models download "Stop Sign Detector" -o model.onnx
# `load` returns an in-process model object - there is no REST endpoint.

Returns AnyModel

AnyModel
AnyModel = DetectionModel | InstanceSegmentationModel | SemanticSegmentationModel | KeypointModel | ClassificationModel

predict

Run ONE image through the model on Pictograph’s GPU service.

Source: Models.predict

Arg Type Default Notes
name str required The model’s name, unique within your organization.
image str | Path | bytes required Path to an image file, or raw image bytes.
confidence float 0.5 Minimum score for returned predictions (0.05-0.95).
top_k int 3 For classification models, how many predictions to return.
result = client.models.predict(
    name="Swift Falcon",
    image="photo.jpg",
    confidence=0.4,
)
for annotation in result.annotations:
    print(annotation.name, round(annotation.confidence, 2))
pictograph models predict "Stop Sign Detector" street.jpg
curl -s -X POST "https://api.pictograph.io/api/v1/developer/models/Stop%20Sign%20Detector/predict?confidence_threshold=0.5&top_k=3" \
  -H "X-API-Key: $PICTOGRAPH_API_KEY"\
  -F "file=@street.jpg"

Returns ModelPredictResult

ModelPredictResult · 6 fields
class ModelPredictResult(BaseModel):
    """Result of a remote single-image test inference (`models.predict`)."""
    success: bool = True
    annotations: list[dict[str, Any]] = []
    tags: list[str] = []
    tag_scores: list[float] = []
    model_type: Optional[Literal['object_detection', 'semantic_segmentation', 'instance_segmentation', 'classification', 'keypoint_detection']] = None
    inference_seconds: float = 0.0

set_current_version

Promote / roll back: pin the model to one of its READY versions.

Source: Models.set_current_version

Arg Type Default Notes
name str | None None Model name. Pass this or model_id.
model_id str | None None Model id. Pass this or name.
version_id str | None required Version to make current.
versions = client.models.set_current_version(
    name="Swift Falcon",
    version_id="3f8a1c22-7d40-4b91-a2e5-6c9b0d1e2f34",
)
print(versions.current_version_id)
# No version command; use the SDK or REST below.
pictograph models get "Stop Sign Detector"
curl -s -X PATCH "https://api.pictograph.io/api/v1/developer/models/Stop%20Sign%20Detector" \
  -H "X-API-Key: $PICTOGRAPH_API_KEY" -H "Content-Type: application/json" \
  -d '{"current_version_id": "6f1c2f0e-6a1e-4a55-9f3a-2f2d3b4c5d6e"}'

Returns ModelVersionsPayload

ModelVersionsPayload · 4 fields
class ModelVersionsPayload(BaseModel):
    """`models.versions` - the version list plus promote state."""
    versions: list[ModelVersionEntry] = []
    current_version_id: str | None = None
    pinned_version_id: str | None = None
    latest_version_id: str | None = None

Common errors

Status Exception Cause
404 NotFoundError Name or model_id missing, or belongs to another organization; or the fork source is not a ready public model
409 ConflictError The requested format was not published for this model, or format="engine" without a target
400 ValidationError download on a non-ready model; or update(new_name=…) collides with an existing model
403 ForbiddenError update, fork and predict require member+; update(visibility=…), set_current_version, delete and bulk_delete require admin+
429 RateLimitError Hosted predict is at its shared daily capacity; retry after the Retry-After interval
Copied to clipboard