DeepCity API Publique

API publique pour récupérer toutes les données d'un bien immobilier à partir de son identifiant de parcelle cadastrale.

Base URL : https://api.deepcity.fr/v1

Authentification : Aucune authentification requise - API publique et gratuite

Endpoints

Recherche par parcelle

Récupérez toutes les données d'un bien à partir de l'identifiant de parcelle cadastrale.

GET /v1/properties?parcel_id={parcel_id}&include={include}

Paramètres de requête

ParamètreTypeRequisDescription
parcel_idstringOuiIdentifiant de parcelle cadastrale (ex: 75101000AB0001)
includestring[]NonTypes de données à inclure. Valeurs possibles : transactions, energy, occupation, proprio, copro, permis, fonds_de_commerce, urbanisme. Note : cadastral, building et addresses sont toujours retournés.

Exemples de requêtes

Avec tous les paramètres :

curl -X GET "https://api.deepcity.fr/v1/properties?parcel_id=75101000AB0001&include=transactions,energy,occupation,proprio,copro,permis,fonds_de_commerce,urbanisme"

Sans paramètre include (retourne toutes les données) :

curl -X GET "https://api.deepcity.fr/v1/properties?parcel_id=75101000AB0001"

Avec seulement les transactions :

curl -X GET "https://api.deepcity.fr/v1/properties?parcel_id=75101000AB0001&include=transactions"

Note importante : Même avec include=transactions, vous recevrez toujours cadastral, buildings (avec addresses) en plus de transactions.

Exemple Python

import requests

# Recherche par parcelle avec tous les types de données
response = requests.get(
    "https://api.deepcity.fr/v1/properties",
    params={
        "parcel_id": "75101000AB0001",
        "include": ["transactions", "energy", "occupation", "proprio", "copro", "permis", "fonds_de_commerce", "urbanisme"]
    }
)

data = response.json()
print(f"Found {len(data['properties'])} properties")

# Vérifier le statut
if response.status_code == 200:
    properties = data['properties']
    if len(properties) > 0:
        property_data = properties[0]
        if property_data.get('cadastral'):
            print(f"Parcelle: {property_data['cadastral']['id']}")
        if property_data.get('buildings'):
            print(f"Bâtiments: {len(property_data['buildings'])}")
        if property_data.get('transactions'):
            print(f"Transactions: {len(property_data['transactions'])}")
elif response.status_code == 429:
    print("Rate limit dépassé, attendez un peu avant de réessayer")
else:
    print(f"Erreur: {data.get('message', 'Unknown error')}")

Exemple de réponse

Note : Les exemples ci-dessous montrent seulement quelques champs pour chaque type de données. Pour voir tous les champs disponibles, consultez les schémas détaillés.

