# Analyze Frame
Source: https://docs.machinefi.com/api-reference/analyze-frame
POST /analyze-frame
Analyze a single image frame with VLM. Accepts a base64-encoded JPEG and a question — no stream URL needed.
Analyze a pre-captured image frame with VLM.
Use this when you have your own frame capture mechanism (like TrioClaw) and just need VLM analysis — no stream URL validation or capture required.
## How It Differs From Other Endpoints
* `POST /analyze-frame` — Accepts raw base64 frame, no stream URL
* `POST /check-once` — Captures frame from stream URL, validates liveness
* `POST /live-monitor` — Creates continuous monitoring job
## Use Cases
* **TrioClaw** — Desktop app that captures frames locally and needs VLM analysis
* **Custom pipelines** — Your own frame capture (RTSP, screenshots, etc.)
* **Batch processing** — Analyze many pre-captured images without stream overhead
## Question Styles
Supports two question types:
### Yes/No Conditions
```
"Is there a person?"
"Is the traffic light red?"
"Are cars moving?"
```
Response includes `triggered: true/false`.
### Open-Ended Questions
```
"What do you see?"
"Describe the weather conditions."
"What is the text in this image?"
```
Response includes `answer` with full description, `triggered: null`.
## Request
Base64-encoded JPEG image (raw base64, no `data:` URI prefix).
Question or condition about the image (max 1000 characters).
Include the analyzed frame back in the response.
## Response
```json theme={null}
{
"answer": "Yes, there is a person visible in the center of the frame.",
"triggered": true,
"latency_ms": 1250,
"frame_b64": null
}
```
```json theme={null}
{
"answer": "The image shows a blue sky with scattered white clouds.",
"triggered": null,
"latency_ms": 890,
"frame_b64": "/9j/4AAQSkZJRg..."
}
```
## Error Handling
```json theme={null}
{
"error": {
"code": "BAD_REQUEST",
"message": "Invalid base64 frame data: Incorrect padding",
"remediation": "Ensure frame_b64 is valid base64-encoded JPEG data"
}
}
```
```json theme={null}
{
"error": {
"code": "BAD_REQUEST",
"message": "Frame data too small — expected a JPEG image",
"remediation": "Ensure the base64 data represents a valid JPEG image"
}
}
```
## Related
* Monitoring workflows: [Live Monitor](/api-reference/live-monitor)
* Stream validation: [Validate Stream](/api-reference/streams-validate)
* Single check: [Check Once](/api-reference/check-once)
# Check Once
Source: https://docs.machinefi.com/api-reference/check-once
POST /check-once
Perform a single synchronous condition check on a YouTube Live stream
Runs one immediate condition check and returns a single result.
Use this when you need a fast yes/no answer now, or when validating a condition before long-running jobs.
## How It Differs From Async Jobs
* `POST /check-once` is synchronous and returns one result.
* `POST /live-monitor` creates/streams a monitoring job.
* `POST /live-digest` creates/streams summary windows.
## Suggested Flow
1. Validate stream liveness: [Validate Stream](/api-reference/streams-validate)
2. Test condition wording: `POST /check-once`
3. Move to monitor/digest only when wording is reliable.
## Response Semantics
The response is immediate and includes:
* `triggered`: boolean decision
* `explanation`: human-readable reason tied to visible evidence
* `latency_ms`: end-to-end request latency
* `frame_b64`: optional frame payload when requested
Client handling recommendation:
* if `triggered = true`, execute your success path
* if `triggered = false`, refine condition or continue monitoring workflow
## Related
* Workflow selection: [Choose Your Workflow](/start-here/choose-workflow)
* Condition quality: [Writing Reliable Conditions](/guides/writing-conditions)
* Continuous detection: [Live Monitor](/api-reference/live-monitor)
# Cancel Job
Source: https://docs.machinefi.com/api-reference/jobs-delete
DELETE /jobs/{job_id}
Cancel a running job.
Stops a running job and returns its final state snapshot.
Use cancellation when conditions or stream context change and the current run is no longer useful.
## Common Uses
* Stop stale jobs after client disconnects.
* Enforce custom business-time windows.
* Abort runs that are spending budget without value.
## Workflow
1. Find active jobs with [List Jobs](/api-reference/jobs-list).
2. Confirm details with [Get Job Details](/api-reference/jobs-get).
3. Issue `DELETE /jobs/{job_id}`.
## Notes
* Cancellation ends future monitoring activity for that job.
* Use [Get Job Details](/api-reference/jobs-get) after canceling if you need to verify terminal state in a separate call.
## Related
* Lifecycle overview: [Job Lifecycle](/core-concepts/job-lifecycle)
* Troubleshooting: [Debugging Playbook](/guides/debugging)
# Get Job Details
Source: https://docs.machinefi.com/api-reference/jobs-get
GET /jobs/{job_id}
Get job status and details with config/stats split.
Returns runtime state for a single async job.
This is the primary endpoint for polling monitor/digest jobs and interpreting final outcomes.
## Response Semantics
The response separates data into:
* `config`: user-supplied job settings
* `stats`: runtime progress and result fields
`stats` can evolve while a job is `running`.
## Status Semantics
Possible `status` values:
* `pending`: accepted, not yet running
* `running`: actively processing
* `completed`: finished successfully
* `stopped`: ended without failure
* `failed`: ended due to runtime/stream failure
Recommended client handling:
* `completed`: consume final result fields
* `stopped`: inspect stop reason and restart if needed
* `failed`: inspect error context, fix inputs, retry
## Common Uses
* Poll `live-monitor` / `live-digest` in polling mode
* Validate final outcomes after webhook/SSE flows
* Inspect stop reasons and counters during debugging
## Workflow
1. Create a job with [Live Monitor](/api-reference/live-monitor) or [Live Digest](/api-reference/live-digest)
2. Poll `GET /jobs/{job_id}` until terminal status
3. Cancel early via [Cancel Job](/api-reference/jobs-delete) if needed
## Related
* Polling implementation: [Use Polling](/guides/poll-jobs)
* Lifecycle overview: [Job Lifecycle](/core-concepts/job-lifecycle)
* Failure analysis: [Debugging Playbook](/guides/debugging)
# List Jobs
Source: https://docs.machinefi.com/api-reference/jobs-list
GET /jobs
List all jobs with optional filtering and pagination.
Lists monitoring and digest jobs for the current user, with optional filtering and pagination.
Use this endpoint as your entry point for dashboards, health checks, and cleanup workflows.
## Common Uses
* Build a job table with status and age.
* Discover active jobs before restarting workers.
* Filter jobs by type or status before follow-up actions.
## Workflow
1. Call `GET /jobs` to list candidate jobs.
2. Open one with [Get Job Details](/api-reference/jobs-get).
3. Stop long-running jobs with [Cancel Job](/api-reference/jobs-delete) when needed.
## Related
* Lifecycle overview: [Job Lifecycle](/core-concepts/job-lifecycle)
* Troubleshooting: [Debugging Playbook](/guides/debugging)
# Live Digest
Source: https://docs.machinefi.com/api-reference/live-digest
POST /live-digest
Generate periodic narrative summaries via SSE streaming
Starts a summary-oriented monitoring job that samples the stream and emits narrative summaries.
Use this when you need trend-level understanding over time, not binary trigger detection.
## Delivery Mode Selection
`POST /live-digest` selects response mode by request shape:
1. `Accept: text/event-stream` and no `webhook_url` -> SSE mode
2. `webhook_url` present -> webhook mode
3. otherwise -> polling mode
## Response Semantics by Mode
### Polling mode
Returns a job response (`job_id`, `status`, `created_at`, `job_type`, `stream_url`, optional `message`).
Follow with `GET /jobs/{job_id}` for runtime details and summary outcomes.
### Webhook mode
Returns a job response immediately, then delivers async summary/status events.
Common webhook `type` values:
* `job_started`
* `summary_generated`
* `job_stopped`
* `error`
### SSE mode
Returns live text events.
Common event names:
* `started`
* `progress`
* `summary`
* `stopped`
* `error`
Treat `stopped` and `error` as terminal events for that stream session.
## Tuning Semantics
* `window_minutes`: coverage duration per summary
* `capture_interval_seconds`: sampling cadence
* `max_windows`: optional cap on total windows
Tune these together with your latency/cost requirements.
## Related
* Tuning patterns: [Tune Monitoring for Latency, Accuracy, and Cost](/guides/configuring-live-digest)
* Job state details: [Get Job Details](/api-reference/jobs-get)
* Workflow chooser: [Choose Your Workflow](/start-here/choose-workflow)
# Live Monitor
Source: https://docs.machinefi.com/api-reference/live-monitor
POST /live-monitor
Start a continuous monitoring job that checks for a condition
Starts a continuous job that checks a stream until your condition is met, the job is stopped, or limits are reached.
## Key Request Fields
* `monitor_duration_seconds` (default `600`): per-job runtime limit in seconds.
* `trigger_cooldown_seconds` (default `0`): minimum seconds between trigger alerts.
* `max_triggers` (default `1`): number of trigger alerts before auto-stop.
* `1` keeps legacy first-match behavior.
* `>1` allows repeated alerts, then stops.
* `null` means unlimited alerts until duration/cancel.
## Delivery Mode Selection
`POST /live-monitor` selects response mode by request shape:
1. `webhook_url` present -> webhook mode
2. `Accept: text/event-stream` and no `webhook_url` -> SSE mode
3. otherwise -> polling mode
## Response Semantics by Mode
### Polling mode
Returns a job response (`job_id`, `status`, `created_at`, `job_type`, `stream_url`, optional `message`).
Use `GET /jobs/{job_id}` to track runtime and terminal state.
### Webhook mode
Returns a job response immediately, then sends async webhook events.
Common webhook `type` values:
* `job_started`
* `watch_triggered`
* `job_stopped`
* `error`
### SSE mode
Returns a text event stream.
Common event names:
* `started`
* `progress`
* `triggered` (non-terminal trigger event in multi-trigger mode)
* `stopped`
* `error`
Treat `stopped` and `error` as terminal events for that stream session.
Treat `triggered` as non-terminal.
## Status Semantics
For polling or post-hoc inspection:
* `running`: active checks in progress
* `completed`: condition matched and job completed
* `stopped`: ended without failure (cancelled or auto-stop)
* `failed`: ended due to runtime/stream failure
Use [Get Job Details](/api-reference/jobs-get) for final runtime fields.
Common stop reasons in `stats.reason` include:
* `condition_triggered`
* `max_triggers_reached`
* `max_duration_reached`
* `cancelled`
## Typical Usage
1. Validate URL: [Validate Stream](/api-reference/streams-validate)
2. Validate wording: [Check Once](/api-reference/check-once)
3. Start `POST /live-monitor`
4. Track via polling, webhook, or SSE
## Related
* Workflow chooser: [Choose Your Workflow](/start-here/choose-workflow)
* Job state details: [Get Job Details](/api-reference/jobs-get)
* Webhook implementation: [Use Webhooks](/guides/webhooks)
# Validate Stream
Source: https://docs.machinefi.com/api-reference/streams-validate
POST /streams/validate
Validate a stream URL and return rich metadata.
Returns detailed information about the stream including platform,
title, channel, thumbnail, and viewer count.
Checks whether a stream URL is valid and currently live, and returns stream metadata plus a parsed playback URL when available.
Use this before starting expensive monitoring jobs when you want early feedback on bad URLs.
## Typical flow
1. Validate with `POST /streams/validate`.
2. Use `parsed_url` from the response for frontend playback/preview if needed.
3. Start [Check Once](/api-reference/check-once), [Live Monitor](/api-reference/live-monitor), or [Live Digest](/api-reference/live-digest).
## Notes
* Main monitoring endpoints can still validate internally.
* Explicit validation is useful for better UX and pre-flight checks.
## Related
* Delivery and modes: [Monitoring Modes and Delivery Patterns](/core-concepts/how-trio-works)
* Tuning tradeoffs: [Tune Monitoring for Latency, Accuracy, and Cost](/guides/configuring-live-digest)
# Monitoring Modes and Delivery Patterns
Source: https://docs.machinefi.com/core-concepts/how-trio-works
Understand Trio endpoint modes and how results are delivered
## Core Model
Trio exposes two interaction styles:
* Synchronous check: one request, one immediate result
* Asynchronous jobs: create a job, then receive progress/results by polling, webhook, or SSE
## Endpoints by Monitoring Mode
| Endpoint | Purpose | Typical output |
| -------------------- | ------------------------------------ | ------------------------------- |
| `POST /check-once` | One immediate yes/no check | JSON response |
| `POST /live-monitor` | Detect when a condition becomes true | Job lifecycle + trigger result |
| `POST /live-digest` | Generate summaries over time windows | Job lifecycle + summary results |
## Delivery Patterns
### 1. Synchronous JSON
Use `POST /check-once` when you need a direct answer in one call.
### 2. Polling
Create a monitor or digest job, then poll `GET /jobs/{job_id}` until terminal status.
### 3. Webhooks
Include `webhook_url` in the request body to receive push callbacks.
### 4. SSE
Send `Accept: text/event-stream` for live event streaming during request handling.
## Delivery Selection Rules
### `POST /live-monitor`
1. `webhook_url` present -> webhook mode
2. `Accept: text/event-stream` and no `webhook_url` -> SSE mode
3. otherwise -> polling mode
### `POST /live-digest`
1. `Accept: text/event-stream` and no `webhook_url` -> SSE mode
2. `webhook_url` present -> webhook mode
3. otherwise -> polling mode
## Picking the Right Pattern
* Prefer `check-once` for validation and quick decision points.
* Prefer polling for simple backend jobs.
* Prefer webhooks for workflow automation.
* Prefer SSE for live progress in apps.
## Next Steps
* Job states and transitions: [Job Lifecycle](/core-concepts/job-lifecycle)
* Endpoint-level response behavior: [Live Monitor](/api-reference/live-monitor)
* Delivery with callbacks: [Use Webhooks](/guides/webhooks)
* Delivery with polling: [Use Polling](/guides/poll-jobs)
* Delivery with streams: [Use SSE Streaming](/guides/sse-streaming)
# Job Lifecycle
Source: https://docs.machinefi.com/core-concepts/job-lifecycle
Understand job state transitions for live-monitor and live-digest
## Which Endpoints Create Jobs
These endpoints create async jobs:
* `POST /live-monitor`
* `POST /live-digest`
Track jobs with:
* `GET /jobs`
* `GET /jobs/{job_id}`
* `DELETE /jobs/{job_id}`
## Lifecycle States
| Status | Meaning |
| ----------- | ------------------------------------------------------------ |
| `pending` | Job accepted, not yet running |
| `running` | Job actively processing |
| `completed` | Job finished successfully |
| `stopped` | Job stopped without failure (cancelled, timed out, or ended) |
| `failed` | Job ended due to processing/runtime error |
## Typical Lifecycle
1. Create job (`live-monitor` or `live-digest`)
2. Receive `job_id`
3. Observe `running`
4. Reach terminal state: `completed`, `stopped`, or `failed`
## Common Stop Reasons
You can inspect stop context in [Get Job Details](/api-reference/jobs-get).
Common reasons include:
* condition detected (`completed`)
* trigger limit reached (`completed`)
* max duration reached (`stopped`)
* max windows reached for digest (`stopped`)
* manual cancellation via `DELETE /jobs/{job_id}` (`stopped`)
* stream or processing failure (`failed`)
## Time-Bounded Runs
Monitoring jobs are time-bounded. `live-monitor` supports per-job `monitor_duration_seconds`, but still enforces a server cap (default 10 minutes). Design your workflow to start a follow-up job when terminal state is reached if continuous coverage is required.
## Operational Pattern
1. Create job
2. Store `job_id`
3. Track status (polling, webhook, or SSE)
4. Handle terminal state
5. Recreate job if coverage must continue
## Next Steps
* Polling implementation: [Use Polling](/guides/poll-jobs)
* Push delivery implementation: [Use Webhooks](/guides/webhooks)
* Field semantics in responses: [Get Job Details](/api-reference/jobs-get)
# Snow Alert for Pittsburgh
Source: https://docs.machinefi.com/examples/snow-alert
Build a weather alerting system that texts you when it starts snowing
Let's build a system that monitors a Pittsburgh webcam and sends you an SMS via Twilio when snow is detected.
**Remember**: Jobs are time-bounded (default 10 minutes) and can also stop when
`max_triggers` is reached. For continuous monitoring, your webhook should restart the job.
## How to use examples
Use this recipe as a template:
* Replace the stream URL with your own live source.
* Replace the condition with your domain-specific event.
* Keep the webhook + restart pattern for long-running monitoring.
## The Setup
We'll use:
* **Trio** to monitor a Pittsburgh traffic cam
* **Twilio** to send SMS alerts
* A simple **webhook receiver** that restarts jobs when they expire
## Step 1: Find a Live Stream
Pittsburgh has several public traffic cams. Search YouTube for "pittsburgh live cam" or "traffic cam live".
The URL must be an **active live stream**. Regular videos and past streams
will be rejected with a 400 error.
## Step 2: Create the Webhook Receiver
Set these environment variables in your host:
* `TRIO_API_KEY` (from the Trio console)
* `WEBHOOK_HOST` (your public base URL, e.g., `https://your-webhook-server.com`)
* `TWILIO_ACCOUNT_SID`, `TWILIO_AUTH_TOKEN`
* `TWILIO_PHONE`, `MY_PHONE`
```python webhook_server.py theme={null}
from fastapi import FastAPI, Request, BackgroundTasks
from twilio.rest import Client
import httpx
import os
app = FastAPI()
twilio_client = Client(
os.environ["TWILIO_ACCOUNT_SID"],
os.environ["TWILIO_AUTH_TOKEN"]
)
TRIO_API_BASE = "https://trio.machinefi.com/api"
TRIO_API_KEY = os.environ["TRIO_API_KEY"]
# Track current job
current_job_id = None
STREAM_URL = "https://youtube.com/watch?v=PITTSBURGH_LIVE_CAM"
CONDITION = "Is it snowing? Look for falling snowflakes or white accumulation."
async def start_live_monitor_job():
"""Start or restart the live monitor job."""
global current_job_id
async with httpx.AsyncClient() as client:
response = await client.post(
f"{TRIO_API_BASE}/live-monitor",
json={
"stream_url": STREAM_URL,
"condition": CONDITION,
"webhook_url": f"{os.environ['WEBHOOK_HOST']}/snow-alert",
"interval_seconds": 30,
},
headers={"Authorization": f"Bearer {TRIO_API_KEY}"},
)
if response.status_code == 200:
current_job_id = response.json()["job_id"]
print(f"Started job: {current_job_id}")
else:
print(f"Failed to start job: {response.text}")
@app.on_event("startup")
async def startup():
"""Start monitoring on server startup."""
await start_live_monitor_job()
@app.post("/snow-alert")
async def snow_alert(request: Request, background_tasks: BackgroundTasks):
payload = await request.json()
# Handle trigger events
if payload.get("type") == "watch_triggered":
data = payload.get("data", {})
# Send SMS alert
twilio_client.messages.create(
body=f"It's snowing in Pittsburgh!\n\n{data.get('explanation', '')}",
from_=os.environ["TWILIO_PHONE"],
to=os.environ["MY_PHONE"],
)
print("Snow alert sent!")
# Handle job status events (auto-stop by duration or trigger limit)
elif payload.get("type") == "job_stopped":
data = payload.get("data", {})
# Restart for continuous coverage when the job auto-stops
if data.get("auto_stopped"):
reason = data.get("reason", "unknown")
print(f"Job auto-stopped ({reason}), restarting...")
background_tasks.add_task(start_live_monitor_job)
else:
print("Job was manually stopped")
return {"status": "ok"}
```
Deploy this to Railway, Vercel, or any hosting provider.
## Step 3: Start Monitoring
The webhook server automatically starts the job on startup. If you need to manually start:
```bash theme={null}
curl -X POST https://trio.machinefi.com/api/live-monitor \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"stream_url": "https://youtube.com/watch?v=PITTSBURGH_LIVE_CAM",
"condition": "Is it snowing? Look for falling snowflakes or white accumulation.",
"webhook_url": "https://your-webhook-server.com/snow-alert",
"interval_seconds": 30
}'
```
## What Happens
1. Trio validates the URL is a live stream
2. Captures a frame every 30 seconds
3. Pre-filter checks for motion (skips static frames)
4. If motion detected, VLM analyzes the frame
5. If snow is detected, webhook fires with `watch_triggered`
6. Your server sends SMS via Twilio
7. After duration limit or `max_triggers` limit, job stops and sends `job_stopped`
8. Your server restarts the job automatically for continuous coverage
## Webhook Payloads
### Watch Trigger
```json theme={null}
{
"type": "watch_triggered",
"timestamp": "2024-01-26T15:30:00Z",
"source_url": "https://youtube.com/watch?v=PITTSBURGH_LIVE_CAM",
"data": {
"condition": "Is it snowing?",
"triggered": true,
"explanation": "Light snow is falling, visible as white particles against the dark buildings.",
"prefilter_skipped": false,
"frame_b64": "base64-encoded-image..."
}
}
```
### Job Auto-Stop (duration limit)
```json theme={null}
{
"type": "job_stopped",
"timestamp": "2024-01-26T15:40:00Z",
"source_url": "https://youtube.com/watch?v=PITTSBURGH_LIVE_CAM",
"data": {
"job_id": "abc123...",
"status": "stopped",
"checks_performed": 20,
"triggers_fired": 0,
"frames_skipped": 80,
"auto_stopped": true,
"reason": "max_duration_reached",
"watch_duration_seconds": 600.0
}
}
```
## Cost Analysis
With 10-minute job cycles and 30-second intervals:
| Metric | Per Job (10 min) | Per Hour | Per Day |
| --------------------------- | ---------------- | --------- | ----------- |
| Frames captured | 20 | 120 | 2,880 |
| VLM calls (with pre-filter) | \~5-10 | \~30-60 | \~720-1,440 |
| VLM cost | \~\$0.001 | \~\$0.006 | \~\$0.14 |
The pre-filter typically saves 50-70% on API costs by skipping static frames.
## Monitoring Dashboard
Check your job status and metrics:
```bash theme={null}
# Current jobs
curl https://trio.machinefi.com/api/jobs \
-H "Authorization: Bearer YOUR_API_KEY"
# API usage metrics (internal endpoint)
curl https://trio.machinefi.com/api/metrics \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "X-Trio-Internal: true"
# Recent logs (internal endpoint)
curl "https://trio.machinefi.com/api/logs?level=INFO&limit=20" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "X-Trio-Internal: true"
```
## Wrapping Up
You now have a production-ready snow alerting system that:
* Automatically restarts after 10-minute job limits
* Sends SMS alerts via Twilio
* Costs less than \$0.15/day with pre-filtering
The same pattern works for:
* Rain detection
* Fog/visibility monitoring
* Traffic incident detection
* Crowd density monitoring
Explore all live monitor endpoint options
# Tune Monitoring for Latency, Accuracy, and Cost
Source: https://docs.machinefi.com/guides/configuring-live-digest
Tune live-monitor and live-digest settings for reliability and efficiency
## Goal
Balance detection speed, output quality, and usage cost for your workload.
## Shared Tuning Principle
Start from a reliable condition, then adjust only one parameter at a time.
1. Validate stream with [Validate Stream](/api-reference/streams-validate)
2. Validate condition with [Check Once](/api-reference/check-once)
3. Launch monitor or digest
4. Review runtime output via [Get Job Details](/api-reference/jobs-get)
5. Iterate
## Live Monitor Levers
### `interval_seconds`
How often condition checks run.
* lower values: faster detection, higher usage
* higher values: slower detection, lower usage
### Condition quality
Precise conditions reduce false triggers and wasted reruns.
Guide: [Writing Reliable Conditions](/guides/writing-conditions)
## Live Digest Levers
### `window_minutes`
How much time each summary covers.
* shorter windows: more frequent summaries
* longer windows: fewer summaries
### `capture_interval_seconds`
How often frames are sampled.
* lower intervals: richer detail, higher usage
* higher intervals: lower usage, less detail
### `max_windows`
Optional cap on number of summary windows per job.
## Starting Profiles
### Fast incident detection (`live-monitor`)
```json theme={null}
{
"interval_seconds": 10
}
```
### Balanced digest (`live-digest`)
```json theme={null}
{
"window_minutes": 10,
"capture_interval_seconds": 60
}
```
### Cost-controlled digest (`live-digest`)
```json theme={null}
{
"window_minutes": 30,
"capture_interval_seconds": 180
}
```
## Common Mistakes
* Skipping `check-once` before long runs
* Changing multiple parameters at once
* Using vague conditions that inflate noise
## Next Steps
* Delivery mode selection: [Choose Your Workflow](/start-here/choose-workflow)
* Troubleshooting: [Debugging Playbook](/guides/debugging)
* Runtime field semantics: [Get Job Details](/api-reference/jobs-get)
# Debugging Playbook
Source: https://docs.machinefi.com/guides/debugging
Systematic triage for stream, condition, and job failures
## Goal
Find root causes quickly with a repeatable API-first debugging sequence.
## Fast Triage Loop
1. Re-run [Validate Stream](/api-reference/streams-validate).
2. Re-test condition with [Check Once](/api-reference/check-once).
3. Inspect [Get Job Details](/api-reference/jobs-get).
4. Map error code in the response payload.
## Failure Patterns and Fixes
### Stream validation fails
Symptoms:
* `NOT_LIVESTREAM`
* `STREAM_FETCH_FAILED`
* `STREAM_OFFLINE`
Actions:
* verify stream is currently live
* replace invalid/unreachable URLs
* retry after transient stream/network issues
### Condition never triggers
Symptoms:
* long-running jobs with no match
Actions:
* rewrite condition with explicit visual criteria
* validate with `check-once` before restarting monitor jobs
Reference: [Writing Reliable Conditions](/guides/writing-conditions)
### Job creation rejected
Symptoms:
* `MAX_JOBS_REACHED`
Actions:
* list jobs: [List Jobs](/api-reference/jobs-list)
* cancel stale jobs: [Cancel Job](/api-reference/jobs-delete)
### Delivery mismatch
Symptoms:
* expected SSE but got JSON
* expected webhook callbacks but none received
Actions:
* ensure `Accept: text/event-stream` for SSE
* ensure `webhook_url` is valid HTTPS and publicly reachable
* confirm your handler returns `2xx` promptly
## Decision Checklist During Incidents
* Is the stream still live?
* Does `check-once` confirm condition wording?
* Is job status progressing?
* Is delivery mode configured as intended?
## Next Steps
* Polling reliability patterns: [Use Polling](/guides/poll-jobs)
* Webhook reliability patterns: [Use Webhooks](/guides/webhooks)
* SSE client handling patterns: [Use SSE Streaming](/guides/sse-streaming)
# Use Polling
Source: https://docs.machinefi.com/guides/poll-jobs
Track async jobs with `GET /jobs/{job_id}`
## Goal
Track async jobs with predictable polling logic and clean terminal-state handling.
## Polling Workflow
1. Create a job with `live-monitor` or `live-digest`.
2. Store returned `job_id`.
3. Poll `GET /jobs/{job_id}` on an interval.
4. Exit on terminal status: `completed`, `stopped`, or `failed`.
## Reference Implementation (Python)
```python theme={null}
import time
import requests
BASE = "https://trio.machinefi.com/api"
HEADERS = {"Authorization": "Bearer YOUR_API_KEY", "Content-Type": "application/json"}
start = requests.post(
f"{BASE}/live-monitor",
headers=HEADERS,
json={
"stream_url": "https://www.youtube.com/watch?v=jfKfPfyJRdk",
"condition": "Is there a cat visible?"
},
timeout=30,
)
start.raise_for_status()
job_id = start.json()["job_id"]
while True:
status_resp = requests.get(f"{BASE}/jobs/{job_id}", headers=HEADERS, timeout=30)
status_resp.raise_for_status()
job = status_resp.json()
status = job["status"]
if status in ("completed", "stopped", "failed"):
print(f"Terminal status: {status}")
print(job.get("stats", {}))
break
time.sleep(5)
```
## Recommended Practices
* Start with 3-5 second intervals.
* Add request timeout guards in your client.
* Treat `404 JOB_NOT_FOUND` as terminal for stale/expired job IDs.
* Persist last known status for auditing.
## When to Switch Away
Use webhooks or SSE when:
* you need lower-latency push updates
* many clients are polling the same stream
* frontend UX needs live progress updates
## Next Steps
* Push callbacks: [Use Webhooks](/guides/webhooks)
* Streaming events: [Use SSE Streaming](/guides/sse-streaming)
* Status semantics: [Get Job Details](/api-reference/jobs-get)
# Use SSE Streaming
Source: https://docs.machinefi.com/guides/sse-streaming
Consume live monitor and digest events over Server-Sent Events
## Goal
Receive progress and result events over a single streaming HTTP response.
## When to Use
Use SSE when your UI or client needs near real-time updates without webhook infrastructure.
## Request Requirement
Send:
```http theme={null}
Accept: text/event-stream
```
## Live Monitor Example
```bash theme={null}
curl -N -X POST https://trio.machinefi.com/api/live-monitor \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-H "Accept: text/event-stream" \
-d '{
"stream_url":"https://www.youtube.com/watch?v=jfKfPfyJRdk",
"condition":"Is there a cat visible?"
}'
```
Common event names:
* `started`
* `progress`
* `triggered` (non-terminal trigger event when `max_triggers` > 1 or `null`)
* `stopped`
* `error`
## Live Digest Example
```bash theme={null}
curl -N -X POST https://trio.machinefi.com/api/live-digest \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-H "Accept: text/event-stream" \
-d '{
"stream_url":"https://www.youtube.com/watch?v=jfKfPfyJRdk",
"window_minutes":10,
"capture_interval_seconds":60
}'
```
Common event names:
* `started`
* `progress`
* `summary`
* `stopped`
* `error`
## Client Handling Rules
* Parse by event name, not by message text.
* Handle reconnects in your application if UX requires continuity.
* Treat `triggered` as non-terminal.
* Treat `stopped` and `error` as terminal stream events.
* Store `job_id` from start event when provided.
## Fallback
If streaming is interrupted or unsupported, use polling via `GET /jobs/{job_id}`.
## Next Steps
* Polling fallback: [Use Polling](/guides/poll-jobs)
* Callback delivery: [Use Webhooks](/guides/webhooks)
* Endpoint schema: [Live Monitor](/api-reference/live-monitor)
# Use Webhooks
Source: https://docs.machinefi.com/guides/webhooks
Deliver Trio events via webhook callbacks
## Goal
Receive Trio events through webhooks and process them safely in production.
## When to Use
Use webhooks when your system should react to events without polling loops.
Typical cases:
* trigger alerts
* start downstream workflows
* update external systems
## Setup Flow
1. Expose a public HTTPS endpoint that accepts `POST` JSON.
2. Start `live-monitor` or `live-digest` with `webhook_url`.
3. Return `2xx` quickly from your handler.
4. Process heavy work asynchronously.
## Minimal Handler Pattern
```python theme={null}
@app.post("/trio-webhook")
async def trio_webhook(request: Request):
payload = await request.json()
# enqueue payload for async processing
return {"ok": True}
```
## Event Types to Handle
Common `type` values:
* `job_started`
* `job_stopped`
* `watch_triggered`
* `summary_generated`
* `error`
## Reliability Requirements
* Use idempotency logic to avoid duplicate side effects.
* Log `type`, `timestamp`, and `job_id` (if present).
* Retry downstream actions with bounded backoff.
* Keep webhook handlers fast; do not block on long work.
## Recovery Pattern
If continuous coverage is required:
1. detect terminal state (`job_stopped`)
2. create a replacement job
3. persist and monitor the new `job_id`
## Next Steps
* Troubleshoot deliveries: [Debugging Playbook](/guides/debugging)
* Compare delivery modes: [Choose Your Workflow](/start-here/choose-workflow)
* Endpoint behavior: [Live Monitor](/api-reference/live-monitor)
# Writing Reliable Conditions
Source: https://docs.machinefi.com/guides/writing-conditions
Write condition text that produces stable yes/no decisions
## Why This Matters
Condition quality is the biggest controllable factor for reliable trigger behavior.
## Rule 1: Ask a Yes/No Question
Use binary wording that can be answered from visible evidence.
Good:
* `Is it snowing?`
* `Are there people visible near the entrance?`
* `Is a vehicle stopped in the lane?`
Avoid:
* `How many cars are there?`
* `Describe what is happening.`
* `What might happen next?`
## Rule 2: Define Visible Evidence
Specify what should count as a match.
Example:
* Weak: `Is there smoke?`
* Better: `Is there smoke visible rising from the building roof?`
## Rule 3: Keep One Intent per Condition
Avoid combining multiple checks in one sentence.
* Avoid: `Is there an accident or heavy traffic?`
* Better: `Is there a visible traffic accident?`
## Rule 4: Use Positive Language
Positive phrasing is easier to evaluate than negations.
* Avoid: `Is the lot not empty?`
* Better: `Are any vehicles visible in the lot?`
## Rule 5: Validate Before Long Jobs
Use `check-once` first, then promote to `live-monitor` only after wording is stable.
## Practical Iteration Loop
1. Draft condition with concrete visual criteria.
2. Test with [Check Once](/api-reference/check-once).
3. Review `triggered` and `explanation`.
4. Refine and retest.
5. Launch [Live Monitor](/api-reference/live-monitor).
## Example Patterns
### Weather
* `Is it actively raining? Look for visible rain streaks or wet pavement.`
* `Is there dense fog reducing visibility of distant objects?`
### Traffic
* `Is there a stopped vehicle blocking a travel lane?`
* `Is there visible bumper-to-bumper congestion?`
### Site Monitoring
* `Is anyone inside the fenced zone?`
* `Is equipment being moved by a person?`
## Next Steps
* Pick endpoint + delivery mode: [Choose Your Workflow](/start-here/choose-workflow)
* Debug missed triggers: [Debugging Playbook](/guides/debugging)
* Endpoint request details: [Check Once](/api-reference/check-once)
# Agent Project Setup
Source: https://docs.machinefi.com/integrations/agent-project-setup
Use Trio REST APIs in coding-agent workflows with OpenAPI-driven scaffolding
## Goal
Set up a coding agent to build features on top of Trio REST APIs with a repeatable workflow.
## OpenAPI Source
Use the OpenAPI schema as:
* Published docs link: [OpenAPI JSON](/openapi.json)
## Bootstrap Prompt (Copy-Paste)
```text theme={null}
You are an AI coding agent building a Trio REST API integration.
Sources of truth:
- OpenAPI schema: docs/openapi.json (repo) or /openapi.json (published). Do not invent fields.
- Base URL: https://trio.machinefi.com/api
- Error handling: /guides/debugging
Deliverables:
1) Typed API client with auth + JSON support.
2) Endpoint wrappers:
- POST /streams/validate
- POST /check-once
- POST /live-monitor
- POST /live-digest
- GET /jobs
- GET /jobs/{job_id}
- DELETE /jobs/{job_id}
3) Workflow functions:
- Preflight: validate_stream (consume parsed_url from response when needed)
- Sync check: check_once (returns triggered/explanation/latency)
- Async monitor: live_monitor -> poll_job_until_terminal -> optional cancel_job
- Async digest: live_digest -> webhook/SSE if configured; otherwise poll like monitor
4) Error handling:
- parse error response shape: { "error": { "code", "message", "remediation" } }
- handle 400/404/422/429 with actionable messages; treat JOB_NOT_FOUND as terminal
5) Tests:
- success path: validate -> live-monitor -> poll to terminal (mocked)
- success path: check-once returns triggered/explanation/latency (mocked)
- failure path: validate fails (INVALID_URL or NOT_LIVESTREAM)
Request details (from OpenAPI):
- ValidateStreamRequest: { stream_url }
- CheckOnceRequest: { stream_url, condition, input_mode, clip_duration_seconds, include_frame }
- LiveMonitorRequest: { stream_url, condition, interval_seconds, input_mode, clip_duration_seconds, webhook_url, monitor_duration_seconds, trigger_cooldown_seconds, max_triggers }
- LiveDigestRequest: { stream_url, window_minutes, capture_interval_seconds, include_frames, max_windows, webhook_url }
- Job status enum: pending | running | stopped | completed | failed
Constraints:
- Use Authorization: Bearer and Content-Type: application/json
- Add request timeouts; retry/backoff only on 429 or transient network errors
- Emit structured logs for each step (validate, check, start, poll, cancel)
- Return clean, typed results for client callers
Output:
- Provide usage examples for the client and workflows.
```
## Minimal Integration Flow
1. Validate URL with [Validate Stream](/api-reference/streams-validate).
2. Start job with [Live Monitor](/api-reference/live-monitor).
3. Poll [Get Job Details](/api-reference/jobs-get) until terminal status.
4. Use [Cancel Job](/api-reference/jobs-delete) if workflow aborts.
5. For push delivery, add [Webhooks](/guides/webhooks).
## Next Steps
* [MCP Integration](/integrations/mcp-integration) for direct agent tooling
* [Debugging Playbook](/guides/debugging) for resilient retries
* [How Trio Works](/core-concepts/how-trio-works)
# MCP Integration
Source: https://docs.machinefi.com/integrations/mcp-integration
Quick add and deep integration guide for Trio MCP tools, patterns, and troubleshooting
## Overview
Trio exposes six MCP tools for stream checks, long-running monitoring, summaries, and job management.
## Quick Add (Claude CLI)
For most users, this single command is enough:
```bash theme={null}
claude mcp add XXX --transport http https://trio.machinefi.com/mcp --header "Authorization: Bearer "
```
Replace:
* `XXX` with your local MCP server name (for example `trio`)
* `` with your Trio API token from `https://console.machinefi.com`
After this, the Trio MCP server and Claude CLI handle the remaining MCP tool wiring automatically.
## Tool Catalog
* `check_once`
* `live_monitor`
* `live_digest`
* `list_jobs`
* `get_job_status`
* `cancel_job`
## Typical Agent Pattern
1. Run `check_once` to validate prompt quality quickly.
2. Promote to `live_monitor` for persistent detection.
3. Use `list_jobs` and `get_job_status` for lifecycle tracking.
4. Stop with `cancel_job` when condition is no longer needed.
## Troubleshooting
* Confirm endpoint and auth header are correct.
* Ensure stream is currently live.
* For monitor timeout behavior, poll follow-up status before retrying.
## Related
* [Trio Agent Skill](/integrations/trio-agent-skill)
* [How Trio Works](/core-concepts/how-trio-works)
# Trio Agent Skill
Source: https://docs.machinefi.com/integrations/trio-agent-skill
High-quality system prompt for enabling Claude Code or other agents to use Trio
## Overview
The Trio Agent Skill is a ready-to-drop system prompt that teaches an agent how to use the Trio REST API safely and effectively. It standardizes validation, workflow selection, job management, and error handling so your agent behaves predictably across sessions.
If you want direct tool wiring instead of a prompt-based skill, use the
[MCP Integration](/integrations/mcp-integration).
## What You Get
* Full endpoint coverage for validate, check-once, live-monitor, live-digest, and jobs.
* Clear workflows for sync checks, long-running monitoring, and digest summaries.
* Guidance on input modes, condition quality, and resource management.
* Auth and safety rules to keep keys and user data protected.
## How to Use
For most agents, paste the template below into the system prompt or custom instructions.
For Claude Code or CLIs, save it as a local file and reference it during setup.
For custom agents, append it to your system message on initialization.
## Skill Template (Copy-Paste)
````text theme={null}
# Trio Agent Skill
> **Role:** You are an expert Video AI Agent capable of analyzing live streams (YouTube/RTSP) in real-time using the Trio API. You translate user intent into precise visual analysis tasks.
## 1. Core Capabilities
- **Stream Validation**: Verify stream availability and extract metadata (title, viewer count).
- **Instant Analysis**: Perform one-off checks to answer immediate questions (e.g., "Is the parking lot full?").
- **Continuous Monitoring**: Watch streams 24/7 for specific events (e.g., "Alert me when a red truck arrives").
- **Live Summaries**: Generate ongoing narrative logs of stream activity.
## 2. API & Tool Definitions
### A. Stream Validation
**Endpoint:** `POST /streams/validate`
**Purpose:** Always run this *first* to ensure the URL is valid and live.
**Payload:** `{"stream_url": "..."}`
**Response:** `{"is_live": true, "title": "Beach Cam", "parsed_url": "...", ...}`
### B. Instant Check (Check Once)
**Endpoint:** `POST /check-once`
**Purpose:** Quick "yes/no" analysis. Use this to test conditions before starting long-running jobs.
**Payload:**
```json
{
"stream_url": "...",
"condition": "A red car is visible",
"input_mode": "hybrid", // "frames" (static), "clip" (motion), "hybrid" (best accuracy)
"include_frame": true // Set true if user needs visual proof
}
```
### C. Continuous Monitoring
**Endpoint:** `POST /live-monitor`
**Purpose:** Long-running job that polls for an event.
**Payload:**
```json
{
"stream_url": "...",
"condition": "A person enters the room",
"input_mode": "clip", // Prefer "clip" or "hybrid" for monitoring
"interval_seconds": 10,
"webhook_url": "..." // Optional: for async notifications
}
```
### D. Live Digest
**Endpoint:** `POST /live-digest`
**Purpose:** Continuous summarization of the stream.
**Payload:**
```json
{
"stream_url": "...",
"window_minutes": 5,
"webhook_url": "..." // Optional
}
```
### E. Job Management
- **List Jobs:** `GET /jobs`
- **Get Job:** `GET /jobs/{job_id}`
- **Cancel Job:** `DELETE /jobs/{job_id}`
## 3. Operational Workflows
### Workflow 1: User asks "Is X happening right now?"
1. **Validate:** Call `/streams/validate` to check the URL.
- *If invalid:* Stop and inform the user.
2. **Analyze:** Call `/check-once` with the user's condition.
- Use `input_mode: "hybrid"` for best results unless specifically asked for "frames" (faster) or "clip" (motion-only).
3. **Report:** Present the `triggered` (true/false) status and the `explanation` to the user.
### Workflow 2: User asks "Tell me when X happens"
1. **Validate:** Call `/streams/validate`.
2. **Test:** Internally call `/check-once` to see if the condition is *already* met or if the model understands it. (Optional but recommended).
3. **Monitor:** Call `/live-monitor`.
4. **Confirm:** Tell the user "I am now watching the stream for [condition]. Job ID: [id]".
### Workflow 3: User asks "What's happening on this stream?"
1. **Validate:** Call `/streams/validate`.
2. **Digest:** Call `/live-digest`.
3. **Confirm:** Tell the user "I've started a digest job to summarize activity. Job ID: [id]".
## 4. Best Practices
- **Condition Crafting:** Use simple, visual descriptions.
- *Bad:* "Is it safe?" (Subjective)
- *Good:* "Are there any people wearing safety vests?" (Visual)
- **Input Modes:**
- Use `frames` for static objects (parked cars, weather).
- Use `clip` for motion/actions (running, falling, driving).
- Use `hybrid` for complex queries requiring both detail and motion.
- **Resource Management:**
- Always check for existing jobs on the same stream before starting a new one (`GET /jobs`).
- Cancel jobs (`DELETE /jobs/{job_id}`) when the user is done.
## 5. Security & Auth
- If an API Key is provided, include it in the header: `Authorization: Bearer `.
- Never expose API keys or internal job details in the final response.
````
[Download Raw Template](/integrations/assets/trio-skill-template.md)
# Authentication
Source: https://docs.machinefi.com/start-here/authentication
Set up your API key and make authenticated requests
## Goal
Make authenticated requests to Trio using a bearer API key.
## Base URL
All examples in these docs use:
`https://trio.machinefi.com/api`
## Step 1: Get an API Key
Create or copy your key from [console.machinefi.com](https://console.machinefi.com).
## Step 2: Send Bearer Auth
Every API request must include:
```http theme={null}
Authorization: Bearer YOUR_API_KEY
```
Example:
```bash theme={null}
curl -X POST https://trio.machinefi.com/api/streams/validate \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"stream_url":"https://www.youtube.com/watch?v=jfKfPfyJRdk"}'
```
## Step 3: Verify Auth Quickly
A successful authenticated call returns normal endpoint JSON.
If auth is missing or invalid, you will receive `401` errors. See [Debugging Playbook](/guides/debugging).
## Security Practices
* Keep API keys server-side whenever possible.
* Do not commit keys to source control.
* Rotate keys if you suspect exposure.
* Use separate keys per environment (dev, staging, prod).
## Next Steps
* Run first end-to-end flow: [First Successful Workflow](/start-here/quickstart)
* Decide endpoint/mode by use case: [Choose Your Workflow](/start-here/choose-workflow)
# Choose Your Workflow
Source: https://docs.machinefi.com/start-here/choose-workflow
Pick the right endpoint and delivery mode for your use case
## Endpoint Selection
| If you need... | Use |
| ------------------------------ | -------------------- |
| A fast yes/no answer right now | `POST /check-once` |
| Condition detection over time | `POST /live-monitor` |
| Periodic narrative summaries | `POST /live-digest` |
## Delivery Mode Selection
| Delivery mode | Best for | How to use |
| ---------------- | --------------------------- | ------------------------------------- |
| Synchronous JSON | Immediate answers | `POST /check-once` |
| Polling | Backend workers and scripts | Create job, then `GET /jobs/{job_id}` |
| Webhook | Event-driven automation | Send `webhook_url` in request body |
| SSE | Real-time client updates | Send `Accept: text/event-stream` |
## Practical Recommendations
1. Start with `check-once` to validate condition wording.
2. Move to `live-monitor` when you need trigger detection over time.
3. Use `live-digest` when you need summaries, not binary triggers.
4. Choose polling first for simple backend workflows.
5. Add webhooks or SSE when you need push delivery.
## Delivery Behavior by Endpoint
### `POST /check-once`
* Returns one JSON result.
* No job lifecycle to track.
### `POST /live-monitor`
* `webhook_url` present: webhook mode.
* `Accept: text/event-stream` and no `webhook_url`: SSE mode.
* Otherwise: polling mode (`job_id` + `GET /jobs/{job_id}`).
### `POST /live-digest`
* `Accept: text/event-stream` and no `webhook_url`: SSE mode.
* `webhook_url` present: webhook mode.
* Otherwise: polling mode.
## Next Steps
* Polling implementation: [Use Polling](/guides/poll-jobs)
* Webhook implementation: [Use Webhooks](/guides/webhooks)
* SSE implementation: [Use SSE Streaming](/guides/sse-streaming)
# Common Setup Issues
Source: https://docs.machinefi.com/start-here/faq
Fast answers for stream validation, conditions, jobs, and delivery modes
## Stream Setup
### Why does stream validation fail?
Common causes are:
* URL is not currently live (`NOT_LIVESTREAM`, `STREAM_OFFLINE`)
* URL format is invalid (`INVALID_URL`)
* Stream cannot be fetched (`STREAM_FETCH_FAILED`)
Start with [Validate Stream](/api-reference/streams-validate), then see [Debugging Playbook](/guides/debugging).
### Which stream types are supported?
* YouTube Live
* Twitch live channels
* RTSP and RTSPS sources
## Conditions
### Why does my condition never trigger?
Most misses come from vague wording. Use strict yes/no language and visible criteria.
Use this loop:
1. Test with [Check Once](/api-reference/check-once)
2. Refine condition text
3. Re-run monitor job
Reference: [Writing Reliable Conditions](/guides/writing-conditions)
## Jobs
### Why did my job stop?
Jobs can end because the condition was met, max duration was reached, the job was cancelled, or an error occurred.
Inspect current and final state with [Get Job Details](/api-reference/jobs-get).
### How do I continue coverage after a job ends?
Create a new monitor or digest job when the previous job reaches terminal state.
Implementation patterns:
* [Use Polling](/guides/poll-jobs)
* [Use Webhooks](/guides/webhooks)
### How do I cancel a running job?
Use [Cancel Job](/api-reference/jobs-delete) with the `job_id`.
## Delivery Modes
### Should I use polling, webhooks, or SSE?
* Polling: simplest for backend scripts.
* Webhooks: best for event-driven systems.
* SSE: best for real-time UI streaming.
Decision guide: [Choose Your Workflow](/start-here/choose-workflow)
## Reliability
### What is the fastest troubleshooting loop?
1. [Validate Stream](/api-reference/streams-validate)
2. [Check Once](/api-reference/check-once)
3. [Get Job Details](/api-reference/jobs-get)
4. [Debugging Playbook](/guides/debugging)
Also see: [Debugging Playbook](/guides/debugging)
## Next Steps
* Core behavior: [Monitoring Modes and Delivery Patterns](/core-concepts/how-trio-works)
* Production guides: [Guides](/guides/webhooks)
* Endpoint details: [API Reference](/api-reference/live-monitor)
# What You Can Build with Trio
Source: https://docs.machinefi.com/start-here/introduction
Understand Trio in one page and start the shortest path to production
## What Trio Does
Trio turns live video streams into API results you can automate against.
You send a stream URL and a natural-language condition, then choose the delivery pattern that fits your app:
* Immediate JSON response for one-off checks
* Async job + polling for backend workflows
* SSE for live client updates
* Webhooks for event-driven automation
## What This Documentation Covers
This documentation is focused on API consumption only:
* How to authenticate and call endpoints
* How to choose delivery patterns
* How to interpret responses and job states
* How to implement reliable production workflows
Internal implementation and architecture details are intentionally out of scope for these tabs.
## Product Surface in 60 Seconds
| Goal | Endpoint |
| -------------------------------- | ---------------------------------------------------------- |
| Confirm a stream is live | `POST /streams/validate` |
| Ask a yes/no question right now | `POST /check-once` |
| Watch for a condition over time | `POST /live-monitor` |
| Get periodic narrative summaries | `POST /live-digest` |
| Track async runs | `GET /jobs`, `GET /jobs/{job_id}`, `DELETE /jobs/{job_id}` |
## Vibe Coding with Agents
If you use a coding agent, you can hand it a ready-made prompt or doc and start building immediately. Pick the path that matches your workflow:
* **Agent Project Setup**: Full bootstrap prompt for building a Trio integration from the OpenAPI schema. [Agent Project Setup](/integrations/agent-project-setup)
* **MCP Integration**: One-line MCP setup for direct tool wiring in Claude CLI. [MCP Integration](/integrations/mcp-integration)
* **Trio Agent Skill**: A drop-in system prompt for agents that need best practices and workflows baked in. [Trio Agent Skill](/integrations/trio-agent-skill)
## Recommended Learning Path
1. Set up API auth: [Authentication](/start-here/authentication)
2. Run your first workflow: [First Successful Workflow](/start-here/quickstart)
3. Pick the right endpoint and delivery mode: [Choose Your Workflow](/start-here/choose-workflow)
4. Learn behavior and tradeoffs: [Monitoring Modes and Delivery Patterns](/core-concepts/how-trio-works)
5. Implement production patterns: [Guides](/guides/webhooks)
## Next Steps
* Start now: [Authentication](/start-here/authentication)
* Build your first run: [First Successful Workflow](/start-here/quickstart)
* Explore endpoint details: [API Reference](/api-reference/check-once)
# First Successful Workflow
Source: https://docs.machinefi.com/start-here/quickstart
Go from API key to a working Trio job in under 15 minutes
## Goal
Validate a stream, run one synchronous check, then start async monitoring and read job status.
## Prerequisites
* API key from [console.machinefi.com](https://console.machinefi.com)
* A live stream URL (YouTube Live, Twitch, RTSP, or RTSPS)
## Step 1: Validate Stream Liveness
```bash theme={null}
curl -X POST https://trio.machinefi.com/api/streams/validate \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"stream_url":"https://www.youtube.com/watch?v=jfKfPfyJRdk"}'
```
If this fails, resolve URL issues first before starting jobs.
## Step 2: Run One Immediate Check
```bash theme={null}
curl -X POST https://trio.machinefi.com/api/check-once \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"stream_url":"https://www.youtube.com/watch?v=jfKfPfyJRdk",
"condition":"Is there an animated character visible?"
}'
```
The response includes:
* `triggered`: boolean
* `explanation`: model explanation
* `latency_ms`: request latency
## Step 3: Start Continuous Monitoring
```bash theme={null}
curl -X POST https://trio.machinefi.com/api/live-monitor \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"stream_url":"https://www.youtube.com/watch?v=jfKfPfyJRdk",
"condition":"Is there a cat visible?"
}'
```
You receive a `job_id` and `status`.
## Step 4: Poll Job Status
```bash theme={null}
curl https://trio.machinefi.com/api/jobs/YOUR_JOB_ID \
-H "Authorization: Bearer YOUR_API_KEY"
```
Terminal statuses are `completed`, `stopped`, and `failed`.
## Step 5: Stop Early (Optional)
```bash theme={null}
curl -X DELETE https://trio.machinefi.com/api/jobs/YOUR_JOB_ID \
-H "Authorization: Bearer YOUR_API_KEY"
```
## What You Just Completed
* Pre-flight URL validation
* One synchronous condition check
* One async monitoring job
* Job lifecycle tracking via `/jobs/{job_id}`
## Next Steps
* Choose best mode for your app: [Choose Your Workflow](/start-here/choose-workflow)
* Write stronger prompts: [Writing Reliable Conditions](/guides/writing-conditions)
* Production delivery patterns: [Guides](/guides/webhooks)