# Product Detail & Price Parser (`jan_hilgard/price-detail-parser`) Actor

Reliable product detail & price extraction from a URL, even on shops behind heavy anti-bot protection. Returns name, price, currency, stock, EAN and image with per-field confidence and a fail-loud reliable flag — never silently wrong. Built on the data.hilgard.cz self-healing engine.

- **URL**: https://apify.com/jan\_hilgard/price-detail-parser.md
- **Developed by:** [Jan Hilgard](https://apify.com/jan_hilgard) (community)
- **Categories:** E-commerce, Developer tools, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$2.00 / 1,000 url parseds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

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

## What's an Apify Actor?

Actors are a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
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.md):

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

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python.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/platform/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

## Product Detail & Price Parser

**Reliable product & price extraction from a URL that fails loud — never silently wrong.**

Give it a product URL. It returns a clean, structured record — name, price, currency,
stock, EAN, image — with a confidence on **every** field and a single `reliable` flag.
When a field does not clear the bar you get `reliable: false` and a `null` with a stated
reason, not a guessed value. It never hands you a plausible-looking price that is quietly
wrong, and never an empty cell dressed up as a successful parse. That guarantee is the
product; the engine underneath is just how it is kept.

Most scrapers are a CSS selector and a hope. The selector breaks the day the shop
ships a redesign, and you find out weeks later from a wrong price in a feed. This one
is built the opposite way: it cross-checks what it extracted, scores its own
confidence, and refuses to call a shaky extraction reliable. A wrong price is worse
than a missing one — a missing one you notice, a wrong one you act on.

Keywords: no silent errors, per-field confidence, validated extraction,
confidence-scored price, EAN / GTIN check-digit, product detail extraction,
price scraping, structured product data, e-commerce price parser,
self-healing scraper, Cloudflare scraper, DataDome bypass, anti-bot scraping,
scrape behind WAF.

---

### Why this beats self-healing / AI scrapers

Self-healing and LLM scrapers adapt to a layout change — that part is table-stakes now,
this one does it too. But adapting is not the same as being right: a scraper can re-find
"a price" after a redesign and still hand you a plausible-but-wrong field — the wrong
variant, a stale crossed-out price, a swapped currency — and say nothing. That silent
wrong value is the expensive one. The difference here is the guarantee, not the healing:
every field carries its own confidence, an EAN/GTIN must pass its check digit, and below
the bar the field comes back `reliable: false` instead of a guess. An honest fail you can
catch beats a confident mistake you cannot. Self-healing is how the field gets re-found;
the confidence and validation are what decide whether you are allowed to trust it.

---

### What a real run looks like

One URL in, one structured row out — with the engine's own confidence attached.

**(a) The layout changed. A selector-based scraper would silently break. This doesn't.**

````

URL:  https://shop.example/iphone-17-512gb   (shop redesigned its price markup last week)

✓  product\_name   "Apple iPhone 17 512 GB Lavender"
✓  price          27990            field confidence: high
✓  currency       "CZK"
✓  ean            "1949483485739"  field confidence: high (check-digit valid)
reliable:      true             overall confidence: 0.96
note:          HTML price node moved; the Vision pass read the price off the
rendered page and the two agreed — extraction self-healed.

```

A hard-coded selector would have returned `null` (or worse, grabbed the crossed-out
old price). The Vision cross-check caught the moved element and confirmed it.

**(b) The page is ambiguous. It does NOT guess — it fails loud.**

```

URL:  https://shop.example/landing/iphone-deals   (a promo page, not one product)

✗  price          null             field confidence: low
reliable:      false            overall confidence: 0.28
success:       false
note:          multiple prices on the page, none clearly the product's — returned
unreliable with low confidence rather than a guessed number.

````

The value is that second row. A cheaper tool would have returned *a* price here —
some price on the page — and you would have trusted it.

---

### Why it is different

- **No silent errors.** Every field carries a confidence, the whole record carries a
  `reliable` flag, and codes are validated — an EAN/GTIN must pass its check digit to
  be trusted. Below the confidence bar the field is returned `null` with low
  confidence and `reliable: false`, never a confident-looking wrong value.
- **Wrong input gets an honest answer too.** Point it at a URL that is not a product
  detail page — a category listing, a promo landing page, a real-estate advert — and
  it does not hallucinate a product out of whatever it found. It returns
  `success: false` with `error: "not a product detail page (entity: …)"`. Even a bad
  input gets the truth, not a fairy tale. Same no-silent-errors rule, applied to the
  page itself.
