# Attesta Portugal Property Verify (`dor-alboim/attesta-portugal-verify`) Actor

Search Portugal residential listings and verify property claims with signed JWS receipts from Attesta.

- **URL**: https://apify.com/dor-alboim/attesta-portugal-verify.md
- **Developed by:** [Dor Alboim](https://apify.com/dor-alboim) (community)
- **Categories:** Real estate, AI
- **Stats:** 2 total users, 1 monthly users, 75.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $30.00 / 1,000 verify claims

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

### What does Attesta Portugal Property Verify do?

This Actor is a **Portugal property verification API** for AI agents and analysts. It does **not** scrape Idealista or Imovirtual itself. It calls [Attesta](https://api-production-d9143.up.railway.app) — a provenance-grade corpus of Portuguese residential listings — and returns either structured search results or a **signed JWS verification receipt**.

Use it when you need to check a claim such as “T2 in Faro €240k, 40 days on market” against stored portal snapshots, with citations that survive later audit.

### Why use Attesta?

Portal listings drift. Prices change, ads vanish, and the same apartment appears on more than one site. Attesta keeps append-only snapshots, strips PII at ingest, and signs a machine-readable attestation you can file.

- Search Portugal listings by region, city, typology, and price
- Verify a natural-language claim (`corpus` or `deep`)
- Receive a JWS receipt plus structured verdicts and confidence
- Run from Apify Console, API, schedules, or other Actors
- Pay per event — no Attesta account required for Store users once the owner configures the backend key

### What data can Attesta extract?

| Field | Type | Description |
| --- | --- | --- |
| `kind` | string | `listing` or `verification` |
| `id` | string | Canonical property id (search) |
| `city` / `region` | string | Location |
| `current_price_eur` | number | Latest observed asking price |
| `days_on_market` | number | Observed time on market |
| `staleness_score` | number | Freshness score (0–1, lower is fresher) |
| `sources` | array | Portal sources (e.g. Idealista PT, Imovirtual) |
| `claim` | string | Input claim (verify) |
| `confidence` | number | Aggregated verification confidence |
| `verdicts` | array | Per-predicate labels with evidence refs |
| `jws` | string | Signed attestation token |
| `attestation_id` | string | Persisted receipt id |

### How to verify a Portugal property claim

1. Open this Actor in Apify Console.
2. Keep **Action** as `verify`.
3. Use the prefilled claim or write your own (city, typology, price, days on market).
4. Choose **corpus** for snapshot evidence or **deep** for a live re-fetch when available.
5. Click **Start**. Download the dataset as JSON, CSV, or Excel.

To search instead of verify, set **Action** to `search` and optionally filter by region (`PT-08`), city (`Faro`), typology (`T2`), and price.

### How much will it cost?

This Actor is designed for **pay-per-event** pricing (configure prices in the Publication tab):

- `search-listings` — one search call
- `listing-item` — each listing written to the dataset
- `verify-claim` — corpus verification + JWS
- `verify-claim-deep` — live-fetch verification + JWS

Suggested starting prices that track Attesta’s own list: about **$0.02** per search, **$0.005** per listing, **$0.03** per corpus verify, **$0.10** per deep verify. Platform compute for a typical run is a few seconds on 1 GB.

### Input

See the **Input** tab for the full form. The important fields are:

- `action` — `search` or `verify`
- `claim` — required for verify
- `depth` — `corpus` or `deep`
- `region`, `city`, `typology`, `minPriceEur`, `maxPriceEur`, `limit` — search filters
- `attestaApiKey` — only needed if the Actor owner has not set `ATTESTA_API_KEY`

### Output

You can download the dataset in JSON, HTML, CSV, or Excel.

Search example:

```json
{
  "kind": "listing",
  "id": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee",
  "region": "PT-08",
  "city": "Faro",
  "current_price_eur": 240000,
  "days_on_market": 40,
  "staleness_score": 0.12,
  "is_active": true,
  "sources": ["idealista_pt"]
}
```

Verify example:

```json
{
  "kind": "verification",
  "claim": "T2 in Faro €240k, 40 days on market",
  "verification_mode": "corpus",
  "confidence": 0.81,
  "verdicts": [{ "verdict": "CORROBORATED", "predicate": "price_eur" }],
  "jws": "eyJhbGciOiJFUzI1NiJ9...",
  "attestation_id": "11111111-2222-3333-4444-555555555555"
}
```

### FAQ, disclaimers, and support

#### Is this an Idealista or Imovirtual scraper?

No. Attesta already ingests those portals (PII-stripped, snapshot-based) and exposes search plus `verify_claim`. This Actor is a Store wrapper around that API so agents can pay per event on Apify.

#### Do I need an Attesta account?

Store users pay through Apify. The Actor owner must set `ATTESTA_API_KEY` (Apify secret `@attestaApiKey`, typically Railway `BOOTSTRAP_API_KEY`) so runs can reach the live Attesta API. `ATTESTA_BASE_URL` defaults to production.

#### What about personal data?

Attesta strips PII at ingestion before database or object-storage writes. Results are property facts, not private contact details. You should still treat outputs as potentially personal under GDPR if they can identify a dwelling owner, and only use them with a legitimate purpose.

#### Support

Use the **Issues** tab on this Actor for bugs and feature requests. Programmatic access is on the **API** tab. Attesta REST/MCP docs live at the Attesta `/docs` endpoint.

# Actor input Schema

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

search returns Portugal listings. verify checks a natural-language claim and returns a signed JWS receipt.

## `claim` (type: `string`):

Natural-language property claim to verify. Required when Action is verify.

## `depth` (type: `string`):

corpus uses Attesta's stored snapshots. deep re-fetches live portal pages when available.

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

ISO-style region code, e.g. PT-08 for Faro district.

## `city` (type: `string`):

City name filter, e.g. Faro or Lisboa.

## `typology` (type: `string`):

Portuguese typology such as T1, T2, T3.

## `minPriceEur` (type: `integer`):

Lower bound for listing search.

## `maxPriceEur` (type: `integer`):

Upper bound for listing search.

## `limit` (type: `integer`):

Maximum listings to return (1–50).

## `attestaBaseUrl` (type: `string`):

Override the Attesta REST host. Leave blank to use the production default.

## `attestaApiKey` (type: `string`):

Optional. If omitted, the Actor uses the ATTESTA\_API\_KEY environment variable set by the Actor owner in Console.

## Actor input object example

```json
{
  "action": "verify",
  "claim": "T2 in Faro €240k, 40 days on market",
  "depth": "corpus",
  "region": "PT-08",
  "city": "Faro",
  "maxPriceEur": 300000,
  "limit": 10
}
```

# Actor output Schema

## `dataset` (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 = {
    "claim": "T2 in Faro €240k, 40 days on market",
    "region": "PT-08",
    "city": "Faro",
    "maxPriceEur": 300000
};

// Run the Actor and wait for it to finish
const run = await client.actor("dor-alboim/attesta-portugal-verify").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 = {
    "claim": "T2 in Faro €240k, 40 days on market",
    "region": "PT-08",
    "city": "Faro",
    "maxPriceEur": 300000,
}

# Run the Actor and wait for it to finish
run = client.actor("dor-alboim/attesta-portugal-verify").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 '{
  "claim": "T2 in Faro €240k, 40 days on market",
  "region": "PT-08",
  "city": "Faro",
  "maxPriceEur": 300000
}' |
apify call dor-alboim/attesta-portugal-verify --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,dor-alboim/attesta-portugal-verify"
        }
    }
}
```

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/E3jaNzZAVUgSgR5ht/builds/ncbhscfUuCUXull3x/openapi.json
