# Comment extraire l'index des immeubles via l'API

Guide pas à pas : commander un index, suivre la tâche, lire les lignes en JSON ou en CSV. Exemples cURL, Python et Node.

Un index des immeubles se commande, se suit puis se lit en trois appels. Chaque inscription de l'index devient une ligne structurée (numéro d'inscription, date de présentation, nature, parties, radiations telles qu'inscrites). Le PDF source est toujours renvoyé avec les lignes, et il fait foi.

Cette page est un guide de l'API. La présentation de l'API Fonciq, ses opérations et ses limites publiées sont sur [fonciq.ca](https://fonciq.ca/api-registre-foncier).

## Prérequis

- Une clé d'API : voir [Premier appel](/plateforme/demarrage). Une clé `fq_test_` ne débite rien et renvoie des données d'exemple.
- Un compte du Registre foncier de votre organisation, ajouté dans [Studio › Développeurs](https://fonciq.ca/studio/developpeurs). Sans compte, aucun index ne se commande. Voir [Authentification](/plateforme/authentification#compte-du-registre).

## 1. Commander l'index

`POST /v1/registre/requests` (portée `registre:write`) exige un en-tête `Idempotency-Key`, conservé 24 heures. Une reprise avec la même clé renvoie la même réponse.

```bash
curl -X POST https://api.fonciq.ca/v1/registre/requests \
  -H "Authorization: Bearer $FONCIQ_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: 3f1c0b2e-7a4d-4e1a-9c2b-0d5e6f7a8b9c" \
  -d '{"lot":"1234567","documents":["index"]}'
```

La réponse est `202` :

```json
{ "job_id": "job_01HZX", "account_id": "rfa_exemple" }
```

## 2. Suivre la tâche

La consultation est asynchrone. `GET /v1/jobs/{id}` (portée `jobs:read`) donne l'état : `queued`, `capacity_wait`, `running`, `succeeded` ou `failed`. L'état `capacity_wait` signifie que le plafond du jour du compte retient encore l'envoi au Registre. La capacité du compte se lit dans la même réponse.

```bash
curl https://api.fonciq.ca/v1/jobs/job_01HZX \
  -H "Authorization: Bearer $FONCIQ_API_KEY"
```

Interrogez à intervalle raisonnable : la clé est limitée à 60 requêtes par minute ([Limites de débit](/plateforme/limites)).

## 3. Lire les lignes

Lorsque la tâche est `succeeded`, le résultat est sur `result.index` (un bloc par lot pour un lot groupé). Il donne `pdf_url`, `entries_url` et `entries`. Les mêmes lignes se lisent directement avec `GET /v1/documents/{id}/entries`, en JSON par défaut ou en CSV avec `format=csv`.

```bash
curl "https://api.fonciq.ca/v1/documents/42/entries?format=csv" \
  -H "Authorization: Bearer $FONCIQ_API_KEY"
```

Le PDF source se télécharge avec `GET /v1/documents/{id}`.

### Python

```python
import os, time, uuid, requests

BASE = "https://api.fonciq.ca"
HEADERS = {"Authorization": f"Bearer {os.environ['FONCIQ_API_KEY']}"}

job = requests.post(
    f"{BASE}/v1/registre/requests",
    headers={**HEADERS, "Idempotency-Key": str(uuid.uuid4())},
    json={"lot": "1234567", "documents": ["index"]},
).json()

while True:
    state = requests.get(f"{BASE}/v1/jobs/{job['job_id']}", headers=HEADERS).json()
    if state["status"] in ("succeeded", "failed"):
        break
    time.sleep(10)

if state["status"] == "succeeded":
    for entry in state["result"]["index"]["entries"]:
        print(entry["inscription"], entry["presentation_date"], entry["nature"])
```

### Node

```js
const BASE = 'https://api.fonciq.ca';
const headers = { Authorization: `Bearer ${process.env.FONCIQ_API_KEY}` };

const created = await fetch(`${BASE}/v1/registre/requests`, {
  method: 'POST',
  headers: { ...headers, 'Content-Type': 'application/json', 'Idempotency-Key': crypto.randomUUID() },
  body: JSON.stringify({ lot: '1234567', documents: ['index'] }),
}).then((r) => r.json());

let job;
do {
  await new Promise((resolve) => setTimeout(resolve, 10_000));
  job = await fetch(`${BASE}/v1/jobs/${created.job_id}`, { headers }).then((r) => r.json());
} while (!['succeeded', 'failed'].includes(job.status));

if (job.status === 'succeeded') {
  for (const entry of job.result.index.entries) console.log(entry.inscription, entry.nature);
}
```

## Ce que contiennent les lignes

| Champ | Contenu |
| --- | --- |
| `inscription` | Numéro d'inscription, espaces conservés. |
| `presentation_date` | Date de présentation, `YYYY-MM-DD`. |
| `nature` | Nature de l'acte. Nulle lorsque la colonne n'a pas été lue. |
| `parties` | `{ "role", "name" }`, lorsque la qualité est reconnue. |
| `radiations` | Mentions de radiation telles qu'inscrites : `inscription`, `mention`, `raw_text`. |
| `confidence` | Toujours le littéral `unscored` : l'analyseur actuel ne produit pas de score. Laissez `unscored`. |
| `source_document_id` | Identifiant du PDF source. |

Le PDF fait foi. Une liste `entries` vide est une lecture vide : aucune ligne n'est inventée pour la remplir, et les rangées sans date ou sans numéro d'inscription sont écartées. Le détail de chaque champ est dans [Tâches et résultats](/registre/taches). Les colonnes du CSV sont les mêmes pour `jobs/{id}/results`, `lots/{lot}` et `documents/{id}/entries`.

## Coût

Chaque index livré coûte 0,99 $ excluant frais du registre. L'index consulte toujours le Registre, qui facture 1,50 $ au titulaire du compte : un index consulté coûte donc 2,49 $ au total. Les frais du Registre ne sont pas un débit Fonciq. Une clé `fq_test_` ne débite pas. Voir [Coûts](/plateforme/couts-par-appel).

## Erreurs fréquentes

| Code | Cause |
| --- | --- |
| `401` | Clé absente, révoquée ou sans la portée `registre:write` ou `jobs:read`. |
| `400` | Corps invalide, ou `format` autre que `csv` sur une lecture de lignes. |
| `409` | Aucun compte du Registre : `rf_account_required`. |
| `404` | Document qui n'est pas un index produit pour votre organisation. |
| `429` | Plus de 60 requêtes par minute (`rate_limited`) : attendez le délai de `Retry-After`. |

Le corps d'erreur est le même partout : voir [Erreurs](/plateforme/erreurs).

## Pour aller plus loin

- Plusieurs lots à la fois : [Consultation en lot par CSV](/guides/consultation-en-lot-csv) ou [Lots groupés](/registre/lots-groupes).
- Être avisé d'une nouvelle inscription : [Webhooks des nouvelles inscriptions](/guides/webhooks-inscriptions).
