Importer une copropriété

Pour enregistrer une copropriété, son adresse suffit. En trois appels, vous obtenez la référence de la finca, tous ses logements, locaux, garages et caves (avec usage, surface, quote-part, escalier, étage et porte) et le détail de n'importe quel logement. Les réponses de ce guide sont réelles, issues de la production.

1. De l'adresse à la finca

GET /v1/search/address/candidates reçoit l'adresse en texte libre (rue et numéro, commune et, si vous l'avez, code postal) et renvoie les entrées d'immeuble correspondantes, classées par confiance, chacune avec sa référence cadastrale de 14 caractères. Ne dépend pas du Catastro : géocode avec CartoCiudad (IGN) et complète avec notre copie du Catastro. Accepte aussi les champs séparés : street, number, municipality et postcode.

curl -G "https://api.parcelgps.com/v1/search/address/candidates" \
  --data-urlencode "q=Avenida José Rodríguez de la Borbolla Camoyán 10, Dos Hermanas" \
  --data-urlencode "limit=3" \
  -H "X-API-Key: $CATASTROGPS_API_KEY"

Réponse réelle

200 OK
{
  "success": true,
  "data": {
    "query": {
      "text": "Avenida José Rodríguez de la Borbolla Camoyán 10, Dos Hermanas",
      "street": "Avenida José Rodríguez de la Borbolla Camoyán",
      "number": 10,
      "municipality": "Dos Hermanas"
    },
    "candidates": [
      {
        "reference": "0745901TG4304N",
        "country": "ES",
        "address": "AVENIDA JOSE RGUEZ BORBOLLA CAMOY 10",
        "number": 10,
        "postalCode": "41704",
        "municipality": "Dos Hermanas",
        "region": "Sevilla",
        "latitude": 37.31947088654626,
        "longitude": -5.926788955974699,
        "confidence": 0.93,
        "numberMatches": true,
        "municipalityMatches": true,
        "inOwnCopy": true,
        "cadastreAddress": "AV JOSE RGUEZ BORBOLLA CAMOY 10",
        "use": "Residencial",
        "dwellings": 346,
        "yearBuilt": 2023
      },
      {
        "reference": "0747201TG4304N",
        "country": "ES",
        "address": "BULEVAR JOSE RODRIGUEZ DE LA BORBOLLA CAMOYAN 11",
        "number": 11,
        "confidence": 0.55,
        "numberMatches": false,
        "municipalityMatches": true,
        "inOwnCopy": true
      }
    ],
    "attribution": "CartoCiudad (Instituto Geográfico Nacional) y Dirección General del Catastro"
  },
  "remainingSearches": 2894
}
  • Avec une confiance de 0,75 ou plus, le numéro et la commune correspondent : vous pouvez importer sans demander. En dessous, montrez les candidats à l'utilisateur pour qu'il choisisse.
  • Au Pays basque et en Navarre, le candidat arrive avec country PV ou NA et la référence forale : l'étape 2 l'accepte avec country=PV ou NA et liste les lots depuis la copie de son cadastre foral, sans quote-part (les données ouvertes forales ne la publient pas).

2. Tous les lots de la finca

GET /v1/parcels/:reference14/units renvoie les lots par pages de 200 maximum, triés par référence. Tant que truncated vaut true, refaites l'appel avec cursor égal à nextCursor. propertyUnitCount indique dès la première page combien il y en a au total.

curl -i "https://api.parcelgps.com/v1/parcels/0745901TG4304N/units" \
  -H "X-API-Key: $CATASTROGPS_API_KEY"

curl -i "https://api.parcelgps.com/v1/parcels/0745901TG4304N/units?cursor=0745901TG4304N0201MZ" \
  -H "X-API-Key: $CATASTROGPS_API_KEY"

Réponse réelle

200 OK
HTTP/2 200
etag: "5ab6bd3d95f85dddba81818bcb0cb65e"
cache-control: private, max-age=21600
x-quota-remaining: 2893

