signals

Create a scout config

Register the config for a skill immediately, without waiting for the coordinator to auto-register it — and the way to make a skill without the signals-scout- prefix a scout at all. The same call can optionally set run_interval_minutes, a cron run_cron_schedule, enabled, emit, network_access, and output destinations. The skill must already exist on this project. Upsert: if a config already exists for the skill, the provided fields are applied to it. Registering puts the skill's body on the schedule as the scout's prompt, so this call needs llm_skill:write and editor access to skills on top of signal_scout:write, like creating a scout.

post/api/projects/{project_id}/signals/scout/configs/

Request

  • Base URL: https://us.posthog.com
  • URL: https://us.posthog.com/api/projects/{project_id}/signals/scout/configs/
  • Auth: one of:
    • HTTP bearer
    • HTTP bearer

Path parameters

project_idstring required

Project ID of the project you're trying to access. To find the ID of the project, make a call to /api/projects/.

Request body

modelstring nullable

Optional model id this scout's runs are pinned to, e.g. claude-opus-4-5. Must be one of the platform's agent models; an invalid id is rejected with the available ones listed. Null keeps the default model, chosen by the platform. Early access: the pin can only be set on projects enrolled in the scout model preview, and only takes effect there. Set null to clear it.

tagsstring[]

Free-form labels for grouping the fleet, e.g. ["revenue", "on-call"]. Normalized to lowercase kebab-case (On Call and on_call both become on-call), deduped, and stored sorted; at most 10 tags, each at most 50 characters once normalized. Pass the full desired set — a write replaces the existing tags rather than merging into them. Filter the config list with the tags query parameter.

structured_output_schemaobject nullable

Optional JSON Schema (draft 2020-12) describing ONE structured record this scout produces via scout-record-output — e.g. a per-report quality judgment ({"type": "object", "properties": {"verdict": {"enum": ["good", "bad", "unsure"]}, "reason": {"type": "string"}}, "required": ["verdict", "reason"]}). The root must be "type": "object". Setting a schema turns the structured-output channel on: the run prompt renders the schema and every submitted record is validated against it and recorded in the project as a $scout_structured_output event, queryable like any event. The channel also requires emit — a dry-run scout has nowhere to record to. Cardinality is the scout's call (one record per run, one per judged entity, ...). Null = channel off. Setting a schema requires skill-authoring authorization (the llm_skill:write scope and skill editor access) since the scout reads it verbatim in its prompt; clearing it needs only the config write. Records validate against the schema in force when the run was dispatched.

mcp_gateway_server_idsstring[]

MCP gateway servers (by id) this scout's runs may use, chosen from the connections members shared to the whole team. Selection is per scout: an empty list gives the scout no MCP servers. Applies from the scout's next run.

repositoriesstring[]

GitHub repositories this scout clones into its sandbox, each in organization/repo format. Set them for a scout that reads code, so it can search the tree and run the project's own tests instead of reading files one API call at a time. Empty (the default) leaves the sandbox without a checkout. The scout's GitHub access stays read-only either way, so a repository listed here is never writable from a run. At most 10, each reachable through the project's GitHub connection. Applies from the scout's next run.

write_scopesstring[]

Extra write access granted to this one scout, as scope strings. The grantable set is alert:write, annotation:write, customer_task:write, dashboard:write, hog_flow_proposal:write, insight:write, llm_skill:write, replay_scanner:write, warehouse_table:write, warehouse_view:write. Empty (the default) means the scout reads the project and writes only what every scout may write: notebooks, its findings, and its own memory. Each scope is project-wide and object-level, so a scout holding dashboard:write can update or delete any dashboard in the project, not only ones it made. Grant only what this scout maintains. Only the person the scout's runs act as (whoever authored it) or a project admin can set it, and a scoped API key must itself carry each scope it grants. A dry run (emit=false) never holds the grant. Applies from the scout's next run.

lifecycle_lockedboolean

