---
title: "Dry-run a monitor against the last week"
method: POST
path: "/api/v1/tools/test_monitor/execute"
tags: ["Adako"]
---

# Dry-run a monitor against the last week

`POST /api/v1/tools/test_monitor/execute`

## Request

- Base URL: `https://adako.ai`
- URL: `https://adako.ai/api/v1/tools/test_monitor/execute`
- Auth: HTTP bearer

Runs a monitor — a saved one, or one described inline — against the synced data for each of the last 7 days and says which days it would have alerted on. Nothing is saved and no email is sent. Free.
Use when: the user is choosing a threshold, or says an alert is too noisy or too quiet. Always dry-run an inline rule before create_monitor when the user is unsure of the number.
Returns a day-by-day table with the value, the baseline and the verdict, plus the same one-line message the alert email would carry.
Pass monitor_id for a saved monitor, or the inline fields (platform, metric, operator, threshold) for a rule that does not exist yet.
If you are unsure which metric, account or threshold the user means, ask. Never invent a threshold.

## Headers

- `Idempotency-Key` string

## Request body

- object
  - `arguments` object
    - `monitor_id` string: A saved monitor to dry-run. Omit to describe one inline.
    - `platform` 'google_ads' | 'meta_ads' | 'chatgpt_ads' | 'tiktok_ads' | 'linkedin_ads': Which ad platform the monitor watches.
    - `account_id` string: Platform account id (Google customer id, Meta act_…). Defaults to the primary active account on the platform.
    - `metric` 'spend' | 'clicks' | 'impressions' | 'conversions' | 'conv_value' | 'ctr' | 'cpc' | 'cpa' | 'cpm' | 'roas' | 'conversion_rate' | 'cost_per_lead' | 'budget_utilization': What to watch. Rates are computed from the window totals: ctr = clicks/impressions, cpc = spend/clicks, cpa = spend/conversions, cpm = spend per 1,000 impressions, roas = conversion value/spend, conversion_rate = conversions/clicks, cost_per_lead = spend/leads, budget_utilization = spend/daily budget.
    - `operator` 'less_than' | 'greater_than' | 'changes_by' | 'drops_by' | 'rises_by': How to compare. less_than/greater_than use the threshold as a level; changes_by, drops_by and rises_by read the threshold as a percent move against the baseline.
    - `threshold` number
    - `threshold_type` 'absolute' | 'relative': absolute (default): the threshold is a value in the account currency or the metric's own unit. relative: the threshold is a multiplier of the baseline, so 0.5 means "half of the usual".
    - `baseline_days` integer
    - `consecutive_days` integer
    - `campaign_ids` string[]: Platform campaign ids as strings. Leave empty to watch the whole account.
    - `conditions` object: Optional extra conditions, for example "ROAS below 2 AND spend above 100".
      - `mode` 'and' | 'or', required: How the extra conditions combine with the main one.
      - `conditions` object[], required
        - `metric` 'spend' | 'clicks' | 'impressions' | 'conversions' | 'conv_value' | 'ctr' | 'cpc' | 'cpa' | 'cpm' | 'roas' | 'conversion_rate' | 'cost_per_lead' | 'budget_utilization', required: What to watch. Rates are computed from the window totals: ctr = clicks/impressions, cpc = spend/clicks, cpa = spend/conversions, cpm = spend per 1,000 impressions, roas = conversion value/spend, conversion_rate = conversions/clicks, cost_per_lead = spend/leads, budget_utilization = spend/daily budget.
        - `operator` 'less_than' | 'greater_than' | 'changes_by' | 'drops_by' | 'rises_by', required: How to compare. less_than/greater_than use the threshold as a level; changes_by, drops_by and rises_by read the threshold as a percent move against the baseline.
        - `threshold` number, required
        - `thresholdType` 'absolute' | 'relative'
    - `days` integer: How many past days to test. Default 7.
    - `raw_data` boolean: Return compact JSON only (no markdown). Use when you will compute on the result.

## Response `200`

The tool ran. A write returns proposal_id and approve_url while the change waits for approval.

- SuccessEnvelope
  - `success` unknown, required
  - `tool` string, required
  - `data` object, required: Machine-readable result.
  - `markdown` string, required: The same result written for a person or a model.
  - `quota` Quota: Task usage for the current billing period.
    - `plan` string
    - `used` integer
    - `limit` integer
    - `period_end` string
    - `upgrade_url` string
  - `proposal_id` string: Present for writes. Nothing changes on the ad platform until it is approved.
  - `approve_url` string: Where a person approves the proposal.
  - `request_id` string, required

## Other responses

- `400`: Invalid arguments, or the ad account could not be resolved.
- `401`: Missing, invalid, revoked or expired API key.
- `402`: Monthly task quota used up, or the plan does not include this tool.
- `403`: The connected ad account lacks the access level this tool needs.
- `404`: Unknown tool name.
- `409`: Not connected, reconnect needed, confirmation required, a proposal already pending or no longer pending, an identical create that failed earlier today (proposal_failed_before), a create that duplicates an approved one (duplicate_create), the ad-account limit of the plan reached (account_limit), or an Idempotency-Key reused with different arguments.
- `429`: Rate limited by Adako or by the ad platform. See Retry-After.
- `500`: Unexpected error inside Adako.
- `502`: The ad platform returned an error.

---

[API](https://skmtc.dev/adako/apis/adako-rest-api.md) · [All operations](https://skmtc.dev/adako/apis/adako-rest-api/llms.txt) · [OpenAPI document](https://skmtc.dev/adako/apis/adako-rest-api/revisions/59ee60d48a56?raw)
