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.

At a glance
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
autopilot and pinned_keywords on 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.


PUT/v1/agents/:id/autonomy

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

    true turns autopilot on, the default. false keeps the agent's setup exactly as you set it.

  • Name
    cognition_enabled
    Type
    boolean
    Description

    false stops the agent reviewing its own runs, so autopilot changes nothing. The agent keeps collecting. true turns 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 or autopilot, 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

PUT
/v1/agents/:id/autonomy
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/v1/agents/:id/activity

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

GET
/v1/agents/:id/activity
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/v1/agents/:id/events

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) or news_scan (from the news, then confirmed on the platforms).
  • salience: importance from 0 to 10.
  • status: candidate, confirmed (active), dismissed, or expired.
  • evidence: url and views are null when the evidence is your agent's own videos.

Request

GET
/v1/agents/:id/events
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"
      }
    ]
  }
}

GET/v1/agents/:id/proposals

List proposals (deprecated)

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, or reverted. An unknown value returns an empty list, not an error.

  • Name
    limit
    Type
    integer
    Description

    1 to 100. Default 50.

Proposal typeWhat it proposes
keyword_refreshSwap stale keywords
filter_changeCollect more broadly
timely_keywordsAdd short-lived keywords for a breaking story
cadence_changeRun daily (costs more)
pausePause the agent
early_runAn extra run now, billed like any other
event_detectedAn alert, not a change. Dismiss it once read.

Request

GET
/v1/agents/:id/proposals
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"
      }
    ]
  }
}

POST

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 .../apply approves 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 .../dismiss rejects a pending proposal.
  • POST .../revert undoes 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

POST
/v1/agents/:id/proposals/:proposal_id/apply
curl -X POST https://api.virlo.ai/v1/agents/{agent_id}/proposals/{proposal_id}/apply \
  -H "Authorization: Bearer YOUR_API_KEY"

Was this page helpful?