Opt-in guard on this scout's lifecycle. Off by default, so anyone with scout write access may pause, resume, switch the scout to dry run, or delete it. On, only the person the scout's runs act as or a project admin may do any of those, or change this flag. Use it on a scout whose output people depend on: signal_scout:write is a project-wide scope held by people and by unattended agents alike, and a resume has to pass the project's enabled-scout maximum that a pause does not, so a bulk pause is not undone in one step. The lock never stops an automatic pause, such as the inactivity sweep or the repeated-failure breaker.

allowed_mcp_toolsstring[] nullable

Exact MCP tool names selected for this scout, excluding its built-in run context tools. Null means no tool restriction; an empty list selects no additional tools. Write access is derived from selected write tools. Clearing to null preserves the last write scopes. Send this field or tool_preset, never both. Requires the scouts-tool-access feature flag.

tool_preset'read_only' | 'support_notes'
  • read_only - Read only
  • support_notes - Support notes
precheck_querystring nullable

Optional HogQL SELECT a scheduled run evaluates before it starts. When it returns no rows, or one row with one false value (false, 0, null or empty), the run is skipped: no sandbox, no model call, and no run row. Any other result starts the run, and the scout reads the rows. A query error also starts the run. Use {since} (the start of the last run that ran, or when the scout was created) and {now} to look only at what is new, e.g. SELECT count() FROM events WHERE event = '$exception' AND timestamp > {since}. To run at least once a week however quiet it is, add OR {since} < {now} - INTERVAL 7 DAY to the condition. Only scheduled runs evaluate it: a manual or workflow run always starts. {interval_minutes} is the gap between two scheduled runs, so a backstop can follow the schedule: {since} < {now} - toIntervalMinute(greatest(1440, 2 * {interval_minutes})) runs at least daily and never more often than every two intervals. The query stops after 10 seconds and reads at most 50 rows. Try a query with scout-config-precheck-test before you save it. Null or blank uses the default pre-check the scout's skill ships, if any. To turn every pre-check off, set precheck_disabled.

enabledboolean

Whether this scout runs on its schedule. Defaults to true.

emitboolean

Whether the scout writes findings to the inbox. False = dry-run: it runs and logs but emits nothing. Defaults to true.

run_interval_minutesinteger

Minutes between runs (30–43200). Defaults to 1440 (every 24 hours).

network_access'trusted' | 'full'
  • trusted - Trusted domains only
  • full - Full
auto_pause_exemptboolean

Exempt this scout from the inactivity pause, which otherwise switches off a scout that goes a fortnight without surfacing anything anyone engages with. Set it on watchdog scouts whose value is staying quiet. Defaults to false.

run_cron_schedulestring nullable

Optional five-field cron expression, e.g. '30 9 * * *' (daily at 09:30), '0 9,17 * * *' (twice daily), or '0 9 * * 1-5' (weekday mornings). Evaluated in the project timezone. Takes precedence over run_interval_minutes; occurrences must be at least 30 minutes apart.

display_namestring

Name shown wherever people identify this scout, written however you want it — spaces, capitalization, and acronyms are kept as typed, and two scouts may share one. It does not change the scout's skill name, which stays its identity, so renaming a scout keeps its schedule, run history, notes, memory, and links. At most 200 characters; blank means the scout has no name of its own and is labelled from its skill name instead.

skill_namestring required

The skill to register a config for. Any valid skill name works — the config row is what makes a skill a scout. The skill must already exist on this project — author it via the skills store first.

Response

A config already existed for this skill; the provided fields were applied to it.

idstring uuid required
skill_namestring required

The skill this config controls as a scout. Set at creation, not editable.

descriptionstring required

Human-readable summary of what this scout investigates, sourced from the scout skill's description metadata. Use it for a quick steer on the scout's focus without loading the full skill body. Empty if the skill is not currently present on the team or carries no description.

display_namestring

Name shown in the UI. Does not change the skill name. Leave blank to use the default name.

scout_origin'canonical' | 'custom' required
  • canonical - canonical
  • custom - custom
