Skip to main content
This page describes all SDK methods for video operations. For in-depth code walkthroughs, see SDK Usage Examples.

upload()

Upload local files or URLs.
Upload examples
# Single local file
result = client.upload("video.mp4")

# Multiple local files
batch = client.upload(["a.mp4", "b.mp4"])

# Public GCS URL (any accessible HTTPS URL(s)
remote = client.upload("https://storage.googleapis.com/my-bucket/videos/demo.mp4")

# With folder organization
result = client.upload("video.mp4", folder="my_folder")

# Organization scope
result = client.upload("launch.mp4", folder="robotics_org", scope="org")
If you don’t provide a folder, we upload to your default personal folder. If you provide a folder that does not exist, it will be created automatically.Folders live in either your personal scope (scope="user") or your organization (scope="org"). If you omit scope we default to your personal space. Organization folders are visible to all other members in your organization.Folder names must be unique within each scope.
Required Parameters:
ParameterTypeDescription
videosstr | Path | Sequence[str | Path]Single file/URL or list of files/URLs
Optional Parameters:
ParameterTypeDefaultDescription
folderstrNoneFolder name for organizing uploads (unique within each scope)
scope'user' | 'org' | 'auto''user'Scope hint for folder resolution. Use 'org' for shared org folders, 'user' for personal, and 'auto' to let the backend reuse whichever exists (personal preferred).
upload_timeoutint1200Timeout in seconds for upload completion
wait_for_uploadedboolTrueWait until upload is complete
Returns: Dict (single) or List[Dict] (multiple) with video_id and status

analyze()

Run analysis on one or more uploaded videos with different analysis types.

ASK

Detect custom events in videos using natural language descriptions. Perfect for finding specific scenarios like “green crosswalk” or “yellow taxi”. Works for all video lengths, including long videos, with fast results.
Ask examples
# Single-video prompt
client.analyze(
    "abc123",
    analysis_type=AnalysisType.ASK,
    custom_event="vehicles parked on sidewalk"
)

# With thumbnails (creates annotated bounding boxes)
client.analyze(
    "abc123",
    analysis_type=AnalysisType.ASK,
    custom_event="delivery vans double parked",
    is_thumbnail=True
)

# Batch Ask: analyze multiple IDs at once
client.analyze(
    ["abc123", "def456"],
    analysis_type=AnalysisType.ASK,
    custom_event="jaywalking near intersections"
)

# Batch Ask: analyze every video in a folder
client.analyze(
    folder="fleet_uploads",
    analysis_type=AnalysisType.ASK,
    custom_event="jaywalking near intersections"
)
Required Parameters:
ParameterTypeDescription
id(s) or folderstr | Sequence[str]Video ID(s) or folder name (use one, not both)
analysis_typeAnalysisTypeMust be AnalysisType.ASK
custom_eventstrEvent description to detect (e.g., “green crosswalk”)
Optional Parameters:
ParameterTypeDefaultDescription
custom_categoryCustomCategory | str"driving"Optional context to steer the answer
model_idstr"Nomadic-VL-XLarge"AI model to use
timeoutint2400Analysis timeout in seconds
wait_for_completionboolTrueWait for analysis to complete
is_thumbnailboolFalseGenerate annotated bounding box thumbnails
return_subsetboolFalseReturn subset of results
use_enhanced_motion_analysisboolFalseGenerates enhanced motion caption of events
confidencestrlowconfidence level for event prediction, either set to low or high
nomadicml.video.CustomCategory
  • CustomCategory.DRIVING
  • CustomCategory.ROBOTICS
  • CustomCategory.AERIAL
  • CustomCategory.SECURITY
  • CustomCategory.ENVIRONMENT
Returns: Dict with video_id, analysis_id, mode, status, summary, and events. If is_thumbnail=True, each event includes an annotated_thumbnail_url.

AGENT

Specialized motion and behavior detection powered by curated agent pipelines:
Agent examples
# General agent (edge-case detection)
client.analyze(
    "abc123",
    analysis_type=AnalysisType.GENERAL_AGENT,
)

# Lane change specialist
client.analyze(
    "abc123",
    analysis_type=AnalysisType.LANE_CHANGE,
)

# Batch agent run
client.analyze(
    ["abc123", "def456"],
    analysis_type=AnalysisType.LANE_CHANGE
)

