---
title: "Update a content research agent"
method: PUT
path: "/v1/agents/{id}"
tags: ["Content Research Agents"]
---

# Update a content research agent

`PUT /v1/agents/{id}`

## Request

- Base URL: `https://api.virlo.ai`
- URL: `https://api.virlo.ai/v1/agents/{id}`
- Auth: HTTP bearer

Updates mutable config. Collection scope (min_views/time_range) is system-managed and cannot be set here.

## Path parameters

- `id` string, required

## Request body

- V1UpdateAgentDto
  - `name` string: Human-friendly name.
  - `active` boolean: Whether the agent is active (recurring runs will be scheduled).
  - `keywords` string[]: Keywords (1-50). Hashtag tokens normalised. Replaces the whole list; autopilot keeps every keyword you set and only adds around them.
  - `platforms` string[]: Platforms to collect from.
  - `cadence` string: Schedule cadence (recurring agents only): "daily", "weekly", "monthly", or a cron expression (minimum daily).
  - `exclude_keywords` string[]: Noise terms to filter out — matched as WHOLE WORDS against captions + hashtags, so use the single word people actually type for the OTHER meaning (researching Apple the company, not the fruit? exclude `recipe`, `fruit`, `orchard`), not multi-word phrases like `apple the fruit` (which never match). Never exclude a word that is part of your own topic. Tip: suggest-keywords returns a ready exclude_keywords list you can pass straight in.
  - `exclude_keywords_strict` boolean: If true, also match exclude_keywords against the video transcript (speech), not just the caption/hashtags — use when the noise word is spoken but rarely written. Default false.
  - `meta_ads_enabled` boolean: Enable Meta ads collection.
  - `intent` string: Research intent (plain language).
  - `data_intelligence_enabled` boolean: Enable per-video AI intelligence.
  - `english_only` boolean: When true, only English-language content is collected. Set false to collect any language.
  - `autopilot` boolean: Turn autopilot on (true) or off (false). Off keeps the configuration exactly as you set it.

## Response `200`

Agent updated

- UpdateAgentResponseDto
  - `data` AgentConfigDto, required
    - `id` string, uuid, required
    - `name` string, nullable
    - `is_recurring` boolean, required: false = one-shot (formerly Orbit); true = recurring + cadence (formerly Comet)
    - `active` boolean, required
    - `team_id` string, nullable
    - `source` string, nullable
    - `keywords` string[], required
    - `platforms` string[], required
    - `exclude_keywords` string[], required
    - `exclude_keywords_strict` boolean, required
    - `meta_ads_enabled` boolean, required
    - `data_intelligence_enabled` boolean, required
    - `english_only` boolean, required
    - `intent` string, nullable
    - `intent_keywords` string[], nullable: The expanded keyword set the agent actually searched, derived from your `intent` + `keywords`. Null until the first run resolves it. Useful for seeing how the agent interpreted your intent.
    - `autopilot` boolean, required: Whether autopilot is on. On by default: after each run a recurring agent rewords its searches, adds keywords and follows breaking stories so it keeps finding new videos. It never removes a keyword or exclude term you set. Turn it off with `autopilot: false` on `PUT /v1/agents/:id`.
    - `pinned_keywords` string[], nullable: The keywords you set. Autopilot always keeps these and only adds around them, so `keywords` holds these plus any autopilot added. Replaced whenever you send `keywords`. Null for agents created in the Virlo app.
    - `autonomy_level` 'suggest' | 'autopilot', required: Older two-field spelling of `autopilot`: "autopilot" = on, "suggest" = off. Read `autopilot` instead.
    - `autopilot_unlocked` boolean, required: Legacy field from when autopilot had to be unlocked first; it no longer gates anything. Read `autopilot` instead.
    - `cognition_enabled` boolean, required
    - `cadence` string, nullable: Cron cadence. Null for one-shot agents.
    - `next_run_at` string, nullable
    - `last_run_at` string, nullable
    - `is_processing` boolean, required
    - `created_at` string, required
    - `updated_at` string, required
    - `latest_run` AgentRunDto
      - `id` string, uuid, required
      - `agent_id` string, uuid, required
      - `status` 'pending' | 'processing' | 'completed' | 'partial_failure' | 'failed', required: `pending` and `processing` are in flight. `completed`, `partial_failure` and `failed` are final. `partial_failure` means one platform or keyword failed and the rest of the data is usable.
      - `total_videos_inserted` number, required
      - `total_videos_updated` number, required
      - `total_videos_failed` number, required
      - `videos_linked` number, required
      - `meta_ads_linked` number, required
      - `slideshows_linked` number, required
      - `youtube_count` number, required
      - `tiktok_count` number, required
      - `instagram_count` number, required
      - `exclude_keywords_filtered` number, required
      - `intent_filtered` number, required
      - `language_filtered_count` number, required
      - `duplicates_dropped` number, required
      - `outliers_identified` number, required
      - `trends_detected` string[], nullable
      - `keyword_breakdown` object[], nullable: Per-keyword collection breakdown. One entry per keyword with `keyword`, `videos_inserted`, `videos_updated`, and per-platform counts (`tiktok_count`, `youtube_count`, `instagram_count`). The fastest way to see which keywords are actually producing content.
      - `execution_time_ms` number, required
      - `created_at` string, required
      - `started_at` string, nullable
      - `completed_at` string, nullable
  - `message` string, required

## Other responses

- `401`: Missing or invalid API key (`missing_api_key` / `invalid_api_key`)
- `404`: Agent not found
- `429`: Rate limit exceeded (`rate_limit_exceeded`); see the Retry-After header

---

[API](https://skmtc.dev/virlo/apis/virlo-public-api.md) · [All operations](https://skmtc.dev/virlo/apis/virlo-public-api/llms.txt) · [OpenAPI document](https://skmtc.dev/virlo/apis/virlo-public-api/revisions/3b69c6145087?raw)
