# FGCMPI Scraper (fgcmpi.org.dz) (`hamza325/fgcmpi-scraper`) Actor

Extract Algeria's FGCMPI registers: guaranteed housing projects with their guarantee dates, insurance policy numbers, locations and housing breakdown, and the affiliated real-estate developers with their agrément, TNPI, registered office and contact details.

- **URL**: https://apify.com/hamza325/fgcmpi-scraper.md
- **Developed by:** [Hamza Abbad](https://apify.com/hamza325) (community)
- **Categories:** Real estate
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.47 / 1,000 results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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

## FGCMPI Scraper

Collect Algeria's guaranteed housing projects or the real-estate developers affiliated to the **[Fonds de Garantie et de Caution Mutuelle de la Promotion Immobilière (FGCMPI)](https://www.fgcmpi.org.dz)**. Results land in a dataset ready to export as CSV, Excel or JSON.

### What you can scrape

- **Guaranteed housing projects** — the FGCMPI project register, with each project's promoter, title, guarantee grant and expiry dates, location, daira, wilaya, phone, insurance policy number, status, construction type and housing-type breakdown. You can narrow the list by promoter, project title, wilaya or housing programme.
- **Affiliated developers** — the affiliation register, with each developer's affiliation, agrément and TNPI numbers, company name, manager, registered office, phone and wilaya.

### Why this Actor

- **The whole picture in one place.** Project rows carry both the register's summary and the full project record, so you do not have to join two exports.
- **Ready for analysis.** Every row uses the same clear field names, so the data drops straight into a spreadsheet, database or downstream workflow.
- **Targeted searches.** Filter projects by promoter, title, wilaya and housing programme; the filters combine to answer a specific question.
- **Resilient results.** A project whose detail page is unavailable still appears with its summary fields, so a broken page does not silently remove it from your dataset.
- **No login required.** The Actor reads public data directly; no account, login or cookie is needed.

#### What the two registers give you together

The Actor covers both public registers, and they answer different questions about the same market:

| Surface | What a run gives you | What it is for |
| --- | --- | --- |
| **Guaranteed housing projects** | promoter, guarantee grant and expiry dates, wilaya and daira, phone, insurance policy number, status, construction type and the housing-type breakdown | track guarantee expiry, or check what a promoter has on the register |
| **Affiliated developers** | affiliation number, agrément and TNPI numbers, company name, manager, registered office, phone and wilaya | verify a developer before you sign with one |
| **Filters** | promoter, project title, wilaya and housing programme, combined | answer "who is building what, where, and is it guaranteed" |

### Quick start

1. Click **Try actor**.
2. Choose the register in **What to scrape** (`startMode`).
3. Click **Start**.
4. Open the **Dataset** tab and use the **All rows**, **Projects** or **Developers** view.

A projects run:

```json
{ "startMode": "projects" }
```

A developers run:

```json
{ "startMode": "developers" }
```

`startMode` defaults to `projects`, so omitting it runs projects mode.

### Tutorial: a real workflow

Say you track the promotion immobilière market in Oran.

#### 1. Choose projects mode and filter

The project filters combine:

```json
{
  "startMode": "projects",
  "wilaya": "ORAN",
  "projectType": "PL"
}
```

You get guaranteed projects filed under Oran for the Promotionnel Libre programme, with their promoter, title, guarantee grant date, location, daira, wilaya and phone.

#### 2. Include the full project record

With **Include full project details** (`includeDetails`) on (the default), every project row also carries the insurance policy number, guarantee expiry date, registered office, destination, construction type, status and housing types — for example `[{ "type": "F3", "nombre": 14 }]`.

#### 3. Collect the developers

Developers mode collects the affiliation register:

```json
{ "startMode": "developers" }
```

One row per developer, with the affiliation, agrément and TNPI numbers, company name, manager, registered office, phone and wilaya.

### Input

See the input tab for the full configuration options.

#### Main input

| Label (`key`) | Description | Default |
| --- | --- | --- |
| **What to scrape** (`startMode`) | `projects` for guaranteed housing projects, `developers` for the affiliation register. | `projects` |

#### Project filters

Used in projects mode; ignored in developers mode.

| Label (`key`) | Description | Default |
| --- | --- | --- |
| **Promoteur** (`promoteurSearch`) | Projects whose promoter name contains this text. | — |
| **Intitulé du projet** (`projetSearch`) | Projects whose title contains this text. | — |
| **Wilaya** (`wilaya`) | Projects in one wilaya, written as published (`ORAN`, `ALGER`, `TIPAZA`…). Matching is case-insensitive. | — |
| **Housing programme** (`projectType`) | `PL` (Promotionnel Libre), `LSP` (Logement Social Participatif) or `LPA` (Logement Promotionnel Aidé). | `""` |

#### Output & debugging

| Label (`key`) | Description | Default |
| --- | --- | --- |
| **Include full project details** (`includeDetails`) | Used in projects mode. Add the full project record: insurance policy number, guarantee expiry date, registered office, construction type and housing breakdown. | `true` |

#### Limits & performance

| Label (`key`) | Description | Default |
| --- | --- | --- |
| **Maximum results** (`maxItems`) | Maximum rows to return in the selected mode. `0` = no cap. | `200` |
| **Maximum pages** (`maxPages`) | Used in projects mode. Maximum result pages to read. `0` = no cap. | `0` |
| **Concurrent requests** (`maxConcurrency`) | How many requests the Actor sends at the same time. | `10` |
| **Requests per minute** (`maxRequestsPerMinute`) | Rate limit for the run. | `240` |
| **Retries per request** (`maxRequestRetries`) | Retries before a failed request is given up on. | `5` |

### Output

One dataset per run. The selected mode decides the row type, and every row carries a `recordType` — `"project"` or `"developer"`. Switch between the **All rows**, **Projects** and **Developers** views in the **Dataset** tab, and download the data as JSON, HTML, CSV or Excel.

#### Modes at a glance

| Mode (`startMode`) | Key fields |
| --- | --- |
| **Guaranteed housing projects** (`projects`) | `projectId`, `promoteur`, `projet`, `dateOctroiGarantie`, `dateExpirationGarantie`, `localisation`, `daira`, `wilaya`, `telephone`, `numeroPolice`, `statut`, `typeLogement`, `url` |
| **Real-estate developers** (`developers`) | `numAffiliation`, `numAgrement`, `numTNPI`, `promoteur`, `dirigeant`, `siegeSocial`, `telephone`, `wilaya` |

#### Project row (`recordType: "project"`)

| Column | What it holds |
| --- | --- |
| `projectId` | Project identifier in the form `YYYY-NNNN`. |
| `promoteur` / `projet` | The promoter and the project title. |
| `dateOctroiGarantie` (+ `…Iso`) | The guarantee grant date, `DD/MM/YYYY` and `YYYY-MM-DD`. |
| `dateExpirationGarantie` (+ `…Iso`) | The guarantee expiry date, `DD/MM/YYYY` and `YYYY-MM-DD`. |
| `localisation` / `daira` / `wilaya` | The project address, daira and wilaya. |
| `siegeSocialDetail` | The promoter's registered office. |
| `localisationProjet` | The full project address as published, including the daira. |
| `numeroPolice` | The guarantee's insurance policy number. |
| `destinationProjet` / `typeConstruction` / `statut` | Project destination, construction type and housing programme status. |
| `typeLogement` / `typeLogementRaw` | Housing types with their counts, as objects and as published text. |
| `superficieGarantie` | Guaranteed surface area in m², when published. |
| `telephone` | The project's phone numbers. |
| `url` / `sourceUrl` | The project page and the page where the row was found. |
| `detailStatus` | Whether the full project record was retrieved — see below. |
| `scrapedAt` | When the row was collected. |

#### Developer row (`recordType: "developer"`)

| Column | What it holds |
| --- | --- |
| `numAffiliation` | The developer's affiliation number in the register. |
| `numAgrement` / `numTNPI` | The agrément and TNPI numbers. |
| `promoteur` | The company name. |
| `dirigeant` | The managing director. |
| `siegeSocial` / `localisation` | The registered office. |
| `telephone` / `wilaya` | The phone/fax and the wilaya. |
| `sourceUrl` | The page where the row was found. |
| `scrapedAt` | When the row was collected. |

#### Example project row

```json
{
  "recordType": "project",
  "projectId": "2026-0438",
  "promoteur": "EURL MEDJARI PROMOTION IMMOBILIERE",
  "projet": "44 Logts",
  "dateOctroiGarantie": "15/10/2026",
  "dateOctroiGarantieIso": "2026-10-15",
  "dateExpirationGarantie": "30/09/2028",
  "dateExpirationGarantieIso": "2028-09-30",
  "localisation": "HAI ABDELMOUMEN, LIEU CITE « CHOUPOU », COTE RUE KARNO",
  "daira": "Oran",
  "wilaya": "ORAN",
  "numeroPolice": "2026-0326-1-31-260360",
  "statut": "LPA2-PL",
  "typeLogement": [{ "type": "F3", "nombre": 14 }],
  "url": "https://www.fgcmpi.org.dz/Detail_projet/2026-0438",
  "detailStatus": "ok",
  "scrapedAt": "2026-10-31T18:30:00.000Z"
}
```

#### Example developer row

```json
{
  "recordType": "developer",
  "numAffiliation": "03952",
  "numAgrement": "0403P3036",
  "numTNPI": "3925-3952-P16",
  "promoteur": "BOUSBAH RAHIMA",
  "dirigeant": "BOUSBAH RAHIMA",
  "siegeSocial": "Cité belle vue N°332, Ain Mlila",
  "telephone": null,
  "wilaya": "O.E.BOUAGHI",
  "sourceUrl": "https://www.fgcmpi.org.dz/Liste_Affiliation",
  "scrapedAt": "2026-10-31T18:30:00.000Z"
}
```

### Notes and limits

- Project filters apply only in projects mode. `maxPages` applies only in projects mode; `maxItems` applies to the selected mode.
- A project whose full record cannot be read keeps its summary row; `detailStatus` explains what happened.
- `detailStatus: "ok"` means the full record was read. `"server-error"` or `"failed"` means only the summary row is available. `"unknown"` means the full record returned no recognizable fields. `"skipped"` means full details were turned off.
- Fields that do not apply to a row type are empty or absent in that row.
- Values that start with `=`, `+`, `-` or `@` are stored with a leading apostrophe so CSV and Excel exports treat them as text, not formulas.
- Text values are returned as published in the register; the `…Iso` date fields add a `YYYY-MM-DD` version.

### FAQ

**How do I filter by wilaya?**
Use projects mode and the `wilaya` field with the published name (`ORAN`, `ALGER`, `TIPAZA`…). Matching is case-insensitive.

**What happens to the project filters in developers mode?**
They are ignored. Projects mode is the only mode that uses them.

**Why is a project missing its policy number or housing breakdown?**
Its full record may not be available. The summary row is still returned, and `detailStatus` tells you why.

**Does the Actor need a login or account to read the data?**
No. It reads public data directly.

**How much data does a run return?**
Up to 200 rows by default. Set `maxItems` to `0` for the whole selected register, or lower it for a smaller run; `maxPages` bounds a projects run.

### Contact

Bug reports, feature requests, or a custom scraper for a site not yet covered? Open an issue on the Actor's Apify Console page or message the maintainer directly there.

# Changelog

This Actor's version history is a separate document: https://apify.com/hamza325/fgcmpi-scraper/changelog.md

# Actor input Schema

## `startMode` (type: `string`):

The register to collect.

## `promoteurSearch` (type: `string`):

Used in projects mode. Only projects whose promoter name contains this text.

## `projetSearch` (type: `string`):

Used in projects mode. Only projects whose title contains this text.

## `wilaya` (type: `string`):

Used in projects mode. Only projects in this wilaya. Use the published name (ORAN, ALGER, TIPAZA); matching is case-insensitive.

## `projectType` (type: `string`):

Used in projects mode. Only projects of this housing programme.

## `includeDetails` (type: `boolean`):

Used in projects mode. Add the full project record: insurance policy number, guarantee expiry date, registered office, construction type and housing breakdown.

## `maxItems` (type: `integer`):

Maximum rows to return in the selected mode. 0 = no cap.

## `maxPages` (type: `integer`):

Used in projects mode. Maximum result pages to read. 0 = no cap.

## `maxConcurrency` (type: `integer`):

How many requests the Actor sends at the same time.

## `maxRequestsPerMinute` (type: `integer`):

Rate limit for the run. Higher values finish faster.

## `maxRequestRetries` (type: `integer`):

How many times a failed request is retried before it is given up on.

## Actor input object example

```json
{
  "startMode": "projects",
  "projectType": "",
  "includeDetails": true,
  "maxItems": 200,
  "maxPages": 0,
  "maxConcurrency": 10,
  "maxRequestsPerMinute": 240,
  "maxRequestRetries": 5
}
```

# Actor output Schema

## `rows` (type: `string`):

Default dataset containing every row the Actor pushed during the run. The selected mode decides whether the rows are projects or developers; filter on `recordType` to identify them.

# 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("hamza325/fgcmpi-scraper").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("hamza325/fgcmpi-scraper").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 '{}' |
apify call hamza325/fgcmpi-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,hamza325/fgcmpi-scraper"
        }
    }
}
```

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/fiXedKexIPAAHwTf5/builds/x3PMO66S37EyvwXX2/openapi.json
