Valuation API
Send the property data you already hold and receive a valuation, an itemised breakdown of every adjustment applied, a rental estimate and a score. No listing URL and no scraping is involved, so results do not depend on a portal being reachable.
This matters for accuracy, not just convenience. Valuing from a listing alone gives a median error near 19% (see methodology), because public data cannot see a property’s floor, condition or the works it needs. You can. Supplying those fields is what closes the gap.
Authentication
Create a key in your dashboard under API keys. Send it as a bearer token. Keys are shown once at creation and stored only as a hash, so a lost key must be replaced rather than recovered. API access requires the Agency plan and is limited to 60 requests per minute.
Authorization: Bearer dq_live_xxxxxxxxxxxxxxxxValue a property
POST https://dwelliq.io/api/public/v1/value
Minimal request
curl -X POST https://dwelliq.io/api/public/v1/value \
-H "Authorization: Bearer $DWELLIQ_KEY" \
-H "Content-Type: application/json" \
-d '{
"city": "Tours",
"surface": 70,
"price": 180000
}'With the characteristics you hold
curl -X POST https://dwelliq.io/api/public/v1/value \
-H "Authorization: Bearer $DWELLIQ_KEY" \
-H "Content-Type: application/json" \
-d '{
"reference": "MANDAT-2026-0412",
"city": "Tours",
"surface": 70,
"price": 180000,
"rooms": 3,
"property_type": "apartment",
"condition": "to_renovate",
"dpe": "G",
"floor": 5,
"total_floors": 5,
"has_lift": false,
"outdoor": "none",
"parking_spaces": 1,
"works_budget": 40000
}'Request fields
| city* | string | Commune name. Arrondissements are understood (“Paris 15e”, “Lyon 3”), as are postal codes (“75015”). |
| surface* | number | Living area in m². Pass surface_unit: "sqft" to send square feet. |
| price | number | Asking price. Omit it to get a valuation without a price comparison. |
| reference | string | Your own mandate or listing reference, echoed back so you can reconcile results. |
| property_type | string | apartment or house. Selects the comparable set and the rent series. |
| rooms | integer | Principal rooms. Determines which official rent series applies. |
| condition | string | to_renovate, needs_work, refreshed, good, renovated, new. Ignored when works_budget is supplied, to avoid charging for the same defect twice. |
| dpe | string | Energy rating A–G. F and G carry a real penalty because letting them is restricted. |
| floor | integer | 0 for ground floor. Combined with has_lift and total_floors. |
| has_lift | boolean | Walk-ups above the second floor are penalised progressively. |
| outdoor | string | none, balcony, terrace, garden. |
| parking_spaces | integer | Added at a flat per-space value. |
| land_m2 | number | Plot area, valued well below built area per m². |
| works_budget | number | € of works, deducted at cost rather than as a percentage. |
| down_payment_pct, interest_rate_pct, loan_term_years | number | Optional financing inputs; when present the response includes cash-flow modelling. |
Response
Every adjustment is itemised. The base value is fitted on recorded sales; the adjustments are conventional market coefficients, not figures fitted from transactions, which is why they are listed separately for you to review or override.
{
"property": { "city": "Tours", "surface": 70, "price": 180000, ... },
"market": {
"market_price_per_m2": 3025,
"fair_market_value": 102815,
"fair_value_low": 83000,
"fair_value_high": 130000,
"value_method": "size_curve",
"comparable_count": 2284,
"data_source": "dvf",
"estimated_monthly_rent": 776,
"estimated_monthly_rent_low": 614,
"estimated_monthly_rent_high": 981,
"rent_source": "carte_des_loyers",
"gross_yield_pct": 5.18,
"price_diff_pct": 75.07
},
"adjustments": {
"base_value": 188709,
"adjusted_value": 102815,
"total_pct": -24.3,
"lines": [
{ "type": "energy", "reason": "Worst energy rating (G) ...", "pct": -14.0, "amount_eur": -26419 },
{ "type": "floor", "reason": "Floor 5 with no lift", "pct": -12.0, "amount_eur": -19475 },
{ "type": "works", "reason": "Works required (deducted at cost)", "pct": null, "amount_eur": -40000 }
],
"basis": "Base value is fitted on recorded DVF sales..."
},
"scores": { "global_score": 27.2, "price_score": ..., "roi_score": ... },
"recommendation": "AVOID",
"analysis_id": "clx..."
}Errors
| 400 | Malformed JSON, or a required field is missing. |
| 401 | Missing, malformed or revoked API key. |
| 403 | Key is valid but the plan does not include API access. |
| 429 | Over 60 requests/minute. Honour the Retry-After header. |
Notes for integrators
- Valuations are deterministic: the same request returns the same value and score. Only the written explanation is generated by a language model.
- Each call is stored against your account so results are retrievable later, keyed by your
referencewhen you supply one. - Coverage is French communes, including Paris, Lyon and Marseille arrondissements. Rent indicators cover 34,970 communes.
- Read the measured accuracy before relying on values in an automated workflow.