Cronitor API

Sites API

The Sites API allows you to programmatically create and manage Real User Monitoring (RUM) sites. Sites collect web vitals, performance metrics, and JavaScript errors from your web applications.

Authentication

The Sites API requires API key authentication with monitor scopes:

  • monitor:read - Required to list and retrieve sites
  • monitor:write - Required to create, update, and delete sites

Create an API key with the appropriate scopes from the API Settings page. For more information about API authentication and scopes, see the API documentation.


Quick Start

Create a Site

curl --user API_KEY: \
    --header "Content-Type: application/json" \
    --request POST \
    --data '{
        "name": "Main Website",
        "webvitals_enabled": true,
        "errors_enabled": true
    }' \
    https://cronitor.io/api/sites

List All Sites

curl https://cronitor.io/api/sites -u API_KEY:

Get Installation Snippet

curl "https://cronitor.io/api/sites/site_abc123?withSnippet=true" -u API_KEY:

Sites

List Sites

Retrieve all RUM sites for your organization.

Endpoint

GET https://cronitor.io/api/sites

Query Parameters

  • page (integer) - Page number for pagination (default: 1)
  • pageSize (integer) - Number of results per page (default: 50)

Example

curl https://cronitor.io/api/sites -u API_KEY:

Response

{
  "page": 1,
  "page_size": 50,
  "total_count": 2,
  "data": [
    {
      "key": "site_abc123def456",
      "name": "Main Website",
      "client_key": "ck_abc123def456",
      "public_report_enabled": false,
      "public_report_key": "pr_abc123def456",
      "webvitals_enabled": true,
      "errors_enabled": true,
      "filter_localhost": true,
      "filter_bots": true,
      "filter_browser_extensions": true,
      "exclude_internal_referrers": false,
      "origin_allowlist": null,
      "ip_denylist": null,
      "country_code_denylist": null,
      "path_denylist": null,
      "sampling": 100,
      "ingestion_enabled": true,
      "created": "2023-06-15T10:00:00Z",
      "updated": "2023-06-15T10:00:00Z"
    }
  ]
}

Create a Site

Create a new RUM site to start collecting web performance data.

Endpoint

POST https://cronitor.io/api/sites

Request Body

{
  "name": "E-Commerce Store",
  "webvitals_enabled": true,
  "errors_enabled": true,
  "filter_localhost": true,
  "filter_bots": true,
  "sampling": 100
}

Parameters

  • name (string, required) - Display name for the site
  • webvitals_enabled (boolean, optional) - Enable Core Web Vitals collection (default: true)
  • errors_enabled (boolean, optional) - Enable JavaScript error tracking (default: true)
  • filter_localhost (boolean, optional) - Filter out localhost traffic (default: true)
  • filter_bots (boolean, optional) - Filter out bot traffic (default: true)
  • filter_browser_extensions (boolean, optional) - Filter out browser extension errors (default: true)
  • exclude_internal_referrers (boolean, optional) - Exclude internal referrer tracking (default: false)
  • public_report_enabled (boolean, optional) - Enable public performance report (default: false)
  • sampling (integer, optional) - Percentage of traffic to sample, 0-100 (default: 100)
  • origin_allowlist (array, optional) - List of allowed origins/hostnames
  • ip_denylist (array, optional) - List of IP addresses or CIDR ranges to block
  • country_code_denylist (array, optional) - List of country codes to block (ISO 3166-1 alpha-2)
  • path_denylist (array, optional) - List of URL paths to exclude

Example

curl --user API_KEY: \
    --header "Content-Type: application/json" \
    --request POST \
    --data '{
        "name": "Marketing Site",
        "webvitals_enabled": true,
        "errors_enabled": true,
        "filter_localhost": true,
        "filter_bots": true,
        "sampling": 50,
        "origin_allowlist": ["example.com", "www.example.com"]
    }' \
    https://cronitor.io/api/sites

Response