{
  "success": true,
  "data": {
    "reference": "0745901TG4304N",
    "address": "AV JOSE RGUEZ BORBOLLA CAMOY 10",
    "postalCode": "41704",
    "municipality": "DOS HERMANAS",
    "region": "Sevilla",
    "mainUse": "Residencial",
    "totalArea": 32789,
    "yearBuilt": 2023,
    "unitCount": 200,
    "propertyUnitCount": 365,
    "units": [
      {
        "reference": "0745901TG4304N0002KH",
        "staircase": "",
        "floor": "01",
        "door": "B",
        "use": "Residencial",
        "area": 155,
        "description": "Planta 01, Pta. B - Residencial",
        "ownershipShare": 0.279543,
        "yearBuilt": 2023,
        "address": "AV JOSE RGUEZ BORBOLLA CAMOY 10 Pl:01 Pt:B"
      },
      {
        "reference": "0745901TG4304N0003LJ",
        "staircase": "",
        "floor": "01",
        "door": "C",
        "use": "Residencial",
        "area": 163,
        "description": "Planta 01, Pta. C - Residencial",
        "ownershipShare": 0.293879,
        "yearBuilt": 2023,
        "address": "AV JOSE RGUEZ BORBOLLA CAMOY 10 Pl:01 Pt:C"
      }
    ],
    "truncated": true,
    "nextCursor": "0745901TG4304N0201MZ",
    "dataSource": "clone",
    "dataDate": "2026-01-23",
    "attribution": "Dirección General del Catastro"
  },
  "remainingSearches": 2893
}
  • Une finca de 365 lots, c'est deux appels : 200 et 165. Le curseur est stable, vous pouvez donc reprendre une importation interrompue.
  • Par lot : reference (20 caractères), use, area (m²), ownershipShare (quote-part en %, nombre en pleine précision), staircase, floor, door, année et adresse.
  • dataSource clone signifie que les données viennent de notre copie du Catastro, sans dépendre de sa disponibilité ; dataDate est la publication du Catastro dont proviennent les lignes. Si une finca n'est pas dans la copie, le Catastro est interrogé en direct (dataSource catastro).

3. Le détail d'un logement

GET /v1/parcels/:reference20 renvoie un logement précis avec les mêmes champs que la liste, plus les coordonnées, le contour et la surface de la parcelle.

curl "https://api.parcelgps.com/v1/parcels/0745901TG4304N0002KH" \
  -H "X-API-Key: $CATASTROGPS_API_KEY"

Réponse réelle

200 OK
{
  "success": true,
  "data": {
    "reference": "0745901TG4304N0002KH",
    "country": "ES",
    "address": "AV JOSE RGUEZ BORBOLLA CAMOY 10 Pl:01 Pt:B",
    "postalCode": "41704",
    "municipality": "DOS HERMANAS",
    "region": "Sevilla",
    "latitude": 37.3194709,
    "longitude": -5.926789,
    "use": "Residencial",
    "landClass": "Urbano",
    "builtArea": 155,
    "parcelArea": 7320,
    "yearBuilt": 2023,
    "ownershipShare": 0.279543,
    "floor": "01",
    "door": "B",
    "fromOwnCopy": true
  },
  "remainingSearches": 2892
}
  • ownershipShare, staircase, floor et door portent le même nom que dans la liste. builtArea correspond ici à area dans la liste.

Réimporter sans consommer de quota

Chaque page de lots et chaque recherche d'adresse portent un ETag. Enregistrez l'ETag de chaque page et envoyez-le dans If-None-Match la fois suivante : si rien n'a changé, la réponse est un 304 sans corps qui ne consomme pas de quota.

curl -i "https://api.parcelgps.com/v1/parcels/0745901TG4304N/units" \
  -H "X-API-Key: $CATASTROGPS_API_KEY" \
  -H 'If-None-Match: "5ab6bd3d95f85dddba81818bcb0cb65e"'

HTTP/2 304
x-quota-remaining: 2929

Le flux complet, avec pagination, nouvelles tentatives et ETag

