---
title: "Create a recurring diagnostic scan schedule."
method: POST
path: "/v1/scheduled-scans"
tags: ["Scheduled scans"]
---

# Create a recurring diagnostic scan schedule.

`POST /v1/scheduled-scans`

## Request

- Base URL: `https://api.on-page.ai`
- URL: `https://api.on-page.ai/v1/scheduled-scans`
- Auth: HTTP bearer
- TypeScript: <https://skmtc.dev/on-page/apis/on-page-ai-api/docs/v1/scheduled-scans/post.ts> (a function with typed inputs; its response is checked against the schema)

Runs while the desktop app is closed. Each occurrence uses the caller's On-Page.ai credits, enforces per-run and monthly budgets, and never performs unattended site edits.

## Request body

- object
  - `name` string, required
  - `url` string, uri, required
  - `keyword` string, required: Primary search keyword. Whitespace is normalized. Must be a concise search query: max 150 characters.
  - `depth` 'lite' | 'standard' | 'deep'
  - `region` 'US' | 'CA' | 'UK' | 'AU' | 'NZ' | 'ES' | 'DE' | 'IT' | 'FR' | 'IE' | 'NL' | 'CH' | 'SE' | 'NO' | 'DK' | 'FI' | 'ZA' | 'MX' | 'BR' | 'CO' | 'IN' | 'SG' | 'MY' | 'JP' | 'KE' | 'AE' | 'HK': Region code. Case-insensitive and trimmed on input. Use canonical uppercase codes in response bodies. See GET /v1/regions.
  - `locale` string: BCP-47 locale tag. Canonicalized via Intl.Locale (`en_us` → `en-US`; `zh_hant_hk` → `zh-Hant-HK`). Max 16 chars.
  - `cadence` object, required
    - `frequency` 'daily' | 'weekly' | 'monthly', required
    - `timezone` string, required
    - `time` string, required
    - `day_of_week` integer
    - `day_of_month` integer
  - `max_credits_per_run` number, required
  - `monthly_credit_budget` number, required
  - `alert_thresholds` object
    - `score_drop` number
    - `entity_loss_count` integer
    - `competitor_gap_increase` number

## Response `201`

Schedule created.

- ScheduledScanEnvelopeResponse
  - `schedule` object, required
    - `id` string, required
    - `name` string, required
    - `url` string, uri, required
    - `keyword` string, required
    - `depth` 'lite' | 'standard' | 'deep', required
    - `region` string, required
    - `locale` string, nullable, required
    - `cadence` object, required
      - `frequency` 'daily' | 'weekly' | 'monthly', required
      - `timezone` string, required
      - `time` string, required
      - `day_of_week` integer
      - `day_of_month` integer
    - `status` 'active' | 'paused', required
    - `pause_reason` string, nullable, required
    - `max_credits_per_run` number, required
    - `monthly_credit_budget` number, required
    - `current_month_spend` number, required
    - `alert_thresholds` object
      - `score_drop` number
      - `entity_loss_count` integer
      - `competitor_gap_increase` number
    - `next_run_at` string, nullable, required
    - `last_run_at` string, nullable, required
    - `created_at` string, required
    - `updated_at` string, required

## Other responses

- `400`: Validation error
- `401`: Unauthorized
- `402`: Scheduled monitoring requires an active subscription entitlement or sufficient credits.
- `403`: Scope forbidden
- `422`: URL not allowed
- `429`: Too many requests. Body is a `oneOf` of rate-limit / org-active-limit / org-queued-limit / scan-queue-saturated variants — branch on `error.code`. `Retry-After` is present when the limiter emits it; `X-RateLimit-*` is present on rate-limit-middleware 429s; `X-Concurrency-*` is present on concurrency-limit 429s (ORG_ACTIVE_LIMIT_REACHED / ORG_QUEUED_LIMIT_REACHED).
- `500`: Internal error
- `503`: Scheduled scans are disabled in this environment.

---

[API](https://skmtc.dev/on-page/apis/on-page-ai-api.md) - [All operations](https://skmtc.dev/on-page/apis/on-page-ai-api/llms.txt) - [OpenAPI document](https://skmtc.dev/on-page/apis/on-page-ai-api/revisions/a081e8701c19?raw)