{
  "properties": [
    {
      "cadastral": {
        "id": "75101000AB0001",
        "area": 1234.56,
        "geometry": {
          "type": "Polygon",
          "coordinates": [[[2.3522, 48.8566], ...]]
        }
      },
      "buildings": [
        {
          "building": {
            "id": "BDNB123456",
            "parcelIds": ["75101000AB0001"],
            "constructionYear": 1985,
            "numberOfUnits": 12,
            "usage": "Résidentiel",
            "mainAddress": "123 Rue Example, 75001 Paris",
            // ... plus de 50 champs disponibles (voir schéma Building)
          },
          "addresses": [
            {
              "id": "75101_1234_00001",
              "label": "123 Rue Example, 75001 Paris",
              "coordinates": [2.3522, 48.8566],
              "postalCode": "75001",
              "city": "Paris"
              // ... autres champs disponibles
            }
          ]
        }
      ],
      "transactions": [
        {
          "mutationId": "123456",
          "mutationDate": "2023-01-15",
          "mutationType": "Vente",
          "value": 450000,
          "address": {...},
          "parcelId": "75101000AB0001",
          "localType": "Appartement",
          "totalSurface": 85.5,
          "totalRooms": 3,
          "coordinates": [2.3522, 48.8566],
          "year": 2023,
          "numberOfLots": 3,
          "lots": [...],
          "landInfo": {...}
          // ... autres champs disponibles
        }
      ],
      "energy": {
        "tertiary": [
          {
            "dpeNumber": "DPE123456",
            "dpeLabel": "C",
            "gesLabel": "B",
            "consumptionKwhPrimaryM2Year": 120,
            "constructionYear": 1990,
            // ... plus de 70 champs disponibles (voir schéma DPE Tertiaire)
          }
        ],
        "residential": [
          {
            "dpeNumber": "DPE789012",
            "dpeLabel": "D",
            "gesLabel": "C",
            "fiveUsesPrimaryConsumption": 15000,
            "constructionYear": 1985,
            // ... plus de 300 champs disponibles (voir schéma DPE Résidentiel)
          }
        ]
      },
      "occupation": [
        {
          "siren": "123456789",
          "name": "Example SARL",
          "activity": "Commerce de détail",
          "address": "123 Rue Example, 75001 Paris",
          // ... plus de 20 champs disponibles (voir schéma Occupation)
        }
      ],
      "owners": [
        {
          "buildingId": "BDNB123456",
          "ownerName": "SCI Example",
          "siren": "123456789",
          "numberOfLocals": 5,
          "isLandlord": true,
          "details": {
            // ... champs enrichis disponibles (voir schéma Owners)
          }
        }
      ],
      "copropriete": [
        {
          "immatriculation": "123456789",
          "name": "Copropriété Example",
          "address": "123 Rue Example, 75001 Paris",
          "numberOfHousingLots": 50,
          "numberOfParkingLots": 15,
          // ... plus de 30 champs disponibles (voir schéma Copropriété)
        }
      ],
      "permis": [
        {
          "id": "PERMIT123",
          "type": "logements",
          "permitNumber": "PC075123456",
          "status": "completed",
          "authorizationDate": "2020-01-15",
          // ... plus de 20 champs disponibles (voir schéma Permis)
        }
      ],
      "fondsDeCommerce": [
        {
          "id": "BODACC123",
          "publicationDate": "2023-05-15",
          "type": "Ventes et cessions",
          "merchant": "SARL Example Commerce",
          "price": 150000,
          // ... plus de 20 champs disponibles (voir schéma Fonds de commerce)
        }
      ],
      "urbanisme": {
        "zones": [...],
        "documents": [...],
        "prescriptions": [...],
        "informations": [...],
        "assiettes": [...],
        "generateurs": [...]
        // ... voir schéma Urbanisme pour détails complets
      }
    }
  ]
}

Codes de statut HTTP

CodeDescription
200Succès - Données retournées
400Requête invalide (paramètres manquants ou invalides)
429Trop de requêtes - Rate limit dépassé (100 req/min)
500Erreur serveur
502Erreur de l'API externe (Bad Gateway)
504Timeout de l'API externe (Gateway Timeout)

Limites de taux (Rate Limiting)

Les limites de taux sont appliquées par adresse IP pour protéger l'API contre les abus et garantir une disponibilité optimale pour tous les utilisateurs.

Configuration actuelle

  • Limite : 100 requêtes par minute par adresse IP
  • Fenêtre de temps : 60 secondes (1 minute)
  • Identification : Par adresse IP source de la requête

Comment ça fonctionne

Le rate limiter utilise une fenêtre glissante (sliding window) :

  1. Chaque requête crée une fenêtre de 1 minute à partir du moment de la requête
  2. Un compteur suit le nombre de requêtes dans cette fenêtre
  3. Si le compteur atteint 100, les requêtes suivantes sont bloquées jusqu'à ce que la fenêtre expire
  4. Après 1 minute, le compteur se réinitialise

Réponse en cas de dépassement

Si vous dépassez la limite, vous recevrez une erreur 429 Too Many Requests :

{
  "statusCode": 429,
  "message": "ThrottlerException: Too Many Requests",
  "error": "Too Many Requests",
  "timestamp": "2024-01-15T10:30:00.000Z",
  "path": "/v1/properties",
  "method": "GET"
}

Bonnes pratiques

  • Respectez la limite : Ne dépassez pas 100 requêtes par minute
  • Implémentez un retry : En cas d'erreur 429, attendez avant de réessayer
  • Backoff exponentiel : Augmentez progressivement le délai entre les tentatives
  • Cachez les résultats : Évitez de refaire les mêmes requêtes
  • Traitez par lots : Si vous avez beaucoup de parcelles, espacez les requêtes

Exemple de gestion du rate limiting

import requests
import time
from typing import Optional

