Getting Started
From access, through your first application, to a fully generated listing - this guide walks you through the complete onboarding.
From access, through your first application, to a fully generated listing - this guide walks you through the complete onboarding.
Register with your business email address. We verify the entry against your real estate license; approval usually happens the next business day.
Until then, the sandbox is open to you. It contains a full sample portfolio of twelve properties, thirty leads and a handful of appointments. Sandbox data resets every night.
Every integration is its own application. Create one under My Apps and choose which APIs it's allowed to use.
Use a separate application per environment - that way a single key can be revoked without interrupting production.
For each application you generate an API key. It's shown exactly once - after that it can't be read again, only replaced.
re_live_7f3c9a24b1e84d05a6c2f8e1d3b70945
Each key has the scopes it's allowed to use attached to it. Grant only what the given process actually needs: an import job doesn't need write access to commissions.
Keep the key in a secret store, not in version control.
The key goes along with every call in the apikey header. The quickest useful call is listing your properties:
curl "https://api.realestateagency.example/v1/properties?status=active&limit=5" \
-H "apikey: $REAL_ESTATE_API_KEY"
{
"data": [
{
"id": "prop_8f2c1a",
"type": "apartment",
"title": "3-Bedroom Period Home near Riverside Park",
"address": { "street": "148 Elm Street", "postal_code": "10001", "city": "Springfield" },
"living_area_sqm": 86.5,
"purchase_price_eur": 645000,
"status": "active"
}
],
"page": { "count": 1, "total": 12, "next_cursor": null }
}
With a property ID and a template, you generate a listing:
curl -X POST https://api.realestateagency.example/v1/listings \
-H "apikey: $REAL_ESTATE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"property_id": "prop_8f2c1a",
"template_id": "tpl_classic",
"sections": ["location", "features", "energy", "floor_plan"]
}'
Generation runs asynchronously. The response returns status in_progress; once it reaches completed, GET /listings/{id}/pdf returns the finished document. Alternatively, subscribe to the listing.completed event via webhook.
Details on templates, sections and mandatory disclosures are in the guide From Property to Listing.
All APIs respond the same way on error:
{
"code": "mandatory_disclosure_missing",
"message": "Mandatory disclosures from the energy certificate are missing for publication.",
"details": [
{ "field": "energy_certificate.final_energy_demand_kwh", "reason": "missing" },
{ "field": "energy_certificate.valid_until", "reason": "expired" }
]
}
| HTTP | code | Meaning |
|---|---|---|
| 400 | validation_failed | Request doesn't match the schema |
| 401 | not_authenticated | Key is missing, revoked or invalid |
| 403 | scope_missing | The key lacks the required scope |
| 404 | not_found | Property, listing or appointment doesn't exist |
| 409 | conflict | State doesn't allow it, e.g. publishing a draft |
| 422 | mandatory_disclosure_missing | A required disclosure is missing |
| 429 | too_many_requests | Rate limit reached |
| Environment | Requests per minute | Listing generations per hour |
|---|---|---|
| Sandbox | 60 | 20 |
| Production | 600 | 200 |
Every response carries RateLimit-Limit, RateLimit-Remaining and RateLimit-Reset. On 429, a well-built client waits the number of seconds stated in Retry-After instead of retrying immediately.
Register, create an application, and generate your first listing in under ten minutes.