Retour au blog
APIdéveloppementguide techniquetutoriel

Comment utiliser l'API DVF : Guide développeur complet

Immo API-

Premiers pas avec Immo API

Ce guide vous accompagne dans l'intégration d'Immo API dans vos projets. Que vous développiez une application web, mobile ou un script d'analyse de données, vous trouverez ici toutes les informations nécessaires pour démarrer rapidement.

Si vous n'êtes pas encore familier avec les données DVF, nous vous recommandons de lire d'abord notre article Qu'est-ce que le DVF ? pour comprendre la structure et le contenu des données.

Architecture de l'API

Immo API est une API REST qui retourne des réponses au format JSON. Elle est accessible via HTTPS et nécessite une authentification par Bearer token pour toutes les requêtes. Vous obtenez votre clé API en créant un compte sur immoapi.app ; elle est disponible immédiatement dans votre tableau de bord.

URL de base

https://immoapi.app/v1

Authentification

Chaque requête doit inclure un header Authorization avec votre clé API au format Bearer token :

Authorization: Bearer YOUR_API_KEY

Si le header est absent ou si la clé est invalide, l'API retourne une erreur 401. Pensez à stocker votre clé dans une variable d'environnement plutôt que de la coder en dur dans votre code source, notamment si vous utilisez un dépôt Git public.

Format des réponses

Toutes les réponses de l'endpoint /v1/mutations suivent une structure cohérente :

{
  "total": 150,
  "mutations": [...],
  "page": 1,
  "per_page": 20
}

Le champ total indique le nombre total de résultats correspondant à vos filtres. Le tableau mutations contient les transactions de la page courante. Les champs page et per_page reflètent les paramètres de pagination utilisés. Pour connaître le nombre total de pages, divisez total par per_page (arrondi au supérieur).

Plans et limites

Immo API propose deux plans tarifaires :

  • Starter (29 euros/mois) : 1 000 requêtes par jour. Idéal pour les phases de développement et les applications à trafic modéré
  • Pro (49 euros/mois) : requêtes illimitées. Conçu pour les applications en production à fort trafic

Les headers de réponse incluent X-RateLimit-Remaining et X-RateLimit-Reset pour suivre votre consommation en temps réel.

Endpoints principaux

Recherche de mutations

L'endpoint principal permet de rechercher des mutations (transactions) avec de nombreux filtres :

GET /v1/mutations?code_commune=75056&annee=2024

Paramètres de filtrage

  • code_commune : code INSEE de la commune (ex : 75056 pour Paris, 69123 pour Lyon, 13055 pour Marseille)
  • code_departement : code du département (ex : 75, 69, 13)
  • type_local : type de bien (Appartement, Maison, Local industriel, Dependance)
  • annee : année de la transaction (ex : 2024)
  • prix_min / prix_max : fourchette de prix en euros
  • surface_min / surface_max : fourchette de surface en m2
  • page : numéro de page (défaut : 1)
  • per_page : résultats par page, max 100 (défaut : 20)

Vous devez fournir au moins un filtre géographique (code_commune ou code_departement) pour que la requête soit valide. Les filtres sont combinés avec un opérateur ET : par exemple, code_departement=75&type_local=Appartement&prix_min=200000 retourne uniquement les appartements à Paris vendus à plus de 200 000 euros.

Recherche par proximité

L'endpoint /v1/mutations/nearby permet de trouver les transactions à proximité d'un point géographique :

GET /v1/mutations/nearby?lat=48.8566&lng=2.3522&radius=500&type_local=Appartement

Les paramètres lat et lng sont requis. Le paramètre radius définit le rayon de recherche en mètres (défaut : 1 000, max : 5 000). Chaque résultat inclut un champ distance_m indiquant la distance en mètres par rapport au point central.

Statistiques agrégées

L'endpoint /v1/stats fournit des statistiques prêtes à l'emploi :

GET /v1/stats?code_departement=75&annee=2024&type_local=Appartement

La réponse inclut le nombre de transactions, le prix médian et moyen au m2, la surface moyenne, la valeur foncière médiane, l'évolution annuelle en pourcentage, la répartition par nombre de pièces et les prix au m2 par trimestre.

Exemples de code

JavaScript / TypeScript (fetch)

const API_KEY = process.env.IMMO_API_KEY;

async function getMutations(codeCommune: string, annee: number) {
  const params = new URLSearchParams({
    code_commune: codeCommune,
    annee: String(annee),
    per_page: '50'
  });

  const response = await fetch(
    `https://immoapi.app/v1/mutations?${params}`,
    {
      headers: {
        'Authorization': `Bearer ${API_KEY}`
      }
    }
  );

  if (!response.ok) {
    throw new Error(`HTTP ${response.status}: ${response.statusText}`);
  }

  const result = await response.json();
  return result.mutations;
}