{
  "key": "site_xyz789abc123",
  "name": "Marketing Site",
  "client_key": "ck_xyz789abc123",
  "public_report_enabled": false,
  "public_report_key": "pr_xyz789abc123",
  "webvitals_enabled": true,
  "errors_enabled": true,
  "filter_localhost": true,
  "filter_bots": true,
  "filter_browser_extensions": true,
  "exclude_internal_referrers": false,
  "origin_allowlist": ["example.com", "www.example.com"],
  "ip_denylist": null,
  "country_code_denylist": null,
  "path_denylist": null,
  "sampling": 50,
  "ingestion_enabled": true,
  "created": "2023-12-01T10:00:00Z",
  "updated": "2023-12-01T10:00:00Z"
}

Get a Site

Retrieve details for a specific site.

Endpoint

GET https://cronitor.io/api/sites/:key

Query Parameters

  • withSnippet (boolean) - Include the JavaScript installation snippet

Example

curl "https://cronitor.io/api/sites/site_abc123?withSnippet=true" -u API_KEY:

Response

{
  "key": "site_abc123def456",
  "name": "Main Website",
  "client_key": "ck_abc123def456",
  "public_report_enabled": false,
  "public_report_key": "pr_abc123def456",
  "webvitals_enabled": true,
  "errors_enabled": true,
  "filter_localhost": true,
  "filter_bots": true,
  "filter_browser_extensions": true,
  "exclude_internal_referrers": false,
  "origin_allowlist": null,
  "ip_denylist": null,
  "country_code_denylist": null,
  "path_denylist": null,
  "snippet": "<script async src=\"https://rum.cronitor.io/script.js\" data-client-key=\"ck_abc123def456\"></script>",
  "sampling": 100,
  "ingestion_enabled": true,
  "created": "2023-06-15T10:00:00Z",
  "updated": "2023-06-15T10:00:00Z"
}

Update a Site

Update a site's configuration.

Endpoint

PUT https://cronitor.io/api/sites/:key

Request Body

{
  "name": "Main Website (Updated)",
  "sampling": 75,
  "errors_enabled": true,
  "path_denylist": ["/admin/*", "/internal/*"]
}

Example

curl --user API_KEY: \
    --header "Content-Type: application/json" \
    --request PUT \
    --data '{
        "name": "Main Website",
        "sampling": 75,
        "ip_denylist": ["192.168.1.0/24", "10.0.0.0/8"]
    }' \
    https://cronitor.io/api/sites/site_abc123

Response

Returns the updated site object.


Delete a Site

Delete a site and stop collecting data.

Endpoint

DELETE https://cronitor.io/api/sites/:key

Example

curl --request DELETE https://cronitor.io/api/sites/site_old123 -u API_KEY:

Response

Returns HTTP 204 No Content on success.


Site Errors

List Site Errors

Retrieve JavaScript errors collected from your sites.

Endpoint

GET https://cronitor.io/api/site_errors

Query Parameters

  • site (string) - Filter by site key
  • page (integer) - Page number for pagination
  • pageSize (integer) - Number of results per page

Example

curl "https://cronitor.io/api/site_errors?site=site_abc123" -u API_KEY:

Response

{
  "page": 1,
  "page_size": 50,
  "total_count": 15,
  "data": [
    {
      "key": "err_abc123def456",
      "message": "TypeError: Cannot read property 'length' of undefined",
      "source": "https://example.com/js/app.js",
      "line": 42,
      "column": 15,
      "count": 127,
      "first_seen": "2023-11-15T08:30:00Z",
      "last_seen": "2023-12-01T14:22:00Z",
      "status": "open"
    }
  ]
}

Get a Site Error

Retrieve details for a specific error.

Endpoint

GET https://cronitor.io/api/site_errors/:key

Example

curl https://cronitor.io/api/site_errors/err_abc123 -u API_KEY:

Site Analytics Query

Query analytics data from your RUM sites to build custom visualizations, reports, and integrations. This endpoint provides access to sessions, pageviews, performance metrics, web vitals, and more.

Query Analytics Data

Endpoint

POST https://cronitor.io/api/sites/query

Request Body

{
  "site": "site_abc123",
  "kind": "breakdown",
  "group_by": "country_code",
  "aggregate": ["session_count", "pageview_count"],
  "time": "7d",
  "timezone": "UTC",
  "filters": [],
  "page": 1,
  "page_size": 50
}

Core Parameters

site[string] **required**

The site key to query data from.

