toppla
Documentation développeur

API Custom Immo

Version 1.0 · Mise à jour le 2 mai 2026

Vue d’ensemble

L’API Custom Immo permet à un hébergeur de pousser ses logements vers Toppla depuis son propre outil (PMS interne, hub immobilier, site vitrine), sans passer par l’UI manuelle. Les biens poussés remontent automatiquement dans la Bourse aux logements entreprise.

Cas d’usage typiques

  • Synchroniser un PMS / outil maison vers la Bourse Toppla.
  • Mettre à jour les prix et disponibilités via un cron nocturne.
  • Désactiver automatiquement un bien loué hors-Toppla.
  • Brancher un site vitrine externe sur le catalogue Toppla.
Article 1

Authentification

Toutes les requêtes utilisent un Bearer token dans l’en-tête Authorization :

Header
Authorization: Bearer sk_immo_eDc72cng7f3EM_yBjyieyt--i35TGjV5-qW1HoFyeIA

Génération. Depuis le dashboard Toppla → Connect → API Custom Immo → bouton « Générer une clé ». L’utilisateur doit avoir le rôle Admin ou Développeur dans son organisation.

Format. sk_immo_ suivi de 43 caractères base64url (32 octets d’entropie aléatoire). La clé est affichée une seule fois à la création — Toppla n’en stocke que le hash SHA-256.

Rotation. Plusieurs clés actives par organisation sont supportées (libellées par environnement : Production, Staging, CI…). Pour révoquer, cliquez sur « Révoquer » sur la ligne de la clé concernée — toute requête avec cette clé renvoie alors 401 immédiatement.

Article 2

Endpoints

POST/api/v1/properties

Crée un bien si l’external_id est inconnu côté Toppla, sinon le met à jour. Idempotent.

201 · création200 · mise à jour
GET/api/v1/properties

Liste paginée des biens poussés via API par votre organisation. Query params : ?limit=50&offset=0 (max 200).

200 · OK
GET/api/v1/properties/:external_id

Récupère un bien individuel avec tous ses attributs.

200 · OK404 · bien introuvable
DELETE/api/v1/properties/:external_id

Soft-delete : passe le statut à 'inactive'. Le bien disparaît de la Bourse mais reste en base.

200 · OK404 · bien introuvable
Article 3

Schéma du payload

Tous les champs sont optionnels sauf external_id. Les valeurs non fournies lors d’un POST de mise à jour ne sont pas réinitialisées — pour effacer un champ, envoyez explicitement null.

ChampTypeDescription
external_idRequis
string ≤200Votre identifiant unique du bien — sert de clé d’upsert.
status
"draft" | "active" | "inactive"Visibilité dans la Bourse. Défaut : draft.
property_type
stringTypologie libre (ex. "T2", "Studio", "Maison").
location_text
stringAdresse ou ville d’affichage.
is_exact_address
booleanSi true, l’adresse exacte est divulguée publiquement.
address_latitude
number ∈ [-90, 90]Latitude WGS84 pour le pinning carte.
address_longitude
number ∈ [-180, 180]Longitude WGS84.
capacity
objectChamps libres : { bedrooms, bathrooms, surface_m2, max_guests }.
amenities
string[]Tableau d’équipements (ex. ["wifi", "parking"]).
photos
arrayTableau d’objets { url, alt? }. URLs HTTPS publiquement accessibles.
description
stringDescription libre.
pricing
objectChamps libres : { monthly_eur, charges_eur, deposit_eur, ... }.
promotion
objectChamps libres pour offres ponctuelles : { discount_percent, end_date }.
Article 4

Exemples

curl
curl -X POST https://app.toppla.io/api/v1/properties \
  -H "Authorization: Bearer sk_immo_..." \
  -H "Content-Type: application/json" \
  -d '{
    "external_id": "BIEN-2024-001",
    "status": "active",
    "property_type": "T2",
    "location_text": "Lyon 7e",
    "pricing": { "monthly_eur": 950, "charges_eur": 60 },
    "capacity": { "bedrooms": 1, "surface_m2": 42 },
    "amenities": ["wifi", "lave-linge"],
    "photos": [{ "url": "https://cdn.exemple.fr/p1.jpg" }]
  }'
Node.js (fetch)
const res = await fetch('https://app.toppla.io/api/v1/properties', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.TOPPLA_API_KEY}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    external_id: 'BIEN-2024-001',
    status: 'active',
    property_type: 'T2',
    location_text: 'Lyon 7e',
    pricing: { monthly_eur: 950, charges_eur: 60 },
  }),
});
const { property } = await res.json();
console.log(property.id);
Python (requests)
import os, requests

r = requests.post(
    "https://app.toppla.io/api/v1/properties",
    headers={
        "Authorization": f"Bearer {os.environ['TOPPLA_API_KEY']}",
        "Content-Type": "application/json",
    },
    json={
        "external_id": "BIEN-2024-001",
        "status": "active",
        "property_type": "T2",
        "location_text": "Lyon 7e",
        "pricing": {"monthly_eur": 950, "charges_eur": 60},
    },
    timeout=10,
)
r.raise_for_status()
print(r.json()["property"]["id"])
Article 5

Codes erreur

  • 400Payload invalideLe body retourne un message précis. Corrigez et réessayez.
  • 401Auth manquante ou clé invalide/révoquéeVérifiez l’en-tête Authorization et que la clé n’a pas été révoquée.
  • 403Mauvais scopeLa clé est de type SIRH mais vous appelez un endpoint Logement (ou inverse). Générez une clé du bon scope.
  • 404Bien introuvableL’external_id est case-sensitive et scopé à votre organisation.
  • 500Erreur serveurRéessayez ; si le problème persiste, contactez le support avec l’horodatage.
Article 6

Limitations connues

  • Pas de webhooks sortants — Toppla ne notifie pas l’intégrateur des changements côté Bourse, l’intégrateur doit poller GET /properties.
  • Pas d’environnement sandbox dédié — testez avec un compte de pré-production séparé.
  • Pas de rate limiting documenté à ce jour (à venir).
  • Pas d’endpoint batch — un appel POST = un bien.
Article 7

Support

Une question, un bug, un besoin spécifique ? Écrivez-nous à support@toppla.fr en précisant l’horodatage de l’appel et l’ID retourné si vous en avez un.