A DevOps lead told me: 'We had synthetic monitoring in Datadog — $15/check/month. 20 checks = $300/month just to know if our APIs were up.' Checkly does the same thing with Playwright-based checks starting at $0.
What Checkly Offers for Free
Checkly Hobby plan:
- 50,000 check runs/month
- 5 browser checks (Playwright scripts)
- 20 API checks (HTTP endpoint monitoring)
- Checks as Code — write checks in TypeScript, deploy from CI/CD
- Alerting — email, Slack, PagerDuty, Opsgenie
- Private locations — run checks from your own infrastructure
- Dashboards — public status dashboards
Quick Start
npm create checkly
cd my-project
npx checkly test # Run checks locally
npx checkly deploy # Deploy to Checkly
API Check (TypeScript)
// __checks__/api/health.check.ts
import { ApiCheck, AssertionBuilder } from 'checkly/constructs';
new ApiCheck('api-health', {
name: 'API Health Check',
activated: true,
frequency: 5, // every 5 minutes
locations: ['us-east-1', 'eu-west-1'],
request: {
method: 'GET',
url: 'https://api.yourapp.com/health',
assertions: [
AssertionBuilder.statusCode().equals(200),
AssertionBuilder.jsonBody('$.status').equals('healthy'),
AssertionBuilder.responseTime().lessThan(2000)
]
},
alertChannels: ['slack-alerts']
});
Browser Check (Playwright)
// __checks__/browser/login-flow.spec.ts
import { test, expect } from '@playwright/test';
test('user can login and see dashboard', async ({ page }) => {
await page.goto('https://yourapp.com/login');
await page.fill('[name=email]', 'test@example.com');
await page.fill('[name=password]', 'testpassword');
await page.click('button[type=submit]');
await expect(page).toHaveURL('/dashboard');
await expect(page.locator('h1')).toContainText('Dashboard');
// Check that key elements load
await expect(page.locator('[data-testid=stats]')).toBeVisible();
});
REST API
# List checks
curl 'https://api.checklyhq.com/v1/checks' \
-H 'Authorization: Bearer YOUR_API_KEY' \
-H 'X-Checkly-Account: YOUR_ACCOUNT_ID'
# Get check results
curl 'https://api.checklyhq.com/v1/check-results/CHECK_ID?limit=10' \
-H 'Authorization: Bearer YOUR_API_KEY' \
-H 'X-Checkly-Account: YOUR_ACCOUNT_ID'
# Create an API check
curl -X POST 'https://api.checklyhq.com/v1/checks' \
-H 'Authorization: Bearer YOUR_API_KEY' \
-H 'X-Checkly-Account: YOUR_ACCOUNT_ID' \
-H 'Content-Type: application/json' \
-d '{
"name": "Production API",
"checkType": "API",
"activated": true,
"frequency": 5,
"locations": ["us-east-1"],
"request": {
"method": "GET",
"url": "https://api.yourapp.com/health"
},
"assertions": [
{"source": "STATUS_CODE", "comparison": "EQUALS", "target": "200"}
]
}'
# Trigger a check manually
curl -X POST 'https://api.checklyhq.com/v1/triggers/CHECK_ID' \
-H 'Authorization: Bearer YOUR_API_KEY' \
-H 'X-Checkly-Account: YOUR_ACCOUNT_ID'
CI/CD Integration
# .github/workflows/checkly.yml
name: Checkly E2E Tests
on: [deployment_status]
jobs:
test:
if: github.event.deployment_status.state == 'success'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
- run: npm ci
- run: npx checkly test --record
env:
CHECKLY_API_KEY: ${{ secrets.CHECKLY_API_KEY }}
CHECKLY_ACCOUNT_ID: ${{ secrets.CHECKLY_ACCOUNT_ID }}
ENVIRONMENT_URL: ${{ github.event.deployment_status.target_url }}
- run: npx checkly deploy --force
Checkly vs Datadog Synthetics
| Checkly | Datadog Synthetics |
|---|---|
| Free: 50K runs/month | $5-12/test/month |
| Playwright native | Custom syntax |
| Checks as Code | Web UI config |
| CLI-first workflow | Dashboard-first |
| Open source CLI | Proprietary |
Need to monitor your scrapers? Check out my web scraping actors on Apify — with built-in monitoring.
Need API monitoring? Email me at spinov001@gmail.com.
Top comments (0)