Autopilot
After each run, a recurring Content Research Agent tunes its own keywords so it keeps finding new videos. Autopilot is on for every new agent, and it never removes the keywords you set.
- What it does
- Rewords the agent's searches, adds keywords, follows breaking stories in its niche, and collects more widely after a thin run. One-time agents do none of this.
- You send
- Nothing. It is on by default. To turn it off, send
autopilot: false. - You get back
autopilotandpinned_keywordson every agent, plus an activity log of what changed and why.- Cost
- Free. Autopilot never adds charges. The price per run stays the same, and it never starts an extra billed run.
How autopilot works
Autopilot is on by default for every new recurring agent (is_recurring: true), whether you make it through the API, over MCP, or in the Virlo app. There is nothing to unlock.
After each run, autopilot can:
- Reword the agent's searches.
- Add keywords, up to 15 in all. If you set 15 or more yourself, it keeps them all and adds none.
- Add short-lived timely keywords for a breaking story in the niche (events). They expire on their own.
- Collect more widely when a run comes back thin.
Every keyword change has to pass a quality check first. The activity log records each change and the reason for it.
Autopilot never:
- Removes a keyword or exclude term you set on an agent made through the API or MCP (see Your keywords stay).
- Adds charges. The price per run stays the same, and it never starts an extra billed run.
- Changes the schedule (
cadence) or pauses the agent.
To turn it off, send autopilot: false when you create or update the agent, or use Turn autopilot on or off. The agent then keeps its setup exactly as you set it, and it still runs on schedule.
Agent responses show the setting as autopilot, true when it is on. autonomy_level and autopilot_unlocked are older fields that still come back. Read autopilot instead.
Your keywords stay
The keywords you send are pinned. The agent returns them as pinned_keywords, and autopilot only adds around them, so keywords holds yours plus any autopilot added.
Send new keywords with Update agent and your list replaces the pinned one. Your edits win. Exclude terms work the same way: autopilot never removes one you set in exclude_keywords.
Agents made in the Virlo app have no pinned keywords (pinned_keywords: null), even after you edit them through the API, so autopilot manages their whole list.
Turn autopilot on or off
Turns autopilot on or off for one agent. It does the same as autopilot on Update agent. Free. Send at least one field.
- Name
autopilot- Type
- boolean
- Description
trueturns autopilot on, the default.falsekeeps the agent's setup exactly as you set it.
- Name
cognition_enabled- Type
- boolean
- Description
falsestops the agent reviewing its own runs, so autopilot changes nothing. The agent keeps collecting.trueturns reviews back on.
- Name
autonomy_level- Type
- string
- Description
The older way to set the same switch, still accepted.
"autopilot"is on and"suggest"is off. Send this orautopilot, not both.
An empty body returns 400 (No autonomy fields provided). So does sending autopilot and autonomy_level with different answers (autopilot and autonomy_level disagree; send one of them).
Request
curl -X PUT https://api.virlo.ai/v1/agents/{agent_id}/autonomy \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "autopilot": false }'
Get activity
The agent's change log: what it noticed, what autopilot changed, and why. Newest first. Free. Empty for one-time agents, and possibly right after a recurring agent's first run.
Each entry has content, created_at, and a category: usually observation, decision, or milestone, sometimes user_pref (a note about your preferences).
- Name
limit- Type
- integer
- Description
- 1 to 100. Default
20.
Request
curl -G https://api.virlo.ai/v1/agents/{agent_id}/activity \
-H "Authorization: Bearer YOUR_API_KEY" \
-d limit=20
Response
{
"data": {
"agent_id": "a1f3c8e2-0b7d-4a91-9c2e-2f5d6b8e1a44",
"count": 1,
"activity": [
{
"content": "This run collected 283 videos, and 71% were on target. No-cook recipes drove most of the reach.",
"category": "observation",
"created_at": "2026-10-04T02:31:04.325401+00:00"
}
]
}
}
Get events
Breaking stories a recurring agent spotted in its niche, such as a launch or a controversy. Free. Active events come first, most important first. The content_research_agent.event.detected webhook fires as soon as one is confirmed.
- Name
limit- Type
- integer
- Description
- 1 to 100. Default
50.
Full field reference
source:corpus_burst(spotted in your agent's videos) ornews_scan(from the news, then confirmed on the platforms).salience: importance from 0 to 10.status:candidate,confirmed(active),dismissed, orexpired.evidence:urlandviewsarenullwhen the evidence is your agent's own videos.
Request
curl -G https://api.virlo.ai/v1/agents/{agent_id}/events \
-H "Authorization: Bearer YOUR_API_KEY" \
-d limit=50
Response
{
"data": {
"agent_id": "a1f3c8e2-0b7d-4a91-9c2e-2f5d6b8e1a44",
"count": 1,
"events": [
{
"id": "c12fc742-7c5d-44fd-9b9c-765710147980",
"title": "New protein cereal launch",
"summary": "A major cereal brand launched a 20g-protein cereal, and taste tests are spreading.",
"source": "news_scan",
"salience": 8,
"status": "confirmed",
"keywords": ["protein cereal launch"],
"evidence": [
{
"url": "https://example.com/protein-cereal-launch",
"views": null,
"description": "Cereal brand announces a 20g-protein cereal"
}
],
"detected_at": "2026-10-01T23:52:14.965821+00:00",
"confirmed_at": "2026-10-01T23:52:15.102+00:00",
"expires_at": "2026-10-08T23:52:21.405+00:00"
}
]
}
}
List proposals (deprecated)
Deprecated. Autopilot applies changes itself, and Get activity shows what changed and why. The proposal endpoints still work for now and send a Deprecation: true header. There is no removal date yet.
The changes this agent has proposed, newest first. Free. Changes autopilot made show as auto_applied. With autopilot off, changes wait here as pending.
- Name
status- Type
- string
- Description
pending,applied,auto_applied,dismissed, orreverted. An unknown value returns an empty list, not an error.
- Name
limit- Type
- integer
- Description
1 to 100. Default
50.
Proposal type | What it proposes |
|---|---|
keyword_refresh | Swap stale keywords |
filter_change | Collect more broadly |
timely_keywords | Add short-lived keywords for a breaking story |
cadence_change | Run daily (costs more) |
pause | Pause the agent |
early_run | An extra run now, billed like any other |
event_detected | An alert, not a change. Dismiss it once read. |
Request
curl -G https://api.virlo.ai/v1/agents/{agent_id}/proposals \
-H "Authorization: Bearer YOUR_API_KEY" \
-d status=pending
Response
{
"data": {
"agent_id": "a1f3c8e2-0b7d-4a91-9c2e-2f5d6b8e1a44",
"count": 1,
"proposals": [
{
"id": "b94357b3-0c3b-4289-87c7-648beb1fe31f",
"content_research_agent_id": "a1f3c8e2-0b7d-4a91-9c2e-2f5d6b8e1a44",
"type": "timely_keywords",
"source": "event",
"rationale": "Detected \"New protein cereal launch\" in your niche. Adding 1 timely keyword.",
"diff": {
"before": { "timely_keywords": [] },
"after": {
"event_id": "c12fc742-7c5d-44fd-9b9c-765710147980",
"timely_additions": [
{ "keyword": "protein cereal launch", "expires_at": "2026-10-08T23:52:21.405+00:00" }
]
},
"event": { "title": "New protein cereal launch", "salience": 8 }
},
"status": "pending",
"created_at": "2026-10-01T23:52:25.448948+00:00",
"decided_at": null,
"updated_at": "2026-10-01T23:52:25.448948+00:00"
}
]
}
}
Apply, dismiss, or revert a proposal (deprecated)
Deprecated, like List proposals. Three free calls, under /v1/agents/:id/proposals/:proposal_id/. Applying an early_run starts an extra run, billed like any other.
POST .../applyapproves a pending proposal and makes the change. On an agent made through the API, the keywords and exclude terms you approve become your pinned lists.POST .../dismissrejects a pending proposal.POST .../revertundoes an applied or auto-applied change.
Only pending proposals can be applied or dismissed, and only applied or auto-applied ones reverted. Otherwise you get 400, such as Proposal ... is already applied. event_detected has nothing to apply, so dismiss it. Applying early_run returns 400 if the agent ran in the last 24 hours or your balance can't cover the run.
To stop autopilot changing an agent, turn it off with autopilot: false (Turn autopilot on or off) instead of reverting each change.
Request
curl -X POST https://api.virlo.ai/v1/agents/{agent_id}/proposals/{proposal_id}/apply \
-H "Authorization: Bearer YOUR_API_KEY"