- **Self-healing — a mechanism that serves the correctness above, not the headline.**
  The engine cross-checks the HTML reading against a Vision reading of the rendered page,
  so a layout change that breaks a selector is caught instead of silently returning the
  wrong node.
- **Gets through where plain scrapers hit a wall.** The heavy anti-bot protections —
  DataDome, Cloudflare, Akamai, PerimeterX and similar — return a challenge page
  instead of data to a simple fetch. This reaches the actual product page through them,
  so you get the product, not a CAPTCHA. (Anti-bot is an arms race, so this is a
  capability that handles these protections, not a guarantee against any one named
  vendor.)
- **Predictable mid price.** One flat price per URL parsed. Not the cheapest
  unreliable scraper where a few wrong values per thousand are "fine", and not an
  enterprise per-seat contract. You pay one predictable price and get validated data
  or an honest confidence — the self-healing and the validation are *why* it sits in
  the middle, not at the bottom.

---

### How it works

Per URL, from input to record:

1. **Fetch — get through to the real page.** Reach the product page through the heavy
   anti-bot / WAF layers (DataDome, Cloudflare, Akamai, PerimeterX and the like) and
   render JS-driven content, so the extractor sees the actual product the way a real
   browser would — not a challenge page, an interstitial, or an empty SPA shell.
2. **Extract by meaning.** Read the product fields by what they *mean* on the page,
   not by a fixed selector path that a redesign would break.
3. **Cross-check & validate.** Reconcile independent readings of the same field
   (HTML and Vision) — this HTML+Vision cross-check is the self-healing part, and it
   is here to serve correctness — score a per-field confidence, and run deterministic
   checks where they exist — an EAN/GTIN must pass its check digit.
4. **Fail loud below the bar.** When confidence does not clear the threshold, the
   field is returned `null` and the record is marked `reliable: false`, with the
   reason — rather than emitting a guess.

This is the principle, not a recipe: the actor deliberately exposes no thresholds,
weights, or model names, because those are tuned on the engine side and change.

