Creating a monitor
A monitor is the core unit of Datarist. It defines what to watch, when to fire, and where to send the alert. This guide walks through all five steps of the creation wizard.
Authentication
Before creating monitors or connecting data sources, you need a Datarist account. Datarist uses email-based authentication — no third-party SSO required on free plans.
API authentication
For programmatic access, Datarist uses bearer tokens. Generate an API key from Settings → API keys in your dashboard. All API keys are prefixed with dt_live_.
curl https://api.datarist.io/v1/monitors \
-H "Authorization: Bearer dt_live_xxxxxxxxxxxx"
Overview
The monitor creation wizard is a five-step flow. Each step is independently editable after activation — you never need to delete and recreate a monitor to change a threshold or add a channel.
| # | Step | What you configure | Required |
|---|---|---|---|
01 | Data source | Which connector to poll and how to authenticate | Yes |
02 | Conditions | Field path, operator, threshold, AND/OR logic | Yes |
03 | Channels | Email recipients, Slack webhook, SMS numbers | Yes |
04 | Schedule | Check frequency, deduplication, auto-resolve | Optional |
05 | Review | Preview sample notification, activate or save draft | Yes |
draft status. They begin polling only after you explicitly click Activate monitor on the review screen.Interactive demo
This is a live replica of the actual monitor creation UI. Click through each step to see exactly what you'll encounter in the dashboard.
condition: field > value
value_seen: —
source: PostgreSQL
fired_at: 2026-03-24T14:32:01Z
Step 1 — Data source
The first step asks you to name the monitor and select the connector type. The name appears in all alert notifications and your dashboard, so be descriptive. "Revenue crossed $50k" is better than "Monitor 3".
Supported connector types
| Connector | Auth method | Query method | Plan |
|---|---|---|---|
| PostgreSQL | Username + password | SQL — must return value column | All |
| MySQL | Username + password | SQL — must return value column | All |
| Google Sheets | OAuth 2.0 | Spreadsheet ID + cell range | All |
| Webhook | None (URL-based) | JSON path to value field | All |
SQL query requirements
For PostgreSQL and MySQL connectors, your query must return exactly one row with a column named value. Datarist reads this column and compares it against your condition thresholds.
SELECT COUNT(*) AS value
FROM orders
WHERE created_at > NOW() - INTERVAL '1 hour';
-- Sum revenue for today
SELECT SUM(amount_cents) / 100.0 AS value
FROM charges
WHERE status = 'succeeded'
AND created_at::date = CURRENT_DATE;
SELECT access. Create a dedicated read-only role with GRANT SELECT ON ALL TABLES IN SCHEMA public TO datarist_ro and use those credentials exclusively.Step 2 — Conditions
Conditions define the logic Datarist evaluates on each check run. Each condition compares a field value against a threshold using an operator. You can stack multiple conditions with AND or OR logic.
Condition structure
Each condition has three parts: a field path, an operator, and a threshold value.
| Operator | Symbol | Fires when | Threshold type |
|---|---|---|---|
gt | > | Value is strictly greater than threshold | Numeric |
gte | ≥ | Value is greater than or equal to threshold | Numeric |
lt | < | Value is strictly less than threshold | Numeric |
lte | ≤ | Value is less than or equal to threshold | Numeric |
eq | = | Value exactly equals threshold | Any |
neq | ≠ | Value does not equal threshold | Any |
pct_change_gt | Δ%> | % change from previous check exceeds threshold | Percentage (0–100) |
is_null | ∅ | Query returned no rows or NULL value | None |
new_row | +1 | Row count increased since last check | None |
Trigger modes
The trigger mode controls when alerts fire relative to your polling cycle:
| Mode | Behavior | Best for |
|---|---|---|
on_crossing | Fires exactly once when the condition transitions from false → true. Suppresses subsequent checks while still true. | Revenue milestones, MRR targets, one-time events |
every_match | Fires on every polling cycle where the condition evaluates to true (subject to deduplication cooldown). | Error rate monitoring, latency spikes, continuous health checks |
on_crossing for milestone alerts (revenue targets, user counts). Use every_match for operational monitoring where you want repeated reminders while a condition persists.Step 3 — Channels
Configure where Datarist sends the alert. All selected channels fire simultaneously — not sequentially. A failed SMS delivery will not delay or prevent email delivery.
Sample alert notifications
monitor: Revenue > $50k
value: $51,240
source: PostgreSQL
fired: 14:32 UTC
current: $51,240
threshold: $50,000
source: PostgreSQL
time: 14:32 UTC
Value: $51,240
Source: PostgreSQL · 14:32 UTC
datarist.io/w/abc123
Message templates
Override the default message with a custom template using handlebars-style variables. Templates are per-monitor and apply to all channels unless overridden at the channel level.
{{field}} — the field or metric that fired
{{value}} — the observed value at fire time
{{threshold}} — the configured threshold
{{operator}} — the condition operator (gt, lt, etc.)
{{source_name}} — the connector display name
{{timestamp}} — ISO 8601 UTC timestamp
{{dashboard_url}} — deep link to this monitor in the app
Step 4 — Schedule
Control how often Datarist polls your source and how it behaves when the same condition fires repeatedly.
Check frequency
| Frequency | Mechanism | Min plan | Approx. checks/month |
|---|---|---|---|
realtime | Webhook push — no polling | All | Unlimited |
1min | Polling | Growth | ~43,200 |
5min | Polling | All | ~8,640 |
15min | Polling | All | ~2,880 |
1hour | Polling | All | ~720 |
daily_digest | Single summary at 9am UTC | All | ~31 |
Deduplication
When dedup_enabled is true, Datarist suppresses repeat alerts for the same monitor within the configured cooldown window. This prevents alert fatigue when using every_match mode on a fast polling interval.
14:01 check run → condition TRUE → suppressed (within 1hr cooldown)
14:05 check run → condition TRUE → suppressed (within 1hr cooldown)
15:01 check run → condition TRUE → alert fires (cooldown expired)
15:02 check run → condition FALSE → no alert (condition not met)
Auto-resolve
When auto_resolve is enabled, Datarist sends a recovery notification the first time a condition returns to false after having been true. Useful for incident-style monitoring where you want to know both when a problem starts and when it ends.
Step 5 — Review & activate
The review screen shows a complete summary of every configured value and a rendered sample notification message. Take a moment to verify the summary is correct — mismatched thresholds are the most common setup mistake.
draft status does not poll your source and will not fire alerts. Activate it from the review screen or from the monitor list in your dashboard.Editing a monitor
You can edit any field of an active monitor without deleting and recreating it. Changes take effect on the next polling cycle after saving.
What can be edited
| Field | Editable while active? | Notes |
|---|---|---|
| Monitor name | Yes | Updates immediately in all notifications |
| Conditions & thresholds | Yes | On-crossing state resets on save |
| Alert channels | Yes | Add or remove channels at any time |
| Message template | Yes | Applied on next alert fire |
| Check frequency | Yes | New schedule begins immediately |
| Data source / connector | Limited | Must re-authenticate if connector changes |
| SQL query | Yes | Validated on save; must still return value |
Editing via dashboard
Editing via API
-H "Authorization: Bearer dt_live_xxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{"frequency": "15min", "dedup_window_secs": 14400}'
Pausing & resuming
Pausing a monitor halts all polling and alert delivery without deleting any configuration. This is useful during planned maintenance windows or when you want to temporarily silence a noisy monitor.
Monitor states
| State | Polling | Alerts | Visible in list |
|---|---|---|---|
draft | No | No | Yes |
active | Yes | Yes | Yes |
paused | No | No | Yes |
error | Retrying | On failure only | Yes |
Pausing via dashboard
Open the monitor detail page and click the Pause button in the top-right action bar. The monitor's status indicator turns gray immediately. All pending check runs are cancelled.
Pausing via API
curl -X PATCH https://api.datarist.io/v1/monitors/mt_9fKx2mQpAbL3 \
-H "Authorization: Bearer dt_live_xxxxxxxxxxxx" \
-d '{"status": "paused"}'
# Resume
curl -X PATCH https://api.datarist.io/v1/monitors/mt_9fKx2mQpAbL3 \
-H "Authorization: Bearer dt_live_xxxxxxxxxxxx" \
-d '{"status": "active"}'
on_crossing mode, Datarist evaluates the current data state fresh. If the condition is already true at the moment of resumption, it will fire once immediately.Alert history
Every alert fired, suppressed, or failed is recorded in the monitor's alert history. History is retained for 90 days on all plans.
History log fields
| Field | Type | Description |
|---|---|---|
id | string | Unique alert event identifier |
monitor_id | string | The monitor that triggered this event |
status | enum | fired, suppressed, failed, resolved |
value_seen | number | The actual value observed at fire time |
condition_snapshot | object | Copy of condition config at the time of fire |
channels_delivered | array | List of channels and their delivery status |
fired_at | ISO 8601 | UTC timestamp of the alert event |
Fetching history via API
-H "Authorization: Bearer dt_live_xxxxxxxxxxxx"
PostgreSQL connector
The PostgreSQL connector allows Datarist to poll any PostgreSQL 12+ database. Datarist connects using a standard TCP connection and executes your configured SQL query on each check run.
Setup
34.90.12.45, 34.90.88.201.5432), database name, username, and password.GRANT CONNECT ON DATABASE your_database TO datarist_ro;
GRANT USAGE ON SCHEMA public TO datarist_ro;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO datarist_ro;
Connection settings
| Setting | Default | Required |
|---|---|---|
| Host | — | Yes |
| Port | 5432 | No |
| Database | — | Yes |
| Username | — | Yes |
| Password | — | Yes |
| SSL mode | require | No |
| Query timeout | 10s | No |
MySQL connector
The MySQL connector supports MySQL 5.7+ and MariaDB 10.3+. Configuration mirrors the PostgreSQL connector — provide host, port, database, and credentials for a read-only user.
Setup
GRANT SELECT ON your_database.* TO 'datarist_ro'@'%';
FLUSH PRIVILEGES;
Connection settings
| Setting | Default | Required |
|---|---|---|
| Host | — | Yes |
| Port | 3306 | No |
| Database | — | Yes |
| Username | — | Yes |
| Password | — | Yes |
| SSL | Enabled | No |
value. The same SQL examples from the PostgreSQL section apply with minor dialect differences (e.g. use NOW() - INTERVAL 1 HOUR instead of NOW() - INTERVAL '1 hour').Google Sheets connector
Monitor values in a Google Sheets spreadsheet using a cell range. Datarist reads the specified range and treats the top-left cell's value as the monitored value.
Connecting your Google account
docs.google.com/spreadsheets/d/SPREADSHEET_ID/editSheet1!B4 or Summary!C2.Webhooks connector
The Webhooks connector gives you a unique inbound URL. When your system posts JSON to this URL, Datarist evaluates the payload against your monitor's conditions in real-time — no polling required.
Setup
Select Webhook as the source type in the monitor wizard. Datarist generates a unique endpoint URL for that monitor. Configure your system to POST JSON to this URL when data changes.
-H "Content-Type: application/json" \
-d '{"revenue": 51240, "currency": "usd", "timestamp": "2026-04-03T14:32:00Z"}'
JSON path configuration
In the monitor setup, specify the JSON path to the numeric field you want to monitor, e.g. revenue or metrics.active_users. Datarist extracts this field and evaluates it against your conditions.
Email channel
Datarist delivers alert emails via SendGrid. Emails arrive from alerts@datarist.io and include the monitor name, observed value, threshold, source, and a direct link to the monitor dashboard.
Configuration
| Setting | Required | Notes |
|---|---|---|
| Recipients | Yes | Comma-separated list of email addresses |
| Subject template | No | Supports {{monitor_name}}, {{value}} |
| Body template | No | Plain text or HTML; uses default if blank |
alerts@datarist.io and the SendGrid IP range to your email provider's allowlist. Enterprise plans support custom sending domains.Slack channel
Datarist posts alerts to Slack via an Incoming Webhook URL. You can configure a different Slack webhook per monitor, allowing you to route alerts to different channels based on severity or team.
Getting a Slack webhook URL
https://hooks.slack.com/services/.SMS channel
Datarist delivers SMS alerts via Twilio. SMS is available on Growth and Enterprise plans. Each alert message is capped at 160 characters; longer messages are truncated.
Configuration
| Setting | Required | Notes |
|---|---|---|
| Phone numbers | Yes | E.164 format: +14155552671 |
| Message template | No | Max 160 chars including variable substitution |
channels_delivered field for the carrier error code.Operators reference
Operators define the comparison logic between an observed value and a configured threshold. All operators are case-insensitive in the API.
| Operator | API value | UI label | Threshold type | Notes |
|---|---|---|---|---|
| Greater than | gt | > | Numeric | Strict; does not fire on equality |
| Greater than or equal | gte | ≥ | Numeric | Fires on equality |
| Less than | lt | < | Numeric | Strict; does not fire on equality |
| Less than or equal | lte | ≤ | Numeric | Fires on equality |
| Equal to | eq | = | Any | String or numeric comparison |
| Not equal to | neq | ≠ | Any | Fires when values differ |
| % change greater than | pct_change_gt | Δ%> | 0–100 | Compares to previous check run's value |
| Is null / no data | is_null | ∅ | None | No threshold required |
| New row inserted | new_row | +1 | None | SQL connectors only; checks row count delta |
Combining operators with logic modes
When a monitor has multiple conditions, the condition_logic field controls how they combine:
all— every condition must be true (AND logic)any— at least one condition must be true (OR logic)
Templates reference
Message templates let you customize the content of alert notifications. Templates use double-brace variable syntax and are evaluated at alert fire time using the actual observed values.
Available variables
| Variable | Type | Example value | Description |
|---|---|---|---|
{{monitor_name}} | string | Revenue > $50k | The monitor's display name |
{{field}} | string | revenue_total | The monitored field or metric |
{{value}} | number | 51240 | Observed value at alert fire time |
{{threshold}} | number | 50000 | Configured threshold value |
{{operator}} | string | gt | Condition operator API code |
{{source_name}} | string | Production DB | Connector display name |
{{timestamp}} | ISO 8601 | 2026-04-03T14:32:01Z | UTC time of the alert event |
{{dashboard_url}} | URL | app.datarist.io/m/mt_… | Deep link to the monitor |
{{org_name}} | string | Acme Corp | Your organization name |
Example templates
Value: {{value}} · Threshold: {{threshold}}
Source: {{source_name}} · At: {{timestamp}}
{{dashboard_url}}
REST API
The Datarist REST API allows full programmatic control over monitors, connectors, and alert history. The base URL is https://api.datarist.io/v1.
Endpoints
| Method | Path | Description |
|---|---|---|
GET | /v1/monitors | List all monitors |
POST | /v1/monitors | Create a new monitor |
GET | /v1/monitors/{id} | Get monitor details |
PATCH | /v1/monitors/{id} | Update a monitor (partial) |
DELETE | /v1/monitors/{id} | Delete a monitor permanently |
GET | /v1/monitors/{id}/history | List alert history for monitor |
GET | /v1/connectors | List connectors |
POST | /v1/connectors | Create a connector |
GET | /v1/connectors/{id}/test | Test connector connectivity |
Create a monitor
-H "Authorization: Bearer dt_live_xxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"name": "Revenue crossed $50k",
"connector_id": "conn_abc123",
"condition_logic": "all",
"trigger_mode": "on_crossing",
"frequency": "5min",
"dedup_enabled": true,
"dedup_window_secs": 3600,
"conditions": [{
"field_path": "value",
"operator": "gt",
"threshold_value": "50000"
}],
"channels": [{
"channel_type": "email",
"config": { "recipients": ["ops@company.com"] }
}, {
"channel_type": "slack",
"config": { "webhook_url": "https://hooks.slack.com/..." }
}]
}'
"id": "mt_9fKx2mQpAbL3",
"name": "Revenue crossed $50k",
"status": "draft",
"org_id": "org_xyz789",
"connector_id": "conn_abc123",
"frequency": "5min",
"created_at": "2026-04-03T14:32:01Z",
"dashboard_url": "https://app.datarist.io/m/mt_9fKx2mQpAbL3"
}
draft status. To activate, send PATCH /v1/monitors/{id} with {"status": "active"}.Plan limits
Datarist enforces limits per plan across monitors, check frequency, and retention. Limits apply per organization workspace.
| Feature | Starter | Growth | Enterprise |
|---|---|---|---|
| Active monitors | 5 | 50 | Unlimited |
| Team members | 1 | 10 | Unlimited |
| Min check frequency | 15 min | 1 min | Real-time |
| Alert history retention | 7 days | 90 days | 365 days |
| SMS alerts | No | Yes | Yes |
| API access | No | Yes | Yes |
| Custom sending domain | No | No | Yes |
| SSO / SAML | No | No | Yes |
| Connectors | 2 | 20 | Unlimited |
| Support | Community | Dedicated SLA |
Troubleshooting
My monitor isn't firing
- Check the monitor status — it may be in
draftorpausedstate. - Navigate to the monitor's Check runs tab and inspect the last run's outcome and observed value.
- Verify your SQL query returns a row with a column named exactly
value— notcount,total, or anything else. - If using
on_crossingmode, confirm the condition was previouslyfalse. It will not re-fire while stilltrue. - Check if deduplication is suppressing the alert — look for
suppressedstatus in the delivery log.
My source connection is failing
- Use the Test connection button on the connector page to validate credentials without creating a monitor.
- For PostgreSQL/MySQL: ensure Datarist's IP range is whitelisted in your database's firewall rules.
- Check the connector's
last_error_msgfield viaGET /v1/connectors/{id}for the exact failure reason.
I'm getting too many alerts
- Switch trigger mode from
every_matchtoon_crossingif you only need to know when the threshold is first breached. - Increase the deduplication cooldown window from 1 hour to 4 hours or 24 hours.
- Reduce polling frequency — switching from 1 min to 5 min cuts check runs by 80% with minimal impact for most use cases.