kind[string] **required**

The type of query to execute. Valid values:

  • aggregation - Return aggregated metrics for the entire time range
  • breakdown - Group aggregated metrics by a dimension
  • timeseries - Return metrics over time with specified bucket granularity
  • search_options - Search for available values within a dimension
  • error_groups - Return grouped error patterns
aggregate[array of strings] **required**

List of metrics to compute (max 10). See Aggregate Fields for valid values.

Time Parameters

time[string] default: "24h"

Predefined time range. Valid values: 1h, 24h, today, 3d, 7d, 14d, 30d, 180d, 4w, mtd, 3m, 6m, 12m, 24m, ytd, custom.

start[string] ISO 8601 datetime

Start of custom time range. Required when time="custom".

end[string] ISO 8601 datetime

End of custom time range. Required when time="custom". Must be after start and not in the future. Maximum range is 730 days.

time_bucket[string]

Bucket size for timeseries queries. Valid values: minute, hour, day, week, month. Must be compatible with the selected time range.

timezone[string] default: "UTC"

IANA timezone for query results (e.g., America/New_York, Europe/London).

Grouping and Filtering

group_by[string]

Dimension to group results by. Required for breakdown queries. See Breakdown Fields for valid values.

filters[array of objects] max: 10

Array of filter objects to apply. Each filter has:

  • dimension - Field to filter on (see Breakdown Fields)
  • operator - One of: eq, ne, gt, gte, lt, lte, startsWith, endsWith, contains
  • value - Value to compare against
filters_behavior[string] default: "and"

How to combine multiple filters. Valid values: and, or.

Ordering and Pagination

order_by[array of strings] max: 2

Sort results by field. Prefix with - for descending order. Fields must be in aggregate or group_by.

page[integer] default: 1, max: 100

Page number for paginated results.

page_size[integer] default: 10, max: 250

Number of results per page.

Comparison

compare[string]

Compare current data with previous period. Valid value: previous_time_range. Returns additional _previous_time_range_value and _previous_time_range_change_rate fields.

Other Parameters

environment[string]

Filter by environment key.

Search term for search_options queries.


Aggregate Fields

Metrics available for the aggregate parameter:

Session & Event Counts

  • session_count - Number of unique sessions
  • pageview_count - Number of pageview events
  • event_count - Total event count
  • error_count - Number of error events

Session Metrics (available for aggregation and timeseries queries only)

  • session_duration_avg - Average session duration (milliseconds)
  • bounce_rate - Percentage of single-page sessions
  • events_per_session_avg - Average events per session
  • errors_per_session_avg - Average errors per session
  • session_error_rate - Percentage of sessions with errors
  • conversion_rate - Conversion rate (for filtered queries)

Page Load Performance (percentiles: p10, p25, p50, p75, p90, p95, p99)

  • page_load_total_p10, page_load_total_p25, page_load_total_p50, page_load_total_p75, page_load_total_p90, page_load_total_p95, page_load_total_p99 - Total page load time (ms)
  • page_load_dns_p50, page_load_dns_p95 - DNS lookup time
  • page_load_ssl_p50 - SSL/TLS negotiation time
  • page_load_connect_p50 - TCP connection time
  • page_load_ttfb_p50 - Time to first byte
  • page_load_download_p50 - Download time
  • page_load_dom_content_loaded_p50 - DOM content loaded time
  • page_load_render_p50 - Render time
  • page_load_network_p50 - Total network time
  • page_load_backend_p50 - Backend time
  • page_load_frontend_p50 - Frontend time

Web Vitals (p50, p95, p99 percentiles)

  • web_vital_lcp_p50, web_vital_lcp_p95, web_vital_lcp_p99 - Largest Contentful Paint (ms)
  • web_vital_fid_p50, web_vital_fid_p95, web_vital_fid_p99 - First Input Delay (ms)
  • web_vital_cls_p50, web_vital_cls_p95, web_vital_cls_p99 - Cumulative Layout Shift

Error Details (for error_groups queries)

  • error_type - Error type/class
  • message - Error message
  • filename - Source filename
  • lineno - Line number
  • colno - Column number
  • first_seen - First occurrence timestamp
  • last_seen - Last occurrence timestamp

