{
  "openapi": "3.1.0",
  "info": {
    "title": "API Fonciq",
    "version": "1.0.0",
    "summary": "API v1. Les consultations du Registre s'exécutent sur le compte de l'organisation.",
    "description": "Contrat HTTP de l'API Fonciq v1. Cette référence est générée uniquement\nà partir du présent document. Les montants sont des entiers en cents\ncanadiens. Seuls les documents sont facturés : un index, un plan\ncadastral ou le PDF d'un acte livré débite 99 cents sur le solde\nFonciq d'une clé réelle. Résoudre ou lire un lot, créer une\nsurveillance, lire une tâche ou un document conservé et les lectures\nde facturation débitent 0. Bientôt : l'acte avec\nl'analyse structurée complète débitera 499 cents. Ce montant comprend\nle tirage et ne s'ajoute pas aux 99 cents. Cette option n'est pas\nencore disponible. Une clé fq_test_,\nune réponse 4xx ou 5xx, et les lectures de facturation débitent 0.\nLes frais du Registre s'appliquent lorsque le Registre est consulté :\n150 cents (1,50 $), Loi sur les bureaux de la publicité des droits\n(B-9), annexe I, art. 15, Avis du 30 mars 2026. L'index des immeubles\nconsulte toujours le Registre. Un acte conservé ou un plan conservé\nn'entraîne pas de frais du Registre. Le Registre facture le titulaire\ndu compte. Fonciq ne prélève pas ce 1,50 $.\n\nLes consultations s'exécutent sur un compte du Registre que\nl'organisation ajoute dans les paramètres de l'API. Le compte est\nchiffré, en écriture seule, et peut être révoqué. L'ajout passe par\nun écran de consentement. Le traitement du compte est décrit dans le\ntableau de bord. Une organisation peut enregistrer plusieurs comptes.\nL'un d'eux est le compte par défaut. Une requête peut en désigner un\nautre avec `rf_account_id`. `account_id` est accepté comme alias de\nce paramètre.\n\n`GET /v1/billing` et `GET /v1/billing/usage` décrivent les frais du\nRegistre imputés à chaque compte connecté, par période et par\ndocument. Ils ne renvoient pas le débit Fonciq de 99 cents et ne\nle prélèvent pas.\n\nAucun relevé du portail n'est lu. Ces deux routes portent `source`\négal à `estimate`. Les lignes sont le journal Fonciq des tirages.\n`statement.available` est faux et `balance_cents` est nul.\n\nUn index récupéré renvoie toujours son PDF (`GET /v1/documents/{id}`).\nCe PDF fait foi, que des lignes aient été lues ou non. Le résultat\nstructuré est sur la tâche (`result.index` ou `result.indexes`) et sur\n`GET /v1/documents/{id}/entries`. Le JSON est le format par défaut.\n`format=csv` ou `Accept: text/csv` renvoie le CSV. `confidence` vaut\nle littéral `unscored`. `needs_review` est nul sur une ligne\nstructurée : aucun seuil de relecture n'est publié. `read_method`,\nle statut de page et les lignes non structurées sont prévus.\nAucune ligne n'est inventée.\n\nChaque compte du Registre est plafonné à 540 index par jour\n(heure de Toronto). Les surveillances consomment la capacité du compte\nsur lequel elles sont placées. Le planificateur étale ces vérifications\net réserve 180 index du plafond quotidien aux appels à la demande.\n\nLe Registre foncier est consulté par les appels d'index, d'acte et\nde plan. `GET /v1/lots/resolve`, `GET /v1/lots/{lot}` et\n`POST /v1/watches` interrogent les rôles d'évaluation foncière des\nmunicipalités du Québec, l'un des jeux de données publics intégrés\naux Données Fonciq. Fonciq n'est\npas affilié à ces organismes.\n\nLe panneau d'essai n'envoie qu'une clé au préfixe `fq_test_` et\nn'effectue aucun débit.\n"
  },
  "servers": [
    {
      "url": "https://api.fonciq.ca",
      "description": "Hôte de l'API. Les clés d'essai portent le préfixe fq_test_.\nLe panneau d'essai n'effectue aucun débit.\n"
    }
  ],
  "tags": [
    {
      "name": "Lots",
      "description": "Résolution d'adresse et fiche de lot. Ces lectures interrogent les\nrôles d'évaluation foncière des municipalités du Québec, l'un des\njeux de données publics intégrés aux Données Fonciq.\n"
    },
    {
      "name": "Registre",
      "description": "Consultation d'index ou d'actes sur un compte du Registre de l'organisation."
    },
    {
      "name": "Tâches",
      "description": "Suivi des consultations et des lots groupés, PDF, lignes d'index\net export CSV. La capacité du jour de chaque compte voyage avec la tâche.\n"
    },
    {
      "name": "Lots groupés",
      "description": "Jusqu'à 500 lots. Sans account_id, le travail est réparti en parallèle sur les comptes actifs."
    },
    {
      "name": "Surveillances",
      "description": "Vérifications planifiées. Créer une surveillance interroge les\nrôles d'évaluation foncière des municipalités du Québec. Les index\nconsultés ensuite consomment la capacité du compte du Registre.\n"
    },
    {
      "name": "Gratuit",
      "description": "Appels gratuits, sans clé et sans débit, limités par adresse IP.\nFree calls, no key, no charge, limited per IP.\n"
    },
    {
      "name": "Facturation",
      "description": "Frais du Registre foncier par compte connecté. Pas les frais de\nplateforme Fonciq.\n"
    }
  ],
  "security": [
    {
      "bearerAuth": []
    }
  ],
  "paths": {
    "/v1/lots/resolve": {
      "get": {
        "operationId": "resolveLot",
        "tags": [
          "Lots"
        ],
        "summary": "Résoudre une adresse ou un matricule",
        "description": "Portée `lots:read`. Cette lecture interroge les rôles\nd'évaluation foncière des municipalités du Québec, l'un des\njeux de données publics intégrés aux Données Fonciq. Elle ne\nlivre pas de document et ne débite rien.\nFournir `address` ou\n`matricule`. La réponse énumère le lot, le cadastre, le\nmatricule et indique si le rôle corrobore le lot.\n",
        "parameters": [
          {
            "name": "address",
            "in": "query",
            "required": false,
            "description": "Adresse au Québec. Mutuellement exclusif avec `matricule` dans l'usage attendu ; fournir l'un des deux.",
            "schema": {
              "type": "string",
              "examples": [
                "100 rue Saint-Paul Est, Montréal"
              ]
            }
          },
          {
            "name": "matricule",
            "in": "query",
            "required": false,
            "description": "Matricule du rôle d'évaluation.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Lots correspondants.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ResolveResponse"
                },
                "example": {
                  "lots": [
                    {
                      "lot": "1234567",
                      "cadastre": "Cadastre du Québec",
                      "matricule": "1234-56-7890-1-234-5678",
                      "role_matched": true
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/InvalidRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/v1/lots/{lot}": {
      "get": {
        "operationId": "getLot",
        "tags": [
          "Lots"
        ],
        "summary": "Lire la fiche d'un lot",
        "description": "Portée `lots:read`. Cette lecture interroge les rôles\nd'évaluation foncière des municipalités du Québec, l'un des\njeux de données publics intégrés aux Données Fonciq. Elle ne\nlivre pas de document et ne débite rien. La fiche\nréunit le cadastre, l'évaluation\ndu rôle en cents et les lignes d'index de `registre.entries`.\nMême objet qu'une tâche terminée. Cette opération ne tire pas\nun index.\n\nJSON par défaut. `format=csv` ou `Accept: text/csv` renvoie ces\nlignes en CSV à la place de la fiche. `format` l'emporte. Toute\nautre valeur de `format` reçoit `400` et le code `invalid_request`.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/Lot"
          },
          {
            "$ref": "#/components/parameters/ResultFormat"
          }
        ],
        "responses": {
          "200": {
            "description": "Fiche JSON, ou CSV des lignes d'index.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LotProfile"
                },
                "example": {
                  "lot": "1234567",
                  "cadastre": {
                    "label": "Cadastre du Québec",
                    "lot": "1234567"
                  },
                  "assessment": {
                    "year": 2026,
                    "value_cents": 45000000
                  },
                  "registre": {
                    "entries": [
                      {
                        "lot": "1234567",
                        "source_document_id": "42",
                        "position": 0,
                        "inscription": "21 014 436",
                        "presentation_date": "2024-03-12",
                        "nature": "Vente",
                        "parties": [
                          {
                            "role": "Vendeur",
                            "name": "EXEMPLE, MARIE"
                          }
                        ],
                        "remarks": null,
                        "radiations": [],
                        "read_method": null,
                        "confidence": "unscored",
                        "needs_review": null
                      }
                    ]
                  }
                }
              },
              "text/csv": {
                "schema": {
                  "$ref": "#/components/schemas/IndexCsv"
                },
                "example": "lot,matricule,inscription,date,nature,parties,document_url,read_method,confidence,needs_review,page_status\n1234567,,\"21 014 436\",2024-03-12,Vente,\"Vendeur: EXEMPLE, MARIE\",https://api.fonciq.ca/v1/documents/42,,unscored,,\n"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/InvalidRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/v1/registre/requests": {
      "post": {
        "operationId": "createRegistreRequest",
        "tags": [
          "Registre"
        ],
        "summary": "Commander un index",
        "description": "Portée `registre:write`. En-tête `Idempotency-Key` obligatoire,\nconservé 24 heures. Une reprise avec la même clé renvoie la réponse\nenregistrée pour cette clé.\n\nLa consultation s'exécute sur le compte du Registre de\nl'organisation. Sans `account_id`, le compte par défaut est utilisé.\nAvec `account_id`, la requête est épinglée à ce compte. Chaque\nindex livré débite 99 cents sur une clé réelle. Les frais du\nRegistre, 150 cents, s'appliquent lorsque le Registre est consulté.\nL'index consulte toujours le Registre. Ces 150 cents sont facturés\npar le Registre au titulaire. Ils ne figurent pas comme un débit\nFonciq.\n\n`documents` vaut `index`. La réponse contient `job_id`.\nLa tâche entre dans la file du compte. Le plafond est de\n540 index par jour pour ce compte.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RegistreRequest"
              },
              "example": {
                "lot": "1234567",
                "documents": [
                  "index"
                ],
                "account_id": "rfa_exemple"
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Tâche acceptée.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AcceptedJob"
                },
                "example": {
                  "job_id": "job_01HZX",
                  "account_id": "rfa_exemple"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/InvalidRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/v1/actes": {
      "post": {
        "operationId": "createActe",
        "tags": [
          "Registre"
        ],
        "summary": "Commander un acte",
        "description": "Portée `registre:write`. En-tête `Idempotency-Key` obligatoire,\nconservé 24 heures. Une reprise avec la même clé renvoie la réponse\nenregistrée pour cette clé.\n\n`registration_number` est le numéro d'inscription.\n`circonscription` est la circonscription foncière. Sans\n`rf_account_id`, le compte par défaut est utilisé.\n\nUn acte conservé est renvoyé. Aucun tirage n'est lancé, et les\nfrais du Registre ne s'appliquent pas. Un acte absent échoue de\nfaçon fermée. Le formulaire d'inscription n'est pas dans le\nproduit : l'appel ne se connecte pas au Registre. Aucun tirage\nen direct n'est promis.\n\nUn PDF d'acte débite 99 cents sur le solde Fonciq d'une clé\nréelle. Bientôt : l'analyse structurée complète débitera\n499 cents. Ce montant comprend le tirage et ne s'ajoute pas\naux 99 cents. Cette option n'est pas encore disponible. Les\nfrais du Registre de 150 cents (1,50 $) s'appliquent seulement\nlorsque le Registre est consulté. Un acte conservé n'entraîne\npas de frais du Registre.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "registration_number",
                  "circonscription"
                ],
                "properties": {
                  "registration_number": {
                    "type": "string",
                    "description": "Numéro d'inscription."
                  },
                  "circonscription": {
                    "type": "string",
                    "description": "Circonscription foncière."
                  },
                  "rf_account_id": {
                    "type": "string",
                    "description": "Compte du Registre. Absent, le compte par défaut est utilisé."
                  }
                }
              },
              "example": {
                "registration_number": "21 014 436",
                "circonscription": "Montréal"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Acte conservé. Aucun tirage n'est lancé.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "document_type",
                    "registration_number",
                    "circonscription",
                    "source",
                    "registry_fee_cents",
                    "pdf_url"
                  ],
                  "properties": {
                    "document_type": {
                      "type": "string",
                      "enum": [
                        "acte"
                      ]
                    },
                    "registration_number": {
                      "type": "string"
                    },
                    "circonscription": {
                      "type": "string"
                    },
                    "source": {
                      "type": "string",
                      "enum": [
                        "stored"
                      ],
                      "description": "L'acte renvoyé est conservé. Un tirage n'est pas lancé."
                    },
                    "registry_fee_cents": {
                      "type": "integer",
                      "description": "0. Un acte conservé n'entraîne pas de frais du Registre."
                    },
                    "pdf_url": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "document_type": "acte",
                  "registration_number": "21 014 436",
                  "circonscription": "Montréal",
                  "source": "stored",
                  "registry_fee_cents": 0,
                  "pdf_url": "https://api.fonciq.ca/v1/documents/42"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/InvalidRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "409": {
            "description": "Acte absent, ou tirage impossible. L'appel ne se connecte pas\nau Registre.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/v1/plans": {
      "post": {
        "operationId": "createPlan",
        "tags": [
          "Registre"
        ],
        "summary": "Commander un plan",
        "description": "Portée `registre:write`. En-tête `Idempotency-Key` obligatoire,\nconservé 24 heures.\n\n`lot` est requis. `cadastre` vaut Cadastre du Québec lorsqu'il\nest absent. Un plan cadastral débite 99 cents sur le solde\nFonciq d'une clé réelle. Les frais du Registre de 150 cents\n(1,50 $) s'appliquent seulement lorsque le Registre est consulté.\nUn plan conservé n'entraîne pas de frais du Registre. Les autres\ncadastres échouent de façon fermée. Aucun tirage en direct n'est\npromis.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "lot"
                ],
                "properties": {
                  "lot": {
                    "type": "string",
                    "description": "Numéro de lot."
                  },
                  "cadastre": {
                    "type": "string",
                    "description": "Cadastre. Absent, la valeur est Cadastre du Québec. Un autre cadastre échoue de façon fermée."
                  },
                  "rf_account_id": {
                    "type": "string",
                    "description": "Compte du Registre. Absent, le compte par défaut est utilisé."
                  }
                }
              },
              "example": {
                "lot": "1234567",
                "cadastre": "Cadastre du Québec"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Demande acceptée. La réponse ne contient pas le PDF et ne\npromet pas un tirage en direct. `registry_fee_cents` vaut\n150 lorsque le Registre est consulté, et 0 pour un plan\nconservé.\n",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "document_type",
                    "lot",
                    "cadastre",
                    "registry_fee_cents"
                  ],
                  "properties": {
                    "document_type": {
                      "type": "string",
                      "enum": [
                        "plan"
                      ]
                    },
                    "lot": {
                      "type": "string"
                    },
                    "cadastre": {
                      "type": "string"
                    },
                    "registry_fee_cents": {
                      "type": "integer",
                      "description": "150 cents (1,50 $) lorsque le Registre est consulté.\n0 pour un plan conservé. Fonciq ne prélève pas ce montant.\n"
                    }
                  }
                },
                "example": {
                  "document_type": "plan",
                  "lot": "1234567",
                  "cadastre": "Cadastre du Québec",
                  "registry_fee_cents": 0
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/InvalidRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "409": {
            "description": "Autre cadastre, ou demande impossible. Échec fermé.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorBody"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/v1/jobs/{id}": {
      "get": {
        "operationId": "getJob",
        "tags": [
          "Tâches"
        ],
        "summary": "Lire une tâche",
        "description": "Portée `jobs:read`. État, documents, résultat et capacité du jour\nde chaque compte touché. Il n'existe pas de route séparée pour la\ncapacité : elle est portée par cette réponse.\n\nTant que l'index n'est pas analysé, `result` est nul. Une tâche\nterminée d'un seul lot porte `result.index`. Un lot groupé porte\n`result.indexes`, un bloc par lot. Chaque bloc contient le PDF\n(`pdf_url`), l'adresse des lignes (`entries_url`) et `entries`.\nLe CSV est `GET /v1/jobs/{id}/results`.\n\nPour un compte, `cap` vaut 540 index par jour (heure de Toronto).\n`on_demand_reserve` vaut 180. Les surveillances ne peuvent pas\nprendre cette réserve. `watch_budget_remaining` vaut\nmin(360 − index de surveillance utilisés ce jour-là,\n540 − index utilisés ce jour-là) pour ce compte. `used_today`\ncompte les index réellement envoyés au Registre sur ce compte,\nappels à la demande et surveillances confondus.\n",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Tâche.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Job"
                },
                "example": {
                  "id": "job_01HZX",
                  "status": "queued",
                  "kind": "registre",
                  "result": null,
                  "documents": [],
                  "capacity": [
                    {
                      "account_id": "rfa_exemple",
                      "cap": 540,
                      "on_demand_reserve": 180,
                      "used_today": 12,
                      "watch_budget_remaining": 348,
                      "resets_at": "2026-10-25T04:00:00Z"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/v1/jobs/{id}/results": {
      "get": {
        "operationId": "getJobResults",
        "tags": [
          "Tâches"
        ],
        "summary": "Lire le résultat d'une tâche",
        "description": "Portée `jobs:read`. Lignes d'index de la tâche. JSON par défaut :\n`indexes`, un bloc par lot. Une tâche unitaire a un seul élément.\nUn lot groupé en a un par lot.\n\n`format=csv` ou `Accept: text/csv` aplatit les lignes structurées\nen CSV. `format` l'emporte. Toute autre valeur reçoit `400` et le\ncode `invalid_request`.\n\nColonnes, dans cet ordre : `lot`, `matricule`, `inscription`,\n`date`, `nature`, `parties`, `document_url`, `read_method`,\n`confidence`, `needs_review`, `page_status`. Une rangée par ligne\nstructurée. `parties` est `Rôle: Nom`, joint par `; `.\n`matricule` vient du rôle du MAMH pour ce lot. La cellule est\nvide sinon. `document_url` est le PDF\nd'index, qui fait foi. `confidence` vaut `unscored`.\n`needs_review` est vide sur une ligne structurée, comme `null`\nen JSON. `read_method` et `page_status` sont vides : ces valeurs\nsont prévues. Les radiations, les remarques, `seqnt_prodt`,\n`portal_href` et `raw_text` restent dans le JSON.\n\nTant que `unparsed_retained` vaut `false`, le CSV ne contient que\nles lignes structurées. Les rangées écartées ne sont pas écrites\ncomme des lignes vides.\n",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/ResultFormat"
          }
        ],
        "responses": {
          "200": {
            "description": "Résultat JSON, ou CSV si demandé.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/IndexResults"
                },
                "example": {
                  "indexes": [
                    {
                      "lot": "1234567",
                      "source_document_id": "42",
                      "pdf_url": "https://api.fonciq.ca/v1/documents/42",
                      "entries_url": "https://api.fonciq.ca/v1/documents/42/entries",
                      "parse": {
                        "confidence": "unscored"
                      },
                      "unparsed_retained": false,
                      "entries": [
                        {
                          "lot": "1234567",
                          "source_document_id": "42",
                          "position": 0,
                          "inscription": "21 014 436",
                          "presentation_date": "2024-03-12",
                          "nature": "Vente",
                          "parties": [
                            {
                              "role": "Vendeur",
                              "name": "EXEMPLE, MARIE"
                            }
                          ],
                          "remarks": null,
                          "radiations": [],
                          "read_method": null,
                          "confidence": "unscored",
                          "needs_review": null
                        }
                      ]
                    }
                  ]
                }
              },
              "text/csv": {
                "schema": {
                  "$ref": "#/components/schemas/IndexCsv"
                },
                "example": "lot,matricule,inscription,date,nature,parties,document_url,read_method,confidence,needs_review,page_status\n1234567,,\"21 014 436\",2024-03-12,Vente,\"Vendeur: EXEMPLE, MARIE\",https://api.fonciq.ca/v1/documents/42,,unscored,,\n"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/InvalidRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/v1/documents/{id}": {
      "get": {
        "operationId": "getDocument",
        "tags": [
          "Tâches"
        ],
        "summary": "Lire le PDF d'un document",
        "description": "Portée `jobs:read`. Renvoie le PDF d'un index ou d'un acte\nproduit pour l'organisation. Le corps est `application/pdf`.\nPour un index, ce PDF est toujours renvoyé et il fait foi, que\ndes lignes aient été lues ou non. Une liste de lignes vide ne\nle remplace pas. Les lignes se lisent sur\n`GET /v1/documents/{id}/entries`, sur la tâche et sur la fiche.\n",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Identifiant du PDF. C'est le `source_document_id` d'une ligne,\nou l'identifiant porté par `document_url`.\n",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "PDF.",
            "content": {
              "application/pdf": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/v1/documents/{id}/entries": {
      "get": {
        "operationId": "getDocumentEntries",
        "tags": [
          "Tâches"
        ],
        "summary": "Lire les lignes d'un index",
        "description": "Portée `jobs:read`. Lecture directe des lignes conservées pour\ncet index. Même objet qu'une tâche terminée : `parse`,\n`unparsed_retained` et `entries`. JSON par défaut. `format=csv`\nou `Accept: text/csv` renvoie le CSV. `format` l'emporte. Toute\nautre valeur reçoit `400` et le code `invalid_request`.\n\n`404` lorsque le document n'est pas un index produit pour\nl'organisation. Le PDF de cet index reste la source, même si\n`entries` est vide. `parse.confidence` et la confiance de chaque\nligne valent `unscored`. `needs_review` est nul sur une ligne\nstructurée. `unparsed_retained` vaut `false` et `unparsed` est\nomis. Aucune ligne n'est inventée. Un tirage sans PDF n'a pas\nde lignes.\n",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/ResultFormat"
          }
        ],
        "responses": {
          "200": {
            "description": "Lignes de cet index, en JSON ou en CSV.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/IndexBlock"
                }
              },
              "text/csv": {
                "schema": {
                  "$ref": "#/components/schemas/IndexCsv"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/InvalidRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/v1/batches": {
      "post": {
        "operationId": "createBatch",
        "tags": [
          "Lots groupés"
        ],
        "summary": "Soumettre un lot groupé",
        "description": "Portée `batches:write`. En-tête `Idempotency-Key` obligatoire,\nconservé 24 heures. Au plus 500 lots par requête.\n\nCorps JSON `{ \"lots\": [\"…\"] }` ou CSV `text/csv` avec une colonne\n`lot` ou `matricule`. Un index débite 99 cents par lot sur une\nclé réelle. Ce débit ne figure pas dans\n`GET /v1/billing`.\n\nSans `account_id`, le lot groupé est réparti en parallèle sur les\ncomptes du Registre actifs de l'organisation. Avec `account_id`,\nchaque lot est épinglé à ce compte. Chaque compte conserve son\nplafond de 540 index par jour. Les consultations demandées passent\npar la même file qu'une requête unitaire. Les frais du Registre,\n150 cents, s'appliquent lorsque le Registre est consulté. L'index\nconsulte toujours le Registre. Le Registre facture le titulaire\ndu compte qui a exécuté la consultation.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BatchRequest"
              },
              "example": {
                "lots": [
                  "1234567",
                  "7654321"
                ],
                "documents": [
                  "index"
                ]
              }
            },
            "text/csv": {
              "schema": {
                "type": "string",
                "description": "CSV. Première ligne d'en-tête `lot` ou `matricule`. Au plus 500 lignes de données."
              },
              "example": "lot\n1234567\n7654321\n"
            }
          }
        },
        "responses": {
          "202": {
            "description": "Tâche de lot groupé acceptée.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AcceptedJob"
                },
                "example": {
                  "job_id": "job_batch_01HZX",
                  "account_id": null
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/InvalidRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/v1/watches": {
      "post": {
        "operationId": "createWatch",
        "tags": [
          "Surveillances"
        ],
        "summary": "Créer une surveillance",
        "description": "Portée `watches:write`. En-tête `Idempotency-Key` obligatoire,\nconservé 24 heures.\n\nLe Registre foncier n'offre pas de flux poussé. Une surveillance\nest une revérification planifiée, comparée à un instantané de\nréférence pris à la création. Sans `account_id`, elle est placée\nsur le compte par défaut. Avec `account_id`, elle est épinglée à\nce compte. Elle consomme la capacité quotidienne d'index de ce\ncompte (plafond 540, dont 180 réservés aux appels à la demande).\n\nCréer la surveillance interroge les rôles d'évaluation foncière\ndes municipalités du Québec, l'un des jeux de données publics\nintégrés aux Données Fonciq.\n\n`cadence` vaut `weekly` (défaut) ou `daily`. Créer la surveillance\nne débite rien. Chaque index consulté ensuite est un document et\ndébite\n99 cents sur une clé réelle et 150 cents au Registre, parce que\nl'index consulte toujours le Registre. Les frais du Registre\ns'appliquent lorsque le Registre est consulté. Ce débit de\n99 cents n'est pas renvoyé ici.\n\nPlafond d’organisation : 25 surveillances actives. Au-delà, la\nréponse est `409` et le code `watch_cap_reached`. Il n’y a pas\nde plafond quotidien d’index de surveillance par organisation.\nChaque compte garde le sien. `cadence` est `weekly` ou `daily`,\npas une cadence mensuelle. La pause, la suppression,\nl’historique et le renvoi manuel se font dans le tableau de bord.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/IdempotencyKey"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/WatchRequest"
              },
              "example": {
                "lot": "1234567",
                "cadence": "weekly",
                "url": "https://exemple.com/hooks/fonciq"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Surveillance créée.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Watch"
                },
                "example": {
                  "id": "watch_01HZX",
                  "lot": "1234567",
                  "cadence": "weekly",
                  "account_id": "rfa_exemple",
                  "url": "https://exemple.com/hooks/fonciq",
                  "status": "active"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/InvalidRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/v1/billing": {
      "get": {
        "operationId": "getBilling",
        "tags": [
          "Facturation"
        ],
        "summary": "Lire le journal estimé du Registre par compte",
        "description": "Portée `billing:read`. Frais du Registre foncier imputés à chaque\ncompte connecté, pour une période. Ce n'est pas la facturation de\nplateforme de Fonciq.\n\nAucun relevé du portail n'est lu. `source` vaut `estimate`.\nLes lignes sont le journal Fonciq des tirages. Le compte est\n`id`. La même valeur est répétée dans `account_id`.\n`statement.available` est faux, `statement.balance_cents` est nul\net `statement.source` vaut `unavailable`. Le détail par document\nest dans `GET /v1/billing/usage`.\n",
        "parameters": [
          {
            "name": "rf_account_id",
            "in": "query",
            "required": false,
            "description": "Limite la réponse à un compte. Omis, tous les comptes de\nl'organisation sont renvoyés. `account_id` est accepté comme\nalias du même paramètre.\n",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Journal estimé par compte. Aucun relevé du portail n'est lu.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Billing"
                },
                "example": {
                  "period": {
                    "start": "2026-10-01T04:00:00.000Z",
                    "end": "2026-11-01T04:00:00.000Z",
                    "timezone": "America/Toronto"
                  },
                  "currency": "CAD",
                  "source": "estimate",
                  "source_note": "Aucun relevé du portail n’est lu. Les lignes reprennent le journal fonciq des tirages sur ce compte et sont une estimation. Le relevé du Registre foncier fait foi.",
                  "refreshed_at": "2026-10-24T18:05:00.000Z",
                  "accounts": [
                    {
                      "id": "rfa_exemple",
                      "account_id": "rfa_exemple",
                      "label": "Compte par défaut",
                      "is_default": true,
                      "statement": {
                        "available": false,
                        "balance_cents": null,
                        "as_of": null,
                        "source": "unavailable"
                      },
                      "totals": {
                        "amount_cents": 150,
                        "transaction_count": 1,
                        "mismatch_count": 0
                      }
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/v1/billing/usage": {
      "get": {
        "operationId": "getBillingUsage",
        "tags": [
          "Facturation"
        ],
        "summary": "Lire les documents du journal estimé",
        "description": "Portée `billing:read`. Même périmètre que `GET /v1/billing` : les\nfrais du Registre, par période et par document. Pas les frais de\nplateforme de Fonciq.\n\nAucun relevé du portail n'est lu. `source` vaut `estimate`.\nChaque ligne porte `rf_account_id`, la date (`at`), le type\n(`document_type`), le lot, l'inscription s'il y en a une, le\nmontant en cents (`amount_cents`) et `rf_reference` (nul).\n`reconciliation` vaut `log_only`. La même valeur de compte est\nrépétée dans `account_id`. `mismatches` est vide. Il n'y a pas\nde champ `estimate`. Sur cette estimation, lorsqu'un acte est\nrécupéré, `amount_cents` vaut 150, les frais du Registre (1,50 $).\nUn acte conservé n'a pas de frais du Registre. Ce n'est pas un\nmontant lu sur un écran du portail.\n",
        "parameters": [
          {
            "name": "rf_account_id",
            "in": "query",
            "required": false,
            "description": "Limite la réponse à un compte. Omis, tous les comptes de\nl'organisation sont renvoyés. `account_id` est accepté comme\nalias du même paramètre.\n",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Lignes du journal estimé. Aucun relevé du portail n'est lu.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BillingUsage"
                },
                "example": {
                  "period": {
                    "start": "2026-10-01T04:00:00.000Z",
                    "end": "2026-11-01T04:00:00.000Z",
                    "timezone": "America/Toronto"
                  },
                  "currency": "CAD",
                  "source": "estimate",
                  "source_note": "Aucun relevé du portail n’est lu. Les lignes reprennent le journal fonciq des tirages sur ce compte et sont une estimation. Le relevé du Registre foncier fait foi.",
                  "transactions": [
                    {
                      "id": "rftx_exemple",
                      "rf_account_id": "rfa_exemple",
                      "account_id": "rfa_exemple",
                      "at": "2026-10-24T15:04:00.000Z",
                      "document_type": "acte",
                      "lot": "1234567",
                      "inscription": "21 014 436",
                      "amount_cents": 150,
                      "rf_reference": null,
                      "source": "estimate",
                      "reconciliation": "log_only",
                      "fonciq_request_id": "req_exemple",
                      "fonciq_job_id": "job_exemple"
                    }
                  ],
                  "mismatches": [],
                  "next_cursor": null
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/v1/free/zones-inondables": {
      "get": {
        "operationId": "getFreeFloodZones",
        "tags": [
          "Gratuit"
        ],
        "summary": "Zones inondables au Québec : point, adresse ou lot (gratuit, sans clé)",
        "description": "Gratuit, sans clé. Free, no key. FR : indique si un point, une\nadresse (Référentiel québécois des adresses) ou les points\nd'adresse d'un lot touchent une zone inondable cartographiée parmi\n9 sources ouvertes sous licence CC BY 4.0 (BDZI, grille de présence\npossible, ZIS 2017-2019 à titre historique, Gatineau, Québec, Sherbrooke, Montréal). Cartographie d’ancienne génération : la nouvelle génération n’est pas incluse (champ `cartographie`, avec le lien vers la carte interactive officielle).\nLa limite du lot n'est pas évaluée. Une réponse sans zone se lit\n« Aucune zone trouvée à ce point » : ce n'est pas une attestation\nqu'une propriété est hors zone inondable. EN: tells whether a\npoint, an address or a lot's address points hit a mapped flood\nzone. Lot boundary not evaluated. A no-hit reads \"No zone found at\nthis point\".\n\nExactly one of `lat`+`lon`, `address` or `lot`. Limits: 30\nrequests per minute and 1 000 per 24 h per IP. CORS\n`Access-Control-Allow-Origin: *`. Every 200 carries per-source\nattribution and the disclaimer. Docs:\nhttps://fonciq.ca/api-gratuite/zones-inondables\n",
        "security": [],
        "parameters": [
          {
            "name": "lat",
            "in": "query",
            "required": false,
            "description": "Latitude WGS84, Québec only (44.9 to 62.6). With `lon`.",
            "schema": {
              "type": "number",
              "minimum": 44.9,
              "maximum": 62.6
            },
            "example": 45.40527
          },
          {
            "name": "lon",
            "in": "query",
            "required": false,
            "description": "Longitude WGS84, Québec only (-79.8 to -57.1). With `lat`.",
            "schema": {
              "type": "number",
              "minimum": -79.8,
              "maximum": -57.1
            },
            "example": -75.87624
          },
          {
            "name": "address",
            "in": "query",
            "required": false,
            "description": "Civic address, resolved in the Référentiel québécois des adresses (RQA).",
            "schema": {
              "type": "string",
              "minLength": 3,
              "maxLength": 200
            },
            "example": "148 rue de la Cédrière, Gatineau"
          },
          {
            "name": "lot",
            "in": "query",
            "required": false,
            "description": "Cadastre du Québec lot number; spaces ignored. Answered through the lot's RQA address points.",
            "schema": {
              "type": "string",
              "pattern": "^[0-9 ]{5,12}$"
            },
            "example": "2 883 944"
          },
          {
            "name": "lang",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "fr",
                "en"
              ],
              "default": "fr"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Answer for each evaluated point.",
            "headers": {
              "Access-Control-Allow-Origin": {
                "schema": {
                  "type": "string"
                },
                "description": "Always `*`."
              },
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests allowed per minute (30)."
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "any_zone_found",
                    "lot_boundary_evaluated",
                    "note",
                    "coverage_note",
                    "cartographie",
                    "results",
                    "attribution",
                    "disclaimer"
                  ],
                  "properties": {
                    "api": {
                      "type": "string",
                      "example": "fonciq-free-zones-inondables"
                    },
                    "version": {
                      "type": "string",
                      "example": "1"
                    },
                    "lang": {
                      "type": "string",
                      "enum": [
                        "fr",
                        "en"
                      ]
                    },
                    "query": {
                      "type": "object",
                      "additionalProperties": true
                    },
                    "match": {
                      "type": "object",
                      "properties": {
                        "type": {
                          "type": "string",
                          "enum": [
                            "coordinates",
                            "address",
                            "lot"
                          ]
                        },
                        "quality": {
                          "type": "string",
                          "enum": [
                            "exact",
                            "approximate",
                            "address_points"
                          ]
                        },
                        "other_candidates": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        },
                        "lot": {
                          "type": "string"
                        },
                        "address_points_truncated": {
                          "type": "boolean"
                        }
                      }
                    },
                    "any_zone_found": {
                      "type": "boolean"
                    },
                    "summary_label": {
                      "type": "string",
                      "example": "Zone trouvée à ce point"
                    },
                    "lot_boundary_evaluated": {
                      "type": "boolean",
                      "enum": [
                        false
                      ]
                    },
                    "note": {
                      "type": "string",
                      "description": "« Limite du lot non évaluée » / \"Lot boundary not evaluated\"."
                    },
                    "notes": {
                      "type": "object",
                      "description": "The lot-boundary note in both languages, whatever `lang` is.",
                      "properties": {
                        "fr": {
                          "type": "string"
                        },
                        "en": {
                          "type": "string"
                        }
                      }
                    },
                    "coverage_note": {
                      "type": "string"
                    },
                    "cartographie": {
                      "type": "object",
                      "description": "Which mapping generation the sources represent, with the official map to confirm. New-generation maps (in force by sector since March 1, 2026) are not included.",
                      "required": [
                        "generation_des_sources",
                        "nouvelle_generation_incluse",
                        "carte_officielle_url"
                      ],
                      "properties": {
                        "generation_des_sources": {
                          "type": "string",
                          "enum": [
                            "ancienne_generation"
                          ]
                        },
                        "nouvelle_generation_incluse": {
                          "type": "boolean",
                          "enum": [
                            false
                          ]
                        },
                        "note": {
                          "type": "string"
                        },
                        "notes": {
                          "type": "object",
                          "properties": {
                            "fr": {
                              "type": "string"
                            },
                            "en": {
                              "type": "string"
                            }
                          }
                        },
                        "carte_officielle_url": {
                          "type": "string",
                          "format": "uri",
                          "example": "https://www.quebec.ca/agriculture-environnement-et-ressources-naturelles/eau/zones-inondables-mobilite-rives-littoral/verifier-propriete"
                        },
                        "carte_interactive_url": {
                          "type": "string",
                          "format": "uri",
                          "example": "https://zonesinondables.mrnf.gouv.qc.ca/"
                        }
                      }
                    },
                    "historical_note": {
                      "type": "string",
                      "description": "Present only when a historical layer (the 2017-2019 ZIS, lifted on March 1, 2022) is found at a point."
                    },
                    "results": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "point": {
                            "type": "object",
                            "properties": {
                              "lat": {
                                "type": "number"
                              },
                              "lon": {
                                "type": "number"
                              },
                              "kind": {
                                "type": "string",
                                "enum": [
                                  "query_coordinates",
                                  "rqa_address_point"
                                ]
                              }
                            }
                          },
                          "address": {
                            "type": [
                              "object",
                              "null"
                            ],
                            "properties": {
                              "rqa_id": {
                                "type": "string"
                              },
                              "address": {
                                "type": "string"
                              },
                              "municipality": {
                                "type": [
                                  "string",
                                  "null"
                                ]
                              },
                              "lot_numbers": {
                                "type": "array",
                                "items": {
                                  "type": "string"
                                }
                              },
                              "positioning_quality": {
                                "type": [
                                  "string",
                                  "null"
                                ]
                              }
                            }
                          },
                          "zone_found_at_point": {
                            "type": "boolean"
                          },
                          "status": {
                            "type": "string",
                            "enum": [
                              "zone_found_at_point",
                              "no_zone_found_at_point"
                            ]
                          },
                          "status_label": {
                            "type": "string",
                            "example": "Aucune zone trouvée à ce point"
                          },
                          "fonciq_level": {
                            "type": "string",
                            "enum": [
                              "eleve",
                              "modere",
                              "a_verifier",
                              "no_known_mapped_zone"
                            ],
                            "description": "Fonciq classification, indicative only (not a government class)."
                          },
                          "fonciq_level_label": {
                            "type": "string"
                          },
                          "zones": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "properties": {
                                "source": {
                                  "type": "string",
                                  "example": "municipal_gat"
                                },
                                "source_name": {
                                  "type": "string"
                                },
                                "publisher": {
                                  "type": "string"
                                },
                                "category": {
                                  "type": "string",
                                  "enum": [
                                    "mapped_zone",
                                    "indicative_grid",
                                    "observed_flood_2017_2019",
                                    "reference_layer"
                                  ]
                                },
                                "category_label": {
                                  "type": "string"
                                },
                                "zone_kind": {
                                  "type": "string",
                                  "example": "recurrence_20"
                                },
                                "zone_label": {
                                  "type": "string"
                                },
                                "source_zone_type": {
                                  "type": [
                                    "string",
                                    "null"
                                  ],
                                  "description": "The source's own zone type value."
                                },
                                "dataset_url": {
                                  "type": "string",
                                  "format": "uri"
                                },
                                "licence": {
                                  "type": "string",
                                  "example": "CC-BY-4.0"
                                },
                                "mapping_generation": {
                                  "type": "string",
                                  "enum": [
                                    "ancienne_generation",
                                    "indicatif",
                                    "historique",
                                    "reference"
                                  ]
                                },
                                "historical": {
                                  "type": "boolean",
                                  "description": "True for the 2017-2019 ZIS (lifted in 2022); never rated \"eleve\"."
                                }
                              }
                            }
                          },
                          "nearest_zone": {
                            "type": "object",
                            "description": "Nearest polygon of any source within 5 000 m; `distance_m` is 0 inside a zone, null when none.",
                            "properties": {
                              "distance_m": {
                                "type": [
                                  "integer",
                                  "null"
                                ]
                              },
                              "searched_within_m": {
                                "type": "integer"
                              },
                              "source": {
                                "type": "string"
                              },
                              "zone_kind": {
                                "type": "string"
                              }
                            }
                          },
                          "nearest_mapped_zone": {
                            "type": "object",
                            "description": "Same, limited to mapped zones (BDZI, Gatineau, Québec, Sherbrooke).",
                            "properties": {
                              "distance_m": {
                                "type": [
                                  "integer",
                                  "null"
                                ]
                              },
                              "searched_within_m": {
                                "type": "integer"
                              },
                              "source": {
                                "type": "string"
                              },
                              "zone_kind": {
                                "type": "string"
                              }
                            }
                          }
                        }
                      }
                    },
                    "data_freshness": {
                      "type": "object",
                      "properties": {
                        "oldest_source_checked_at": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "format": "date-time"
                        },
                        "newest_source_checked_at": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "format": "date-time"
                        },
                        "oldest_source_loaded_at": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "format": "date-time"
                        },
                        "newest_source_loaded_at": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "format": "date-time"
                        }
                      }
                    },
                    "attribution": {
                      "type": "object",
                      "properties": {
                        "text": {
                          "type": "string"
                        },
                        "sources": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "source": {
                                "type": "string"
                              },
                              "name": {
                                "type": "string"
                              },
                              "publisher": {
                                "type": "string"
                              },
                              "dataset_url": {
                                "type": "string",
                                "format": "uri"
                              },
                              "licence": {
                                "type": "string",
                                "example": "CC-BY-4.0"
                              },
                              "licence_url": {
                                "type": "string",
                                "format": "uri"
                              },
                              "checked_at": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "format": "date-time"
                              },
                              "loaded_at": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "format": "date-time"
                              }
                            }
                          }
                        }
                      }
                    },
                    "disclaimer": {
                      "type": "string"
                    },
                    "limits": {
                      "type": "object",
                      "properties": {
                        "per_minute": {
                          "type": "integer",
                          "example": 30
                        },
                        "per_day": {
                          "type": "integer",
                          "example": 1000
                        },
                        "key_required": {
                          "type": "boolean",
                          "example": false
                        }
                      }
                    },
                    "docs": {
                      "type": "string",
                      "format": "uri"
                    },
                    "terms": {
                      "type": "string",
                      "format": "uri"
                    },
                    "request_id": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "`invalid_query` or `out_of_coverage` (point outside Québec).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string"
                        },
                        "message": {
                          "type": "string"
                        },
                        "request_id": {
                          "type": "string"
                        },
                        "suggestions": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        }
                      }
                    },
                    "disclaimer": {
                      "type": "string"
                    },
                    "docs": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "`address_not_found` (with `error.suggestions`) or `lot_not_found_in_rqa`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string"
                        },
                        "message": {
                          "type": "string"
                        },
                        "request_id": {
                          "type": "string"
                        },
                        "suggestions": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        }
                      }
                    },
                    "disclaimer": {
                      "type": "string"
                    },
                    "docs": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "`rate_limited`: 30 per minute or 1 000 per 24 h per IP. See `Retry-After`.",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string"
                        },
                        "message": {
                          "type": "string"
                        },
                        "request_id": {
                          "type": "string"
                        },
                        "suggestions": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        }
                      }
                    },
                    "disclaimer": {
                      "type": "string"
                    },
                    "docs": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  },
  "webhooks": {
    "event": {
      "post": {
        "operationId": "webhookEvent",
        "tags": [
          "Surveillances"
        ],
        "summary": "Avis envoyé à l'URL de la surveillance",
        "description": "Fonciq appelle l'URL enregistrée sur la surveillance lorsque l'écart\navec l'instantané de référence n'est pas vide. Un écart vide\nn'envoie rien.\n\nEn-tête `Fonciq-Signature: t=<unix>,v1=<hex>`. `v1` est le\nHMAC-SHA256 de `{t}.{corps brut}` signé avec le secret du point\nde terminaison, montré une seule fois. Le récepteur rejette un\n`t` éloigné de plus de cinq minutes.\n\nTypes : `index.inscription_added`, `acte.added`,\n`cadastre.changed`, `assessment.changed`. `document_url` est nul\npour un changement de cadastre ou d'évaluation sans PDF du\nRegistre.\n\nTentatives : envoi immédiat, puis environ 24 h, 48 h et 72 h\n(quatre essais). L'état passe ensuite à `failed`. Le renvoi manuel,\ndepuis le tableau de bord, est un nouvel essai.\n\nUne relecture humaine des index manuscrits anciens est prévue.\nLorsqu'elle sera offerte, l'avis signé `index.review_completed`\nportera l'identifiant de l'avis, l'identifiant de la tâche et\n`document_url`. Le PDF reste la source. Ce palier n'a pas de\nprix publié et pas de délai publié. Il n'est pas envoyé\naujourd'hui.\n\nL'avis concerne le compte du Registre sur lequel la surveillance\nest placée. Cette vérification a consommé la capacité de ce compte.\n",
        "parameters": [
          {
            "name": "Fonciq-Signature",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string"
            },
            "example": "t=1729785600,v1=ab12"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/WebhookEvent"
              },
              "example": {
                "id": "evt_01HZX",
                "type": "index.inscription_added",
                "account_id": "rfa_exemple",
                "lot": "1234567",
                "change": "Inscription 21 014 436",
                "old": {
                  "inscriptions": []
                },
                "new": {
                  "inscriptions": [
                    "21 014 436"
                  ]
                },
                "document_url": "https://api.fonciq.ca/v1/documents/42"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Le point de terminaison a accepté l'avis."
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "description": "Clé d'API de l'organisation. Le secret n'est montré qu'une fois.\nLe préfixe affichable d'une clé d'essai est `fq_test_`. Le hachage\nSHA-256 est la seule forme conservée. Le panneau d'essai de cette\ndocumentation n'envoie qu'une clé `fq_test_` et n'effectue aucun\ndébit.\n"
      }
    },
    "parameters": {
      "Lot": {
        "name": "lot",
        "in": "path",
        "required": true,
        "description": "Numéro de lot.",
        "schema": {
          "type": "string",
          "examples": [
            "1234567"
          ]
        }
      },
      "ResultFormat": {
        "name": "format",
        "in": "query",
        "required": false,
        "description": "`json` est le défaut. `csv`, ou l'en-tête `Accept: text/csv`\nlorsque `format` est absent, sélectionne le CSV. `format`\nl'emporte lorsque les deux sont envoyés. Toute autre valeur\nreçoit `400` et le code `invalid_request`.\n",
        "schema": {
          "type": "string",
          "enum": [
            "json",
            "csv"
          ],
          "default": "json"
        }
      },
      "IdempotencyKey": {
        "name": "Idempotency-Key",
        "in": "header",
        "required": true,
        "description": "Clé d'idempotence conservée 24 heures. La même clé et le même corps renvoient la réponse enregistrée.",
        "schema": {
          "type": "string",
          "minLength": 8,
          "maxLength": 255
        }
      }
    },
    "responses": {
      "InvalidRequest": {
        "description": "Requête refusée.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorBody"
            },
            "example": {
              "error": {
                "code": "invalid_request",
                "message": "Indiquer une adresse ou un matricule.",
                "request_id": "req_01HZX"
              }
            }
          }
        }
      },
      "Unauthorized": {
        "description": "Clé absente, révoquée ou mal formée.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorBody"
            },
            "example": {
              "error": {
                "code": "unauthorized",
                "message": "Clé d'API refusée.",
                "request_id": "req_01HZX"
              }
            }
          }
        }
      },
      "NotFound": {
        "description": "Ressource ou compte introuvable.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorBody"
            },
            "example": {
              "error": {
                "code": "account_not_found",
                "message": "Ce compte du Registre n'appartient pas à l'organisation.",
                "request_id": "req_01HZX"
              }
            }
          }
        }
      },
      "Conflict": {
        "description": "Conflit. `watch_cap_reached` lorsque l'organisation dépasse\n25 surveillances actives. `account_required` lorsqu'une\nconsultation est demandée sans compte du Registre.\n",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorBody"
            },
            "examples": {
              "watchCap": {
                "value": {
                  "error": {
                    "code": "watch_cap_reached",
                    "message": "Le plafond de surveillances actives est atteint.",
                    "request_id": "req_01HZX"
                  }
                }
              },
              "accountRequired": {
                "value": {
                  "error": {
                    "code": "account_required",
                    "message": "Ajoutez un compte du Registre foncier dans les paramètres de l'API.",
                    "request_id": "req_01HZX"
                  }
                }
              }
            }
          }
        }
      },
      "RateLimited": {
        "description": "Plafond de 60 requêtes par minute pour cette clé.",
        "headers": {
          "Retry-After": {
            "description": "Secondes à attendre avant un nouvel essai.",
            "schema": {
              "type": "integer"
            }
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorBody"
            },
            "example": {
              "error": {
                "code": "rate_limited",
                "message": "Trop de requêtes pour cette clé.",
                "request_id": "req_01HZX"
              }
            }
          }
        }
      }
    },
    "schemas": {
      "ErrorBody": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "error"
        ],
        "properties": {
          "error": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "code",
              "message",
              "request_id"
            ],
            "properties": {
              "code": {
                "type": "string",
                "enum": [
                  "invalid_request",
                  "unauthorized",
                  "forbidden",
                  "not_found",
                  "account_not_found",
                  "account_required",
                  "watch_cap_reached",
                  "rate_limited"
                ]
              },
              "message": {
                "type": "string"
              },
              "request_id": {
                "type": "string"
              }
            }
          }
        }
      },
      "ResolveResponse": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "lots"
        ],
        "properties": {
          "lots": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": false,
              "required": [
                "lot",
                "cadastre",
                "matricule",
                "role_matched"
              ],
              "properties": {
                "lot": {
                  "type": "string"
                },
                "cadastre": {
                  "type": "string"
                },
                "matricule": {
                  "type": "string"
                },
                "role_matched": {
                  "type": "boolean",
                  "description": "Vrai lorsque le rôle d'évaluation du MAMH corrobore le lot."
                }
              }
            }
          }
        }
      },
      "LotProfile": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "lot",
          "cadastre",
          "assessment",
          "registre"
        ],
        "properties": {
          "lot": {
            "type": "string"
          },
          "cadastre": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "label",
              "lot"
            ],
            "properties": {
              "label": {
                "type": "string"
              },
              "lot": {
                "type": "string"
              }
            }
          },
          "assessment": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "year",
              "value_cents"
            ],
            "description": "Évaluation du rôle du MAMH. `value_cents` est un entier en cents CAD.",
            "properties": {
              "year": {
                "type": "integer"
              },
              "value_cents": {
                "type": "integer"
              }
            }
          },
          "registre": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "entries"
            ],
            "description": "Lignes d'index de ce lot.",
            "properties": {
              "entries": {
                "type": "array",
                "description": "Même objet qu'une tâche d'index terminée.",
                "items": {
                  "$ref": "#/components/schemas/IndexLine"
                }
              }
            }
          }
        }
      },
      "RegistreRequest": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "lot",
          "documents"
        ],
        "properties": {
          "lot": {
            "type": "string"
          },
          "documents": {
            "type": "array",
            "minItems": 1,
            "items": {
              "type": "string",
              "enum": [
                "index"
              ]
            }
          },
          "account_id": {
            "type": "string",
            "description": "Compte du Registre à utiliser. Omis, la requête prend le\ncompte par défaut.\n"
          }
        }
      },
      "AcceptedJob": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "job_id"
        ],
        "properties": {
          "job_id": {
            "type": "string"
          },
          "account_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Compte épinglé. Nul lorsqu'un lot groupé est réparti sur\nplusieurs comptes. Le détail figure alors dans `GET /v1/jobs/{id}`.\n"
          }
        }
      },
      "Capacity": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "account_id",
          "cap",
          "on_demand_reserve",
          "used_today",
          "watch_budget_remaining",
          "resets_at"
        ],
        "properties": {
          "account_id": {
            "type": "string"
          },
          "cap": {
            "type": "integer",
            "description": "Plafond d'index pour ce compte, par jour de Toronto. Valeur 540.",
            "examples": [
              540
            ]
          },
          "on_demand_reserve": {
            "type": "integer",
            "description": "Index réservés aux appels à la demande. Les surveillances ne peuvent pas les prendre. Valeur 180.",
            "examples": [
              180
            ]
          },
          "used_today": {
            "type": "integer",
            "description": "Index réellement envoyés au Registre aujourd'hui sur ce compte."
          },
          "watch_budget_remaining": {
            "type": "integer",
            "description": "min(360 − index de surveillance utilisés aujourd'hui,\n540 − used_today) pour ce compte.\n"
          },
          "resets_at": {
            "type": "string",
            "format": "date-time",
            "description": "Minuit, heure de Toronto, en instant UTC."
          }
        }
      },
      "IndexParse": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "confidence"
        ],
        "properties": {
          "confidence": {
            "type": "string",
            "enum": [
              "unscored"
            ],
            "description": "Disponible. Littéral `unscored`. L'analyseur ne note pas une\nligne. Un score numérique est prévu. Laissez `unscored`.\n"
          }
        }
      },
      "IndexParty": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "role",
          "name"
        ],
        "description": "Partie retenue parce que sa qualité a été reconnue. Une qualité\nhors vocabulaire n'est pas émise. Le nom et le rôle manquants\nne sont pas inventés.\n",
        "properties": {
          "role": {
            "type": "string",
            "description": "Qualité imprimée par le Registre, par exemple Vendeur ou Créancier."
          },
          "name": {
            "type": "string"
          }
        }
      },
      "IndexRadiation": {
        "type": "object",
        "additionalProperties": false,
        "description": "Ligne lue dans la colonne Radiations, lorsqu'elle contient un\nlien ou un texte de mention.\n",
        "properties": {
          "inscription": {
            "type": [
              "string",
              "null"
            ],
            "description": "Numéro d'inscription de l'acte radiant, lorsqu'il a été lu."
          },
          "mention": {
            "type": [
              "string",
              "null"
            ],
            "description": "Indicateur imprimé à côté de la radiation, par exemple T, P ou R."
          },
          "raw_text": {
            "type": [
              "string",
              "null"
            ],
            "description": "Texte de la cellule conservé par l'analyseur."
          }
        }
      },
      "IndexLine": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "source_document_id",
          "position",
          "inscription",
          "confidence",
          "needs_review"
        ],
        "description": "Ligne d'index structurée et conservée. L'analyseur exige un\nlien d'acte, un numéro d'inscription et une date de présentation.\nLes lignes qui n'ont pas ces trois éléments sont écartées.\n",
        "properties": {
          "lot": {
            "type": "string",
            "description": "Lot de la consultation. Il vient du tirage, pas de l'analyse\nde la rangée. Répété sur chaque ligne afin qu'un lot groupé\ngarde une seule forme.\n"
          },
          "source_document_id": {
            "type": "string",
            "description": "Identifiant du PDF d'index source. Ce n'est pas une colonne\ndu tableau HTML. `GET /v1/documents/{id}` renvoie ce PDF.\n"
          },
          "position": {
            "type": "integer",
            "description": "Ordre de la ligne dans l'index."
          },
          "inscription": {
            "type": "string",
            "description": "Numéro d'inscription, espaces conservés."
          },
          "presentation_date": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "description": "Date de présentation, `YYYY-MM-DD`."
          },
          "nature": {
            "type": [
              "string",
              "null"
            ],
            "description": "Nature de l'acte. Libellé connu, sinon le texte de la\ncellule lorsqu'il ne commence pas par une qualité de partie\net qu'il ne dépasse pas 200 caractères. Nulle si la colonne\nn'a pas été lue.\n"
          },
          "parties": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/IndexParty"
            }
          },
          "remarks": {
            "type": [
              "string",
              "null"
            ],
            "description": "Texte de la colonne Remarques, lorsqu'il est présent. Montant,\nréférence ou autre texte libre. Nul si la cellule est vide.\n"
          },
          "radiations": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/IndexRadiation"
            }
          },
          "seqnt_prodt": {
            "type": [
              "string",
              "null"
            ],
            "description": "Identifiant stable de l'acte lu sur le lien (`NO_SEQNT_PRODT`)."
          },
          "portal_href": {
            "type": [
              "string",
              "null"
            ],
            "description": "Lien du portail conservé par l'analyseur. Ce n'est pas l'URL\ndu PDF Fonciq. Le PDF se lit avec `pdf_url` ou\n`GET /v1/documents/{id}`.\n"
          },
          "raw_text": {
            "type": [
              "string",
              "null"
            ],
            "description": "Texte brut de la rangée, tronqué à 500 caractères par l'analyseur."
          },
          "read_method": {
            "type": [
              "string",
              "null"
            ],
            "enum": [
              "text_layer",
              "ocr_print",
              "handwriting",
              null
            ],
            "description": "Prévu. Nul aujourd'hui. L'analyseur lit le tableau HTML et\nn'enregistre pas `text_layer`, `ocr_print` ni `handwriting`.\nNe pas déduire une de ces valeurs.\n"
          },
          "confidence": {
            "type": "string",
            "enum": [
              "unscored"
            ],
            "description": "Disponible. Littéral `unscored`. L'analyseur ne produit pas\nde score. Laissez cette valeur.\n"
          },
          "needs_review": {
            "type": [
              "boolean",
              "null"
            ],
            "description": "Nul sur une ligne structurée. Aucun seuil de relecture n'est\npublié. `unscored` n'est pas sous un seuil. Lorsqu'un seuil\nsera écrit ici, une ligne dont la confiance est un score réel\ninférieur à ce seuil aura `needs_review` vrai.\n"
          }
        }
      },
      "IndexPage": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "status"
        ],
        "description": "Prévu. Omis tant que les pages ne sont pas qualifiées. Omettre\n`pages` ne signifie pas que le PDF a été entièrement lu. Ne pas\nenvoyer `parsed` tant que des rangées sont encore écartées.\n",
        "properties": {
          "page": {
            "type": [
              "integer",
              "null"
            ],
            "description": "Numéro de page dans le PDF, à partir de 1. Nul tant qu'il n'est pas enregistré."
          },
          "status": {
            "type": "string",
            "enum": [
              "parsed",
              "partial",
              "unreadable"
            ],
            "description": "`parsed` : chaque rangée d'inscription de la page est devenue\nune ligne. `partial` : au moins une ligne et au moins une\nrangée non structurée. `unreadable` : la page n'a pas pu être\nlue. Sa liste de lignes est vide. Le PDF est quand même\nrenvoyé. Aucune ligne n'est inventée.\n"
          },
          "needs_review": {
            "type": "boolean",
            "description": "Vrai pour une page `unreadable`."
          }
        }
      },
      "IndexUnparsedLine": {
        "type": "object",
        "additionalProperties": false,
        "description": "Prévu. L'analyseur écarte encore une rangée sans date ou sans\nnuméro d'inscription, et il ne la renvoie pas. Lorsque ce sera\nle cas, chaque rangée écartée portera le texte brut, la page,\net `needs_review` vrai.\n",
        "required": [
          "reason",
          "raw_text",
          "needs_review"
        ],
        "properties": {
          "position": {
            "type": "integer"
          },
          "raw_text": {
            "type": "string",
            "description": "Texte brut de la rangée écartée, pas une ligne reconstruite."
          },
          "page": {
            "type": [
              "integer",
              "null"
            ],
            "description": "Prévu. Nul tant qu'un numéro de page n'est pas enregistré.\nL'analyseur n'a pas de numéro de page.\n"
          },
          "needs_review": {
            "type": "boolean",
            "const": true,
            "description": "Toujours vrai. La rangée n'est pas devenue une ligne."
          },
          "reason": {
            "type": "string",
            "enum": [
              "no_acte_link",
              "missing_date_or_inscription"
            ],
            "description": "`no_acte_link` : pas de lien d'acte. `missing_date_or_inscription` :\nla date ou le numéro d'inscription manque.\n"
          }
        }
      },
      "IndexBlock": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "source_document_id",
          "pdf_url",
          "parse",
          "unparsed_retained",
          "entries"
        ],
        "properties": {
          "lot": {
            "type": "string"
          },
          "source_document_id": {
            "type": "string"
          },
          "pdf_url": {
            "type": "string",
            "format": "uri",
            "description": "PDF d'index, toujours présent. Il fait foi, que `entries`\nsoit vide ou non. `GET /v1/documents/{id}`.\n"
          },
          "entries_url": {
            "type": "string",
            "format": "uri",
            "description": "Lignes de cet index. `GET /v1/documents/{id}/entries`."
          },
          "parse": {
            "$ref": "#/components/schemas/IndexParse"
          },
          "unparsed_retained": {
            "type": "boolean",
            "description": "Faux aujourd'hui. L'analyseur écarte les rangées sans date\nou sans inscription et ne les conserve pas. `unparsed` est\nalors omis. Ce n'est pas disponible. Lorsqu'il deviendra\nvrai, chaque rangée écartée sera dans `unparsed`, avec le\ntexte brut, la page, et `needs_review` vrai.\n"
          },
          "unparsed": {
            "type": "array",
            "description": "Prévu. Présent seulement lorsque `unparsed_retained` vaut\n`true`. Ne pas envoyer un tableau vide tant que le drapeau\nest faux.\n",
            "items": {
              "$ref": "#/components/schemas/IndexUnparsedLine"
            }
          },
          "pages": {
            "type": "array",
            "description": "Prévu. Omis aujourd'hui. Une page `unreadable` n'ajoute\naucune ligne à `entries`. Son `needs_review` vaut vrai.\nAucune ligne n'est inventée. Le PDF reste renvoyé.\n",
            "items": {
              "$ref": "#/components/schemas/IndexPage"
            }
          },
          "entries": {
            "type": "array",
            "description": "Lignes structurées et conservées.",
            "items": {
              "$ref": "#/components/schemas/IndexLine"
            }
          }
        }
      },
      "IndexResults": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "indexes"
        ],
        "properties": {
          "indexes": {
            "type": "array",
            "description": "Un bloc par lot. Une tâche unitaire a un seul élément.",
            "items": {
              "$ref": "#/components/schemas/IndexBlock"
            }
          },
          "documents": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": false,
              "required": [
                "id",
                "type",
                "url"
              ],
              "properties": {
                "id": {
                  "type": "string"
                },
                "type": {
                  "type": "string",
                  "enum": [
                    "index",
                    "acte"
                  ]
                },
                "url": {
                  "type": "string",
                  "format": "uri"
                }
              }
            }
          }
        }
      },
      "IndexCsv": {
        "type": "string",
        "description": "CSV RFC 4180. En-tête, dans cet ordre :\n`lot,matricule,inscription,date,nature,parties,document_url,read_method,confidence,needs_review,page_status`.\nUne rangée par ligne structurée.         `confidence` vaut `unscored`. `needs_review` est vide sur une\nligne structurée. `read_method` et `page_status` sont vides :\nprévus. Tant que\n`unparsed_retained` vaut `false`, les rangées écartées\nn'apparaissent pas.\n"
      },
      "JobIndexResult": {
        "type": "object",
        "additionalProperties": false,
        "description": "Présent une fois l'index analysé. `index` pour un seul lot.\n`indexes` pour un lot groupé.\n",
        "properties": {
          "index": {
            "$ref": "#/components/schemas/IndexBlock"
          },
          "indexes": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/IndexBlock"
            }
          }
        }
      },
      "JobDocument": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "lot",
          "kind",
          "document_url",
          "registry_fee_cents"
        ],
        "properties": {
          "lot": {
            "type": "string"
          },
          "kind": {
            "type": "string",
            "enum": [
              "index",
              "acte"
            ]
          },
          "document_url": {
            "type": [
              "string",
              "null"
            ],
            "description": "URL du PDF (`GET /v1/documents/{id}`). Nulle lorsqu'il n'y a\npas de PDF. La portée `jobs:read` est exigée pour le lire.\n"
          },
          "registry_fee_cents": {
            "type": "integer",
            "description": "Frais de registre journalisé, en cents CAD. Facturé par le\nRegistre au titulaire du compte, pas par Fonciq.\n"
          }
        }
      },
      "Job": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "id",
          "status",
          "kind",
          "documents",
          "capacity"
        ],
        "properties": {
          "id": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "enum": [
              "queued",
              "capacity_wait",
              "running",
              "succeeded",
              "failed"
            ]
          },
          "kind": {
            "type": "string",
            "enum": [
              "registre",
              "batch"
            ]
          },
          "result": {
            "description": "Nul tant que l'index n'est pas analysé. Ensuite, `index`\npour un seul lot et `indexes` pour un lot groupé.\n",
            "oneOf": [
              {
                "type": "null"
              },
              {
                "$ref": "#/components/schemas/JobIndexResult"
              }
            ]
          },
          "documents": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/JobDocument"
            }
          },
          "capacity": {
            "type": "array",
            "description": "Capacité du jour pour chaque compte touché par la tâche.",
            "items": {
              "$ref": "#/components/schemas/Capacity"
            }
          }
        }
      },
      "BatchRequest": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "lots"
        ],
        "properties": {
          "lots": {
            "type": "array",
            "minItems": 1,
            "maxItems": 500,
            "items": {
              "type": "string"
            }
          },
          "documents": {
            "type": "array",
            "description": "Omis, aucun document n'est commandé au Registre.",
            "items": {
              "type": "string",
              "enum": [
                "index",
                "actes"
              ]
            }
          },
          "account_id": {
            "type": "string",
            "description": "Présent, tout le lot groupé est épinglé à ce compte. Omis, le\ntravail est réparti en parallèle sur les comptes actifs.\n"
          }
        }
      },
      "WatchRequest": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "lot",
          "url"
        ],
        "properties": {
          "lot": {
            "type": "string"
          },
          "cadence": {
            "type": "string",
            "enum": [
              "weekly",
              "daily"
            ],
            "default": "weekly",
            "description": "`weekly` est le défaut. `daily` est l'option plus fréquente.\nLe prix de plateforme Fonciq n'est pas renvoyé par l'API de\nfacturation.\n"
          },
          "url": {
            "type": "string",
            "format": "uri",
            "description": "URL qui recevra les avis signés."
          },
          "account_id": {
            "type": "string",
            "description": "Compte du Registre dont la surveillance consommera la capacité. Omis, le compte par défaut est utilisé."
          }
        }
      },
      "Watch": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "id",
          "lot",
          "cadence",
          "account_id",
          "url",
          "status"
        ],
        "properties": {
          "id": {
            "type": "string"
          },
          "lot": {
            "type": "string"
          },
          "cadence": {
            "type": "string",
            "enum": [
              "weekly",
              "daily"
            ]
          },
          "account_id": {
            "type": "string"
          },
          "url": {
            "type": "string",
            "format": "uri"
          },
          "status": {
            "type": "string",
            "enum": [
              "active",
              "paused"
            ]
          }
        }
      },
      "BillingPeriod": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "start",
          "end",
          "timezone"
        ],
        "properties": {
          "start": {
            "type": "string",
            "format": "date-time"
          },
          "end": {
            "type": "string",
            "format": "date-time"
          },
          "timezone": {
            "type": "string",
            "const": "America/Toronto"
          }
        }
      },
      "BillingStatement": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "available",
          "balance_cents",
          "as_of",
          "source"
        ],
        "description": "Aucun relevé du portail n'est lu. `available` est faux,\n`balance_cents` est nul et `source` vaut `unavailable`.\n",
        "properties": {
          "available": {
            "type": "boolean",
            "const": false
          },
          "balance_cents": {
            "type": "null"
          },
          "as_of": {
            "type": "null"
          },
          "source": {
            "type": "string",
            "const": "unavailable"
          }
        }
      },
      "BillingAccount": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "id",
          "label",
          "is_default",
          "statement",
          "totals"
        ],
        "properties": {
          "id": {
            "type": "string",
            "description": "Identifiant public du compte (`rfa_…`)."
          },
          "account_id": {
            "type": "string",
            "description": "Même valeur que `id`. Le paramètre de requête canonique est\n`rf_account_id`. `account_id` est l'alias accepté sur la requête.\n"
          },
          "label": {
            "type": "string"
          },
          "is_default": {
            "type": "boolean"
          },
          "statement": {
            "$ref": "#/components/schemas/BillingStatement"
          },
          "totals": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "amount_cents",
              "transaction_count",
              "mismatch_count"
            ],
            "properties": {
              "amount_cents": {
                "type": "integer",
                "description": "Somme des lignes du journal pour lesquelles le Registre\nest consulté. 150 cents par consultation, soit le tarif\nde 1,50 $, et non un montant lu sur un écran.\n"
              },
              "transaction_count": {
                "type": "integer"
              },
              "mismatch_count": {
                "type": "integer",
                "description": "Zéro. Aucun relevé du portail n'est rapproché."
              }
            }
          }
        }
      },
      "Billing": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "period",
          "currency",
          "source",
          "source_note",
          "accounts"
        ],
        "properties": {
          "period": {
            "$ref": "#/components/schemas/BillingPeriod"
          },
          "currency": {
            "type": "string",
            "const": "CAD"
          },
          "source": {
            "type": "string",
            "const": "estimate",
            "description": "Le journal Fonciq des tirages. Aucun relevé du portail n'est lu.\n"
          },
          "source_note": {
            "type": "string"
          },
          "refreshed_at": {
            "type": "string",
            "format": "date-time"
          },
          "accounts": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/BillingAccount"
            }
          }
        }
      },
      "RegistryDocumentCharge": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "id",
          "rf_account_id",
          "at",
          "document_type",
          "amount_cents",
          "rf_reference",
          "source",
          "reconciliation"
        ],
        "properties": {
          "id": {
            "type": "string"
          },
          "rf_account_id": {
            "type": "string",
            "description": "Compte du Registre (`rfa_…`) auquel la ligne est imputée."
          },
          "account_id": {
            "type": "string",
            "description": "Même valeur que `rf_account_id`."
          },
          "at": {
            "type": "string",
            "format": "date-time",
            "description": "Date de l'imputation dans le journal."
          },
          "document_type": {
            "type": "string",
            "enum": [
              "index",
              "acte"
            ]
          },
          "lot": {
            "type": [
              "string",
              "null"
            ]
          },
          "inscription": {
            "type": [
              "string",
              "null"
            ],
            "description": "Numéro d'inscription lorsque le document en a un. Nul pour un index sans inscription associée."
          },
          "amount_cents": {
            "type": "integer",
            "description": "Montant inscrit au journal pour ce document, en cents CAD.\nSur `source` égal à `estimate`, 150 cents (1,50 $) lorsque\nl'acte est récupéré. Un acte conservé n'a pas de frais du\nRegistre. Ce n'est pas un montant lu sur un écran.\n"
          },
          "rf_reference": {
            "type": "null",
            "description": "Nul. Aucun relevé du portail n'est lu."
          },
          "source": {
            "type": "string",
            "const": "estimate"
          },
          "reconciliation": {
            "type": "string",
            "const": "log_only",
            "description": "La ligne n'est pas rapprochée d'un relevé du portail."
          },
          "fonciq_request_id": {
            "type": [
              "string",
              "null"
            ]
          },
          "fonciq_job_id": {
            "type": [
              "string",
              "null"
            ]
          }
        }
      },
      "BillingUsage": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "period",
          "currency",
          "source",
          "source_note",
          "transactions",
          "mismatches"
        ],
        "properties": {
          "period": {
            "$ref": "#/components/schemas/BillingPeriod"
          },
          "currency": {
            "type": "string",
            "const": "CAD"
          },
          "source": {
            "type": "string",
            "const": "estimate"
          },
          "source_note": {
            "type": "string"
          },
          "transactions": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/RegistryDocumentCharge"
            }
          },
          "mismatches": {
            "type": "array",
            "maxItems": 0,
            "items": {
              "$ref": "#/components/schemas/RegistryDocumentCharge"
            },
            "description": "Tableau vide. Aucun relevé du portail n'est lu."
          },
          "next_cursor": {
            "type": [
              "string",
              "null"
            ]
          }
        }
      },
      "WebhookEvent": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "id",
          "type",
          "account_id",
          "lot",
          "change",
          "old",
          "new",
          "document_url"
        ],
        "properties": {
          "id": {
            "type": "string"
          },
          "type": {
            "type": "string",
            "enum": [
              "index.inscription_added",
              "acte.added",
              "cadastre.changed",
              "assessment.changed"
            ]
          },
          "account_id": {
            "type": "string",
            "description": "Compte du Registre dont la capacité a été consommée."
          },
          "lot": {
            "type": "string"
          },
          "change": {
            "type": "string"
          },
          "old": {
            "type": "object",
            "description": "Champs de l'instantané précédent qui ont changé.",
            "additionalProperties": true
          },
          "new": {
            "type": "object",
            "description": "Champs observés après la vérification.",
            "additionalProperties": true
          },
          "document_url": {
            "type": [
              "string",
              "null"
            ],
            "description": "URL du PDF (`GET /v1/documents/{id}`), ou nul pour un changement\nde cadastre ou d'évaluation sans document du Registre.\n"
          }
        }
      }
    }
  }
}
