Sign in Get started

Deployments

Stand a trained model up as an always-on, per-organization inference endpoint, billed by uptime, and call it directly.

View as Markdown

A deployment turns a trained model into a live /predict endpoint you call directly over HTTP. Each deployment is its own isolated app with one authenticated URL. Billing is by uptime (the underlying GPU/CPU cost plus the platform markup), so you pause a deployment to stop charges and resume it to bring the endpoint back.

There are two authentication contexts, and they are deliberately separate:

  • Managing deployments (create, list, pause, resume, delete) goes through the Pictograph backend with your normal X-API-Key, shown in every example below.
  • Calling a deployment’s /predict endpoint uses a different, per-deployment bearer token (prefix pk_deploy_) that is returned once at create time — not your X-API-Key. See Calling your deployment.

Deployments require a paid tier (the model_deployment feature). Use the Workflows API instead if you only need batch inference over a dataset or video, since a workflow loads the model per run and needs no standing deployment.

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

Compute types

A deployment runs on one compute tier. min_containers=0 is scale-to-zero (you are billed only while the endpoint is actively serving, with a short cold start on the first request after idle); min_containers>=1 keeps that many containers always warm (lowest latency, billed continuously).

compute_typegpu_typeNotes
gpu (default)t4 (default), l4, a10g, a100GPU inference; pick the smallest tier your model fits
cpunot applicableCPU-only inference for light models

compute_options

List the selectable compute tiers with their per-minute rate (already marked up, micro-USD). Use this to populate a picker before quoting or creating.

for opt in client.deployments.compute_options():
    print(opt.label, opt.compute_type, opt.gpu_type, opt.rate_per_min_micro_usd)
curl -s "https://api.pictograph.io/api/v1/developer/deployments/compute-options" \
  -H "X-API-Key: $PICTOGRAPH_API_KEY"

Returns list[DeploymentComputeOption].

quote

Get a cost quote for a tier before you create a deployment. The args mirror create, so you can quote and then create with the same values.

ArgTypeDefaultNotes
compute_typeComputeType"gpu""gpu" or "cpu"
gpu_typeDeploymentGpuType | NoneNoneRequired when compute_type="gpu"
min_containersint00 quotes scale-to-zero; >=1 quotes always-warm
q = client.deployments.quote(compute_type="gpu", gpu_type="t4", min_containers=0)
print(q.rate_per_min_micro_usd, q.cost_per_hour_micro_usd, q.billing_note)
curl -s "https://api.pictograph.io/api/v1/developer/deployments/quote?compute_type=gpu&gpu_type=t4&min_containers=0" \
  -H "X-API-Key: $PICTOGRAPH_API_KEY"

Returns DeploymentQuote.

create

Deploy a trained model to a live endpoint. The response includes a one-time plaintext bearer token (prefix pk_deploy_). Store it now: only its hash is kept, so it can never be retrieved again. The deployment starts in provisioning; poll get until status is active and endpoint_url is set, then call it (see Calling your deployment).

ArgTypeDefaultNotes
model_idstrrequiredThe trained model to deploy
namestr | NoneNoneUnique within your org; auto-generated if omitted
compute_typeComputeType"gpu""gpu" or "cpu"
gpu_typeDeploymentGpuType | None"t4"Ignored for compute_type="cpu"
min_containersint00 is scale-to-zero; >=1 keeps warm
max_containersint1Upper bound for autoscale
scaledown_windowint60Seconds a container stays warm after the last request
inference_configdict | NoneNonePer-model defaults (e.g. confidence threshold)
created = client.deployments.create(
    "model-uuid",
    name="prod-detector",
    compute_type="gpu",
    gpu_type="t4",
    min_containers=0,      # scale-to-zero
    max_containers=2,
    scaledown_window=60,
)
print(created.deployment.id, created.deployment.status)
print(created.auth_token)   # pk_deploy_… shown ONCE — store it now
curl -s -X POST "https://api.pictograph.io/api/v1/developer/deployments/" \
  -H "X-API-Key: $PICTOGRAPH_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"model_id": "model-uuid", "name": "prod-detector", "compute_type": "gpu", "gpu_type": "t4", "min_containers": 0, "max_containers": 2, "scaledown_window": 60}'

Returns CreatedDeployment (the Deployment plus the one-time auth_token).

get

Fetch a single deployment by UUID. Poll this after create until status is active.

dep = client.deployments.get("deployment-uuid")
print(dep.status, dep.endpoint_url)
curl -s "https://api.pictograph.io/api/v1/developer/deployments/deployment-uuid" \
  -H "X-API-Key: $PICTOGRAPH_API_KEY"

Returns Deployment. A cross-org or missing id is a 404.

list

Single-page list of deployments in your organization, optionally filtered by model or status.

ArgTypeDefaultNotes
model_idstr | NoneNoneRestrict to deployments of one model
statusDeploymentStatus | NoneNoneprovisioning / active / paused / failed / terminated
limitint50Page size
offsetint0Page offset
for dep in client.deployments.list(status="active", limit=50):
    print(dep.name, dep.status, dep.endpoint_url)
curl -s "https://api.pictograph.io/api/v1/developer/deployments/?status=active&limit=50" \
  -H "X-API-Key: $PICTOGRAPH_API_KEY"