Relance les 429 et 503 qui portent Retry-After, lève les autres erreurs avec leur code et réutilise les pages qui n'ont pas changé.

const BASE = "https://api.parcelgps.com/v1";
const KEY = process.env.CATASTROGPS_API_KEY;

async function call(path, etag) {
  for (let attempt = 0; attempt < 5; attempt++) {
    const headers = { "X-API-Key": KEY };
    if (etag) headers["If-None-Match"] = etag;
    const res = await fetch(BASE + path, { headers });
    if (res.status === 304) return { data: null, etag };
    const retryAfter = res.headers.get("Retry-After");
    if ((res.status === 429 || res.status === 503) && retryAfter) {
      await new Promise((resolve) => setTimeout(resolve, Number(retryAfter) * 1000));
      continue;
    }
    const body = await res.json();
    if (!res.ok) throw new Error(`${res.status} ${body.code}: ${body.message}`);
    return { data: body.data, etag: res.headers.get("ETag") };
  }
  throw new Error("retries exhausted");
}

export async function findBuilding(address) {
  const { data } = await call("/search/address/candidates?q=" + encodeURIComponent(address));
  const best = data.candidates[0];
  if (best.confidence < 0.75) throw new Error("Ambiguous address: ask the user to pick a candidate");
  return best.reference;
}

export async function importUnits(reference14, pages = new Map()) {
  const units = [];
  let cursor = "";
  for (;;) {
    const cached = pages.get(cursor);
    const query = cursor ? "?cursor=" + cursor : "";
    const { data, etag } = await call(`/parcels/${reference14}/units${query}`, cached?.etag);
    const page = data ?? cached.data;
    pages.set(cursor, { etag, data: page });
    units.push(...page.units);
    if (!page.truncated) return { units, pages };
    cursor = page.nextCursor;
  }
}

const reference14 = await findBuilding("Avenida José Rodríguez de la Borbolla Camoyán 10, Dos Hermanas");
const { units, pages } = await importUnits(reference14);
console.log(reference14, units.length);

Combien ça coûte

AppelUnités de quota
GET /v1/search/address/candidates1 par recherche avec résultats.
GET /v1/parcels/:reference14/units1 par lot de la page (minimum 1). Une page de 200 coûte 200.
GET /v1/parcels/:reference1 par logement.
304 / 4xx / 5xxGratuit : ni un 304 ni une erreur ne consomment de quota.

Exemple : une copropriété de 365 lots coûte 1 (adresse) + 200 + 165 (deux pages) = 366 unités. La réimporter sans changement coûte 0.

Erreurs

HTTPCodeCe que cela signifie et que faire
304-Rien n'a changé depuis votre ETag. Utilisez ce que vous aviez. Gratuit.
400VALIDATION_ERRORParamètres mal formés (adresse vide, code postal sans 5 chiffres, curseur d'une autre finca). Corrigez la requête.
401KEY_AUTH_001 / 002 / 003La clé API est absente ou invalide.
404NOT_FOUNDL'adresse ou la référence n'existe pas. Jamais utilisé pour les pannes du Catastro.
429KEY_RATE_002Vous avez dépassé le nombre de requêtes par minute de votre clé. Attendez les secondes indiquées par Retry-After.
429KEY_AUTH_004Quota et solde épuisés (voir X-Quota-Remaining et X-Quota-Reset) : rechargez depuis le portail ou attendez la réinitialisation du 1er.
503SERVICE_UNAVAILABLELa source officielle (Catastro ou CartoCiudad) est en panne ou saturée et notre copie n'a pas la donnée. Réessayez après Retry-After. Gratuit.
{
  "success": false,
  "code": "NOT_FOUND",
  "message": "No building entrance (portal) with a cadastral reference matches that address. Include the street number and the municipality."
}

Référence complète

Tous les endpoints, champs et codes figurent dans la spécification OpenAPI 3.1, que vous pouvez importer dans Postman, Insomnia ou un générateur de clients : https://api.parcelgps.com/v1/openapi.json