# Website Change Monitor (MCP) (`blyck/website-change-monitor`) Actor

Website change monitor and webhook scheduler for AI agents. Track job completion, price drops, restocks, uptime, JSON values, and page changes after the agent disconnects, then POST the result to Slack, Discord, n8n, Zapier, Make, or your own webhook.

- **URL**: https://apify.com/blyck/website-change-monitor.md
- **Developed by:** [JONGMIN LEE](https://apify.com/blyck) (community)
- **Categories:** Automation, MCP servers, Agents
- **Stats:** 1 total users, 0 monthly users, 0.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per event + usage

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js/docs.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python/docs.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/integrations/mcp.md).

If your project is in a different language, use the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).


# README

### Website change monitor and webhook scheduler for AI agents

Website Change Monitor is a persistent **website monitoring API and MCP server** for AI agents and automations. Track a job until it completes, watch a price until it drops, detect a restock, wait for a service to recover, or monitor visible page text — then receive a webhook when the condition becomes true.

Tell us what you are waiting for. We keep checking while you are gone, and when it happens we POST it to a URL you choose.

An agent cannot wait. Its session ends and it is gone — it cannot watch a page, poll a job, or wake up later. This can, and it wakes the agent back up when the moment arrives.

### Quick start

#### Try it in Apify Console

1. Click **Try for free**.
2. Select **Register a website watch**.
3. Enter a public HTTPS URL, the check interval, and the condition you are waiting for.
4. Optionally add an encrypted callback URL for Slack, Discord, n8n, Zapier, Make, or your own service.
5. Start the Actor. The Dataset returns the `watchId`, next check time, remaining checks, and evidence.

Use **Get a watch's status** or **Cancel a watch** with the returned `watchId`. Selecting **Check my existing watches now** performs one immediate round for your account.

#### Connect an MCP client

Streamable HTTP endpoint:

```text
https://blyck--website-change-monitor.apify.actor/mcp
````

Send your Apify API token as a bearer token. The token identifies your account so watches remain private to you.

```json
{
  "mcpServers": {
    "website-change-monitor": {
      "command": "npx",
      "args": [
        "mcp-remote",
        "https://blyck--website-change-monitor.apify.actor/mcp",
        "--header",
        "Authorization: Bearer <YOUR_APIFY_TOKEN>"
      ]
    }
  }
}
```

Or call the MCP tool directly:

```bash
curl -X POST "https://blyck--website-change-monitor.apify.actor/mcp" \
  -H "Authorization: Bearer <YOUR_APIFY_TOKEN>" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/call",
    "params": {
      "name": "watch.url-change",
      "arguments": {
        "url": "https://api.example.com/jobs/8471",
        "interval": "5m",
        "when": "json",
        "path": "$.status",
        "op": "eq",
        "value": "completed",
        "callbackUrl": "https://hooks.example.com/apify",
        "checkBlocks": 1,
        "label": "render job 8471"
      }
    }
  }'