scout_role'specialist' | 'operational' required
enabledboolean required

Whether this scout runs on its schedule. Disabled scouts are skipped by the coordinator. Derived from status: true for active and pending_pause, false for the paused statuses.

status'active' | 'pending_pause' | 'paused_by_system' | 'paused_by_user' required
  • active - Active
  • pending_pause - Pending pause
  • paused_by_system - Paused by system
  • paused_by_user - Paused by user
managed_by'team' | 'background' required
  • team - Team
  • background - Background
emitboolean required

Whether the scout writes findings to the inbox. False = dry-run: it runs and logs but emits nothing.

run_interval_minutesinteger required

Minutes between runs (30–43200). The scout runs once this interval has elapsed since its last run.

run_cron_schedulestring nullable required

Optional five-field cron expression evaluated in the project timezone, e.g. '30 9 * * *'. Takes precedence over run_interval_minutes when set. Null means the rolling interval schedule.

structured_output_schemaobject nullable required

Optional JSON Schema (draft 2020-12) describing ONE structured record this scout produces via scout-record-output — e.g. a per-report quality judgment ({"type": "object", "properties": {"verdict": {"enum": ["good", "bad", "unsure"]}, "reason": {"type": "string"}}, "required": ["verdict", "reason"]}). The root must be "type": "object". Setting a schema turns the structured-output channel on: the run prompt renders the schema and every submitted record is validated against it and recorded in the project as a $scout_structured_output event, queryable like any event. The channel also requires emit — a dry-run scout has nowhere to record to. Cardinality is the scout's call (one record per run, one per judged entity, ...). Null = channel off. Setting a schema requires skill-authoring authorization (the llm_skill:write scope and skill editor access) since the scout reads it verbatim in its prompt; clearing it needs only the config write. Records validate against the schema in force when the run was dispatched.

network_access'trusted' | 'full' required
  • trusted - Trusted domains only
  • full - Full
modelstring nullable required

Optional model id this scout's runs are pinned to, e.g. claude-opus-4-5. Must be one of the platform's agent models; an invalid id is rejected with the available ones listed. Null keeps the default model, chosen by the platform. Early access: the pin can only be set on projects enrolled in the scout model preview, and only takes effect there. Set null to clear it.

mcp_gateway_server_idsstring[] required

MCP gateway servers (by id) this scout's runs may use, chosen from the connections members shared to the whole team. Selection is per scout: an empty list gives the scout no MCP servers. Applies from the scout's next run.

repositoriesstring[]

GitHub repositories this scout clones into its sandbox, each in organization/repo format. Set them for a scout that reads code, so it can search the tree and run the project's own tests instead of reading files one API call at a time. Empty (the default) leaves the sandbox without a checkout. The scout's GitHub access stays read-only either way, so a repository listed here is never writable from a run. At most 10, each reachable through the project's GitHub connection. Applies from the scout's next run.

write_scopesstring[] required

Extra write access granted to this one scout, as scope strings. The grantable set is alert:write, annotation:write, customer_task:write, dashboard:write, hog_flow_proposal:write, insight:write, llm_skill:write, replay_scanner:write, warehouse_table:write, warehouse_view:write. Empty (the default) means the scout reads the project and writes only what every scout may write: notebooks, its findings, and its own memory. Each scope is project-wide and object-level, so a scout holding dashboard:write can update or delete any dashboard in the project, not only ones it made. Grant only what this scout maintains. Only the person the scout's runs act as (whoever authored it) or a project admin can set it, and a scoped API key must itself carry each scope it grants. A dry run (emit=false) never holds the grant. Applies from the scout's next run.

lifecycle_lockedboolean required

Opt-in guard on this scout's lifecycle. Off by default, so anyone with scout write access may pause, resume, switch the scout to dry run, or delete it. On, only the person the scout's runs act as or a project admin may do any of those, or change this flag. Use it on a scout whose output people depend on: signal_scout:write is a project-wide scope held by people and by unattended agents alike, and a resume has to pass the project's enabled-scout maximum that a pause does not, so a bulk pause is not undone in one step. The lock never stops an automatic pause, such as the inactivity sweep or the repeated-failure breaker.

