toppla
Developer documentation

Custom Property API

Version1.0 · Updated on 2 mai 2026

Overview

The Custom Property API lets housing providers push properties to Toppla from their own tools (internal PMS, property hub or website), without manual entry. Pushed properties automatically appear in the corporate housing marketplace.

Typical use cases

  • Sync a PMS or internal tool with the Toppla marketplace.
  • Update prices and availability through a nightly cron job.
  • Automatically deactivate a property rented outside Toppla.
  • Connect an external website to the Toppla catalogue.
Article1

Authentication

All requests use a Bearer token in the Authorization :

Header
Authorization: Bearer sk_immo_eDc72cng7f3EM_yBjyieyt--i35TGjV5-qW1HoFyeIA

Generation. From the Toppla dashboard → Connect → Custom Property API→ “Generate a key”. The user must have the Admin or Developer role in their organisation.

Format. sk_immo_ followed by 43 base64url characters (32 bytes of random entropy). The key is displayedonly oncewhen created — Toppla stores only its SHA-256 hash.

Rotation.Multiple active keys per organisation are supported (labelled by environment: Production, Staging, CI…). To revoke one, click “Revoke” on its row. Any request with that key then returns 401 immediately.

Article2

Endpoints

POST/api/v1/properties

Creates a property if the external_id is unknown to Toppla; otherwise updates it. Idempotent.

201 · creation200 · updated
GET/api/v1/properties

Paginated list of properties pushed by your organisation through the API. Query parameters: ?limit=50&offset=0 (maximum 200).

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

Retrieves an individual property with all its attributes.

200 · OK404 · property not found
DELETE/api/v1/properties/:external_id

Soft delete: sets status to 'inactive'. The property disappears from the marketplace but remains in the database.

200 · OK404 · property not found
Article3

Payload schema

All fields are optional except external_id. Values omitted from an update POST request are not reset— to clear a field, explicitly send null.

FieldTypeDescription
external_idRequired
string ≤200Your unique property identifier, used as the upsert key.
status
"draft" | "active" | "inactive"Marketplace visibility. Default: draft.
property_type
stringFree-form property type (e.g. "T2", "Studio", "House").
location_text
stringDisplay address or city.
is_exact_address
booleanIf true, the exact address is disclosed publicly.
address_latitude
number ∈ [-90, 90]WGS84 latitude for map placement.
address_longitude
number ∈ [-180, 180]WGS84 longitude.
capacity
objectFree-form fields: { bedrooms, bathrooms, surface_m2, max_guests }.
amenities
string[]Array of amenities (e.g. ["wifi", "parking"]).
photos
arrayArray of objects { url, alt? }. Publicly accessible HTTPS URLs.
description
stringFree-form description.
pricing
objectFree-form fields: { monthly_eur, charges_eur, deposit_eur, ... }.
promotion
objectFree-form fields for temporary offers: { discount_percent, end_date }.
Article4

Examples

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"])
Article5

Error codes

  • 400Invalid payloadThe body returns a specific message. Correct the issue and retry.
  • 401Missing authentication or invalid/revoked keyCheck the Authorization header and that the key has not been revoked.
  • 403Invalid scopeThe key is for HRIS but you are calling a Housing endpoint (or vice versa). Generate a key with the correct scope.
  • 404Property not foundThe external_id is case-sensitive and scoped to your organisation.
  • 500Server errorRetry; if the issue persists, contact support with the timestamp.
Article6

Known limitations

  • No outgoing webhooks — Toppla does not notify integrators of marketplace changes; integrators must poll GET /properties.
  • No dedicated sandbox — test with a separate pre-production account.
  • No documented rate limiting at present (coming soon).
  • No batch endpoint — one POST request = one property.
Article7

Support

A question, bug or specific need? Write to support@toppla.fr with the request timestamp and returned ID, if available.

Custom Property API — Toppla documentation