AEY Cloud — Python SDK
Computer vision over images, video and cameras. Run a model from the catalogue — detection, segmentation, keypoints, embeddings — and get its own output back, or describe what matters as rules and get back only the events you asked for.
Paid from prepaid credits: every run and event records exactly what it cost. Queue time is reported and never charged, and failed runs are free.
Install
pip install https://cloud.aeyvision.com/sdk/python/latest.tar.gz
No dependencies — standard library only. An SDK that drags in an HTTP stack is an SDK that eventually conflicts with the one your application already chose.
A key
Create one in the dashboard at https://cloud.aeyvision.com, or with
POST /v1/keys. The client reads AEYVISION_API_KEY from the environment if
you do not pass one — the form that works in a container without putting a
credential in an argument list.
from aeyvision import AeyVision
cv = AeyVision(api_key="aey_...")
What it can do
from aeyvision import AeyVision
cv = AeyVision() # reads AEYVISION_API_KEY
Browse the catalogue. tasks explains what each capability returns and
which parameters it honours; models is the menu.
catalogue = cv.list_catalogue()
for task in catalogue["tasks"].values():
print(task["label"], "—", task["summary"])
for model in catalogue["models"]:
if model["available"]:
print(model["id"], model["task"], model["licence"])
Detect objects in a clip.
answer = cv.create_run(
model="rfdetr-nano",
video_url="https://example.com/forecourt.mp4",
params={"classes": ["person", "car"], "confidence": 0.4, "sample_fps": 2},
)
print(answer["run"]["cost"]["priceUsd"], "for", answer["run"]["frames"], "frames")
for frame in answer["output"]["frames"]:
for found in frame.get("detections", []):
print(frame["index"], found["label"], round(found["confidence"], 2), found["box"])
Ask a question instead of reading boxes. Rules turn detections into
events; level is None when nothing you asked about happened.
verdict = cv.analyse(
video_url="https://example.com/yard.mp4",
areas=[{"name": "driveway", "points": [[0, 0.5], [1, 0.5], [1, 1], [0, 1]]}],
rules=[{"when": {"object": "car", "state": "moving", "area": "driveway"}, "raise": "alert"}],
)
if verdict["level"] == "alert":
for event in verdict["events"]:
print(event["message"])
Segment things with a text prompt, using SAM 3.
cv.create_run(
model="sam3",
video_url="https://example.com/site.mp4",
params={"prompt": ["forklift", "hard hat", "spilled liquid"]},
)
Redact footage before you share it: everyone blurred but the people you leave visible. The pixels are destroyed, not drawn over, and audio is removed.
import time
with open("door.mp4", "rb") as handle:
upload = cv.create_upload(handle.read(), filename="door.mp4")["upload"]
redaction = cv.create_redaction(upload_id=upload["id"])["redaction"]
while redaction["status"] == "analysing":
time.sleep(5)
redaction = cv.get_redaction(redaction["id"])["redaction"]
# Every person and vehicle, as a track. Leave the first person visible.
tracks = cv.get_redaction_analysis(redaction["id"])["analysis"]["tracks"]
keep = [t["id"] for t in tracks if t["label"] == "face"][:1]
cv.render_redaction(redaction["id"], review={"keep": keep, "boxes": []})
while redaction["status"] != "ready":
time.sleep(5)
redaction = cv.get_redaction(redaction["id"])["redaction"]
with open("door-redacted.mp4", "wb") as handle:
handle.write(cv.get_redaction_video(redaction["id"]))
Processing price
cost = answer["run"]["cost"]
print(cost["seconds"], "s on", cost["gpu"])
print("price per hour", cost["pricePerHour"])
print("charged", cost["priceUsd"])
print("queued ", cost["queuedSeconds"], "s — not billed")
Full logs of what the container did — the same ones the console renders:
log = cv.get_run_logs(answer["run"]["id"])
for line in log["lines"]:
print(line["t"], line["level"], line["message"], line.get("fields", ""))
for stage in log["stages"]:
print(stage["name"], stage["ms"], "ms")
And spend across the account:
usage = cv.get_usage(days=30)
print(usage["total"]["runs"], "runs,", usage["total"]["priceUsd"], "USD")
Watch out for
Two-stage models such as object-search run their second stage once per
detected object, not once per frame. A busy car park costs meaningfully more
than an empty drive. The catalogue flags these
with scales_with_objects, before the run rather than on the invoice.
sample_fps is the biggest lever on cost. Two frames a second answers most
questions; ten costs five times as much to answer them slightly better.
Every method
Training
| Method | Endpoint | What it does |
|---|---|---|
add_training_image |
POST /v1/training/datasets/{id}/images |
Add an image and its boxes. JSON, or the image as the body with ?split= and ?annotations= (URL-encoded JSON). |
cancel_training_job |
POST /v1/training/jobs/{id}/cancel |
Stop a job. Charged for the time it ran; the rest of the hold is returned. |
create_training_dataset |
POST /v1/training/datasets |
Create a trainingDataset. |
create_training_job |
POST /v1/training/jobs |
Fine-tune RF-DETR on a dataset. Sets aside the most it can cost, and charges for the time it uses. |
delete_training_dataset |
DELETE /v1/training/datasets/{id} |
Delete a trainingDataset. |
delete_training_image |
DELETE /v1/training/datasets/{id}/images/{imageId} |
Remove an image from a dataset. |
delete_training_job |
DELETE /v1/training/jobs/{id} |
Delete a finished job. Its model stays. |
estimate_training |
POST /v1/training/estimate |
What a training job would set aside and most likely cost, without starting it. |
get_training_dataset |
GET /v1/training/datasets/{id} |
Get one trainingDataset. |
get_training_image_file |
GET /v1/training/datasets/{id}/images/{imageId}/file |
The image itself. |
get_training_job |
GET /v1/training/jobs/{id} |
A job's progress, metrics, charge and model. |
list_training_datasets |
GET /v1/training/datasets |
List trainingDatasets owned by the account. |
list_training_images |
GET /v1/training/datasets/{id}/images |
Every image in a dataset, with its boxes. |
list_training_jobs |
GET /v1/training/jobs |
Training jobs, newest first. |
update_training_dataset |
PATCH /v1/training/datasets/{id} |
Update a trainingDataset. |
update_training_image |
PATCH /v1/training/datasets/{id}/images/{imageId} |
Replace an image's boxes, or move it between train and valid. |
Rules
| Method | Endpoint | What it does |
|---|---|---|
analyse |
POST /v1/analyse |
Grade media against rules sent with the request. Nothing saved unless asked. |
analyse_with_detector |
POST /v1/detectors/{id}/analyse |
Grade media against a saved detector. |
create_detector |
POST /v1/detectors |
Create a detector. |
delete_detector |
DELETE /v1/detectors/{id} |
Delete a detector and everything it recorded. |
get_detector |
GET /v1/detectors/{id} |
One detector, with its twenty most recent events. |
get_event |
GET /v1/events/{id} |
One event in full. |
get_event_clip |
GET /v1/events/{id}/clip |
The annotated clip for an event. |
get_event_image |
GET /v1/events/{id}/image |
The annotated frame for an event. |
list_detectors |
GET /v1/detectors |
Every detector on this account. |
list_events |
GET /v1/events |
Everything analysed, including the calls that raised nothing. |
list_models |
GET /v1/models |
The rules product's detector variants, and every class a rule may name. |
update_detector |
PATCH /v1/detectors/{id} |
Change a detector. Only the fields you send. |
Analytics
| Method | Endpoint | What it does |
|---|---|---|
append_analytics_event |
POST /v1/analytics/events |
Record an analytics point. |
query_analytics |
POST /v1/analytics/query |
Query recalled analytics points with a structured filter. |
query_analytics_events |
GET /v1/analytics/events |
Recall analytics points stored for the account. |
Sites
| Method | Endpoint | What it does |
|---|---|---|
check_camera_health |
POST /v1/cameras/{id}/health |
Inspect what this camera is actually showing. |
create_camera |
POST /v1/cameras |
Create a camera. |
create_customer |
POST /v1/customers |
Create a customer. |
create_site |
POST /v1/sites |
Create a site. |
delete_camera |
DELETE /v1/cameras/{id} |
Delete a camera. |
delete_customer |
DELETE /v1/customers/{id} |
Delete a customer. |
delete_site |
DELETE /v1/sites/{id} |
Delete a site. |
dial_camera |
POST /v1/cameras/{id}/dial |
Dial this camera's RTSP stream and take a frame. |
get_camera |
GET /v1/cameras/{id} |
Get one camera. |
get_camera_false_alarms |
GET /v1/cameras/{id}/false-alarms |
Where this camera's false alarms come from, using outcomes stored on its events. |
get_camera_snapshot |
GET /v1/cameras/{id}/snapshot |
The most recent frame taken from this camera. |
get_camera_zone_suggestions |
GET /v1/cameras/{id}/zones/suggestions |
The last scene reading stored for this camera, without running SAM 3. |
get_customer |
GET /v1/customers/{id} |
Get one customer. |
get_site |
GET /v1/sites/{id} |
Get one site. |
list_camera_health |
GET /v1/cameras/{id}/health |
This camera's health history, newest first. |
list_cameras |
GET /v1/cameras |
List cameras owned by the account. |
list_customers |
GET /v1/customers |
List customers owned by the account. |
list_customer_sites |
GET /v1/customers/{customerId}/sites |
List sites belonging to one customer. |
list_site_cameras |
GET /v1/sites/{siteId}/cameras |
List cameras belonging to one site. |
list_site_health |
GET /v1/sites/{siteId}/health |
Every camera at this site, with its latest health answer. |
list_sites |
GET /v1/sites |
List sites owned by the account. |
report_camera_false_alarms |
POST /v1/cameras/{id}/false-alarms |
Where this camera's false alarms come from, and which zones would stop them. |
suggest_camera_zones |
POST /v1/cameras/{id}/zones/suggest |
Read the camera's scene into zone-shaped regions with SAM 3. |
suggest_zones |
POST /v1/zones/suggest |
Read any frame into zone-shaped regions with SAM 3. Nothing is stored. |
update_camera |
PATCH /v1/cameras/{id} |
Update a camera. |
update_customer |
PATCH /v1/customers/{id} |
Update a customer. |
update_site |
PATCH /v1/sites/{id} |
Update a site. |
Object search
| Method | Endpoint | What it does |
|---|---|---|
clear_site_objects |
DELETE /v1/sites/{siteId}/objects |
Delete this site's object index, and the crops with it. |
get_object |
GET /v1/objects/{id} |
One kept object crop. |
get_object_image |
GET /v1/objects/{id}/image |
The crop itself, as a JPEG. |
list_site_objects |
GET /v1/sites/{siteId}/objects |
List the object crops this site has kept. |
search_site_objects |
POST /v1/sites/{siteId}/search |
Find the objects this site has already seen that look like this one. |
Account
| Method | Endpoint | What it does |
|---|---|---|
create_checkout_session |
POST /v1/billing/checkout-session |
Create a hosted Stripe Checkout Session for credits. |
create_free_trial_session |
POST /v1/billing/free-trial-session |
Start claiming the free credits: a Stripe Checkout Session in setup mode. |
create_key |
POST /v1/keys |
Mint a key. The secret is returned once and never again. |
get_billing |
GET /v1/billing |
Credit balance, billing fee minimum, and account entitlement. |
get_brand |
GET /v1/brand |
What the console is called on the domain this request was made to. |
get_invite |
GET /v1/invites/{token} |
Who a sub-account invitation is from, and for which address. |
health |
GET /health |
Liveness. Unauthenticated. |
invite_sub_account |
POST /v1/sub-accounts/invites |
Invite an email address to become a sub-account. |
list_keys |
GET /v1/keys |
Every key on this account. Never the secrets. |
list_sub_accounts |
GET /v1/sub-accounts |
Your sub-accounts, and invitations not yet accepted. |
me |
GET /v1/me |
The authenticated account, and how it authenticated. |
revoke_key |
DELETE /v1/keys/{id} |
Revoke a key. Immediate. |
revoke_sub_account_invite |
DELETE /v1/sub-accounts/invites/{id} |
Withdraw an invitation that has not been accepted. |
update_sub_account |
PATCH /v1/sub-accounts/{id} |
Change a sub-account's customer or monthly cap, or suspend it. |
| Method | Endpoint | What it does |
|---|---|---|
create_email_destination |
POST /v1/email/destinations |
Create a emailDestination. |
delete_email_destination |
DELETE /v1/email/destinations/{id} |
Delete a emailDestination. |
get_email_destination |
GET /v1/email/destinations/{id} |
Get one emailDestination. |
list_email_destinations |
GET /v1/email/destinations |
List emailDestinations owned by the account. |
update_email_destination |
PATCH /v1/email/destinations/{id} |
Update a emailDestination. |
Models
| Method | Endpoint | What it does |
|---|---|---|
create_model_registration |
POST /v1/model-registrations |
Create a modelRegistration. |
delete_model_registration |
DELETE /v1/model-registrations/{id} |
Delete a modelRegistration. |
get_model_registration |
GET /v1/model-registrations/{id} |
Get one modelRegistration. |
list_model_registrations |
GET /v1/model-registrations |
List modelRegistrations owned by the account. |
put_model_artifact |
PUT /v1/model-registrations/{id}/artifact |
Upload the ONNX file for a model registration. |
update_model_registration |
PATCH /v1/model-registrations/{id} |
Update a modelRegistration. |
Redaction
| Method | Endpoint | What it does |
|---|---|---|
create_redaction |
POST /v1/redactions |
Redact an upload: find every face and number plate in it, to review. |
delete_redaction |
DELETE /v1/redactions/{id} |
Delete a redaction and its original footage. Its runs, and the redacted video, stay under Runs. |
delete_redaction_footage |
DELETE /v1/redactions/{id}/footage |
Delete the original footage and keep the redacted video. The redaction can no longer be edited. |
get_redaction |
GET /v1/redactions/{id} |
One redaction, brought up to date with the run it is waiting on. |
get_redaction_analysis |
GET /v1/redactions/{id}/analysis |
Every person and vehicle found, as tracks of normalised boxes over time. |
get_redaction_source |
GET /v1/redactions/{id}/source |
The original footage. Honours Range, so a video player can seek. |
get_redaction_video |
GET /v1/redactions/{id}/video |
The redacted video, once status is ready. Honours Range. |
list_redactions |
GET /v1/redactions |
Every redaction on this account, newest first. |
render_redaction |
POST /v1/redactions/{id}/render |
Make the redacted video from a review. |
retry_redaction_analysis |
POST /v1/redactions/{id}/analyse |
Analyse the footage again, after an analysis failed. |
update_redaction |
PATCH /v1/redactions/{id} |
Rename a redaction, or save a review in progress as its draft. |
Platform
| Method | Endpoint | What it does |
|---|---|---|
create_run |
POST /v1/runs |
Run one model over one video or image. |
create_upload |
POST /v1/uploads |
Upload footage for a footage job, up to 4 GB. |
delete_upload |
DELETE /v1/uploads/{id} |
Delete an upload: the footage itself, not just the record. |
get_customer_usage |
GET /v1/usage/customers |
Spend split by your own customers, for rebilling. |
get_pricing |
GET /v1/pricing |
Customer processing price per hour. |
get_rates |
GET /v1/rates |
Public list prices per processing hour. |
get_run |
GET /v1/runs/{id} |
One run: its status, its counts and exactly what it cost. |
get_run_clip |
GET /v1/runs/{id}/clip |
The annotated clip, when the run produced one. |
get_run_logs |
GET /v1/runs/{id}/logs |
Every line the container logged for this run. |
get_run_output |
GET /v1/runs/{id}/output |
The model's full output — every frame, every detection. |
get_upload |
GET /v1/uploads/{id} |
One upload. |
get_upload_file |
GET /v1/uploads/{id}/file |
The uploaded footage itself. Honours Range, so a video player can seek. |
get_usage |
GET /v1/usage |
Spend, by day and by model. |
list_catalogue |
GET /v1/catalogue |
Every model this platform can run, and what each capability returns. |
list_runs |
GET /v1/runs |
Run history, newest first. |
list_uploads |
GET /v1/uploads |
Footage this account has uploaded and not yet deleted. |
Scripts
| Method | Endpoint | What it does |
|---|---|---|
create_script |
POST /v1/scripts |
Create a script. |
delete_script |
DELETE /v1/scripts/{id} |
Delete a script. |
get_script |
GET /v1/scripts/{id} |
Get one script. |
list_scripts |
GET /v1/scripts |
List scripts owned by the account. |
update_script |
PATCH /v1/scripts/{id} |
Update a script. |
write_script |
POST /v1/scripts/ai-write |
Generate a reviewable Python video handler from a behavior brief. |
UI Components
| Method | Endpoint | What it does |
|---|---|---|
create_ui_component |
POST /v1/ui-components |
Create a uiComponent. |
delete_ui_component |
DELETE /v1/ui-components/{id} |
Delete a uiComponent. |
get_ui_component |
GET /v1/ui-components/{id} |
Get one uiComponent. |
list_ui_components |
GET /v1/ui-components |
List uiComponents owned by the account. |
update_ui_component |
PATCH /v1/ui-components/{id} |
Update a uiComponent. |
Events
| Method | Endpoint | What it does |
|---|---|---|
list_audit |
GET /v1/audit |
Query the account audit log. |
set_event_outcome |
POST /v1/events/{id}/outcome |
Record whether an event was a false alarm or a real one. |
Platform resources
The package also includes a typed PlatformClient for the domain resource
contract: sites, cameras, models, scripts, events, training jobs and runs.
These routes are configurable so a customer can proxy them through a different
gateway without changing the generated client.
from aeyvision import PlatformClient
platform = PlatformClient(api_key="aey_...")
sites = platform.list_sites(limit=25)
For TypeScript, import PlatformClient from @aeyvision/sdk. Both clients
default to /v1/customers, /v1/sites, /v1/cameras,
/v1/model-registrations, /v1/scripts, /v1/ui-components,
/v1/events, /v1/training/jobs and /v1/runs; pass route overrides
when your gateway uses a different mount.
Errors
Anything but a 2xx raises AeyVisionError, carrying status and — when the
rules API rejected a configuration — problems, the per-rule complaints. Both
are attributes rather than prose in the message, because code that retries on
429 and gives up on 400 should not have to parse English.
Requests are retried on 429 and 5xx with exponential backoff, twice by default. Nothing else is retried: a 400 will be a 400 again, and a run that failed on the GPU has already cost real money — repeating it spends more of it for the same answer.
Licences
Every catalogue entry carries its licence, and commercial is a field. An
entry whose weights you cannot ship inside a closed product is marked
commercial: false with a licence_note saying why, and the warning rides
on every response that used one. Read output.warnings before
you build on a result.
This package is generated
Everything here comes from functions/api/src/openapi.ts by way of
scripts/generate-sdk.mjs. Run npm run sdk to rebuild it. Editing it by hand
is how a generated client starts lying about the API it describes.
Release files for aeyvision-cloud 1.0.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| aeyvision_cloud-1.0.0.tar.gz | 45.8 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| aeyvision_cloud-1.0.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 87.5 kB
Release files / aeyvision_cloud-1.0.0.tar.gz
| Download URL | aeyvision_cloud-1.0.0.tar.gz |
|---|---|
| Size | 45.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
ea7ca39a762a25c693ced8ab89a25b2622207f6aefd9ed8599475b447f9fc1cd
|
|
BLAKE2b-256 checksum How to use checksums |
9a0b0e9c16baed4e8015e42597ef9388ddba3df69b2713b333715af08ecb19ae
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.7
|
Release files / aeyvision_cloud-1.0.0-py3-none-any.whl
| Download URL | aeyvision_cloud-1.0.0-py3-none-any.whl |
|---|---|
| Size | 41.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
72446ee82d2b279d78847aca9970cd28ae03af58b709282aac9ba6039c563d01
|
|
BLAKE2b-256 checksum How to use checksums |
292539e1580cbc9b5a4d7d187c660df3110cd89a6df9d3f5e288394e44effb15
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.7
|