API Documentation
Contents
Endpoints
- FREE
GET /api/getQuota - GET
/api/getSites - POST
/api/runSiteTest - GET
/api/getSiteResults/{siteId} - GET
/api/getCrawlers - POST
/api/runCrawl - GET
/api/getCrawlDetailedResult/{id} - GET
/api/getMonitors - GET
/api/getMonitorResults/{id} - POST
/api/runJourney/{monitorId}
Authentication
All API requests must include the following HTTP headers:
| Header | Value | Description |
|---|---|---|
X-Email |
Your account email address | The email address associated with your Webtools account. |
X-API-Key |
Your plaintext API key | Generated from your profile page. Keep this secret. |
Generate your API key on the Profile page. Each time you generate a new key the previous one is invalidated immediately.
Pagination
All data endpoints support optional pagination via query parameters:
| Parameter | Default | Max | Description |
|---|---|---|---|
page |
1 | — | Page number (1-based). |
per_page |
50 | 100 | Number of records per page. Maximum is 100. |
Every response includes a meta object with page,
per_page, and total (total matching records before pagination).
Date Filtering
All data endpoints support optional date range filtering:
| Parameter | Format | Description |
|---|---|---|
from |
ISO 8601 | Inclusive lower bound. Example: 2026-01-01T00:00:00Z |
to |
ISO 8601 | Inclusive upper bound. Example: 2026-01-31T23:59:59Z |
Both parameters are optional. If omitted, no date filter is applied.
from must not be later than to.
Response Format
All successful responses use this envelope:
{
"data": [ ... ],
"meta": {
"page": 1,
"per_page": 50,
"total": 123
},
"server_time": "2026-05-14T10:00:00+00:00"
}
GET
/api/getQuota
Free — does not use a quota call
Returns your plan's total monthly API call allowance, how many calls you have used this month, and how many remain. This endpoint is authenticated but never counts against your quota.
Query parameters: None
Example request:
curl -X GET "https://webtools.ayalr.com/api/getQuota" \
-H "X-Email: [email protected]" \
-H "X-API-Key: your_api_key_here"Example response:
{
"data": {
"plan_name": "Pro",
"total_calls": 1000,
"used_calls": 42,
"remaining_calls": 958
},
"server_time": "2026-05-14T10:00:00+00:00"
}
GET
/api/getSites
Returns all configured sites belonging to your account.
Query parameters: None
Example request:
curl -X GET "https://webtools.ayalr.com/api/getSites" \
-H "X-Email: [email protected]" \
-H "X-API-Key: your_api_key_here"Example response:
{
"sites": [
{
"id": 1,
"name": "My Website",
"user": 42,
"created_at": "2026-01-15 09:00:00",
"updated_at": "2026-03-10 14:30:00",
"urls": [
{ "id": 3, "url": "https://example.com", "label": "Homepage" },
{ "id": 4, "url": "https://example.com/about", "label": "About" }
]
}
],
"server_time": "2026-05-14 10:00:00"
}
GET
/api/getCrawlers
Returns all crawler monitors belonging to your account.
Query parameters: None
Example request:
curl -X GET "https://webtools.ayalr.com/api/getCrawlers" \
-H "X-Email: [email protected]" \
-H "X-API-Key: your_api_key_here"Example response:
{
"crawlers": [
{
"id": 8,
"name": "Main Site Crawler",
"url": "https://example.com",
"type": "crawler",
"status": null,
"lastRun": 1746172800000,
"paused": 0,
"verified": 1,
"crawls": [
{
"id": 101,
"monitorId": 8,
"time": 1746172800000,
"success": 1,
"totalCrawled": 142,
"securityIssues": 0,
"non200s": 3,
"multipleH1s": 1,
"errorMessage": null,
"detail_ref": "/api/getCrawlDetailedResult/101"
}
]
}
],
"server_time": "2026-05-14 10:00:00"
}
Each crawl entry includes a detail_ref path. Pass the crawl id to GET /api/getCrawlDetailedResult/{id} to retrieve the full raw crawl data.
GET
/api/getCrawlDetailedResult/{crawlId}
Returns the full raw crawl result for a specific crawl execution, including the complete JSON crawl data (visited URLs, response codes, H1s, canonicals, mixed content, etc.). Use the id from the crawls array in GET /api/getCrawlers.
Path parameter:
| Parameter | Type | Description |
|---|---|---|
crawlId |
integer | The ID of the crawl execution. Obtained from the id field in the crawls array returned by GET /api/getCrawlers. |
Example request:
curl -X GET "https://webtools.ayalr.com/api/getCrawlDetailedResult/101" \
-H "X-Email: [email protected]" \
-H "X-API-Key: your_api_key_here"Example response:
{
"data": {
"id": 101,
"monitorId": 8,
"monitorName": "Main Site Crawler",
"monitorUrl": "https://example.com",
"time": 1746172800000,
"success": 1,
"totalCrawled": 142,
"securityIssues": 0,
"non200s": 3,
"multipleH1s": 1,
"errorMessage": null,
"rawResult": {
"visited": { "https://example.com": true, "...": "..." },
"responseCodes": { "https://example.com": 200, "...": "..." },
"contentH1s": { "https://example.com": ["Home"], "...": "..." },
"summary": {
"non200": 3,
"noTitle": 0,
"multipleH1s": 1,
"multipleCanonicals": 0,
"mixedContent": 0,
"error500": 0,
"error400": 2,
"error300": 1
}
}
},
"server_time": "2026-05-14T10:00:00+00:00"
}
GET
/api/getMonitors
Returns all uptime, RUM, and Server monitors belonging to your account, grouped by type.
Query parameters: None
Example request:
curl -X GET "https://webtools.ayalr.com/api/getMonitors" \
-H "X-Email: [email protected]" \
-H "X-API-Key: your_api_key_here"Example response:
{
"data": {
"uptime": [
{
"id": 12,
"name": "Homepage Uptime",
"type": "website",
"url": "https://example.com",
"ipOrDomain": null,
"status": null,
"lastRun": 1746172800000,
"paused": 0,
"location": "MT"
}
],
"rum": [
{
"id": 7,
"name": "Main Site RUM",
"type": "RUM",
"url": null,
"ipOrDomain": null,
"status": null,
"lastRun": 1746172800000,
"paused": 0,
"location": null
}
],
"server": [
{
"id": 15,
"name": "App Server",
"type": "Server",
"url": null,
"ipOrDomain": "192.168.1.1",
"status": null,
"lastRun": 1746172800000,
"paused": 0,
"location": "MT"
}
]
},
"server_time": "2026-05-14 10:00:00"
}
GET
/api/getMonitorResults/{monitorId}
Returns test results for a specific monitor. The data source varies by monitor type:
- website — last 24 hours of uptime check results from the database
- RUM — session data from the metric server, scoped by
mode - Server — server metrics from the metric server, scoped by
mode
Use GET /api/getMonitors to find your monitor IDs.
Path parameter:
| Parameter | Type | Description |
|---|---|---|
monitorId |
integer | The ID of the monitor. Must be of type website, RUM, or Server and belong to your account. |
Query parameters:
| Parameter | Default | Options | Description |
|---|---|---|---|
mode |
hour |
hour, day, week |
Time window for RUM and Server monitors. Ignored for website monitors (always returns last 24h). |
Example request (website monitor):
curl -X GET "https://webtools.ayalr.com/api/getMonitorResults/12" \
-H "X-Email: [email protected]" \
-H "X-API-Key: your_api_key_here"Example request (RUM or Server monitor):
curl -X GET "https://webtools.ayalr.com/api/getMonitorResults/7?mode=day" \
-H "X-Email: [email protected]" \
-H "X-API-Key: your_api_key_here"Example response (website monitor):
{
"data": {
"monitor_id": 12,
"monitor_name": "Homepage Uptime",
"monitor_type": "website",
"results": [
{
"monitorId": 12,
"time": 1746172800000,
"success": 1,
"totalTime": 183,
"errorMessage": null,
"ip": "93.184.216.34",
"country": "MT"
}
]
},
"server_time": "2026-05-14T10:00:00+00:00"
}
Example response (RUM or Server monitor):
{
"data": {
"monitor_id": 7,
"monitor_name": "Main Site RUM",
"monitor_type": "RUM",
"mode": "day",
"results": { "...": "metric server response" }
},
"server_time": "2026-05-14T10:00:00+00:00"
}
POST
/api/runSiteTest
Triggers a lab test for one of your configured sites, exactly as if you clicked Run Tests Now in the dashboard. The test is queued asynchronously — the endpoint returns immediately and the test runs in the background.
If you provide a webhook_url, Webtools will send a fire-and-forget POST request to that URL when the test completes, allowing you to react to results in your own systems.
Request body (JSON or form data):
| Parameter | Type | Required | Description |
|---|---|---|---|
site_id |
integer | Yes | The ID of the site to test. Must belong to your account. Use GET /api/getSites to find your site IDs. |
webhook_url |
string (URL) | No | A fully-qualified HTTP or HTTPS URL. Webtools will POST to this URL when the test completes. The request body will contain the siteId and urlId of the completed report. |
Example request (no webhook):
curl -X POST "https://webtools.ayalr.com/api/runSiteTest" \
-H "X-Email: [email protected]" \
-H "X-API-Key: your_api_key_here" \
-H "Content-Type: application/json" \
-d '{"site_id": 1}'Example request (with webhook):
curl -X POST "https://webtools.ayalr.com/api/runSiteTest" \
-H "X-Email: [email protected]" \
-H "X-API-Key: your_api_key_here" \
-H "Content-Type: application/json" \
-d '{"site_id": 1, "webhook_url": "https://your-app.com/webhooks/webtools"}'Example response:
{
"data": {
"site_id": 1,
"site_name": "My Website",
"urls_queued": 2,
"webhook_url": "https://your-app.com/webhooks/webtools"
},
"message": "Test queued successfully.",
"server_time": "2026-05-14T10:00:00+00:00"
}
Note: This endpoint consumes one on-demand test from your monthly allowance per URL configured on the site.
A 429 response is returned if your on-demand test limit is reached.
If a site has multiple URLs, the webhook will be called once for each URL as each individual test completes —
not once for the whole site. Use the urlId in the webhook payload to identify which URL's test finished.
POST
/api/runCrawl
Queues a crawl run for a specific crawler monitor, exactly as if you clicked Queue Now in the dashboard. The crawl runs asynchronously — the endpoint returns immediately.
If you provide a webhook_url, Webtools will POST to that URL when the crawl completes.
Request body (JSON or form data):
| Parameter | Type | Required | Description |
|---|---|---|---|
crawler_id |
integer | Yes | The ID of the crawler monitor to run. Must belong to your account. Use GET /api/getCrawlers to find your crawler IDs. |
webhook_url |
string (URL) | No | A fully-qualified HTTP or HTTPS URL. Webtools will POST to this URL when the crawl completes. |
Example request:
curl -X POST "https://webtools.ayalr.com/api/runCrawl" \
-H "X-Email: [email protected]" \
-H "X-API-Key: your_api_key_here" \
-H "Content-Type: application/json" \
-d '{"crawler_id": 8, "webhook_url": "https://your-app.com/webhooks/crawl-done"}'Example response:
{
"data": {
"crawler_id": 8,
"crawler_name": "Main Site Crawler",
"crawler_url": "https://example.com",
"webhook_url": "https://your-app.com/webhooks/crawl-done"
},
"message": "Crawl queued successfully.",
"server_time": "2026-05-14T10:00:00+00:00"
}
Note: This endpoint consumes one ad-hoc crawl from your monthly allowance. A 429 response is returned if your ad-hoc crawl limit is reached. Paused crawlers cannot be queued — unpause them first.
POST
/api/runJourney/{monitorId}
Queues an ad-hoc run of a Journey monitor (JourneyGuard synthetic test), exactly as if you clicked Run Now in the dashboard. The journey runs asynchronously — the endpoint returns immediately after enqueueing.
If you provide a webhook_url, Webtools will POST to that URL when the journey completes. This is useful for wiring the endpoint to a CI pipeline (GitHub Actions, Bitbucket Pipelines) on a post-merge event.
Path parameter:
| Parameter | Type | Description |
|---|---|---|
monitorId |
integer | The ID of the Journey monitor to run. Must belong to your account and have type = "Journey". Use GET /api/getMonitors to find your journey IDs. |
Request body (JSON or form data, optional):
| Parameter | Type | Required | Description |
|---|---|---|---|
webhook_url |
string (URL) | No | A fully-qualified HTTP or HTTPS URL. Webtools will POST to this URL when the journey completes. |
Example request (no webhook):
curl -X POST "https://webtools.ayalr.com/api/runJourney/34" \
-H "X-Email: [email protected]" \
-H "X-API-Key: your_api_key_here"Example request (with webhook):
curl -X POST "https://webtools.ayalr.com/api/runJourney/34" \
-H "X-Email: [email protected]" \
-H "X-API-Key: your_api_key_here" \
-H "Content-Type: application/json" \
-d '{"webhook_url": "https://your-app.com/webhooks/journey-done"}'Example response:
{
"data": {
"monitor_id": 34,
"monitor_name": "Checkout Flow",
"webhook_url": "https://your-app.com/webhooks/journey-done"
},
"message": "Journey queued successfully.",
"server_time": "2026-07-25T10:00:00+00:00"
}
Note: This endpoint consumes one ad-hoc journey run from your monthly allowance. A 429 response is returned if your ad-hoc journey limit is reached. Paused journeys cannot be queued — unpause them first.
For a full GitHub Actions / Bitbucket Pipelines walkthrough, see the CI setup guide →
GET
/api/getSiteResults/{siteId}
Returns lab test results for a specific site over the last x days, grouped by each URL configured on the site. Use GET /api/getSites to find your site IDs and their URL IDs.
Path parameter:
| Parameter | Type | Description |
|---|---|---|
siteId |
integer | The ID of the site to retrieve results for. Must belong to your account. |
Query parameters:
| Parameter | Default | Max | Description |
|---|---|---|---|
days |
7 | 90 | Number of days of history to return. |
page |
1 | — | Page number applied independently to each URL's result set. |
per_page |
50 | 100 | Records per page per URL. |
Example request:
curl -X GET "https://webtools.ayalr.com/api/getSiteResults/1?days=14&per_page=10" \
-H "X-Email: [email protected]" \
-H "X-API-Key: your_api_key_here"Example response:
{
"data": {
"site_id": 1,
"site_name": "My Website",
"days": 14,
"urls": [
{
"url_id": 3,
"url": "https://example.com",
"label": "Homepage",
"meta": { "page": 1, "per_page": 10, "total": 28 },
"reports": [
{
"id": 201,
"siteId": 1,
"urlId": 3,
"performance": 87,
"accessibility": 95,
"seo": 92,
"bestPractices": 100,
"firstContentfulPaint": 1200,
"largestContentfulPaint": 2100,
"cumulativeLayoutShift": 0.05,
"totalBlockingTime": 120,
"speedIndex": 1800,
"ttfb": 210,
"time": 1746172800000,
"created_at": "2026-05-02T10:00:00.000000Z"
}
]
},
{
"url_id": 4,
"url": "https://example.com/about",
"label": "About",
"meta": { "page": 1, "per_page": 10, "total": 14 },
"reports": [ "..." ]
}
]
},
"server_time": "2026-05-14T10:00:00+00:00"
}
Error Responses
| HTTP Status | Cause | Message |
|---|---|---|
| 400 | Missing headers | Email and API key are required in headers. |
| 401 | Invalid credentials | Invalid email or API key. |
| 401 | Quota exceeded | Quota exceeded. |
| 403 | Free-tier account | This endpoint requires a paid plan. Please upgrade your account to access the API. |
| 422 | Invalid pagination | page and per_page must be positive integers. / per_page must not exceed 100. |
| 422 | Invalid date params | from and to must be valid ISO 8601 date-time strings. / from must not be later than to. |
Website Monitoring API — Automate Your Web Health Checks
The Webtools API gives developers and DevOps teams programmatic access to every monitoring capability available in the dashboard. Whether you need to trigger on-demand performance tests, pull uptime history into your own reporting pipeline, or react to crawl completions via webhooks, the REST API lets you integrate website health data directly into your workflows.
Integrate Website Performance Data Into Your CI/CD Pipeline
Use POST /api/runSiteTest to kick off a Lighthouse-based lab test after every deployment and receive the results
— Core Web Vitals, performance score, accessibility, SEO, and best practices — via webhook the moment the test completes.
Catch regressions in LCP, CLS, and TBT before they reach your users, without leaving your existing toolchain.
Automate SEO Crawl Audits at Scale
Schedule or trigger site crawls programmatically with POST /api/runCrawl and retrieve detailed results — broken
links, non-200 responses, missing H1 tags, duplicate canonicals, and mixed content — through GET /api/getCrawlDetailedResult/{id}.
Feed crawl data into your own dashboards, Slack alerts, or data warehouses to keep SEO health visible across your entire team.
Uptime and RUM Monitoring via API
Retrieve real-time and historical uptime check results, Real User Monitoring (RUM) session data, and server metrics through
GET /api/getMonitorResults/{monitorId}. Filter by hour, day, or week to build custom SLA reports, feed observability
platforms, or power internal status pages — all without manual exports.
Simple Authentication, Predictable Rate Limits
Every API request authenticates with two HTTP headers — X-Email and X-API-Key — generated from your
profile page. Monthly quota usage is always visible through the free GET /api/getQuota endpoint, which never counts
against your allowance. Upgrade your plan at any time to increase your API call limit and unlock higher crawl and test quotas.