// Exemple : transactions a Paris en 2024
const transactions = await getMutations('75056', 2024);
console.log(`Nombre de transactions : ${transactions.length}`);

Python (requests)

import os
import requests

API_KEY = os.environ['IMMO_API_KEY']

def get_mutations(code_commune, annee):
    params = {
        'code_commune': code_commune,
        'annee': annee,
        'per_page': 50
    }
    response = requests.get(
        'https://immoapi.app/v1/mutations',
        params=params,
        headers={'Authorization': f'Bearer {API_KEY}'}
    )
    response.raise_for_status()
    return response.json()['mutations']

# Exemple : transactions a Lyon en 2024
transactions = get_mutations('69123', 2024)
print(f'Nombre de transactions : {len(transactions)}')

cURL

curl "https://immoapi.app/v1/mutations?code_departement=75&type_local=Appartement&annee=2024&per_page=10" \
  -H "Authorization: Bearer YOUR_API_KEY"

Astuce : pour un affichage formaté en local, ajoutez | python3 -m json.tool (ou | jq . si vous avez jq installé) à la fin de la commande cURL.

Gestion de la pagination

Pour les requêtes retournant de nombreux résultats, l'API utilise un système de pagination. Le nombre total de résultats est indiqué dans le champ total de la réponse. Voici comment parcourir toutes les pages :

const API_KEY = process.env.IMMO_API_KEY;

async function getAllMutations(codeCommune: string) {
  let allMutations = [];
  let page = 1;
  const perPage = 100;
  let totalPages = 1;

  while (page <= totalPages) {
    const params = new URLSearchParams({
      code_commune: codeCommune,
      page: String(page),
      per_page: String(perPage)
    });

    const response = await fetch(
      `https://immoapi.app/v1/mutations?${params}`,
      {
        headers: {
          'Authorization': `Bearer ${API_KEY}`
        }
      }
    );
    const result = await response.json();

    allMutations = [...allMutations, ...result.mutations];
    totalPages = Math.ceil(result.total / perPage);
    page++;
  }

  return allMutations;
}

Attention : si vous parcourez toutes les pages d'un département complet, le nombre de requêtes peut être important. Avec le plan Starter (1 000 requêtes/jour), pensez à mettre en cache les résultats pour éviter de dépasser votre quota. Les données DVF ne changent que deux fois par an, donc un cache de 24 heures est parfaitement raisonnable.

Bonnes pratiques

Sécuriser votre clé API

  • Variables d'environnement : stockez votre clé dans IMMO_API_KEY plutôt que dans le code source
  • Côté serveur uniquement : n'exposez jamais votre clé dans du code JavaScript côté client (navigateur). Utilisez un backend ou une fonction serverless comme intermédiaire
  • Rotation : si votre clé est compromise, vous pouvez en générer une nouvelle depuis votre tableau de bord

Optimiser vos requêtes

  • Utilisez des filtres précis : plus vos filtres sont précis, plus la réponse sera rapide. Préférez code_commune à code_departement quand c'est possible
  • Limitez la taille des pages : ne demandez que le nombre de résultats dont vous avez besoin via le paramètre per_page
  • Cachez les résultats : les données DVF ne changent que deux fois par an (avril et octobre), mettez en cache les réponses pour réduire votre consommation
  • Utilisez /v1/stats pour les agrégats : plutôt que de récupérer toutes les transactions pour calculer une moyenne, utilisez l'endpoint de statistiques qui fait le calcul côté serveur
  • Gérez les erreurs : implémentez un mécanisme de retry avec backoff exponentiel pour les erreurs 429 (rate limit) et 500 (erreur serveur)

Gestion des erreurs

Voici un wrapper robuste qui gère les retries et les différents codes d'erreur :

const API_KEY = process.env.IMMO_API_KEY;

async function safeFetch(url: string, retries = 3) {
  for (let i = 0; i < retries; i++) {
    try {
      const response = await fetch(url, {
        headers: {
          'Authorization': `Bearer ${API_KEY}`
        }
      });

      if (response.status === 401) {
        throw new Error('Cle API invalide');
      }
      if (response.status === 429) {
        const resetTime = response.headers.get('X-RateLimit-Reset');
        console.warn(`Rate limit atteint. Reset: ${resetTime}`);
      }
      if (!response.ok) {
        throw new Error(`HTTP ${response.status}`);
      }
      return await response.json();
    } catch (error) {
      if (i === retries - 1) throw error;
      await new Promise(r =>
        setTimeout(r, Math.pow(2, i) * 1000)
      );
    }
  }
}