Returns list[Deployment].

iter

Auto-paging iterator over every deployment (transparently follows offset).

for dep in client.deployments.iter(page_size=50):
    print(dep.name, dep.status)
# Page manually with limit + offset until fewer than `limit` rows return.
curl -s "https://api.pictograph.io/api/v1/developer/deployments/?limit=50&offset=0" \
  -H "X-API-Key: $PICTOGRAPH_API_KEY"

pause

Pause an active deployment. This scales its containers to zero and stops uptime billing. Idempotent.

dep = client.deployments.pause("deployment-uuid")
print(dep.status)   # "paused"
curl -s -X POST "https://api.pictograph.io/api/v1/developer/deployments/deployment-uuid/pause" \
  -H "X-API-Key: $PICTOGRAPH_API_KEY"

Returns Deployment.

resume

Resume a paused deployment. This re-provisions the endpoint (a short credit pre-check runs first), so the endpoint_url may take a few seconds to come back. Requires the model_deployment feature (paid tier).

dep = client.deployments.resume("deployment-uuid")
print(dep.status)   # "provisioning" then "active"
curl -s -X POST "https://api.pictograph.io/api/v1/developer/deployments/deployment-uuid/resume" \
  -H "X-API-Key: $PICTOGRAPH_API_KEY"

Returns Deployment.

delete

Terminate a deployment and tear down its app. The endpoint and its bearer token stop working immediately. Requires admin or owner role.

client.deployments.delete("deployment-uuid")
curl -s -X DELETE "https://api.pictograph.io/api/v1/developer/deployments/deployment-uuid" \
  -H "X-API-Key: $PICTOGRAPH_API_KEY"

bulk_pause / bulk_resume / bulk_delete

Apply pause, resume, or delete to many deployments in one org-scoped server-side call, instead of fanning out N single requests. The backend resolves each id per item; duplicate ids are collapsed, and any id that does not resolve in your org or is not in a valid state for the action lands in not_found rather than raising. Each requires the same role as its single-item counterpart.

res = client.deployments.bulk_pause(["dep-a", "dep-b", "dep-c"])
print(res.succeeded, res.not_found, res.count)

client.deployments.bulk_resume(["dep-a", "dep-b"])
client.deployments.bulk_delete(["dep-c"])
curl -s -X POST "https://api.pictograph.io/api/v1/developer/deployments/bulk-pause" \
  -H "X-API-Key: $PICTOGRAPH_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"deployment_ids": ["dep-a", "dep-b", "dep-c"]}'

# bulk-resume and bulk-delete take the same body shape:
#   POST /api/v1/developer/deployments/bulk-resume
#   POST /api/v1/developer/deployments/bulk-delete

bulk_pause and bulk_resume return BulkActionResult (succeeded / not_found / count); bulk_delete returns BulkDeleteResult (deleted / not_found / count).

Calling your deployment

Once a deployment is active, call its endpoint_url (it already ends in /predict) with the pk_deploy_ token returned by create. This request uses the per-deployment bearer token, NOT your X-API-Key. The SDK ships a small DeploymentClient (its ergonomics mirror Roboflow’s InferenceHTTPClient).

infer argTypeDefaultNotes
imagestr | bytes | PathrequiredA local path, an http(s):// URL, or raw image bytes
confidencefloat | NoneNoneOverride the deployment’s default confidence threshold
class_filterlist[str] | NoneNoneRestrict the returned classes
top_kint | NoneNoneFor classifiers, how many predictions to return
from pictograph import Client, DeploymentClient

client = Client()
dep = client.deployments.get("deployment-uuid")

# Build the direct client from the active deployment + the pk_deploy_ token.
infer = client.deployments.connect(dep, api_key="pk_deploy_…")
# or, equivalently, construct it yourself from the endpoint URL:
# infer = DeploymentClient(dep.endpoint_url, "pk_deploy_…")

result = infer.infer("photo.jpg", confidence=0.4)   # path | URL | bytes
print(result["predictions"])
# Direct call to the deployment endpoint — Bearer pk_deploy_ token, NOT X-API-Key.
# A local file as multipart:
curl -s -X POST "$ENDPOINT_URL" \
  -H "Authorization: Bearer pk_deploy_…" \
  -F "file=@photo.jpg"

# Or a URL / base64 image as JSON, with options inline:
curl -s -X POST "$ENDPOINT_URL" \
  -H "Authorization: Bearer pk_deploy_…" \
  -H "Content-Type: application/json" \
  -d '{"image": {"type": "url", "value": "https://example.com/photo.jpg"}, "confidence": 0.4}'

$ENDPOINT_URL is the deployment’s endpoint_url (it already ends in /predict). The response is the model’s JSON, shaped {"predictions": [...], ...}.

Common errors

StatusExceptionCause
402PaymentRequiredErrorInsufficient credits to provision or resume
403ForbiddenErrorRole too low (delete needs admin+), or the model_deployment feature is not on your tier
404NotFoundErrorDeployment or model id does not exist in your org
409ConflictErrorDuplicate name, or an action invalid for the current status (e.g. resume a non-paused deployment)
422ValidationErrorUnknown gpu_type, or gpu_type missing for compute_type="gpu"
Copied to clipboard