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 eurossurface_min/surface_max: fourchette de surface en m2page: 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_KEYplutô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_departementquand 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/statspour 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_communeoucode_departementretournera une erreur 400. Précisez toujours une zone géographique - Confondre code INSEE et code postal : le paramètre
code_communeattend 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
- Consultez la documentation complète de l'API pour l'ensemble des endpoints et le détail des réponses
- Découvrez comment exploiter les données DVF pour l'analyse de marché
- Apprenez-en plus sur les API de transactions immobilières en France
- Explorez les données brutes sur data.gouv.fr et la version géolocalisée sur datafoncier.cerema.fr