Les codes d'erreur principaux sont : 400 (paramètres invalides), 401 (clé API manquante ou invalide), 429 (limite de requêtes atteinte) et 500 (erreur serveur). Consultez la documentation complète pour le détail de chaque code d'erreur.

Cas d'usage avancés

Calcul du prix médian au m2

Plutôt que la moyenne, privilégiez la médiane qui est plus robuste face aux valeurs aberrantes :

async function getPrixMedianM2(codeCommune: string) {
  const mutations = await getAllMutations(codeCommune);

  const appartements = mutations.filter(
    (m: any) => m.type_local === 'Appartement'
      && m.surface_reelle_bati > 0
      && m.valeur_fonciere > 0
  );

  const prixM2 = appartements
    .map((m: any) => m.valeur_fonciere / m.surface_reelle_bati)
    .filter((p: number) => p > 500 && p < 25000)
    .sort((a: number, b: number) => a - b);

  if (prixM2.length === 0) return null;

  const mid = Math.floor(prixM2.length / 2);
  const mediane = prixM2.length % 2 === 0
    ? (prixM2[mid - 1] + prixM2[mid]) / 2
    : prixM2[mid];

  return Math.round(mediane);
}

Notez le filtre p > 500 && p < 25000 qui exclut les valeurs aberrantes (donations déguisées, transactions multi-lots mal renseignées). Pour un calcul encore plus fiable, utilisez directement l'endpoint /v1/stats qui applique ces filtres côté serveur et renvoie le prix médian pré-calculé.

Analyse des tendances de prix

En récupérant les statistiques sur plusieurs années, vous pouvez tracer l'évolution des prix et détecter les tendances :

const API_KEY = process.env.IMMO_API_KEY;

async function getEvolutionPrix(codeDepartement: string) {
  const annees = [2019, 2020, 2021, 2022, 2023, 2024];
  const evolution = [];

  for (const annee of annees) {
    const stats = await safeFetch(
      `https://immoapi.app/v1/stats?code_departement=${codeDepartement}&annee=${annee}&type_local=Appartement`
    );
    evolution.push({
      annee,
      prix_median_m2: stats.prix_median_m2,
      nombre_transactions: stats.nombre_transactions
    });
  }

  return evolution;
}

// Exemple : evolution des prix a Paris
const evolution = await getEvolutionPrix('75');
evolution.forEach(e =>
  console.log(`${e.annee}: ${e.prix_median_m2} euros/m2 (${e.nombre_transactions} ventes)`)
);

Ce type d'analyse permet de constater, par exemple, que le prix médian au m2 parisien a reculé d'environ 5 à 8 % entre 2020 et 2024, alors que certaines métropoles régionales (Lyon, Bordeaux, Nantes) ont connu des hausses significatives sur la même période.

Comparaison entre communes

Pour comparer les prix entre plusieurs communes, utilisez l'endpoint /v1/stats en boucle :

const communes = [
  { code: '75056', nom: 'Paris' },
  { code: '69123', nom: 'Lyon' },
  { code: '13055', nom: 'Marseille' },
  { code: '31555', nom: 'Toulouse' },
  { code: '33063', nom: 'Bordeaux' }
];

for (const commune of communes) {
  const stats = await safeFetch(
    `https://immoapi.app/v1/stats?code_commune=${commune.code}&annee=2024&type_local=Appartement`
  );
  console.log(
    `${commune.nom}: ${stats.prix_median_m2} euros/m2 (${stats.nombre_transactions} transactions)`
  );
}

Erreurs courantes à éviter

Voici les erreurs les plus fréquentes rencontrées par les développeurs qui intègrent Immo API pour la première fois :

  • Oublier le header Authorization : toutes les requêtes nécessitent le header Authorization: Bearer YOUR_API_KEY. Sans ce header, l'API retourne systématiquement une erreur 401
  • Ne pas filtrer géographiquement : une requête sans filtre code_commune ou code_departement retournera une erreur 400. Précisez toujours une zone géographique
  • Confondre code INSEE et code postal : le paramètre code_commune attend un code INSEE (ex : 75056 pour Paris), pas un code postal (75001). Un même code postal peut couvrir plusieurs communes, et une grande ville comme Paris ou Lyon n'a qu'un seul code INSEE mais de nombreux codes postaux
  • Ignorer les mutations multi-lots : lorsqu'une transaction porte sur plusieurs lots (appartement + cave + parking), la valeur foncière couvre l'ensemble. Diviser cette valeur par la seule surface de l'appartement donne un prix au m2 artificiellement élevé
  • Ne pas mettre en cache : les données DVF ne changent que deux fois par an. Interroger l'API pour les mêmes paramètres à chaque requête utilisateur est un gaspillage de quota. Mettez en cache les résultats pendant au moins quelques heures

Pour aller plus loin


Articles connexes