```

### What you can wait for

| You want | How you say it |
|---|---|
| A long job to finish | `when: json`, `path: $.status`, `value: completed` |
| A price to drop | `when: json`, `path: data.price`, `value: 30000`, `op: lt` |
| A sold-out item to come back | `when: contains`, `value: back in stock` |
| A service to recover | `when: status`, `value: 200` |
| A page to change at all | `when: changed` (the default) |

A condition fires **once, on the moment it becomes true** — not on every check. By default the watch then ends, because waiting is over. Pass `stopWhenMet: false` to keep monitoring instead.

### Why a condition instead of "tell me if it changed"

Real pages change on every single load: CSRF tokens, session ids, rotating banners, inline timestamps. "Tell me when it changes" turns into noise, and noise is worse than nothing.

Saying what you are actually waiting for removes that by construction. And when you do use `when: changed`, we compare the **visible text** — scripts, styles, comments and markup are stripped first — so a rotating tracking id does not wake you at 3am.

### Two ways to use it

#### 1. As an MCP server (AI agents)

Standard JSON-RPC 2.0: `initialize`, `tools/list`, `tools/call`. There is no session handshake — every request is independent, so restarts and scaling never break your integration.

| Tool | What it does |
|---|---|
| `watch.url-change` | Register a URL, a condition, and where to notify you. Register and disconnect. |
| `watch.status` | What you are waiting for, whether it has happened, remaining checks, and evidence. |
| `watch.cancel` | Stop waiting. |
| `schedule.at` | Fire a notification at a future point in time. |

#### 2. As a normal Actor

The generated Input UI can register, inspect, cancel, and immediately check watches without an MCP client. You do not have to create your own recurring Apify Schedule — the service already performs the checks after registration.

### Getting notified

Pass a `callbackUrl` when you register. When the watch fires, we POST JSON to it:

```json
{
  "kind": "condition_met",
  "at": "2026-07-26T16:19:00.130Z",
  "watchId": "watch-87a670fd",
  "url": "https://api.example.com/jobs/8471",
  "when": "json",
  "path": "$.status",
  "expected": "completed",
  "actual": "completed",
  "label": "render job"
}
```

Anything that accepts an HTTPS POST works — a **Slack or Discord incoming webhook**, an **n8n / Zapier / Make** hook, or your own endpoint.

#### Waking an agent

An agent that has ended cannot be notified over MCP: the connection is gone with the session. A callback is the way back in.

If your agent is itself an Apify Actor, point the callback at its run endpoint and the event starts it:

```
callbackUrl: https://api.apify.com/v2/acts/<your-actor>/runs?token=<token>
```

> Use a token scoped to that one Actor. The callback URL is stored so we can reach you later, so treat it like any other credential you hand to a third party — and prefer an automation hook (n8n, Zapier, Make) if you would rather not share a platform token at all.

If your agent runs in a desktop client (Claude Desktop, Cursor, ChatGPT), it has no inbound address. Send the callback to Slack or Discord instead, and pick the work back up from there.

### What you get back

Every result carries **evidence**, and a result that cannot be evidenced is reported as a failure rather than dressed up as success.

```json
{
  "status": "ok",
  "data": { "watchId": "watch-a4f93d0a", "nextCheckAt": "…", "checksRemaining": 1000 },
  "evidence": { "reused": false, "when": "json", "stopWhenMet": true, "intervalMs": 300000 },
  "latencyMs": 10
}
```

Guarantees enforced by the runtime, not by prompt:

- **No unevidenced success.** A handler returning `ok` without evidence is downgraded to `failed`.
- **No undeclared inputs.** Fields outside the declared schema are rejected (`unknown_field`), which closes the instruction-injection path through arguments.
- **No silently useless watch.** A condition missing the value or path it needs is rejected at registration instead of never firing.
- **Failures stay failures.** A check that could not be fetched is reported as failed and is not billed.
- **Idempotent registration.** Re-registering the same target, interval and condition returns the existing watch instead of duplicating it.

### Billing

Checks are **prepaid in blocks** when you register a watch. One block buys **one wait, up to 1,000 checks**.

If your condition is met after 12 checks, the watch is done and the remaining checks are not refunded or carried over — you paid for the answer, not for the polling. If you want a watch that keeps running past the first hit, register it with `stopWhenMet: false` and the block is spent the usual way.

```
watch.url-change  { url, when, value, checkBlocks: 3 }   → 3,000 checks prepaid
```

| Event | When | Charged |
|---|---|---|
| `watch-register` | A watch is registered | **$0.25 per 1,000-check block** |
| `schedule-register` | A one-off `schedule.at` is registered | **$0.002** |
| `status-query` | A status or cancel call succeeds | **$0.002** |
| `watch-trigger` | A condition was met, a change was detected, or a schedule fired | **$0.01** |

Typical 30-day watch costs before trigger or optional status-query events:

| Check interval | Checks in 30 days | Blocks | Registration price |
|---|---:|---:|---:|
| 1 hour | about 720 | 1 | **$0.25** |
| 15 minutes | about 2,880 | 3 | **$0.75** |
| 5 minutes | about 8,640 | 9 | **$2.25** |

At a 15-minute interval, one block lasts about 10 days; three blocks about a month.

**What is not charged**

- Failed calls, and checks that could not fetch the target — a failed fetch does not consume your prepaid budget either
- Re-registering an identical watch. It returns the existing watch instead of duplicating it and costs nothing, so agent retries are safe

**When the budget runs out** the watch moves to `exhausted` and stops being checked.
`watch.status` returns `checksRemaining` so you can top up in time — register again to buy a new budget.

### Limits

- **Delivery is best-effort, and never silently so.** We retry once; a `4xx` is treated as your configuration being wrong and is not retried. The outcome is stored on the trigger and returned by `watch.status`, so you can always tell "nothing happened" apart from "we could not reach you".
- **Public HTTPS callbacks only.** Private, loopback and link-local targets are rejected, including hostnames that resolve to them. Redirects are not followed and the request times out after 5 seconds.
- **The same applies to the URL you watch.** It is resolved and checked before every fetch, redirects are re-checked at each hop, and anything pointing at a private, loopback or link-local address is refused. This service is not a way to reach networks you cannot reach yourself.
- **Public HTTPS targets only.** Pages behind a login, paywall, or bot protection are out of scope and are reported as failures rather than worked around.
- `when: changed` tells you *that* the visible text changed, with a fingerprint as evidence. It does not diff the content for you. Per-element selectors are not supported yet — use a condition when you care about one specific thing.
- A watch that fails 5 times in a row is marked `failing` and stops consuming checks.
- Minimum interval is 5 minutes; maximum is 24 hours. A fetch times out after 15 seconds, and the response body is read up to 512 KB — reading stops there rather than downloading the rest.
- Trigger history is kept to the most recent 200 notifications per account, and watches that ended (cancelled, exhausted, met) are removed 30 days later.

# Actor input Schema

## `action` (type: `string`):

Register a new watch, inspect or cancel an existing watch, schedule a one-off notification, or check your existing watches now.

## `url` (type: `string`):

Public HTTPS URL to check. Pages behind logins, paywalls, private networks, or bot protection are not supported.

## `interval` (type: `string`):

How often to check. Minimum 5 minutes, maximum 24 hours.

## `when` (type: `string`):

Choose a precise condition to avoid noisy alerts from timestamps, ads, or rotating page content.

## `path` (type: `string`):

For a JSON condition, enter the scalar value path, for example <code>$.status</code> or <code>data.items\[0].price</code>.

## `op` (type: `string`):

Comparison used by HTTP status and JSON conditions.

## `value` (type: `string`):

Text, status code, or JSON scalar value to compare. Example: <code>completed</code>, <code>200</code>, or <code>29.99</code>.

## `stopWhenMet` (type: `boolean`):

Recommended for job completion, restock, price threshold, and service recovery waits.

## `label` (type: `string`):

Optional note returned with the result so your automation can identify this watch.

## `callbackUrl` (type: `string`):

Optional public HTTPS endpoint that receives a POST when the condition is met. Slack, Discord, n8n, Zapier, Make, and your own webhook are supported. Stored encrypted by Apify.

## `checkBlocks` (type: `integer`):

One block costs $0.25 and includes up to 1,000 checks. Identical retries reuse the existing watch for free.

## `watchId` (type: `string`):

Returned by <code>register\_watch</code>. Required for <code>watch\_status</code> and <code>cancel\_watch</code>.

## `runAt` (type: `string`):

Future ISO 8601 time, for example <code>2030-01-01T09:00:00Z</code>.

## `note` (type: `string`):

Optional text included in the scheduled notification.

## `mode` (type: `string`):

Internal compatibility field used by the owner schedule and local development.

## Actor input object example

```json
{
  "action": "check_now",
  "url": "https://api.example.com/jobs/8471",
  "interval": "1h",
  "when": "changed",
  "path": "$.status",
  "op": "eq",
  "value": "completed",
  "stopWhenMet": true,
  "label": "render job 8471",
  "checkBlocks": 1,
  "watchId": "watch-a4f93d0a",
  "runAt": "2030-01-01T09:00:00Z",
  "note": "Resume the deployment check",
  "mode": "tick"
}
```

# Actor output Schema

## `summary` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {};

// Run the Actor and wait for it to finish
const run = await client.actor("blyck/website-change-monitor").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {}

# Run the Actor and wait for it to finish
run = client.actor("blyck/website-change-monitor").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{}' |
apify call blyck/website-change-monitor --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=blyck/website-change-monitor",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Website Change Monitor (MCP)",
        "description": "Website change monitor and webhook scheduler for AI agents. Track job completion, price drops, restocks, uptime, JSON values, and page changes after the agent disconnects, then POST the result to Slack, Discord, n8n, Zapier, Make, or your own webhook.",
        "version": "0.1",
        "x-build-id": "ZchCf5qGDHHhTj3Yq"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/blyck~website-change-monitor/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-blyck-website-change-monitor",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/blyck~website-change-monitor/runs": {
            "post": {
                "operationId": "runs-sync-blyck-website-change-monitor",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/blyck~website-change-monitor/run-sync": {
            "post": {
                "operationId": "run-sync-blyck-website-change-monitor",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "properties": {
                    "action": {
                        "title": "What do you want to do?",
                        "enum": [
                            "check_now",
                            "register_watch",
                            "watch_status",
                            "cancel_watch",
                            "schedule_notification"
                        ],
                        "type": "string",
                        "description": "Register a new watch, inspect or cancel an existing watch, schedule a one-off notification, or check your existing watches now.",
                        "default": "check_now"
                    },
                    "url": {
                        "title": "URL to monitor",
                        "pattern": "^https://.+",
                        "type": "string",
                        "description": "Public HTTPS URL to check. Pages behind logins, paywalls, private networks, or bot protection are not supported."
                    },
                    "interval": {
                        "title": "Check interval",
                        "enum": [
                            "5m",
                            "15m",
                            "30m",
                            "1h",
                            "6h",
                            "12h",
                            "24h"
                        ],
                        "type": "string",
                        "description": "How often to check. Minimum 5 minutes, maximum 24 hours.",
                        "default": "1h"
                    },
                    "when": {
                        "title": "Notify me when",
                        "enum": [
                            "changed",
                            "contains",
                            "not_contains",
                            "status",
                            "json"
                        ],
                        "type": "string",
                        "description": "Choose a precise condition to avoid noisy alerts from timestamps, ads, or rotating page content.",
                        "default": "changed"
                    },
                    "path": {
                        "title": "JSON path",
                        "type": "string",
                        "description": "For a JSON condition, enter the scalar value path, for example <code>$.status</code> or <code>data.items[0].price</code>."
                    },
                    "op": {
                        "title": "Comparison",
                        "enum": [
                            "eq",
                            "ne",
                            "lt",
                            "lte",
                            "gt",
                            "gte"
                        ],
                        "type": "string",
                        "description": "Comparison used by HTTP status and JSON conditions.",
                        "default": "eq"
                    },
                    "value": {
                        "title": "Expected value",
                        "type": "string",
                        "description": "Text, status code, or JSON scalar value to compare. Example: <code>completed</code>, <code>200</code>, or <code>29.99</code>."
                    },
                    "stopWhenMet": {
                        "title": "Stop after the first match",
                        "type": "boolean",
                        "description": "Recommended for job completion, restock, price threshold, and service recovery waits.",
                        "default": true
                    },
                    "label": {
                        "title": "Label",
                        "type": "string",
                        "description": "Optional note returned with the result so your automation can identify this watch."
                    },
                    "callbackUrl": {
                        "title": "Callback URL",
                        "type": "string",
                        "description": "Optional public HTTPS endpoint that receives a POST when the condition is met. Slack, Discord, n8n, Zapier, Make, and your own webhook are supported. Stored encrypted by Apify."
                    },
                    "checkBlocks": {
                        "title": "Prepaid check blocks",
                        "minimum": 1,
                        "maximum": 100,
                        "type": "integer",
                        "description": "One block costs $0.25 and includes up to 1,000 checks. Identical retries reuse the existing watch for free.",
                        "default": 1
                    },
                    "watchId": {
                        "title": "Watch ID",
                        "type": "string",
                        "description": "Returned by <code>register_watch</code>. Required for <code>watch_status</code> and <code>cancel_watch</code>."
                    },
                    "runAt": {
                        "title": "Run at",
                        "type": "string",
                        "description": "Future ISO 8601 time, for example <code>2030-01-01T09:00:00Z</code>."
                    },
                    "note": {
                        "title": "Notification note",
                        "type": "string",
                        "description": "Optional text included in the scheduled notification."
                    },
                    "mode": {
                        "title": "Legacy runtime mode",
                        "type": "string",
                        "description": "Internal compatibility field used by the owner schedule and local development.",
                        "default": "tick"
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