allowed_mcp_toolsstring[] nullable required

Exact MCP tool names selected for this scout, excluding its built-in run context tools. Null means no tool restriction; an empty list selects no additional tools. Write access is derived from selected write tools. Clearing to null preserves the last write scopes. Send this field or tool_preset, never both. Requires the scouts-tool-access feature flag.

tool_presetstring nullable required

Preset used to select the saved tool list, custom for an explicit list, or null when unrestricted.

precheck_querystring nullable required

Optional HogQL SELECT a scheduled run evaluates before it starts. When it returns no rows, or one row with one false value (false, 0, null or empty), the run is skipped: no sandbox, no model call, and no run row. Any other result starts the run, and the scout reads the rows. A query error also starts the run. Use {since} (the start of the last run that ran, or when the scout was created) and {now} to look only at what is new, e.g. SELECT count() FROM events WHERE event = '$exception' AND timestamp > {since}. To run at least once a week however quiet it is, add OR {since} < {now} - INTERVAL 7 DAY to the condition. Only scheduled runs evaluate it: a manual or workflow run always starts. {interval_minutes} is the gap between two scheduled runs, so a backstop can follow the schedule: {since} < {now} - toIntervalMinute(greatest(1440, 2 * {interval_minutes})) runs at least daily and never more often than every two intervals. The query stops after 10 seconds and reads at most 50 rows. Try a query with scout-config-precheck-test before you save it. Null or blank uses the default pre-check the scout's skill ships, if any. To turn every pre-check off, set precheck_disabled.

precheck_disabledboolean required

True turns off the pre-check, both precheck_query and the default the skill ships, so every scheduled run starts. False (the default) uses precheck_query, or the skill default when that is null.

effective_precheck_querystring nullable required

The pre-check query the next scheduled run uses: precheck_query, or the default the scout's skill ships. Null when no pre-check runs.

precheck_query_source'config' | 'skill_default' | 'off' required
last_run_atstring date-time nullable required

When the coordinator last dispatched this scout. Null if it has never run.

consecutive_failure_countinteger required

How many of this scout's runs have failed in a row. Back to 0 after a successful run or any config edit. At the failure limit the scout pauses itself (status becomes paused_by_system with pause_reason repeated_failures) and retries about once a day; a successful retry resumes it, and so does setting enabled=true.

status_changed_atstring date-time nullable required

When status last changed. For pending_pause this is when the warning was issued (an ignored warning pauses about a week later unless someone engages with the scout's reports — opening one counts; a no_output warning only flags the scout); for the paused statuses it is when the scout was paused. Null if the status never changed.

auto_pause_exemptboolean required

Whether this scout is exempt from the inactivity sweep, meaning both the ignored pause and the no_output quiet warning. Set it on watchdog scouts whose value is staying quiet. Only ever set explicitly: re-enabling a swept scout instead grants a fresh grace window before the sweep may judge it again.

tagsstring[]

Free-form labels for grouping the fleet, e.g. ["revenue", "on-call"]. Normalized to lowercase kebab-case (On Call and on_call both become on-call), deduped, and stored sorted; at most 10 tags, each at most 50 characters once normalized. Pass the full desired set — a write replaces the existing tags rather than merging into them. Filter the config list with the tags query parameter.

source_productstring nullable required

The product that stood this scout up for one of its own objects. Null when a person created it.

source_idstring nullable required

Id of the owning object in source_product, e.g. a Replay Vision scanner id.

created_atstring date-time required
updated_atstring date-time required

When this config last changed: an edit through this API, or a status change the system made such as an automatic pause. A scheduled run does not bump it — the coordinator stamps last_run_at with a direct write — so this reads as when the scout was last tuned rather than when it last ran.

Changes

No recorded changes to this operation across all 1 revision of this API.