def get_property_safe(parcel_id: str, max_retries: int = 3) -> Optional[dict]:
    """
    Récupère les données d'une propriété avec gestion du rate limiting.
    """
    for attempt in range(max_retries):
        try:
            response = requests.get(
                "https://api.deepcity.fr/v1/properties",
                params={"parcel_id": parcel_id},
                timeout=30
            )

            if response.status_code == 200:
                return response.json()
            elif response.status_code == 429:
                # Rate limit dépassé
                wait_time = (2 ** attempt) * 60  # Backoff exponentiel: 60s, 120s, 240s
                print(f"Rate limit atteint (tentative {attempt + 1}/{max_retries})")
                print(f"Attente de {wait_time} secondes...")
                time.sleep(wait_time)
            else:
                response.raise_for_status()

        except requests.exceptions.RequestException as e:
            print(f"Erreur réseau: {e}")
            if attempt < max_retries - 1:
                time.sleep(5)  # Attendre 5s avant de réessayer

    print("Nombre maximum de tentatives atteint")
    return None

# Utilisation
data = get_property_safe("75101000AB0001")
if data:
    print(f"Données récupérées: {len(data['properties'])} propriété(s)")

Format de l'identifiant de parcelle

L'identifiant de parcelle (parcel_id) suit le format cadastral français :

Format standard (11 caractères)

code_insee (5) + section (2) + numero (4) = 11 caractères

Exemple : 75101000AB0001

  • 75101 = code INSEE
  • 00 = section
  • AB = section (lettres)
  • 0001 = numéro de parcelle

Format avec arrondissement (16 caractères)

Pour Paris, Lyon, Marseille, peut contenir code_arr (5) = 16 caractères

code_insee (5) + code_arr (5) + section (2) + numero (4) = 16 caractères

Exemple : 7510100000AB0001

  • 75101 = code INSEE
  • 00000 = code arrondissement
  • AB = section
  • 0001 = numéro

Cas d'usage

Recherche simple

# Récupérer toutes les données d'une parcelle
response = requests.get(
    "https://api.deepcity.fr/v1/properties",
    params={"parcel_id": "75101000AB0001"}
)

Recherche avec filtrage

# Récupérer uniquement les transactions immobilières
response = requests.get(
    "https://api.deepcity.fr/v1/properties",
    params={
        "parcel_id": "75101000AB0001",
        "include": ["transactions"]
    }
)

Traitement par lots

import requests
import time

parcel_ids = ["75101000AB0001", "75101000AB0002", "75101000AB0003"]

for parcel_id in parcel_ids:
    response = requests.get(
        "https://api.deepcity.fr/v1/properties",
        params={"parcel_id": parcel_id}
    )

    if response.status_code == 200:
        data = response.json()
        print(f"{parcel_id}: {len(data['properties'])} propriété(s)")
    elif response.status_code == 429:
        print("Rate limit atteint, attente de 60s...")
        time.sleep(60)  # Attendre 1 minute
    else:
        print(f"Erreur pour {parcel_id}: {response.status_code}")

    # Espacer les requêtes pour éviter le rate limiting
    time.sleep(0.6)  # 0.6s entre chaque requête = max 100/min

Schémas de données

Les schémas ci-dessous décrivent tous les champs disponibles pour chaque type de données retourné par l'API. Les exemples de réponse dans la section Endpoints montrent seulement quelques champs pour la lisibilité.

Cadastral (Parcelle)

Données cadastrales de la parcelle. ~5 champs

id, area, geometry

Building (Bâtiment)

Données complètes du bâtiment depuis la BDNB. ~50+ champs

id, parcelIds, constructionYear, numberOfUnits, height, footprintArea, geometry, usage, usageLevel1, numberOfFloors, numberOfTertiaryLots, numberOfParkingLots, wallMaterial, roofMaterial, wallStructure, mainAddress, coproRegistrationNumber, ownerNames, ownerSirens, ...

Addresses (Adresses)

Adresses associées aux bâtiments depuis la BAN. ~8 champs

id, label, coordinates, postalCode, city, street, houseNumber, ...

Transactions (DVF)

Transactions immobilières. ~20+ champs

mutationId, mutationDate, mutationType, value, address, parcelId, localType, totalSurface, totalRooms, coordinates, year, numberOfLots, lots, landInfo, ...

DPE Tertiaire

Diagnostic de Performance Énergétique pour bâtiments tertiaires. ~70+ champs

dpeNumber, dpeLabel, gesLabel, consumptionKwhPrimaryM2Year, constructionYear, inspectorVisitDate, dpeEstablishmentDate, dpeReceptionDate, dpeValidityEndDate, address, surface, occupantCount, energyTypeN1, energyTypeN2, energyTypeN3, primaryConsumptionEnergyN1, finalConsumptionEnergyN1, annualEnergyCostN1, primaryConsumptionEnergyN2, finalConsumptionEnergyN2, annualEnergyCostN2, primaryConsumptionEnergyN3, finalConsumptionEnergyN3, annualEnergyCostN3, mainHeatingEnergyType, gesEmissionKgCo2M2Year, geopoint, ...