Mechanically: the actor is a thin client. The heavy work (anti-bot fetch, headed
browser, model-by-meaning extraction, Vision cross-check, validation) runs on the
[data.hilgard.cz](https://data.hilgard.cz) service. The actor sends the URL to
`POST /api/parse`, streams the engine's progress over SSE, and writes one validated
row to the dataset. A fresh extraction can take minutes; if the stream drops before a
result, the actor retries the parse within the per-URL budget.

---

### Input

```jsonc
{
  "urls": [
    "https://www.alza.cz/apple-iphone-17-512gb"   // 1–N product detail URLs
  ],
  "forceFresh": false,          // optional, force a fresh extraction (skip cache)
  "includeDebug": false,        // optional, keep the full _debug block in each row
  "requestTimeoutSecs": 360,    // optional, per-URL budget across retries (hard-capped at 600)
  "maxRetries": 3,              // optional, re-parse attempts after a dropped stream
  "retryBackoffSecs": 3         // optional, delay between retries
}
````

Each entry in `urls` must be an `http(s)` URL and is parsed independently, in order.
`forceFresh: false` (the default) lets the service serve a fast cached extraction when
it has one; set it `true` to force a full fresh self-healing extraction every time.
`requestTimeoutSecs` is the per-URL budget across retries (default 360s); a single parse
is hard-capped at 600s no matter what you set, so one pathologically slow page is aborted
at the cap and reported as a fail-loud error (`per-URL time budget exceeded`) — and a URL
cut off this way produces no result, so it is **not** charged.

### Output

One dataset row **per URL**:

```json
{
  "url": "https://www.alza.cz/apple-iphone-17-512gb",
  "domain": "alza.cz",
  "product_name": "Apple iPhone 17 512 GB",
  "price": 27990,
  "currency": "CZK",
  "in_stock": true,
  "ean": "1949483485739",
  "image_url": "https://...",
  "reliable": true,
  "overall_confidence": 0.96,
  "fields": {
    "product_name": { "status": "confirmed", "score": 1 },
    "price":        { "status": "high",      "score": 0.97 },
    "currency":     { "status": "confirmed", "score": 1 },
    "in_stock":     { "status": "confirmed", "score": 1 },
    "ean":          { "status": "confirmed", "score": 1 },
    "image_url":    { "status": "single",    "score": 1 }
  },
  "entity": "product",
  "scraped_at": "2026-06-18T10:00:00.000Z",
  "success": true
}
```

The product payload is exactly the fields the engine reliably yields — `product_name`,
`price`, `currency`, `in_stock`, `ean`, `image_url`. It does not invent `brand` /
`model` / `specs` columns; you get what the page actually supports, validated, rather
than padded with empty fields. `domain` is normalized without a `www.` prefix.

`reliable` and `overall_confidence` (0–1) are the top-level trust signals. Under
`fields`, every product field carries its own `status` and numeric `score` (0–1) — and
**every** field appears, including the ones that came back empty: a missing `ean` is
`{ "status": "absent", "score": null }`, never silently omitted, so a `null` always has a
stated reason.

**`success` vs `reliable`:** `success` says the parse technically produced a product
record from a product page; `reliable` says that record cleared the engine's trust
threshold. They diverge when a product was extracted but the engine is not confident in
it — then `success` is `true` while `reliable` is `false`, and the per-field scores stay
low, so a hedge never reads as a clean hit. A page that is not a product, or that yields
no record at all, is `success: false` with the reason in `error`.

When `includeDebug` is `true`, each row also carries the service's full `_debug` block
plus the raw `security` block (detected protection + fetch strategy; kept out of the
default output because its vendor reading can look odd without that context). If a URL
fails entirely, a single placeholder row is written with `success: false`,
`reliable: false`, and an `error` message.

***

### Pricing

This actor uses **Pay Per Event**, with a single event:

- **`url-parsed`** — one flat fee per product URL parsed.

You are charged once per URL that the engine actually parses — whether the result comes
back `reliable: true` or, honestly, `reliable: false`. The fee pays for the work that
ran either way: the anti-bot fetch, the model-by-meaning extraction, the Vision
cross-check, and the validation. A URL that hard-fails before producing any result
(network error, retries exhausted) is **not** charged.

No flat monthly fee. No per-seat pricing. One predictable price per processed URL, and
in return you get validated data or an honest confidence — never a silent mistake.
Reach, self-healing, and validation together are why this is not the cheapest option:
it gets through to data on protected shops where a selector-based scraper just hits a
challenge page, recovers when a layout shifts, and validates every field before it
trusts it. The current price of the event is in the Apify Console pricing tab.

***

### When NOT to use this

I would rather you not waste money, so:

- **You want the cheapest possible scraper at huge volume and a few silently-wrong
  values per thousand are acceptable.** This one spends real work self-healing and
  validating every field; if that correctness is not worth a mid price to you, a
  lighter selector-based scraper will cost less.
- **You only have a handful of one-off URLs.** Just paste them into the
  [data.hilgard.cz](https://data.hilgard.cz) UI and read the result. No actor run
  needed.

If the correctness story above is not what you need, one of these is the better call.

***

### About

Built on the [data.hilgard.cz](https://data.hilgard.cz) parsing engine — the same
self-healing stack that does anti-bot fetching, model-by-meaning extraction, and
independent verification, here applied to single-URL product detail & price extraction.

By Jan Hilgard (founder of Hosting90, acquired; core contributor to vllm-mlx). The
precision-first stance is deliberate: I would rather return an honest "not sure" than a
confident wrong price you build decisions on.

### Development

```bash
npm install
npm run build      # tsc → dist/
npm run start:dev  # tsx src/main.ts, reads .actor/INPUT.json
```

# Actor input Schema

## `urls` (type: `array`):

List of product detail URLs to parse. Each must be an http(s) URL. One dataset row is written per URL. URLs are processed sequentially.

## `forceFresh` (type: `boolean`):

When enabled, force a full fresh extraction for every URL — the engine re-fetches and re-runs the AI/Vision self-heal, never serving a cached result. Slower, but always re-validated now. When disabled (default), the service may serve a fast cached extraction when one is available.

## `includeDebug` (type: `boolean`):

When enabled, keep the service's full internal \_debug block (page type, arbitration, verification, quality notes) in each output row. Per-field confidence is always included regardless of this flag.

## `requestTimeoutSecs` (type: `integer`):

Total time budget for parsing one URL, ACROSS retries. A fresh extraction (anti-bot fetch, model-by-meaning extraction, Vision cross-check) can take minutes. Hard-capped at 600s internally (a single pathologically slow parse is aborted at the cap and reported as a fail-loud error, not charged) — values above the cap are clamped.

## `maxRetries` (type: `integer`):

The parse runs as a single streamed connection with no resume — if the stream drops before a result, the actor retries the whole parse from scratch. This bounds how many times, before giving up on that URL.

## `retryBackoffSecs` (type: `integer`):

Delay before retrying a parse after the stream drops.

## Actor input object example

```json
{
  "urls": [
    "https://www.alza.cz/apple-iphone-17-512gb"
  ],
  "forceFresh": false,
  "includeDebug": false,
  "requestTimeoutSecs": 360,
  "maxRetries": 3,
  "retryBackoffSecs": 3
}
```

# Actor output Schema

## `overview` (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 = {
    "urls": [
        "https://www.alza.cz/apple-iphone-17-512gb"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("jan_hilgard/price-detail-parser").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 = { "urls": ["https://www.alza.cz/apple-iphone-17-512gb"] }

# Run the Actor and wait for it to finish
run = client.actor("jan_hilgard/price-detail-parser").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 '{
  "urls": [
    "https://www.alza.cz/apple-iphone-17-512gb"
  ]
}' |
apify call jan_hilgard/price-detail-parser --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=jan_hilgard/price-detail-parser",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Product Detail & Price Parser",
        "description": "Reliable product detail & price extraction from a URL, even on shops behind heavy anti-bot protection. Returns name, price, currency, stock, EAN and image with per-field confidence and a fail-loud reliable flag — never silently wrong. Built on the data.hilgard.cz self-healing engine.",
        "version": "0.0",
        "x-build-id": "lQalncUkEjv5TfWOl"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/jan_hilgard~price-detail-parser/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-jan_hilgard-price-detail-parser",
                "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/jan_hilgard~price-detail-parser/runs": {
            "post": {
                "operationId": "runs-sync-jan_hilgard-price-detail-parser",
                "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/jan_hilgard~price-detail-parser/run-sync": {
            "post": {
                "operationId": "run-sync-jan_hilgard-price-detail-parser",
                "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",
                "required": [
                    "urls"
                ],
                "properties": {
                    "urls": {
                        "title": "Product URLs",
                        "type": "array",
                        "description": "List of product detail URLs to parse. Each must be an http(s) URL. One dataset row is written per URL. URLs are processed sequentially.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "forceFresh": {
                        "title": "Force a fresh extraction",
                        "type": "boolean",
                        "description": "When enabled, force a full fresh extraction for every URL — the engine re-fetches and re-runs the AI/Vision self-heal, never serving a cached result. Slower, but always re-validated now. When disabled (default), the service may serve a fast cached extraction when one is available.",
                        "default": false
                    },
                    "includeDebug": {
                        "title": "Include debug data",
                        "type": "boolean",
                        "description": "When enabled, keep the service's full internal _debug block (page type, arbitration, verification, quality notes) in each output row. Per-field confidence is always included regardless of this flag.",
                        "default": false
                    },
                    "requestTimeoutSecs": {
                        "title": "Per-URL budget (seconds)",
                        "minimum": 60,
                        "maximum": 3600,
                        "type": "integer",
                        "description": "Total time budget for parsing one URL, ACROSS retries. A fresh extraction (anti-bot fetch, model-by-meaning extraction, Vision cross-check) can take minutes. Hard-capped at 600s internally (a single pathologically slow parse is aborted at the cap and reported as a fail-loud error, not charged) — values above the cap are clamped.",
                        "default": 360
                    },
                    "maxRetries": {
                        "title": "Max retries on dropped stream",
                        "minimum": 0,
                        "maximum": 20,
                        "type": "integer",
                        "description": "The parse runs as a single streamed connection with no resume — if the stream drops before a result, the actor retries the whole parse from scratch. This bounds how many times, before giving up on that URL.",
                        "default": 3
                    },
                    "retryBackoffSecs": {
                        "title": "Retry backoff (seconds)",
                        "minimum": 0,
                        "maximum": 120,
                        "type": "integer",
                        "description": "Delay before retrying a parse after the stream drops.",
                        "default": 3
                    }
                }
            },
            "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
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
