---
title: "Create a daily monitor on an ad account"
method: POST
path: "/api/v1/tools/create_monitor/execute"
tags: ["Adako"]
---

# Create a daily monitor on an ad account

`POST /api/v1/tools/create_monitor/execute`

## Request

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

Saves a rule that Adako evaluates once a day against its synced copy of the account — no platform call, no task cost. When the rule holds it emails the operator, and when it carries an action it creates a proposal they can approve.
Use when: the user asks to be told about a metric ("alert me if…", "watch…", "let me know when…") and has named a metric, a direction and a number.
Do not use when: the user wants a one-off answer about the last few days — read the data instead. Do not create a second monitor for a rule that already exists; call list_monitors first.
Returns the monitor, the rule in plain words, and the day it will first be evaluated. Monitors read yesterday in the account's timezone once that day has fully synced (a day later for accounts far behind UTC), compared with a baseline of the previous baseline_days days.
A monitor with an action still changes nothing on its own: the action becomes a proposal the user approves. Actions need exactly one campaign id so the proposal names one object, and they run on Google Ads, Meta Ads, LinkedIn Ads and ChatGPT Ads; a monitor on any other platform emails and proposes nothing.
Watching an agency's whole platform: pass all_accounts instead of account_id. One monitor then covers every active account on that platform, each judged on its own numbers and currency, and one email a day lists the accounts that fired. Leave platform out as well and it covers every platform the user has connected. Either way it cannot carry an action or campaign ids, because both name one account.
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, required
    - `name` string, required: Short name the operator will recognise in email, for example "ROAS floor — Brand".
    - `platform` 'google_ads' | 'meta_ads' | 'chatgpt_ads' | 'tiktok_ads' | 'linkedin_ads': Which ad platform the monitor watches. Leave it out only with all_accounts, which then covers every synced platform this user has connected.
    - `account_id` string: Platform account id (Google customer id, Meta act_…). Defaults to the primary active account on the platform.
    - `all_accounts` boolean: Watch every active account on the platform instead of one, including accounts connected later. Each account is judged on its own numbers, in its own currency and its own timezone, so a money threshold means that number of each account's own currency. Leave it out, or pass false, to watch a single account.
    - `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: The number to compare against: a value in the account currency for money metrics, a count for volume metrics, a fraction for ctr / conversion_rate / budget_utilization (0.02 means 2%, never 2), a multiplier of the baseline when threshold_type is relative, or a percent move for changes_by / drops_by / rises_by.
    - `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: Days of history the baseline averages. Default 30.
    - `consecutive_days` integer: Require the rule to hold this many days in a row before alerting. Default 1.
    - `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'
    - `notify_email` string, email: Where to send the alert. Defaults to the account owner’s email. Any other address gets a confirmation link first, and alerts go to the owner’s email until someone at that address confirms.
    - `action` object: Optional. When set, a firing monitor creates a proposal the user still has to approve (in chat or at /approvals). Requires exactly one campaign id. Available on Google Ads, Meta Ads, LinkedIn Ads and ChatGPT Ads; on any other platform a monitor emails and proposes nothing.
      - `type` 'pause_campaign' | 'lower_budget', required: What to propose when the monitor fires. Nothing is applied automatically.
      - `percent` number: lower_budget only: how much to cut the daily budget by, in percent. Default 20.
    - `enabled` boolean: Create it switched off by passing false. Default true.

## 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)