# Batch agent run using a folder
client.analyze(
    folder="san_francisco_midday",
    analysis_type=AnalysisType.LANE_CHANGE
)
  • AnalysisType.GENERAL_AGENT: zero-shot edge-case hunting (General Edge Case)
  • AnalysisType.LANE_CHANGE: lane-change manoeuvre detection
  • AnalysisType.TURN: left/right turn behaviour
  • AnalysisType.RELATIVE_MOTION: relative motion between vehicles
  • AnalysisType.DRIVING_VIOLATIONS: speeding, stop, red-light, and related violations
Required Parameters:
ParameterTypeDescription
ids or folderstr | Sequence[str]Video ID(s) or folder name (use one, not both)
analysis_typeAnalysisTypeOne of AnalysisType.GENERAL_AGENT, AnalysisType.LANE_CHANGE, AnalysisType.TURN, AnalysisType.RELATIVE_MOTION, AnalysisType.DRIVING_VIOLATIONS
Optional Parameters:
ParameterTypeDefaultDescription
model_idstr"Nomadic-VL-XLarge"AI model to use
timeoutint2400Analysis timeout in seconds
wait_for_completionboolTrueWait for analysis to complete
concept_idsList[str]NoneConcept IDs for specialized detection
return_subsetboolFalseReturn subset of results
Returns: Dict with video_id, analysis_id, mode, status, and events.

my_videos()

Retrieve your uploaded videos, optionally filtered by folder.
# Get all videos
videos = client.my_videos()

# Get videos in specific folder
videos = client.my_videos(folder_id="my_folder")
Parameters:
ParameterTypeDefaultDescription
folder_idstr | NoneNoneFilter videos by folder name
Returns: List[Dict] with video information (video_id, filename, duration, size, etc.)

create_or_get_folder()

Create a folder if it does not exist and get its metadata. Helpful when you need a folder identifier before uploading.
marketing = client.create_or_get_folder("driving", scope="org")
print(driving["id"], driving["org_id"])
Parameters:
ParameterTypeDefaultDescription
namestrFolder name to create or fetch
scope'user' | 'org' | 'auto''user'Scope to search/create in
org_idstr | NoneNoneOptional explicit org ID (rarely needed; defaults to the caller’s org)
Returns: Dict with folder id, name, org_id, and scope

delete_video()

Remove a video by ID.
client.delete_video("video_id")
Parameters:
ParameterTypeDescription
video_idstrID of the video to delete (required)
Returns: Dict with deletion status Run semantic search across all analysed events inside a folder. You can use open-ended natural language queries.
results = client.search(
    query="red pickup truck overtaking",
    folder_name="my_fleet_uploads",
    scope="org",                 # optional, defaults to "user"
)

print(results["summary"])
for thought in results["thoughts"]:
    print("•", thought)
Required Parameters:
ParameterTypeDescription
querystrNatural-language search query
folder_namestrHuman-friendly folder name to search within
Optional Parameters:
ParameterTypeDefaultDescription
scope'user' | 'org' | 'sample' | 'auto''user'Scope hint for folder resolution. Use 'org' for organization folders, 'sample' for demo/sample folders, 'auto' to let the backend choose based on your access.
Returns: Dict with:
  • summary: string overview of the findings
  • thoughts: list of reasoning steps (chain-of-thought) shown in the UI
  • matches: list of {video_id, analysis_id, event_index, similarity, reason}
  • session_id: identifier for the associated search session (useful for re-fetching or sharing)

get_visuals()

Retrieve thumbnail URLs for all events in an analysis. If thumbnails don’t exist, they will be generated automatically.
# Get all thumbnail URLs from an analysis
visuals = client.get_visuals("video_id", "analysis_id")

# Returns list of thumbnail URLs
# ['https://storage.googleapis.com/.../event_0_thumb.jpg',
#  'https://storage.googleapis.com/.../event_1_thumb.jpg']
Parameters:
ParameterTypeDescription
video_idstrID of the video (required)
analysis_idstrID of the analysis containing events (required)
Returns: List[str] of thumbnail URLs with bounding box annotations

get_visual()

Retrieve a single thumbnail URL for a specific event in an analysis.
# Get thumbnail for the first event (index 0)
thumbnail_url = client.get_visual("video_id", "analysis_id", 0)

# Get thumbnail for the third event (index 2)
thumbnail_url = client.get_visual("video_id", "analysis_id", 2)
Parameters:
ParameterTypeDescription
video_idstrID of the video (required)
analysis_idstrID of the analysis containing events (required)
event_idxint0-based index of the event (required)
Returns: str - Single thumbnail URL Raises: ValueError if event index is out of range For a step-by-step tutorial, head over to SDK Usage Examples.
I