# EU Pay Transparency Compliance Checker (`penpaste/eu-pay-transparency-checker`) Actor

Audit any company's job adverts against the EU Pay Transparency Directive. Flags missing salary ranges, vague pay wording, and illegal pay-history questions. Reads public ATS feeds from Greenhouse, Lever, Ashby, Recruitee and Personio. No login or API key needed.

- **URL**: https://apify.com/penpaste/eu-pay-transparency-checker.md
- **Developed by:** [Mike Zyke](https://apify.com/penpaste) (community)
- **Categories:** Lead generation, Jobs
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $4.00 / 1,000 job advert checkeds

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 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

## EU Pay Transparency Compliance Checker

**Audit any company's job adverts against the EU Pay Transparency Directive — every open role, in seconds.**

Since **7 June 2026**, employers hiring in the EU must state the salary or salary range for a role. "Competitive salary" no longer satisfies the law. Penalties reach the five- to six-figure range per breach, and in a pay dispute the burden of proof falls on the employer.

Point this Actor at a careers page. It tells you, role by role, whether the pay disclosure holds up.

---

### Real example

A live scan of a Berlin AI company's job board (16 open roles, all EU):

| Job | Status | Pay found |
|---|---|---|
| Senior Computer Vision Engineer | ✅ compliant | €80,000 – €120,000 / year |
| Senior Backend Engineer | ✅ compliant | €70,000 – €90,000 / year |
| Account Executive | ✅ compliant | €70,000 – €90,000 / year |
| Sales Development Representative | ✅ compliant | €40,000 – €50,000 / year |
| Field Installation Engineer | ✅ compliant | €45,000 – €58,000 / year |
| Senior/Staff Robotics Engineer | ❌ **no pay disclosed** | — |
| VLM Research Engineer | ❌ **no pay disclosed** | — |
| Senior Edge Infrastructure Engineer | ❌ **no pay disclosed** | — |

**Compliance score: 69%** — 11 of 16 roles disclosed pay. Five did not, including one posted after the directive took effect.

That is the report. One run, no configuration.

---

### What you get

One row per job:

| Field | Example |
|---|---|
| `complianceStatus` | `compliant` · `review` · `non_compliant` · `out_of_scope` |
| `issueCodes` | `["VAGUE_PAY_LANGUAGE"]` |
| `salaryMin` / `salaryMax` | `70000` / `90000` |
| `salaryCurrency` / `salaryInterval` | `EUR` / `year` |
| `salaryEvidence` | the exact text the figure came from |
| `jurisdiction` | `EU` · `US-transparency-state` · `unknown` |
| `applyUrl` | direct link to the advert |

Plus one `company_summary` row per employer with a 0–100 score.

```json
{
  "recordType": "job",
  "company": "almetra",
  "title": "Senior Backend Engineer (m/f/d)",
  "location": "Berlin",
  "complianceStatus": "compliant",
  "issueCodes": [],
  "salaryMin": 70000,
  "salaryMax": 90000,
  "salaryCurrency": "EUR",
  "salaryInterval": "year",
  "salarySource": "ats_field",
  "jurisdiction": "EU",
  "jurisdictionConfidence": "high",
  "applyUrl": "https://jobs.ashbyhq.com/almetra/ec1bfd2d-..."
}
````

***

### What it catches

| Issue | Meaning |
|---|---|
| `NO_PAY_INFORMATION` | No pay figure anywhere in the advert |
| `VAGUE_PAY_LANGUAGE` | "Competitive salary", "attraktives Gehalt", "salaire compétitif", "según experiencia" — 60+ phrases across 8 languages |
| `RANGE_TOO_WIDE` | €30k–€120k. Technically a range; arguably not informative. Threshold configurable |
| `SINGLE_VALUE_ONLY` | One figure, no range |
| `SALARY_HISTORY_QUESTION` | Asking what a candidate currently earns — banned outright by Art. 5(2) |
| `AI_DETECTED_PAY` | Found by AI review but not deterministic rules — verify before relying on it |

#### Pay parsing built for European adverts

European job ads write money in ways that break naive parsing. `45.000` means forty-five thousand in Berlin and forty-five point zero in Boston. All of these are handled:

```
€45,000 – €60,000 per year          55.000 EUR bis 70.000 EUR
zwischen 55.000 € und 70.000 €      40 000 € à 55 000 € par an
€ 3.500 tot € 4.500 per maand       15 000 - 22 000 PLN
85k - 110k                          $255k - $290k per year
```

Numbers that are *not* pay — headcounts, funding rounds, version numbers, "up to 6% matching" — are ignored.

***

### Who uses this

- **HR and compliance teams** — audit your own postings before a regulator or candidate does
- **Recruitment agencies** — check client adverts before they go live
- **Pay-equity and HR-tech vendors** — a live external signal alongside internal payroll analysis
- **Sales teams** — set `onlyNonCompliant: true` for a prospecting list of companies with a visible, dated problem
- **Journalists and researchers** — measure real compliance rates across an industry or country

***

### Supported job boards

Reads the **public, keyless JSON feeds** each ATS publishes so customers can embed job widgets on their own sites. No login, no API key, no HTML scraping, no anti-bot fight.

| ATS | Identifier | Notes |
|---|---|---|
| Greenhouse | `greenhouse:stripe` | Widely used by tech |
| Lever | `lever:netflix` | |
| Ashby | `ashby:notion` | Exposes structured salary data |
| Recruitee | `recruitee:acme` | Common with EU scale-ups |
| Personio | `personio:acme` | Common with German mid-market |

Accepts `ats:slug`, a full board URL (`https://jobs.lever.co/netflix`), or a bare slug to auto-detect.

***

### Input

```json
{
  "companies": ["ashby:almetra", "greenhouse:stripe"],
  "onlyNonCompliant": false,
  "maxRangeRatio": 2.0
}
```

| Option | Default | Notes |
|---|---|---|
| `companies` | — | Required. Slugs, URLs, or `ats:slug` |
| `atsHint` | `auto` | Force a platform instead of probing |
| `maxJobsPerCompany` | `200` | Stops one large board dominating a run |
| `onlyNonCompliant` | `false` | Output only problem roles |
| `maxRangeRatio` | `2.0` | Flag bands wider than this multiple |
| `assumeEuOnly` | `false` | Skip jurisdiction detection, check everything |
| `useAiReview` | `true` | Only used where rules find nothing |
| `geminiApiKey` | — | Optional. Blank = rules-only |

***

### Optional AI review

The rules engine is deterministic and conservative: it reports only pay it can prove is there. A minority of adverts bury pay in prose or phrase it unusually.

Add a **free Gemini API key** and those get a second look — **only** on jobs the rules engine could not resolve, so cost scales with ambiguity, not volume.

Three safety rules, each covered by tests:

1. The model can **never overturn** a deterministic extraction. A hallucinated figure cannot overwrite a real one.
2. An AI-only finding is capped at **`review`**, never `compliant`. A human confirms.
3. Low-confidence verdicts are **discarded**.

**No key? Everything still works.** You'll just see slightly more `NO_PAY_INFORMATION` on unusually worded adverts.

**Model availability is handled for you.** Google retires Gemini models on a fast cycle and blocks older ones for newly created API keys. If the selected model isn't available to your key, the Actor logs a warning, switches to the next current model automatically, and carries on. If none are reachable it drops to rules-only rather than failing the run.

***

### Pricing

Pay-per-event. Boards that return nothing cost nothing.

| Event | Charged when |
|---|---|
| `company-scanned` | A board resolves successfully |
| `job-checked` | A job is analysed and returned |
| `ai-review` | Only when AI review actually changed a verdict |

***

### Scope and limitations

Read this before acting on the output.

**A `non_compliant` result is a risk flag, not proof of a breach.** Article 5(1) lets an employer disclose pay *before the first interview* instead of in the advert. This Actor can only observe the advert. Some member states (Ireland and the Netherlands among them) go further and require it in the advert itself — but the base directive does not.

Also:

- **Heuristics, not legal advice.** A screening tool for human review.
- **Jurisdiction is inferred** from location text and can be wrong, especially for "Remote" roles. Use `assumeEuOnly` when you already know the board's scope.
- **`maxRangeRatio` is a judgement call**, not a legal threshold. The directive doesn't define a maximum width.
- **Only published jobs** appear in public ATS feeds. Internal or unlisted roles are invisible.
- **Company data only.** No personal data about applicants or employees is collected.
- Pay-gap reporting duties (Art. 9) apply to employers with 100+ staff and are assessed from internal payroll — outside what any external tool can see.

***

### Legal basis for the data

Every endpoint used is the public, unauthenticated feed each ATS provides so that customer job boards can be embedded and syndicated. This is the same data any visitor sees on the company's careers page. No authentication is bypassed, no personal data is collected, and no login-walled content is accessed.

***

### FAQ

**Does this need an API key or login?**
No. The ATS feeds are public and keyless. The Gemini key is optional.

**Can it check LinkedIn or Indeed job ads?**
No. It reads employers' own ATS feeds, which are published for syndication. Aggregator sites prohibit scraping.

**Why is a job marked `out_of_scope`?**
The role appears to sit outside the EU/EEA and outside a US pay-transparency state, so no disclosure duty applies. Set `assumeEuOnly: true` to check everything regardless.

**A company scored badly — are they breaking the law?**
Not necessarily. See Scope and limitations above. They may disclose pay before interview, which the directive permits.

**How do I find a company's slug?**
Look at their careers page URL. `boards.greenhouse.io/acme` → `greenhouse:acme`. `jobs.ashbyhq.com/acme` → `ashby:acme`. You can also paste the full URL.

***

### Development

```bash
npm install
npm test        # 54 tests, no network required
apify run
apify push
```

```
src/
  main.js        orchestration, billing, dataset output
  ats.js         one adapter per ATS, normalised to a common shape
  compliance.js  rules engine — extraction, checks, scoring
  gemini.js      optional AI adjudication + safe merge
  logger.js      SDK-safe logging shim
  text.js        HTML/entity handling, interval normalisation
```

# Actor input Schema

## `companies` (type: `array`):

One per line, up to 200. Use 'ats:slug' (e.g. greenhouse:stripe), a full careers board URL, or a bare slug to auto-detect.

## `atsHint` (type: `string`):

Force a platform for bare slugs. 'auto' probes each in turn.

## `maxJobsPerCompany` (type: `integer`):

Caps large boards so a single company cannot consume the whole run.

## `onlyNonCompliant` (type: `boolean`):

Skip compliant roles. Useful for a remediation worklist or a prospecting feed.

## `maxRangeRatio` (type: `number`):

Flags bands wider than this multiple as potentially non-informative. 2.0 means €40k-€80k passes but €40k-€120k is flagged.

## `assumeEuOnly` (type: `boolean`):

Skip jurisdiction detection and check all roles. Use when you already know the whole board is EU.

## `useAiReview` (type: `boolean`):

Uses Gemini only where the rules engine finds no pay data, to catch unusual phrasing and untemplated languages. Optional.

## `geminiApiKey` (type: `string`):

Free key from aistudio.google.com. Leave blank to run rules-only. Stored encrypted.

## `geminiModel` (type: `string`):

Gemini 3.5 Flash-Lite is the current cheapest option and the safe default. The 2.5 models are blocked for new API keys and shut down 16 Oct 2026 - only pick one if you have an older key that already works.

## `maxAiCalls` (type: `integer`):

Protects your free-tier quota. Rules-only analysis continues after the cap.

## Actor input object example

```json
{
  "companies": [
    "greenhouse:stripe",
    "https://jobs.lever.co/netflix"
  ],
  "atsHint": "auto",
  "maxJobsPerCompany": 200,
  "onlyNonCompliant": false,
  "maxRangeRatio": 2,
  "assumeEuOnly": false,
  "useAiReview": true,
  "geminiModel": "gemini-3.5-flash-lite",
  "maxAiCalls": 100
}
```

# Actor output Schema

## `results` (type: `string`):

One row per job advert with its compliance verdict, extracted salary and issue codes, plus one company\_summary row per employer carrying the 0-100 compliance score. Filter on the recordType field to separate them.

## `remediation` (type: `string`):

Same rows shown through the remediation view: the issue detail and evidence behind each finding, with a direct link to every advert.

## `salaryData` (type: `string`):

Adverts where pay was found, for benchmarking. Rows without a salary appear with empty pay columns.

## `runReport` (type: `string`):

Run-level totals: companies resolved, jobs analysed, average compliance score, count of pay-history questions found, and the scope disclaimer.

# 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 = {
    "companies": [
        "greenhouse:stripe",
        "lever:netflix",
        "ashby:notion"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("penpaste/eu-pay-transparency-checker").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 = { "companies": [
        "greenhouse:stripe",
        "lever:netflix",
        "ashby:notion",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("penpaste/eu-pay-transparency-checker").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 '{
  "companies": [
    "greenhouse:stripe",
    "lever:netflix",
    "ashby:notion"
  ]
}' |
apify call penpaste/eu-pay-transparency-checker --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=penpaste/eu-pay-transparency-checker",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "EU Pay Transparency Compliance Checker",
        "description": "Audit any company's job adverts against the EU Pay Transparency Directive. Flags missing salary ranges, vague pay wording, and illegal pay-history questions. Reads public ATS feeds from Greenhouse, Lever, Ashby, Recruitee and Personio. No login or API key needed.",
        "version": "0.0",
        "x-build-id": "GoTP0b4TcbUfnujhl"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/penpaste~eu-pay-transparency-checker/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-penpaste-eu-pay-transparency-checker",
                "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/penpaste~eu-pay-transparency-checker/runs": {
            "post": {
                "operationId": "runs-sync-penpaste-eu-pay-transparency-checker",
                "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/penpaste~eu-pay-transparency-checker/run-sync": {
            "post": {
                "operationId": "run-sync-penpaste-eu-pay-transparency-checker",
                "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": [
                    "companies"
                ],
                "properties": {
                    "companies": {
                        "title": "Companies to check",
                        "maxItems": 200,
                        "type": "array",
                        "description": "One per line, up to 200. Use 'ats:slug' (e.g. greenhouse:stripe), a full careers board URL, or a bare slug to auto-detect.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "atsHint": {
                        "title": "ATS platform",
                        "enum": [
                            "auto",
                            "greenhouse",
                            "lever",
                            "ashby",
                            "recruitee",
                            "personio"
                        ],
                        "type": "string",
                        "description": "Force a platform for bare slugs. 'auto' probes each in turn.",
                        "default": "auto"
                    },
                    "maxJobsPerCompany": {
                        "title": "Max jobs per company",
                        "minimum": 1,
                        "maximum": 2000,
                        "type": "integer",
                        "description": "Caps large boards so a single company cannot consume the whole run.",
                        "default": 200
                    },
                    "onlyNonCompliant": {
                        "title": "Only output non-compliant jobs",
                        "type": "boolean",
                        "description": "Skip compliant roles. Useful for a remediation worklist or a prospecting feed.",
                        "default": false
                    },
                    "maxRangeRatio": {
                        "title": "Max acceptable range width (x)",
                        "minimum": 1.1,
                        "maximum": 10,
                        "type": "number",
                        "description": "Flags bands wider than this multiple as potentially non-informative. 2.0 means €40k-€80k passes but €40k-€120k is flagged.",
                        "default": 2
                    },
                    "assumeEuOnly": {
                        "title": "Treat every job as in-scope",
                        "type": "boolean",
                        "description": "Skip jurisdiction detection and check all roles. Use when you already know the whole board is EU.",
                        "default": false
                    },
                    "useAiReview": {
                        "title": "Enable AI review for ambiguous adverts",
                        "type": "boolean",
                        "description": "Uses Gemini only where the rules engine finds no pay data, to catch unusual phrasing and untemplated languages. Optional.",
                        "default": true
                    },
                    "geminiApiKey": {
                        "title": "Gemini API key (optional)",
                        "type": "string",
                        "description": "Free key from aistudio.google.com. Leave blank to run rules-only. Stored encrypted."
                    },
                    "geminiModel": {
                        "title": "Gemini model",
                        "enum": [
                            "gemini-3.5-flash-lite",
                            "gemini-3.1-flash-lite",
                            "gemini-3.6-flash",
                            "gemini-3.5-flash",
                            "gemini-2.5-flash-lite",
                            "gemini-2.5-flash"
                        ],
                        "type": "string",
                        "description": "Gemini 3.5 Flash-Lite is the current cheapest option and the safe default. The 2.5 models are blocked for new API keys and shut down 16 Oct 2026 - only pick one if you have an older key that already works.",
                        "default": "gemini-3.5-flash-lite"
                    },
                    "maxAiCalls": {
                        "title": "Max AI calls per run",
                        "minimum": 0,
                        "maximum": 1000,
                        "type": "integer",
                        "description": "Protects your free-tier quota. Rules-only analysis continues after the cap.",
                        "default": 100
                    }
                }
            },
            "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
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