DPE Résidentiel

Diagnostic de Performance Énergétique pour bâtiments résidentiels. ~300+ champs

dpeNumber, dpeLabel, gesLabel, fiveUsesPrimaryConsumption, constructionYear, buildingType, heatingInstallationType, ecsInstallationType, ceilingHeight, apartmentCount, habitableBuildingSurface, habitableHousingSurface, banAddress, summerComfortIndicator, envelopeLosses, thermalBridgeLosses, wallLosses, upperFloorLosses, lowerFloorLosses, envelopeInsulationQuality, wallInsulationQuality, heatingNeed, ecsNeed, coolingNeed, fiveUsesPrimaryConsumption, fiveUsesFinalConsumption, fiveUsesGesEmission, heatingPrimaryConsumption, ecsPrimaryConsumption, coolingPrimaryConsumption, heatingFinalConsumption, ecsFinalConsumption, coolingFinalConsumption, heatingGesEmission, ecsGesEmission, coolingGesEmission, energyTypeN1, energyTypeN2, energyTypeN3, fiveUsesFinalConsumptionEnergyN1, heatingFinalConsumptionEnergyN1, ecsFinalConsumptionEnergyN1, totalFiveUsesCostEnergyN1, heatingCostEnergyN1, ecsCostEnergyN1, mainHeatingEnergyType, mainHeatingGeneratorType, heatingInstallationTypeN1, heatingInstallationTypeN2, generatorTypeN1InstallationN1, generatorTypeN2InstallationN1, ecsInstallationTypeN1, generatorTypeN1EcsN1, generatorTypeN2EcsN1, ventilationType, coldGeneratorType, pvProductionPresence, pvElectricityProductionKwhEpPerYear, geopoint, ...

Occupation (Occupants)

Entreprises occupant les bâtiments. ~25+ champs

siren, name, isHeadquarters, isClosed, activity, nafCode, companyType, address, acronym, establishmentCount, openEstablishmentCount, companyCategory, employeeRange, creationDate, managers, finances, complements, coordinates, matchingEstablishments, ...

Owners (Propriétaires)

Propriétaires des bâtiments. ~30+ champs (avec détails enrichis)

buildingId, ownerName, siren, numberOfLocals, inMajicPm, isLandlord, details (siren, name, activity, nafCode, companyType, address, managers, finances, complements, coordinates, ...)

Copropriété

Copropriétés associées aux bâtiments. ~35+ champs

immatriculation, name, address, fullAddress, communeCode, commune, postalCode, latitude, longitude, numberOfParkingLots, numberOfHousingLots, numberOfParcels, syndicType, representantDetails, regulationDate, mandatEnCours, constructionPeriod, isInAcv, isInPvd, ...

Permis de construire

Permis de construire (SITADEL). ~25+ champs

id, type, permitNumber, parcelId, status, authorizationDate, constructionStartDate, completionDate, applicantName, applicantSiren, applicantSiret, terrainAddress, projectNature, mainDestination, housingCreated, surfaceHousingCreated, surfaceCommercialCreated, surfaceOfficeCreated, depositYear, ...

Fonds de commerce

Ventes de fonds de commerce (BODACC). ~20+ champs

id, publicationDate, announcementNumber, type, subType, tribunal, merchant, department, region, postalCode, city, establishmentAddress, headquartersAddress, activity, price, currency, legalForm, denomination, rcsNumber, previousOwner, url, ...

Urbanisme

Données d'urbanisme (GPU). Structure complexe

zones (id, libelle, libelong, typezone, destdomi, geometry, ...), documents (id, name, type, gridName, gpuDocId, ...), prescriptions (id, libelle, txt, typepsc, stypepsc, ...), informations (id, libelle, txt, typeinf, stypeinf, ...), assiettes (id, idass, idgen, nomass, typeass, suptype, ...), generateurs (id, idgen, idsup, nomgen, typegen, ...), assiettesAvecGenerateurs, ...

Note : Les schémas complets avec tous les champs détaillés sont disponibles dans la documentation complète de l'API. Les exemples ci-dessus montrent les principaux champs pour chaque type de données.

Support

Pour toute question ou problème, contactez-nous :