Breakdown Fields

Dimensions available for group_by and filter dimension parameters:

Geography

  • country_code - ISO 3166-1 alpha-2 country code
  • city_name - City name

Navigation

  • path - URL path
  • hostname - Domain/hostname

Device & Browser

  • device_type - Device classification (desktop, mobile, tablet)
  • browser - Browser name
  • operating_system - Operating system name

Acquisition

  • referrer_hostname - Referrer domain
  • utm_source - UTM source parameter
  • utm_campaign - UTM campaign parameter
  • utm_medium - UTM medium parameter
  • utm_content - UTM content parameter
  • utm_term - UTM term parameter

Events

  • event_name - Custom event name
  • event_group - Event group classification

Network

  • connection_type - Network connection type

Time Bucket Compatibility

Valid time_bucket values depend on the selected time range:

Time RangeValid Buckets
1hminute
24h, todayhour
3d, 7d, 14dhour, day
30d, 4w, mtdhour, day, week
180d, 3m, 6m, 12m, 24m, ytdday, week, month
customhour, day, week, month

Query Examples

Aggregation Query

Get total sessions and median page load for the last 7 days:

curl --user API_KEY: \
    --header "Content-Type: application/json" \
    --request POST \
    --data '{
        "site": "site_abc123",
        "kind": "aggregation",
        "aggregate": ["session_count", "page_load_total_p50", "bounce_rate"],
        "time": "7d",
        "timezone": "America/New_York"
    }' \
    https://cronitor.io/api/sites/query

Response:

{
  "data": {
    "session_count": {"value": 15420},
    "page_load_total_p50": {"value": 2340},
    "bounce_rate": {"value": 0.42}
  }
}

Breakdown Query

Get sessions by country with filtering:

curl --user API_KEY: \
    --header "Content-Type: application/json" \
    --request POST \
    --data '{
        "site": "site_abc123",
        "kind": "breakdown",
        "group_by": "country_code",
        "aggregate": ["session_count", "pageview_count"],
        "time": "30d",
        "filters": [
            {"dimension": "device_type", "operator": "eq", "value": "mobile"}
        ],
        "order_by": ["-session_count"],
        "page": 1,
        "page_size": 10
    }' \
    https://cronitor.io/api/sites/query

Response:

{
  "data": [
    {"country_code": "US", "session_count": 5230, "pageview_count": 12450},
    {"country_code": "GB", "session_count": 2100, "pageview_count": 4820},
    {"country_code": "DE", "session_count": 1450, "pageview_count": 3200}
  ],
  "page": 1,
  "page_size": 10,
  "page_count": 5,
  "total_count": 48
}

Timeseries Query

Get daily session counts for the last 30 days:

curl --user API_KEY: \
    --header "Content-Type: application/json" \
    --request POST \
    --data '{
        "site": "site_abc123",
        "kind": "timeseries",
        "aggregate": ["session_count", "pageview_count"],
        "time": "30d",
        "time_bucket": "day",
        "timezone": "UTC"
    }' \
    https://cronitor.io/api/sites/query

Response:

{
  "data": [
    {"ts": "2025-12-01T00:00:00+00:00", "session_count": 520, "pageview_count": 1240},
    {"ts": "2025-12-02T00:00:00+00:00", "session_count": 485, "pageview_count": 1180},
    {"ts": "2025-12-03T00:00:00+00:00", "session_count": 612, "pageview_count": 1450}
  ],
  "time_bucket": "day"
}

Custom Date Range Query

Query a specific date range:

curl --user API_KEY: \
    --header "Content-Type: application/json" \
    --request POST \
    --data '{
        "site": "site_abc123",
        "kind": "timeseries",
        "aggregate": ["session_count"],
        "time": "custom",
        "start": "2025-01-01T00:00:00Z",
        "end": "2025-01-31T23:59:59Z",
        "time_bucket": "day"
    }' \
    https://cronitor.io/api/sites/query

Comparison Query

Compare current period with previous period:

curl --user API_KEY: \
    --header "Content-Type: application/json" \
    --request POST \
    --data '{
        "site": "site_abc123",
        "kind": "aggregation",
        "aggregate": ["session_count", "bounce_rate"],
        "time": "7d",
        "compare": "previous_time_range"
    }' \
    https://cronitor.io/api/sites/query

