# expressleasing-machine-search (`expressleasing/expressleasing-machine-search`) Actor

Crawler for construction machinery using Apify, Airtable and OpenAI API, which returns most relevant offer links from WHITELISTED suppliers, and parameters like brand, model, price, year etc.

Airtable serves as a search + for gathering results. Crawler was built in Apify (Javascript + Playground)

- **URL**: https://apify.com/expressleasing/expressleasing-machine-search.md
- **Developed by:** [DARIUSZ SUCHY](https://apify.com/expressleasing) (community)
- **Categories:** AI, E-commerce, Automation
- **Stats:** 1 total users, 0 monthly users, 0.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.00005 / actor start

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

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

## What's an Apify Actor?

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

## ExpressLeasing Machine Search Actor

### Project purpose

This Actor automates the machine search process for ExpressLeasing client requests.

Business flow:

1. The user enters a search phrase in Airtable, for example:

   * `Kubota KX027 up to 120,000 PLN net`
   * `kubota kx016 price from 80000 to 120000 pln`
   * `mini excavator 2.5-3 tons up to 130,000 PLN net`
   * `JCB 3CX up to 180,000 PLN net`
   * `Manitou telehandler`
2. Airtable triggers the Apify Actor.
3. The Actor reads the supplier list and inventory URLs from Airtable.
4. The Actor searches supplier inventory pages using Playwright.
5. The Actor identifies candidate listings, scores them, and writes the results back to Airtable.
6. Optionally, the Actor uses OpenAI to rerank the best candidates.
7. Final results appear in the `Wyniki wyszukiwania` table in Airtable.

The MVP goal is to reduce manual browsing across many supplier websites and return the best matching offers and alternatives in one place.

---

### Current MVP scope

The Actor currently supports:

* reading a search request from Airtable,
* reading suppliers from Airtable,
* cleaning supplier inventory URLs,
* skipping contact-page URLs,
* searching inventory pages with Playwright,
* detecting likely offer links,
* opening offer detail pages,
* extracting basic offer data:

  * title,
  * offer URL,
  * supplier,
  * net price,
  * brand,
  * model,
  * production year,
  * operating hours / mth,
  * machine weight in kg,
* rule-based scoring,
* result classification:

  * `Dokładne`,
  * `Alternatywa`,
  * `Słabe`,
* supplier filtering by tags,
* optional OpenAI reranking,
* writing results back to Airtable.

---

### Architecture

```text
Airtable
  ├── Wyszukiwania maszyn
  ├── Dostawcy
  └── Wyniki wyszukiwania
        ↓
Airtable Automation
        ↓
Apify Actor
        ↓
Playwright / Chromium
        ↓
Supplier websites / Otomoto / OLX / Machineryline / inventory pages
        ↓
Rule-based scoring
        ↓
Optional OpenAI reranking
        ↓
Airtable: Wyniki wyszukiwania
````

***

### Main Airtable tables

#### 1. `Wyszukiwania maszyn`

This is the table where the user enters search requests.

Required fields:

| Field                           | Type           | Description                                               |
| ------------------------------- | -------------- | --------------------------------------------------------- |
| `Nazwa`                         | Text / formula | Search record name                                        |
| `Record ID`                     | Formula        | `RECORD_ID()`                                             |
| `Fraza wyszukiwania`            | Long text      | Client search phrase                                      |
| `Status`                        | Single select  | `Robocze`, `Do wyszukania`, `W trakcie`, `Gotowe`, `Błąd` |
| `Limit źrodeł` / `Limit źródeł` | Number         | Number of supplier sources to check                       |
| `Limit wyników`                 | Number         | Number of final results to save                           |
| `Max stron na źródło`           | Number         | Number of inventory pages to scan per source              |
| `Parametry AI`                  | Long text      | Recognized query parameters and supplier filter data      |
| `Podsumowanie`                  | Long text      | Run summary                                               |
| `Liczba wyników`                | Number         | Number of saved results                                   |
| `Run ID`                        | Text           | Apify run ID                                              |
| `Data startu`                   | Date/time      | Run start time                                            |
| `Data zakończenia`              | Date/time      | Run end time                                              |
| `Błąd`                          | Long text      | Error message                                             |

Setting `Status = Do wyszukania` starts the search automation.

***

#### 2. `Dostawcy`

This table contains suppliers and their inventory links.

Required fields:

| Field                | Type                  | Description                      |
| -------------------- | --------------------- | -------------------------------- |
| `Name`               | Text                  | Supplier name                    |
| `Kod dostawcy`       | Text                  | Supplier code                    |
| `Produkty`           | Linked records / text | Related products or notes        |
| `Link do dostawcy 1` | URL                   | Supplier inventory URL           |
| `Tagi wyszukiwania`  | Multiple select       | Supplier category and brand tags |

The field `Link do dostawcy 1` should point to an inventory or offer-listing page, not to a contact page.

Good examples:

```text
https://example.otomoto.pl/inventory
https://example.pl/maszyny-uzywane
https://www.olx.pl/oferty/uzytkownik/...
```

Weak examples:

```text
https://example.pl/kontakt
https://example.pl/o-nas
```

***

#### 3. `Wyniki wyszukiwania`

This table stores the results returned by the Actor.

Required fields:

| Field               | Type              | Description                                     |
| ------------------- | ----------------- | ----------------------------------------------- |
| `Tytuł oferty`      | Text              | Offer title                                     |
| `Wyszukiwanie`      | Linked record     | Link to the search record                       |
| `Score`             | Number            | Rule-based score                                |
| `Typ wyniku`        | Single select     | `Dokładne`, `Alternatywa`, `Słabe`              |
| `Score AI`          | Number            | OpenAI score                                    |
| `Typ wyniku AI`     | Single select     | `Dokładne`, `Alternatywa`, `Słabe`, `Odrzucone` |
| `Powód AI`          | Long text         | OpenAI reasoning                                |
| `OpenAI użyte`      | Checkbox          | Whether OpenAI was used for this result         |
| `Dostawca`          | Linked record     | Link to supplier                                |
| `Link do oferty`    | URL               | Direct offer URL                                |
| `Cena netto`        | Currency / number | Net price, if detected                          |
| `Marka`             | Text              | Detected brand                                  |
| `Model`             | Text              | Detected model                                  |
| `Rok produkcji`     | Number            | Detected production year                        |
| `Przebieg / mth`    | Number            | Operating hours                                 |
| `Masa kg`           | Number            | Machine weight in kg                            |
| `Powód dopasowania` | Long text         | Rule-based matching reason                      |
| `Braki danych`      | Long text         | Missing data                                    |
| `Status wyniku`     | Single select     | `Do sprawdzenia`, `Dobry`, `Odrzucony`          |
| `Data znalezienia`  | Date/time         | Result creation time                            |

***

### Supplier tags

The field:

```text
Tagi wyszukiwania
```

is used to reduce the number of supplier sources that must be searched.

Example category tags:

```text
#minikoparki
#koparki
#koparki_kolowe
#koparki_gasienicowe
#koparko_ladowarki
#ladowarki
#ladowarki_teleskopowe
#ladowarki_kolowe
#mini_ladowarki
#wozki_widlowe
#podnosniki
#walce
#wozidla
#wywrotki
#zurawie_dekarskie
#rolnicze
#mix
```

Example brand tags:

```text
#kubota
#jcb
#takeuchi
#yanmar
#bobcat
#caterpillar
#komatsu
#volvo
#manitou
#merlo
#liebherr
#wacker_neuson
#sany
#hitachi
#doosan
#develon
#case
#new_holland
#mecalac
#kramer
#hamm
#bomag
#ammann
#dynapac
#toyota
#linde
#still
#unicarriers
```

Rules:

- tags describe the supplier’s actual specialization,
- not every supplier needs to be tagged immediately,
- broad suppliers can be tagged with `#mix`,
- if there are too few matching tags, the Actor falls back to searching a broader supplier set.

***

### Actor input

The Actor requires one input value:

```json
{
  "searchRecordId": "recXXXXXXXXXXXXXX"
}
```

`searchRecordId` is the technical Airtable record ID from the `Wyszukiwania maszyn` table.

It can be exposed in Airtable using a formula field:

```text
RECORD_ID()
```

***

### Environment variables

#### Required

| Name               | Example               | Secret | Description                    |
| ------------------ | --------------------- | ------ | ------------------------------ |
| `AIRTABLE_PAT`     | `pat...`              | Yes    | Airtable Personal Access Token |
| `AIRTABLE_BASE_ID` | `app...`              | No     | Airtable base ID               |
| `SEARCHES_TABLE`   | `Wyszukiwania maszyn` | No     | Search table name              |
| `SUPPLIERS_TABLE`  | `Dostawcy`            | No     | Supplier table name            |
| `RESULTS_TABLE`    | `Wyniki wyszukiwania` | No     | Results table name             |

#### Airtable field names

| Name                  | Default value        | Description                  |
| --------------------- | -------------------- | ---------------------------- |
| `SUPPLIER_NAME_FIELD` | `Name`               | Supplier name field          |
| `SUPPLIER_CODE_FIELD` | `Kod dostawcy`       | Supplier code field          |
| `INVENTORY_URL_FIELD` | `Link do dostawcy 1` | Supplier inventory URL field |
| `SUPPLIER_TAGS_FIELD` | `Tagi wyszukiwania`  | Supplier tags field          |
| `SEARCH_QUERY_FIELD`  | `Fraza wyszukiwania` | Search phrase field          |

#### Runtime limits

| Name                     | Default value | Description                                                |
| ------------------------ | ------------: | ---------------------------------------------------------- |
| `MIN_TAGGED_SOURCES`     |          `12` | Minimum number of sources after tag filtering              |
| `MAX_DETAILS_PER_SOURCE` |           `8` | Maximum number of offer details opened per supplier source |

Recommended test setting:

```text
MAX_DETAILS_PER_SOURCE = 4 or 5
```

Lower values reduce runtime and cost.

#### OpenAI

| Name                   | Example        | Secret | Description                             |
| ---------------------- | -------------- | ------ | --------------------------------------- |
| `OPENAI_API_KEY`       | `sk-...`       | Yes    | OpenAI API key                          |
| `USE_OPENAI_RERANK`    | `true`         | No     | Enables OpenAI reranking                |
| `OPENAI_MODEL`         | `gpt-5.4-mini` | No     | Model used for reranking                |
| `OPENAI_RERANK_LIMIT`  | `20`           | No     | Number of candidates sent to OpenAI     |
| `OPENAI_FINAL_RESULTS` | `5`            | No     | Final number of results after reranking |

If OpenAI fails, the Actor should still complete successfully and fall back to the rule-based ranking.

***

### How to run a search

#### From Airtable

1. Open the `Wyszukiwania maszyn` table.
2. Create a new search record.
3. Enter `Fraza wyszukiwania`, for example:

```text
kubota kx016 cena od 80000 do 120000 pln
```

4. Set search parameters:

```text
Limit źrodeł = 30
Limit wyników = 20
Max stron na źródło = 1
```

5. Set:

```text
Status = Do wyszukania
```

6. Airtable Automation triggers the Apify Actor.
7. When the Actor finishes, it updates:

```text
Status = Gotowe
Liczba wyników = number of saved results
Podsumowanie = run summary
```

8. Results appear in the `Wyniki wyszukiwania` table.

***

### Recommended test settings

#### Quick test

```text
Limit źrodeł = 10
Limit wyników = 5
Max stron na źródło = 1
MAX_DETAILS_PER_SOURCE = 4
OPENAI_RERANK_LIMIT = 10
```

#### MVP test

```text
Limit źrodeł = 30
Limit wyników = 10-20
Max stron na źródło = 1
MAX_DETAILS_PER_SOURCE = 4-5
OPENAI_RERANK_LIMIT = 15-20
```

#### Broader test

```text
Limit źrodeł = 50
Limit wyników = 5-20
Max stron na źródło = 1
MAX_DETAILS_PER_SOURCE = 4-5
OPENAI_RERANK_LIMIT = 20
```

Do not increase `Max stron na źródło` to `2` until the first-page results are reliable.

***

### How scoring works

The Actor uses two scoring layers.

#### 1. Rule-based scoring

The rule-based scoring evaluates:

- exact model match,
- brand match,
- machine category,
- weight class,
- budget,
- production year,
- operating hours,
- title and description similarity,
- known model catalog.

Example:

```text
Kubota KX016-4
```

for the query:

```text
kubota kx016 cena od 80000 do 120000 pln
```

should be classified as `Dokładne`.

Possible alternatives:

```text
Kubota KX018-4
Kubota KX019-4
JCB 8018
Takeuchi TB216
Yanmar SV17
```

may be classified as `Alternatywa` if they are in a similar weight class.

#### 2. OpenAI reranking

If `USE_OPENAI_RERANK = true`, the Actor sends the best candidates to OpenAI.

OpenAI evaluates:

- whether the offer is in the correct machine category,
- whether it is the exact model,
- whether it is a reasonable alternative,
- whether the result is clearly from the wrong category,
- how to justify the match.

OpenAI results are written to:

```text
Score AI
Typ wyniku AI
Powód AI
OpenAI użyte
```

***

### Supported categories

The rule-based logic recognizes, among others:

```text
minikoparki
midikoparki
koparko_ladowarki
koparki_kolowe
koparki_gasienicowe
ladowarki_teleskopowe
ladowarki_kolowe
mini_ladowarki
wozki_widlowe
podnosniki
walce
wozidla
wywrotki
zurawie_dekarskie
rolnicze
kruszarki_przesiewacze
```

***

### Example test queries

```text
kubota kx016 cena od 80000 do 120000 pln
```

```text
Kubota KX027 do 120 000 zł netto
```

```text
minikoparka 2,5-3 tony do 130 000 zł netto
```

```text
JCB 3CX do 180 000 zł netto
```

```text
ładowarka teleskopowa JCB 540-140
```

```text
ładowarka teleskopowa Manitou 14m
```

```text
koparka kołowa 15 ton
```

```text
walec 2-3 tony
```

```text
wózek widłowy LPG 2,5 tony
```

***

### Expected Airtable output

Example result table:

| Score | Typ wyniku  | Score AI | Typ wyniku AI | Offer          | Supplier   | URL |
| ----: | ----------- | -------: | ------------- | -------------- | ---------- | --- |
|    94 | Dokładne    |       96 | Dokładne      | Kubota KX016-4 | Supplier X | URL |
|    78 | Alternatywa |       84 | Alternatywa   | JCB 8018       | Supplier Y | URL |
|    72 | Alternatywa |       81 | Alternatywa   | Takeuchi TB216 | Supplier Z | URL |

***

### Known limitations

1. The Actor does not use official marketplace APIs.
2. The crawler works through Playwright, so runtime depends on website speed.
3. Some websites may block automation, load offers dynamically, or change their HTML.
4. Price, year, weight, and operating hours may not always be extracted correctly.
5. `Cena netto` may be empty if the price is not available in a readable format.
6. OpenAI reranking improves result quality but does not reduce scraping time.
7. Supplier tags improve speed and relevance only after they are filled in.
8. Rerunning the same search record may create duplicate results.

***

### Performance and cost

Observed benchmark from an earlier version:

```text
50 sources
1 page per source
5 results
around 33 minutes
around 0.45 USD
```

Main runtime drivers:

- number of sources,
- `Max stron na źródło`,
- `MAX_DETAILS_PER_SOURCE`,
- supplier website speed,
- number of offer detail pages opened,
- whether OpenAI reranking is enabled.

The simplest optimization:

```text
MAX_DETAILS_PER_SOURCE = 4 or 5
```

Larger future optimization:

```text
global candidate ranking before opening offer detail pages
```

***

### Troubleshooting

#### `Brak searchRecordId w input Actora`

The Actor did not receive the Airtable search record ID.

Check the input:

```json
{
  "searchRecordId": "recXXXXXXXXXXXXXX"
}
```

Also check the Airtable Automation input variable `recordId`.

***

#### `Brak AIRTABLE_PAT`

The required environment variable is missing:

```text
AIRTABLE_PAT
```

Add it in Apify as a secret.

***

#### `Airtable API error 401 / 403`

This usually means an Airtable token or permission issue.

Check:

```text
AIRTABLE_PAT
AIRTABLE_BASE_ID
token access to the base
read/write permissions
```

***

#### `Unknown field name`

Airtable field names do not match the code.

Check especially:

```text
Fraza wyszukiwania
Link do dostawcy 1
Tagi wyszukiwania
Wyniki wyszukiwania
Score AI
Typ wyniku AI
Powód AI
OpenAI użyte
```

***

#### `OpenAI reranking failed`

The Actor should fall back to rule-based ranking.

Check:

```text
OPENAI_API_KEY
OPENAI_MODEL
USE_OPENAI_RERANK
model availability
API limits
```

If the model is not available, change:

```text
OPENAI_MODEL
```

to a model available in the API project.

***

#### Results are from the wrong category

Example: a wheel loader appears for a mini excavator query.

Possible causes:

- missing model alias,
- ambiguous offer title,
- OpenAI reranking disabled,
- too little data on the offer page,
- supplier has no tags.

Actions:

1. Check `Typ wyniku AI`.
2. Check `Powód AI`.
3. Check `Powód dopasowania`.
4. Add missing models or aliases to the catalog.
5. Add supplier tags.

***

#### Too few results

Actions:

1. Increase `Limit źrodeł`.
2. Increase `MAX_DETAILS_PER_SOURCE`.
3. Increase `OPENAI_RERANK_LIMIT`.
4. Try `Max stron na źródło = 2`, but only as a test.
5. Check whether supplier tag filtering is too narrow.

***

#### Run takes too long

Actions:

1. Reduce `MAX_DETAILS_PER_SOURCE` to `4`.
2. Use supplier tags.
3. Reduce `Limit źrodeł`.
4. Avoid increasing `Max stron na źródło` unless necessary.
5. Future improvement: implement global candidate ranking before opening detail pages.

***

### Operational best practices

1. Create a new `Wyszukiwania maszyn` record for each test.
2. Do not rerun the same record repeatedly without clearing old results.
3. Start tests with `Limit źrodeł = 10-15`.
4. Run broader tests only after the smaller tests succeed.
5. Manually classify results as:

   - `Dobry`,
   - `Do sprawdzenia`,
   - `Odrzucony`.
6. Review incorrect results and improve the model catalog or supplier tags.

***

### Roadmap

#### Stage 1 — current MVP

- live search across known sources,
- rule-based scoring,
- supplier tags,
- OpenAI reranking,
- results in Airtable.

#### Stage 2 — runtime optimization

- global candidate ranking,
- opening detail pages only for the best candidates,
- limited concurrency,
- lower run cost.

#### Stage 3 — better query interpretation

- OpenAI query parser,
- automatic category, brand, model, budget, weight, year, and hours extraction,
- automatic alternative model expansion.

#### Stage 4 — offer cache / offer index

- scheduled inventory crawling,
- local `Znalezione oferty` table,
- fast search over already collected offers,
- live search only as fallback.

#### Stage 5 — result handling automation

- mark result as `Dobry`,
- create supplier contact task,
- prepare supplier availability message,
- prepare a client proposal draft.

***

### Project status

The project is currently in a usable MVP stage.

The current scope satisfies the target flow:

```text
The user enters a search phrase in Airtable.
The system searches supplier sources.
After several to several dozen minutes, the user receives top offers.
Most top results are from the correct category.
Exact models and close alternatives rank above random machines.
```

Current priorities:

```text
1. Test OpenAI reranking across several machine categories.
2. Set MAX_DETAILS_PER_SOURCE to 4 or 5.
3. Fill supplier tags.
4. Collect incorrect results and improve the model catalog.
5. Plan runtime optimization.
```

# Actor input Schema

## `searchRecordId` (type: `string`):

reckvawHfbWCC2AQd

## Actor input object example

```json
{}
```

# Actor output Schema

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

No description

# API

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

## JavaScript example

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

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

// Prepare Actor input
const input = {};

// Run the Actor and wait for it to finish
const run = await client.actor("expressleasing/expressleasing-machine-search").call(input);

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

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

```

## Python example

```python
from apify_client import ApifyClient

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

# Prepare the Actor input
run_input = {}

# Run the Actor and wait for it to finish
run = client.actor("expressleasing/expressleasing-machine-search").call(run_input=run_input)

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

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

```

## CLI example

```bash
echo '{}' |
apify call expressleasing/expressleasing-machine-search --silent --output-dataset

```

## MCP server setup

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

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "expressleasing-machine-search",
        "description": "Crawler for construction machinery using Apify, Airtable and OpenAI API, which returns most relevant offer links from WHITELISTED suppliers, and parameters like brand, model, price, year etc.\n\nAirtable serves as a search + for gathering results. Crawler was built in Apify (Javascript + Playground)",
        "version": "0.0",
        "x-build-id": "6KUlvfanBf6215vN8"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/expressleasing~expressleasing-machine-search/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-expressleasing-expressleasing-machine-search",
                "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/expressleasing~expressleasing-machine-search/runs": {
            "post": {
                "operationId": "runs-sync-expressleasing-expressleasing-machine-search",
                "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/expressleasing~expressleasing-machine-search/run-sync": {
            "post": {
                "operationId": "run-sync-expressleasing-expressleasing-machine-search",
                "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": [
                    "searchRecordId"
                ],
                "properties": {
                    "searchRecordId": {
                        "title": "Airtable search record ID",
                        "type": "string",
                        "description": "reckvawHfbWCC2AQd"
                    }
                }
            },
            "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
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
