# Property Listing Signal Monitor — US Authorized Feeds (`afkdigital/property-listing-signal-monitor`) Actor

Monitor U.S. property prices and listing text from your authorized JSON/CSV feed. Literal keyword evidence and successful-run history. No site scraping.

- **URL**: https://apify.com/afkdigital/property-listing-signal-monitor.md
- **Developed by:** [AFK Digital](https://apify.com/afkdigital) (community)
- **Categories:** Real estate
- **Stats:** 2 total users, 1 monthly users, 7.1% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$2.00 / 1,000 property listing observations

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/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
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.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

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

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Property Listing Signal Monitor — US Authorized Feeds

Monitor **U.S. property listings from a JSON or CSV feed you own or are authorized to use**. Get literal keyword matches with short evidence, compare supplied prices and descriptions with previous successful observations, and export structured listing records from Apify.

**You provide the data source.** This release has no built-in MLS, listing portal or third-party property database. It does not crawl property pages. The examples are fictional and demonstrate the processing contract; they are not current market inventory.

### What you receive

- One Dataset row per matching listing, deduplicated by source listing ID within the run.
- Listing ID, title, supplied price/currency, source location, supplied listing date and listing URL.
- Area, its unit and room count only when explicitly supplied.
- Each matched word or phrase and a short evidence excerpt from the title/description.
- Factual price, currency and description change indicators, with the previous observed price and timestamps when comparable.
- A separate `OUTPUT` record containing source coverage, duplicate count, result limits and comparison details.

**“Urgent”, “reduced”, and every other keyword are text matches only.** Wording does not establish that a property is below market value, that the seller is distressed, or that an investment will produce returns. The Actor performs no valuation, yield calculation, prediction or recommendation.

### Quick start with the fictional example

The prefilled inline examples are original fictional records provided for unrestricted demonstration use.

1. Keep `country` as `US`, enter a stable `sourceId`, and acknowledge authorization.
2. Provide exactly one source: an inline `listings` array **or** a direct HTTPS `feedUrl`.
3. Set your currency, optional region/price filters, literal keywords and `maxResults`.
4. Run the Actor and check that the run status is **SUCCEEDED** before using the Dataset.
5. Run again with the same source and monitor IDs to compare observations. The first successful run establishes the baseline; it does not report historical changes.

```json
{
  "country": "US",
  "sourceId": "my-us-inventory",
  "monitorId": "daily",
  "authorizationConfirmed": true,
  "currency": "USD",
  "region": "Texas",
  "keywords": ["urgent", "reduced"],
  "maxResults": 100,
  "listings": [
    {
      "id": "DEMO-US-001",
      "title": "Fictional Austin townhome — demo only",
      "description": "Price reduced. Fictional demonstration listing.",
      "price": 300000,
      "currency": "USD",
      "country": "US",
      "location": "Austin, TX",
      "region": "Texas",
      "area": 1500,
      "areaUnit": "sqft",
      "rooms": 3,
      "listedAt": "2026-10-01",
      "sourceUrl": "https://example.com/property/demo-us-001"
    }
  ]
}
```

For HTTPS input, **remove the `listings` field** and set `feedUrl`, `feedFormat` (`json` or `csv`), and an optional `bearerToken`. The URL and token are secret input fields. The feed must be a direct, uncompressed UTF-8 response: no redirects, HTML pages, archives, pagination or authentication flows. The token is sent only to the feed URL in an Authorization header. The Actor never follows the `sourceUrl` values in listing rows.

### Input reference

| Input | Behavior |
|---|---|
| `country` | Only `US` in version 1; each record must also explicitly say `US`. |
| `sourceId` | Required stable lowercase ID, 1–64 letters/digits/underscores/hyphens, beginning with a letter or digit. Distinguish inventories selected by different query parameters. |
| `monitorId` | Same format, default `default`. Keep stable across runs; a new ID intentionally starts a new baseline. |
| `authorizationConfirmed` | Must be `true`. You confirm permission for automated retrieval, processing and your intended reuse. |
| `feedUrl` / `listings` | Exactly one. Direct authorized HTTPS feed URL or an inline JSON array. |
| `bearerToken` | Optional feed-owner-issued bearer token; omit the `Bearer ` prefix. |
| `feedFormat` | `json` (default) or `csv`. Applies to URL input. |
| `region` | Case-insensitive substring of `location` or `region`; empty accepts all supplied regions. |
| `minPrice`, `maxPrice` | Optional inclusive bounds. Missing prices do not match bounds. Minimum must not exceed maximum. |
| `currency` | Explicit ISO currency filter; default `USD`. No currency inference or exchange-rate conversion. |
| `keywords` | Up to 20 literal phrases, at most 60 characters each; default `urgent`, `reduced`. Empty array accepts all otherwise matching listings. |
| `maxResults` | 1–1,000, default 100. Caps returned, billable listing rows; all valid source observations still enter history. |

### Canonical feed contract

JSON can be an array of listing objects, or `{ "listings": [...], "complete": true }`. Only `listings` and optional `complete: true` are accepted in a wrapper. Pagination/error/partial-result wrappers are rejected. Supply a complete single response for the inventory you intend to observe.

CSV must use the canonical header names below, with comma delimiters, a header row, standard double-quoted escaping and UTF-8 encoding. Quoted commas, quotes and multiline descriptions are supported. Omit unused optional columns. In CSV, an included empty `description` cell means explicitly empty text; omit the description column to mark it unavailable.

```csv
id,title,description,price,currency,country,location,region,area,areaUnit,rooms,listedAt,sourceUrl
DEMO-US-001,Fictional townhome,Price reduced — fictional demo,300000,USD,US,"Austin, TX",Texas,1500,sqft,3,2026-10-01,https://example.com/property/demo-us-001
```

| Field | Required / interpretation |
|---|---|
| `id` | Required stable nonempty source ID; duplicate IDs with conflicting normalized content fail the whole feed. |
| `title` | Required nonempty source title. |
| `country` | Required literal `US`; unsupported/mixed-country records fail the feed. |
| `location` | Required nonempty source location string. |
| `sourceUrl` | Required public HTTPS listing URL, without user information or credential parameters. It is output as provenance and is never fetched. |
| `price` | Optional finite nonnegative number; `0` is preserved. CSV numbers use a dot decimal separator, without currency signs or thousands separators. |
| `currency` | Required when price exists; explicit recognized ISO currency code. The currency filter also applies when price is missing. |
| `description` | Optional text; missing/null differs from explicitly empty text. Markup and whitespace are normalized before matching/comparison. |
| `region` | Optional source region/state label. |
| `area`, `areaUnit` | Optional pair; both must be present together. The source's unit label is preserved, for example `sqft`, `sqm` or `acre`. No area is inferred or converted. |
| `rooms` | Optional finite nonnegative source-supplied room count. Do not map bedrooms to total rooms unless your source defines them that way. |
| `listedAt` | Optional valid ISO date or ISO timestamp with timezone. Source listing date is kept separate from observation time. |

Extra JSON listing fields are ignored; they are not copied to output or history. CSV accepts only documented columns. No arbitrary source field mapping, XML/RSS, MLS/RESO connector, address geocoding, photos or contact enrichment is included.

### Keyword and change semantics

Matching is a case-insensitive, Unicode-normalized **substring OR match** in the combined title and description. For example, `reduced` also matches within a longer phrase; punctuation has no regular-expression meaning. Evidence is bounded to 180 characters per keyword. No translation, synonym inference or sentiment analysis is performed.

The first successful observation is `first_observation`. Subsequent records report `unchanged` or `changed`, with separate `priceChanged`, `descriptionChanged` and `currencyChanged` flags. Monetary differences are computed only when both observations supply a price in the same currency. When currencies differ, `priceDifference` is null. A newly supplied optional value is a first value, not a change from zero. Missing fields preserve the last supplied values in history and do not create a change. Explicitly empty description text can be a real description change.

Listings absent from a response are **never** reported as removed. This Actor cannot prove full market coverage or distinguish withdrawn listings from records omitted by the source. `observedCount` describes the valid records in that response, not a market-wide inventory size.

### Persistent history and safe operation

History is isolated by the executing Apify user, Actor, country, stable source/monitor IDs, and feed origin/path. Signed query credentials are not stored. If the same endpoint serves different inventories through query parameters, assign different `sourceId` values. Switching between inline and URL input, changing endpoint path, or changing either ID starts a separate history.

An immutable snapshot becomes eligible only after Apify records its producing run as **SUCCEEDED**. A run-specific completion webhook writes the official terminal status into the Actor's history store, bound to that snapshot's hash. Eligible runs must have completed before the current run started. Price and description observations are merged by their individual timestamps across eligible successes, so overlapping partial responses cannot erase a successful observation. Per-field producer run IDs appear in `changes`; the top-level baseline run identifies the most recent eligible snapshot. The retained completion proof survives run-log expiry. Unknown, unavailable or inconsistent history fails with an explicit error; it is never silently treated as a new monitor.

Completion webhooks can arrive after the run ends. If a previous snapshot has no terminal proof yet, the Actor reports `HISTORY_PENDING` and preserves history. Retry with a new run after delivery; inspect Apify's webhook dispatch status if the condition persists. Failed, aborted and timed-out completion proofs never establish a baseline.

Use one Apify task and **one exclusive schedule** per monitor. Overlapping manual/API runs can repeat the same real transition; exactly-once alert delivery is not promised. Consume only successful runs and use comparison/run identifiers to deduplicate downstream. Repeating a successful monitor intentionally returns current matching observations again and incurs the normal per-row price.

Source failures, empty feeds, invalid records, conflicting duplicates, excessive size, redirects, HTTP errors and declared partial responses fail the run. They do not become successful baselines. Partial Dataset rows can exist after an output failure or interrupted run; discard those rows. Start a fresh run instead of resurrecting a partially completed run.

Named history stores retain at most 5,000 distinct listing IDs. Older successful snapshots are pruned only when their observations are safely retained; active/unverified attempts are not silently deleted. More than 100 pending snapshots fails with an inspection-required error. To intentionally reset history, use a new monitor ID; the old named store remains available for your inspection/removal.

### Bounds and pricing

- Source response: at most **5 MiB** and **5,000 records**, fully validated before result filtering.
- Output: at most **1,000 listings** per run, subject to your input limit and budget.
- Direct feed request: **30-second total deadline**, one request, no redirects, retries or proxy routing.
- Launch price: **$0.002 per returned listing row — $2.00 per 1,000 results**.
- No Actor start fee and no per-keyword, per-change or summary fee. Unchanged matching observations are also returned/billed.

The Actor uses Apify's automatic `apify-default-dataset-item` event only. It checks whether your remaining run budget covers the selected output before pushing rows. An insufficient budget fails before fresh rows/state are committed; lower `maxResults` or raise the budget. The source provider may charge separately under your agreement. `OUTPUT.estimatedResultChargeUsd` estimates the configured result fee; it is not an invoice or measured compute cost.

### Permissions and data care

The Actor uses **Apify Limited permissions**. It accesses its current run and its own storage, and registers a current-run completion webhook targeting its own history store. Apify supplies authentication for that internal API delivery. The Actor does not store an account API token or request account-wide access to read past runs.

Your authorization acknowledgement records your representation and does not independently establish a license. Confirm your rights to automate access, process the supplied content, retain comparison state and use the resulting excerpts. A public URL or permissive robots.txt alone is not a commercial reuse license.

Zillow and Rightmove are not supported feed sources. The Actor has no residential proxy, CAPTCHA bypass, login automation or private-network access. HTTPS hosts resolving to private/reserved addresses are rejected, and the selected public address is pinned for the request. Normal output contains source facts and small excerpts; history stores minimal price/currency data, timestamps and description hashes instead of whole descriptions. Keep your Apify Dataset and storage access appropriate for your feed license.

### Development and verification

Source, tests, schemas and examples are maintained as the independent API12 project. Run `npm ci` and `npm test` on Node 22 or newer. Tests exercise normalization, real change semantics, failed-run exclusion, source/transport errors, isolation and billing boundaries. The published release's coverage and measured run evidence are documented in `docs/VALIDATION.md`; fictional tests never establish live-market coverage.

#### Release validation — 10 October 2026

The release passed **76 automated tests** and **eight Apify cloud acceptance scenarios** with Limited permissions: first observation, unchanged repeat, price/description update, malformed source, recovery, no matches, insufficient budget and HTTPS CSV. The fixture consists of three original fictional U.S. listings, with two keyword matches. JSON and CSV transfer were tested through an officially authorized HTTPS record URL.

The eight acceptance runs reported **$0.002388 in combined platform usage** at the measurement time. Ten returned rows generated ten automatic Dataset charge events, corresponding to **$0.020 at the configured Store price**. This compares owner test usage with the configured customer fee; it is not a customer invoice or a large-feed benchmark. Builds, diagnostic attempts, later storage/access costs and any separately accounted completion-webhook activity are outside that run-usage figure.

No real third-party property feed passed the source suitability review. The supported data coverage remains exactly the authorized feed you provide.

# Actor input Schema

## `country` (type: `string`):

Version 1 processes only records explicitly marked US.

## `sourceId` (type: `string`):

Stable ID for this authorized inventory. Different query-selected inventories must have different source IDs. Keep it unchanged for comparisons.

## `monitorId` (type: `string`):

Keep the same value across runs. A new value intentionally starts fresh history.

## `authorizationConfirmed` (type: `boolean`):

Required: I own the feed or have permission for automated retrieval, processing and my intended data reuse. This declaration does not create or independently verify legal rights. Bundled fictional examples may be used for testing. The prefilled confirmation applies only to the included demonstration input. If you replace the sample, check your own rights and confirm deliberately.

## `feedUrl` (type: `string`):

Direct HTTPS JSON or CSV feed. Use exactly one of feedUrl or listings. Remove the inline example when using a URL. No redirects, HTML, proxies or login flows. Up to 5 MiB / 5,000 records.

## `bearerToken` (type: `string`):

Optional token supplied by the feed owner, used only in the Authorization header for that feed. Do not include the word Bearer.

## `feedFormat` (type: `string`):

Canonical JSON array or {listings:\[...],complete:true}; UTF-8 CSV with the documented headers. No pagination or arbitrary field mapping.

## `listings` (type: `array`):

Paste a JSON array using the canonical fields. Demonstration rows are fictional. Delete this field when specifying feedUrl.

## `region` (type: `string`):

Case-insensitive literal substring in location or region; empty means all supplied regions.

## `minPrice` (type: `number`):

Optional inclusive minimum. Listings without a supplied price are excluded when any price bound is used.

## `maxPrice` (type: `number`):

Optional inclusive maximum in the selected currency. No exchange-rate conversion.

## `currency` (type: `string`):

An ISO currency code, usually USD for U.S. feeds. Records must explicitly supply this currency to match; no currency is inferred.

## `keywords` (type: `array`):

Up to 20 phrases, 60 characters each. Case-insensitive Unicode-normalized substring OR matching in title/description. Empty array returns all otherwise matching records. These words do not imply value or returns.

## `maxResults` (type: `integer`):

Maximum billed listing rows. All valid source rows still inform history, including rows outside filters or this limit.

## Actor input object example

```json
{
  "country": "US",
  "sourceId": "fictional-us-demo",
  "monitorId": "apify-qa-demo",
  "authorizationConfirmed": true,
  "feedFormat": "json",
  "listings": [
    {
      "id": "DEMO-US-001",
      "title": "Fictional Austin townhome — demo only",
      "description": "Price reduced. This fictional listing exists only to demonstrate literal text matching.",
      "price": 300000,
      "currency": "USD",
      "country": "US",
      "location": "Austin, TX",
      "region": "Texas",
      "area": 1500,
      "areaUnit": "sqft",
      "rooms": 3,
      "listedAt": "2026-10-01",
      "sourceUrl": "https://example.com/property/demo-us-001"
    },
    {
      "id": "DEMO-US-002",
      "title": "Fictional Denver apartment — demo only",
      "description": "Urgent viewing request. Fictional sample; no actual property is offered.",
      "price": 240000,
      "currency": "USD",
      "country": "US",
      "location": "Denver, CO",
      "region": "Colorado",
      "listedAt": "2026-10-02",
      "sourceUrl": "https://example.com/property/demo-us-002"
    },
    {
      "id": "DEMO-US-003",
      "title": "Fictional Portland cottage — demo only",
      "description": "Fictional sample with no configured keyword.",
      "price": 350000,
      "currency": "USD",
      "country": "US",
      "location": "Portland, OR",
      "region": "Oregon",
      "area": 92,
      "areaUnit": "sqm",
      "rooms": 2,
      "sourceUrl": "https://example.com/property/demo-us-003"
    }
  ],
  "region": "",
  "currency": "USD",
  "keywords": [
    "urgent",
    "reduced"
  ],
  "maxResults": 100
}
```

# Actor output Schema

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

No description

## `coverage` (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 = {
    "sourceId": "fictional-us-demo",
    "monitorId": "apify-qa-demo",
    "authorizationConfirmed": true,
    "listings": [
        {
            "id": "DEMO-US-001",
            "title": "Fictional Austin townhome — demo only",
            "description": "Price reduced. This fictional listing exists only to demonstrate literal text matching.",
            "price": 300000,
            "currency": "USD",
            "country": "US",
            "location": "Austin, TX",
            "region": "Texas",
            "area": 1500,
            "areaUnit": "sqft",
            "rooms": 3,
            "listedAt": "2026-10-01",
            "sourceUrl": "https://example.com/property/demo-us-001"
        },
        {
            "id": "DEMO-US-002",
            "title": "Fictional Denver apartment — demo only",
            "description": "Urgent viewing request. Fictional sample; no actual property is offered.",
            "price": 240000,
            "currency": "USD",
            "country": "US",
            "location": "Denver, CO",
            "region": "Colorado",
            "listedAt": "2026-10-02",
            "sourceUrl": "https://example.com/property/demo-us-002"
        },
        {
            "id": "DEMO-US-003",
            "title": "Fictional Portland cottage — demo only",
            "description": "Fictional sample with no configured keyword.",
            "price": 350000,
            "currency": "USD",
            "country": "US",
            "location": "Portland, OR",
            "region": "Oregon",
            "area": 92,
            "areaUnit": "sqm",
            "rooms": 2,
            "sourceUrl": "https://example.com/property/demo-us-003"
        }
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("afkdigital/property-listing-signal-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 = {
    "sourceId": "fictional-us-demo",
    "monitorId": "apify-qa-demo",
    "authorizationConfirmed": True,
    "listings": [
        {
            "id": "DEMO-US-001",
            "title": "Fictional Austin townhome — demo only",
            "description": "Price reduced. This fictional listing exists only to demonstrate literal text matching.",
            "price": 300000,
            "currency": "USD",
            "country": "US",
            "location": "Austin, TX",
            "region": "Texas",
            "area": 1500,
            "areaUnit": "sqft",
            "rooms": 3,
            "listedAt": "2026-10-01",
            "sourceUrl": "https://example.com/property/demo-us-001",
        },
        {
            "id": "DEMO-US-002",
            "title": "Fictional Denver apartment — demo only",
            "description": "Urgent viewing request. Fictional sample; no actual property is offered.",
            "price": 240000,
            "currency": "USD",
            "country": "US",
            "location": "Denver, CO",
            "region": "Colorado",
            "listedAt": "2026-10-02",
            "sourceUrl": "https://example.com/property/demo-us-002",
        },
        {
            "id": "DEMO-US-003",
            "title": "Fictional Portland cottage — demo only",
            "description": "Fictional sample with no configured keyword.",
            "price": 350000,
            "currency": "USD",
            "country": "US",
            "location": "Portland, OR",
            "region": "Oregon",
            "area": 92,
            "areaUnit": "sqm",
            "rooms": 2,
            "sourceUrl": "https://example.com/property/demo-us-003",
        },
    ],
}

# Run the Actor and wait for it to finish
run = client.actor("afkdigital/property-listing-signal-monitor").call(run_input=run_input)

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

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

```

## CLI example

```bash
echo '{
  "sourceId": "fictional-us-demo",
  "monitorId": "apify-qa-demo",
  "authorizationConfirmed": true,
  "listings": [
    {
      "id": "DEMO-US-001",
      "title": "Fictional Austin townhome — demo only",
      "description": "Price reduced. This fictional listing exists only to demonstrate literal text matching.",
      "price": 300000,
      "currency": "USD",
      "country": "US",
      "location": "Austin, TX",
      "region": "Texas",
      "area": 1500,
      "areaUnit": "sqft",
      "rooms": 3,
      "listedAt": "2026-10-01",
      "sourceUrl": "https://example.com/property/demo-us-001"
    },
    {
      "id": "DEMO-US-002",
      "title": "Fictional Denver apartment — demo only",
      "description": "Urgent viewing request. Fictional sample; no actual property is offered.",
      "price": 240000,
      "currency": "USD",
      "country": "US",
      "location": "Denver, CO",
      "region": "Colorado",
      "listedAt": "2026-10-02",
      "sourceUrl": "https://example.com/property/demo-us-002"
    },
    {
      "id": "DEMO-US-003",
      "title": "Fictional Portland cottage — demo only",
      "description": "Fictional sample with no configured keyword.",
      "price": 350000,
      "currency": "USD",
      "country": "US",
      "location": "Portland, OR",
      "region": "Oregon",
      "area": 92,
      "areaUnit": "sqm",
      "rooms": 2,
      "sourceUrl": "https://example.com/property/demo-us-003"
    }
  ]
}' |
apify call afkdigital/property-listing-signal-monitor --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,afkdigital/property-listing-signal-monitor"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/Xm3MIhbnzgG5BcTjs/builds/vnileSE1nNFgCsixN/openapi.json