Response:

{
  "data": {
    "session_count": {
      "value": 15420,
      "previous_time_range_value": 14200,
      "previous_time_range_change_rate": 0.086
    },
    "bounce_rate": {
      "value": 0.42,
      "previous_time_range_value": 0.45,
      "previous_time_range_change_rate": -0.067
    }
  }
}

Hourly Timeseries Query

Get hourly session data for granular traffic analysis:

curl --user API_KEY: \
    --header "Content-Type: application/json" \
    --request POST \
    --data '{
        "site": "site_abc123",
        "kind": "timeseries",
        "aggregate": ["session_count"],
        "time": "30d",
        "time_bucket": "hour",
        "timezone": "America/New_York"
    }' \
    https://cronitor.io/api/sites/query

Top Pages Query

Get the most visited pages:

curl --user API_KEY: \
    --header "Content-Type: application/json" \
    --request POST \
    --data '{
        "site": "site_abc123",
        "kind": "breakdown",
        "group_by": "path",
        "aggregate": ["pageview_count", "session_count"],
        "time": "7d",
        "order_by": ["-pageview_count"],
        "page_size": 20
    }' \
    https://cronitor.io/api/sites/query

Web Vitals by Device

Compare Core Web Vitals across device types:

curl --user API_KEY: \
    --header "Content-Type: application/json" \
    --request POST \
    --data '{
        "site": "site_abc123",
        "kind": "breakdown",
        "group_by": "device_type",
        "aggregate": ["web_vital_lcp_p50", "web_vital_fid_p50", "web_vital_cls_p50", "session_count"],
        "time": "7d"
    }' \
    https://cronitor.io/api/sites/query

Site Attributes

key[string] read-only

Unique identifier for the site.

name[string] **required**

Display name for the site. Shown in the Cronitor dashboard.

client_key[string] read-only

Client-side key used in the JavaScript snippet. Safe to expose in browser code.

public_report_enabled[boolean] default: false

Whether to enable a public performance report for this site.

public_report_key[string] read-only

Key for accessing the public performance report.

webvitals_enabled[boolean] default: true

Enable collection of Core Web Vitals (LCP, FID, CLS, TTFB, INP).

errors_enabled[boolean] default: true

Enable JavaScript error tracking.

filter_localhost[boolean] default: true

Filter out traffic from localhost origins.

filter_bots[boolean] default: true

Filter out traffic from known bots and crawlers.

filter_browser_extensions[boolean] default: true

Filter out errors caused by browser extensions.

exclude_internal_referrers[boolean] default: false

Exclude internal navigation from referrer tracking.

origin_allowlist[array of strings]

List of allowed hostnames. If set, only traffic from these origins will be collected.

ip_denylist[array of strings]

List of IP addresses or CIDR ranges to block from collection.

country_code_denylist[array of strings]

List of ISO 3166-1 alpha-2 country codes to block.

path_denylist[array of strings]

List of URL paths to exclude from collection. Supports wildcards (e.g., /admin/*).

snippet[string] read-only

The JavaScript snippet to install on your site. Available when requesting with withSnippet=true.

sampling[integer] default: 100

Percentage of traffic to sample (0-100). Lower values reduce data volume for high-traffic sites.

ingestion_enabled[boolean] read-only

Whether data ingestion is currently enabled for this site.


Installation

After creating a site, add the JavaScript snippet to your website:

<script async src="https://rum.cronitor.io/script.js" data-client-key="YOUR_CLIENT_KEY"></script>

Place this snippet in the <head> of your HTML pages, or use the snippet returned by the API with withSnippet=true.

For more installation options, see the RUM Quickstart Guide.


Best Practices

  • Use origin allowlists: Restrict data collection to your production domains
  • Enable filtering: Use bot and localhost filtering to improve data quality
  • Adjust sampling: For high-traffic sites, reduce sampling to control costs while maintaining statistical significance
  • Block internal IPs: Add office/VPN IP ranges to the denylist to exclude internal traffic
  • Monitor errors proactively: Enable error tracking and review new errors regularly
Previous
Status Pages