> ## Documentation Index
> Fetch the complete documentation index at: https://docs.spidra.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Estimate a Monitor

> Credits per check and per month for a monitor, before you create it.

Takes the same body as [Create a Monitor](https://docs.spidra.io/api-reference/monitors/create.md), checks it the same way, and returns the cost. Free.

```bash theme={null}
curl -X POST https://api.spidra.io/api/monitors/estimate \
  -H "Authorization: Bearer $SPIDRA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "sources": [{ "kind": "template", "template": "google-maps-leads", "inputs": { "query": "dentist", "areas": ["Lekki, Lagos"] } }],
    "schedule": { "every": "1h" },
    "alertOn": "new"
  }'
```

```json theme={null}
{ "status": "success", "creditsPerCheck": 1, "checksPerMonth": 720, "creditsPerMonth": 720, "usesAi": false }
```

The same source checked daily is 30 credits a month. `usesAi` is `true` when a source extracts with AI, which adds token credits on top. A `goal` adds a little AI only on checks where something changed, and isn't part of the estimate.


## OpenAPI

````yaml POST /monitors/estimate
openapi: 3.1.0
info:
  title: Spidra API
  version: 1.0.0
  description: >-
    Public API endpoints for web scraping via Spidra. Authenticate with
    `Authorization: Bearer YOUR_API_KEY`.
servers:
  - url: https://api.spidra.io/api
security:
  - BearerAuth: []
  - ApiKeyAuth: []
paths:
  /monitors/estimate:
    post:
      tags:
        - Monitors
      summary: Estimate a Monitor
      description: >-
        Credits per check and per month for a monitor, before you create it.
        Takes the same body as [Create a
        Monitor](/api-reference/monitors/create). Free.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/MonitorInput'
            example:
              name: Dentists in Lekki
              sources:
                - kind: template
                  template: google-maps-leads
                  inputs:
                    query: dentist
                    areas:
                      - Lekki, Lagos
              schedule:
                every: 1d
                at: '08:00'
                timezone: Africa/Lagos
              alertOn: new
              notify:
                email:
                  enabled: true
      responses:
        '200':
          description: The estimate.
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    enum:
                      - success
                  creditsPerCheck:
                    type: number
                  checksPerMonth:
                    type: integer
                  creditsPerMonth:
                    type: number
                  usesAi:
                    type: boolean
                    description: >-
                      true when a source extracts with AI, which adds token
                      credits.
        '401':
          description: Missing or invalid API key.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: Some inputs need fixing. `errors` lists each field.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/InvalidInputError'
components:
  schemas:
    MonitorInput:
      type: object
      properties:
        name:
          type: string
          description: Defaults to the first source's label.
        sources:
          type: array
          items:
            $ref: '#/components/schemas/MonitorSource'
          minItems: 1
          maxItems: 10
        schedule:
          $ref: '#/components/schemas/MonitorSchedule'
        alertOn:
          type: string
          enum:
            - new
            - changed
            - removed
            - page
            - every
          description: >-
            What counts as a change. Default `page` when every source is a URL
            list, otherwise `new`.
        watchFields:
          type: array
          items:
            type: string
          maxItems: 20
          description: 'alertOn changed: only these fields count. Empty means every field.'
        rule:
          $ref: '#/components/schemas/MonitorRule'
        goal:
          type:
            - string
            - 'null'
          maxLength: 1000
          description: >-
            Plain-language goal. When something changed, AI decides whether it
            matches before alerting, and says why.
        notify:
          $ref: '#/components/schemas/MonitorNotify'
        checkNow:
          type: boolean
          default: true
          description: >-
            Create only: run the first check straight away. It records the
            starting point and doesn't alert.
    ErrorResponse:
      type: object
      properties:
        status:
          type: string
          enum:
            - error
        message:
          type: string
      required:
        - status
        - message
    InvalidInputError:
      type: object
      properties:
        status:
          type: string
          enum:
            - error
        code:
          type: string
          enum:
            - INVALID_INPUT
        message:
          type: string
        errors:
          type: array
          items:
            type: object
            properties:
              field:
                type: string
              message:
                type: string
          description: One entry per field that needs fixing.
    MonitorSource:
      type: object
      required:
        - kind
      properties:
        id:
          type: string
          description: >-
            Optional. Kept per source so changes are compared against the same
            source next time.
        kind:
          type: string
          enum:
            - template
            - preset
            - urls
        label:
          type: string
          description: Shown in alerts. Defaults to the template, preset or site name.
        template:
          type: string
          description: 'kind template: the template''s slug.'
        inputs:
          type: object
          description: 'kind template: the template''s inputs.'
        presetId:
          type: string
          description: >-
            kind preset: the preset's ID. Scrape, batch, map, search and
            template presets can be watched.
        urls:
          type: array
          items:
            type: string
          maxItems: 50
          description: 'kind urls: up to 50 public pages.'
    MonitorSchedule:
      type: object
      properties:
        every:
          type: string
          enum:
            - 5m
            - 15m
            - 30m
            - 1h
            - 6h
            - 12h
            - 1d
            - 1w
        at:
          type: string
          description: >-
            "HH:MM". The time for 1d and 1w, and the minute past the hour for
            1h, 6h and 12h. Default 09:00.
        day:
          type: integer
          minimum: 0
          maximum: 6
          description: '1w only: 0 is Sunday. Default 1 (Monday).'
        cron:
          type: string
          description: 'Instead of `every`: a 5-field cron expression.'
        timezone:
          type: string
          description: An IANA time zone such as Africa/Lagos. Default UTC.
      description: >-
        Your plan sets the shortest interval: daily on Free, hourly on Starter,
        every 15 minutes on Builder, every 5 minutes on Pro.
    MonitorRule:
      type:
        - object
        - 'null'
      properties:
        field:
          type: string
        op:
          type: string
          enum:
            - lt
            - lte
            - gt
            - gte
            - eq
            - neq
            - contains
            - drops_by_pct
            - rises_by_pct
        value:
          type:
            - number
            - string
      description: >-
        Only alert about items where this is true, for example `{ "field":
        "price", "op": "drops_by_pct", "value": 10 }`.
    MonitorNotify:
      type: object
      properties:
        email:
          type: object
          properties:
            enabled:
              type: boolean
              default: true
            recipients:
              type: array
              items:
                type: string
              maxItems: 10
              description: >-
                Extra addresses. Each gets alerts only after confirming by
                email.
          description: Your account's email is on unless `enabled` is false.
        webhook:
          type: object
          properties:
            url:
              type: string
              description: A public https URL.
            secret:
              type: string
              description: >-
                16 to 128 letters, digits, - or _. Generated when you leave it
                out.
        slack:
          type: object
          properties:
            webhookUrl:
              type: string
              description: A Slack incoming webhook URL (https://hooks.slack.com/...).
        discord:
          type: object
          properties:
            webhookUrl:
              type: string
              description: A Discord webhook URL (https://discord.com/api/webhooks/...).
  securitySchemes:
    BearerAuth:
      type: http
      scheme: bearer
      bearerFormat: API key
    ApiKeyAuth:
      type: apiKey
      in: header
      name: x-api-key

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.