> ## Documentation Index
> Fetch the complete documentation index at: https://api.housera.ro/llms.txt
> Use this file to discover all available pages before exploring further.

# Publică un ansamblu

> Pentru dezvoltatorii imobiliari: un ansamblu rezidențial cu tipurile de unități, regimul de înălțime și termenul de livrare.

Un ansamblu rezidențial (`type: complex`) e un singur anunț pentru un proiect întreg: blocurile sau casele, tipurile de unități din ele, prețul de pornire și termenul de livrare. Fiecare apartament, casă, spațiu comercial sau loc de parcare scos la vânzare e un anunț separat, legat de ansamblu.

## Cine publică un ansamblu

Ansamblurile le publică dezvoltatorii imobiliari a căror firmă e aprobată de Housera și agențiile care au un mandat exclusiv de comercializare confirmat pe proiect. Dezvoltatorul creează ansamblul și prin API, cu o cheie obișnuită din contul lui, de la [Setări → API](https://housera.ro/setari/api). O agenție creează ansamblul din portal, la „Adaugă anunț”: numește dezvoltatorul și încarcă contractul de mandat. După ce mandatul e confirmat, îl editează și prin API. Vezi [Mandatul de comercializare](https://api.housera.ro/ro/guides/complex.md#mandatul-de-comercializare).

| Situația | Răspuns |
| - | - |
| O agenție creează un ansamblu prin API (`POST /listings`, sau `PUT /listings/ref/{ref}` cu un id nou) | `422`, `complex_developers_only` pe `/type` |
| O agenție editează ansamblul ei cât mandatul e confirmat sau cererea încă așteaptă decizia | `200` sau `202`, ca la orice editare |
| O agenție editează ansamblul după ce mandatul a fost revocat sau a expirat | `404`: ansamblul a ieșit de pe site (`hidden`) și nu se mai editează, ca orice anunț ascuns |
| O agenție editează ansamblul după ce mandatul a fost refuzat | `422`, `complex_developers_only` pe `/type` |
| Dezvoltatorul a preluat ansamblul | `404` pe cheile agenției |
| Contul e al unei persoane | `422`, `complex_developers_only` pe `/type` |
| Contul e al unei firme care încă nu e aprobată | `422`, `firm_not_approved` pe `/contact_as` (pentru orice anunț, nu doar pentru ansambluri) |

O agenție fără mandat nu publică ansamblul. Publică unitățile din el drept anunțuri obișnuite și le leagă de ansamblu după ce firma ansamblului o aprobă ca parteneră. Vezi [Agențiile partenere](https://api.housera.ro/ro/guides/partners.md).

## Ce trimiți

Un ansamblu are câmpurile comune ale oricărui anunț: `type`, `transaction`, `title`, `description` și locația (`latitude`, `longitude`, `city`, `street`, vezi [Locația](https://api.housera.ro/ro/guides/location.md)). Nu are subtip, etaj, suprafață principală sau preț propriu. În locul lor trimiți forma proiectului și lista tipurilor de unități.

### Forma proiectului

**complex\_mode** `string`

Ce fel de proiect e: `blocks` (blocuri de apartamente), `houses` (case) sau `offices` (clădiri de birouri). Fără el, regulile de regim sunt cele de la blocuri.

**reg\_s** `integer`

Numărul de subsoluri, între 0 și 20.

**reg\_d** `integer`

Demisolul: `1` dacă există, `0` dacă nu.

**reg\_p** `integer`

Parterul: `1` dacă există, `0` dacă nu.

**reg\_e** `integer`

Numărul de etaje, între 0 și 200.

**top\_level** `string`

Ultimul nivel: `attic` (mansardă), `roof_space` (pod) sau `none`.

**house\_regime** `string`

Regimul caselor, la `complex_mode: houses`: `ground`, `ground_plus_1`, `ground_plus_1_attic` sau `ground_plus_2`.

**sections\_count** `integer`

Numărul de tronsoane, între 1 și 40.

**phases\_count** `integer`

Numărul de faze ale proiectului, între 1 și 20.

Regimul de înălțime e obligatoriu. La blocuri și birouri trimiți cel puțin parterul (`reg_p: 1`) sau un etaj (`reg_e` peste 0); altfel primești `complex_regime_missing` pe `/reg_e`. La case trimiți `house_regime`; altfel primești `complex_regime_missing` pe `/house_regime`.

### Livrarea

**project\_stage** `string`

Stadiul proiectului: `launch` (lansare), `under_construction` (în construcție), `finished` (finalizat) sau `mixed` (faze în stadii diferite).

**delivery\_quarter** `integer`

Trimestrul de livrare, de la 1 la 4.

**delivery\_year** `integer`

Anul de livrare, de la 2000 până la anul curent plus 10.

Un termen de livrare deja trecut e refuzat cu `delivery_in_past` pe `/delivery_quarter`, cât timp `project_stage` nu e `finished`. Trimestrul în curs e acceptat.

### Tipurile de unități

`unit_types` e lista tipurilor de unități din proiect, cel mult 50 de rânduri. Fiecare rând descrie un grup de unități asemănătoare.

**unit\_types\[].kind** `string`

Felul unității: `studio`, `apartment`, `penthouse`, `house`, `duplex`, `triplex`, `villa`, `commercial`, `office`, `parking` sau `storage` (boxă).

**unit\_types\[].label** `string`

O denumire proprie, de cel mult 120 de caractere, de exemplu `Tip A`. Obligatorie doar când lipsește `kind`.

**unit\_types\[].rooms** `integer`

Numărul de camere, între 0 și 20. O garsonieră (`studio`) are mereu o cameră, iar `commercial`, `office`, `parking` și `storage` nu au camere.

**unit\_types\[].floors** `string`

Etajele pe care se află unitățile, ca interval `de_la|până_la` din codurile de nivel: `ground|floor_4`, `floor_1|floor_8`. Un singur nivel se scrie fără bară (`floor_8`). Numerele simple sunt acceptate (`1|8`). La case nu se trimite.

**unit\_types\[].area\_sqm** `number`

Suprafața, de la 1 la 10.000 m², cu cel mult două zecimale. Când unitățile au suprafețe diferite, e suprafața cea mai mică.

**unit\_types\[].area\_sqm\_to** `number`

Suprafața cea mai mare, când tipul acoperă un interval.

**unit\_types\[].units\_count** `integer`

Câte unități de acest tip are proiectul, de la 1 la 10.000.

**unit\_types\[].price\_from** `integer`

Prețul de pornire pentru acest tip, în moneda din `price_currency`.

Cel puțin un rând trebuie să fie complet, adică să aibă `kind` sau `label`, `area_sqm`, `units_count` și `price_from`. Fără niciun rând complet primești `complex_needs_complete_type` pe `/unit_types`.

Etajele unui rând trebuie să existe în regimul de înălțime al proiectului. Cu `reg_p: 1` și `reg_e: 8`, intervalul `floor_1|floor_10` e refuzat cu `floor_range_invalid` pe `/unit_types/0/floors`. Mansarda sau podul intră în interval doar dacă le-ai trimis în `top_level`.

### Prețul

Nu trimiți `price`, îl calculează Housera. Când ansamblul are unități disponibile (anunțuri active și nerezervate, legate de el și cu aceeași tranzacție), prețul lui e prețul celei mai ieftine unități. Unitățile rezervate, vândute sau nepublicate nu intră în calcul. Locurile de parcare și boxele contează doar când ansamblul nu mai are disponibilă nicio altă unitate. Cât timp nu are nicio unitate disponibilă, prețul e cel mai mic `price_from` dintre rândurile complete. Prețul se actualizează singur după ce se schimbă o unitate. Dacă trimiți prețurile în altă monedă decât euro, pui moneda în `price_currency`, ca la orice anunț.

## Exemplu: blocuri

```json theme={null}
{
  "type": "complex",
  "transaction": "sale",
  "title": "Ansamblul Nord, apartamente noi în Copou, Iași",
  "description": "Două blocuri cu parter și opt etaje, la zece minute de Parcul Copou. Apartamente cu una, două și patru camere, cu parcare subterană și spații verzi între clădiri.",
  "city": "Iași",
  "county": "Iași",
  "area": "Copou",
  "street": "Strada Sărărie",
  "street_number": "40",
  "latitude": 47.1712,
  "longitude": 27.5749,
  "complex_mode": "blocks",
  "project_stage": "under_construction",
  "delivery_quarter": 4,
  "delivery_year": 2027,
  "sections_count": 2,
  "reg_s": 1,
  "reg_p": 1,
  "reg_e": 8,
  "top_level": "roof_space",
  "unit_types": [
    { "kind": "studio", "rooms": 1, "floors": "floor_1|floor_7", "area_sqm": 38, "area_sqm_to": 42, "units_count": 16, "price_from": 59000 },
    { "kind": "apartment", "rooms": 2, "floors": "floor_1|floor_7", "area_sqm": 54, "area_sqm_to": 60, "units_count": 48, "price_from": 72000 },
    { "kind": "penthouse", "rooms": 4, "floors": "floor_8", "area_sqm": 120, "units_count": 4, "price_from": 189000 }
  ]
}
```

`price` va fi 59.000 EUR, cel al garsonierelor.

## Exemplu: case

```json theme={null}
{
  "type": "complex",
  "transaction": "sale",
  "title": "Casele din Valea Lungă, cartier nou lângă Iași",
  "description": "Douăzeci și patru de case cu parter și etaj, fiecare cu curte proprie și loc de parcare. Drumurile interioare sunt asfaltate, iar utilitățile sunt trase la fiecare lot.",
  "city": "Miroslava",
  "county": "Iași",
  "street": "Strada Valea Lungă",
  "latitude": 47.1452,
  "longitude": 27.5126,
  "complex_mode": "houses",
  "house_regime": "ground_plus_1",
  "project_stage": "launch",
  "delivery_quarter": 2,
  "delivery_year": 2028,
  "unit_types": [
    { "kind": "house", "rooms": 4, "area_sqm": 120, "area_sqm_to": 135, "units_count": 18, "price_from": 145000 },
    { "kind": "duplex", "rooms": 3, "area_sqm": 98, "units_count": 6, "price_from": 118000 }
  ]
}
```

## După creare

Ansamblul trece prin aceleași etape ca orice anunț: intră la moderare cu starea `pending`, primește pozele ca orice anunț (vezi [Pozele](https://api.housera.ro/ro/guides/photos.md)) și se editează cu `PATCH /listings/{code}`. Când citești anunțul, primești `unit_types` cu rândurile salvate. Când trimiți `unit_types` la editare, lista se înlocuiește în întregime, deci pui în ea toate rândurile.

## Unitățile ansamblului

Un apartament, o casă, un spațiu comercial sau un loc de parcare din ansamblu se publică drept anunț propriu, cu tipul lui (`apartment`, `house`, `commercial` sau `garage`), și se leagă de ansamblu prin câmpul `complex`, care primește codul ansamblului.

**complex** `string`

Codul ansamblului (`code`) de care ține unitatea. La editare, `null` scoate unitatea din ansamblu, iar dacă nu trimiți câmpul, legătura rămâne cum era.

**unit\_ref** `string`

Identificatorul unității în ansamblu, de cel mult 64 de caractere: corpul sau scara și numărul, de exemplu `B2-14` sau `Scara A ap. 7`. Housera îl salvează normalizat, cu litere mari, fără diacritice, fără cuvinte ca „scara”, „ap” sau „bloc” și cu `-` între părți: `Scara A ap. 7` devine `A-7`. Nu apare public. Îl citește doar firma care a publicat unitatea.

```json theme={null}
{
  "type": "apartment",
  "transaction": "sale",
  "title": "Apartament cu 2 camere în Ansamblul Nord, Copou",
  "complex": "HEWPUTA8",
  "unit_ref": "B2-14"
}
```

O cheie leagă unități de ansamblurile firmei ei: cele active, cele aflate la moderare și ciornele. Managerul unui proiect le leagă doar de proiectele lui. De ansamblul activ al altei firme, cheia leagă doar după ce dezvoltatorul a aprobat firma cheii ca parteneră, și atunci `unit_ref` e obligatoriu. Vezi [Agențiile partenere](https://api.housera.ro/ro/guides/partners.md).

Legătura se aplică pe loc, și pe un anunț publicat, fără să aștepte moderarea ca restul editării. Ea face parte din versiunea anunțului, deci schimbă `etag`-ul. Ce răspuns primești la o editare care schimbă doar legătura e în [Legătura cu un ansamblu](https://api.housera.ro/ro/concepts/editing.md#legătura-cu-un-ansamblu).

Aceeași firmă publică o unitate o singură dată pe tranzacție: un al doilea anunț cu același `unit_ref` în același ansamblu primește `unit_ref_taken`.

### Inventarul

La un ansamblu, `GET /listings/{code}` și `GET /account/listings/{code}` întorc câmpul `inventory`, numărat din unitățile legate:

```json theme={null}
"inventory": {
  "sale": {
    "source": "units",
    "available": 50,
    "reserved": 3,
    "sold": 12,
    "price_min": 96000,
    "price_max": 209042,
    "groups": [
      { "family": "apartments", "rooms": 2, "available": 30, "reserved": 1, "sold": 5,
        "area_min": 41, "area_max": 61, "land_min": null, "land_max": null,
        "floor_min": 1, "floor_max": 9, "price_min": 96000, "price_max": 155844 }
    ]
  },
  "rent": null
}
```

O unitate își păstrează tranzacția: un ansamblu de vânzare poate avea și unități de închiriat. `inventory` are câte un obiect pe tranzacție, `sale` și `rent`, cu aceeași formă. Tranzacția ansamblului e mereu prezentă; cealaltă e `null` cât timp nu are unități. Prețul ansamblului (`price`) și contoarele lui vin doar din tranzacția lui. La `rent`, prețurile sunt pe lună.

* `source` e `units` când ansamblul are unități publicate și `declared` cât timp nu are. La `declared`, contoarele sunt zero, `groups` e gol, iar proiectul se citește din `unit_types`.
* `available` numără unitățile active și nerezervate, `reserved` pe cele active și rezervate, iar `sold` pe cele vândute. O unitate oferită de mai multe firme se numără o singură dată.
* `price_min` și `price_max` sunt prețurile unităților disponibile, în euro. Locurile de parcare și boxele intră în interval doar când ansamblul nu mai are disponibilă nicio altă unitate.
* `groups` are câte o grupă pe familie (`apartments`, `houses`, `commercial`, `offices`, `parking`). O familie ale cărei unități au număr diferit de camere se împarte pe camere, iar `rooms` spune câte camere au unitățile grupei; `rooms: 5` înseamnă 5 camere sau mai multe. `rooms` e `null` când familia nu e împărțită: toate unitățile ei au același număr de camere, sau familia nu are camere (`commercial`, `offices`, `parking`). Într-o familie împărțită, grupa cu `rooms: null` strânge unitățile fără număr de camere. Intervalele unei grupe acoperă unitățile încă în ofertă, disponibile și rezervate.

`inventory` are doar numere și intervale. Unitățile le citești cu `GET /listings?complex={code}` în catalog sau cu `GET /account/listings?complex={code}` printre anunțurile tale. La o unitate, câmpul `complex` numește ansamblul, cu `code`, `title` și `url`.

Inventarul îl citesc cheile firmei care a publicat ansamblul și partenerii cu dreptul `catalog:read`. Cheia unei agenții partenere nu îl vede. Vezi [Ce vede cheia agenției](https://api.housera.ro/ro/guides/partners.md#ce-vede-cheia-agenției).

Câmpurile de proiect mai rare (finisajele, detaliile tehnice, vecinătățile, consumul energetic) sunt în [vocabular](https://api.housera.ro/ro/vocabulary.md), la câmpurile care au `complex` între tipuri.

## Dezvoltatorul și comercializatorul

La un ansamblu, `GET /listings/{code}` și `GET /account/listings/{code}` întorc și firma care construiește proiectul (`developer`) și firma care îl comercializează (`marketer`). La celelalte tipuri de anunț, amândouă sunt `null`. Le citești doar: nu le trimiți la creare sau la editare.

```json theme={null}
"developer": {
  "name": "Construct Nord SRL",
  "country": "RO",
  "tax_id": "12345678",
  "verified": true,
  "url": "https://housera.ro/agentii/construct-nord"
},
"marketer": {
  "name": "Imobiliara Sud",
  "kind": "agency",
  "url": "https://housera.ro/agentii/imobiliara-sud"
}
```

* `marketer` e firma ansamblului: ea publică pagina și primește cererile clienților. `kind` e `agency` când proiectul îl comercializează o agenție și `developer` când îl comercializează chiar dezvoltatorul. În al doilea caz, `developer` și `marketer` numesc aceeași firmă.
* `developer` e `null` cât timp Housera nu știe cine construiește proiectul.
* `verified` e `true` când Housera a verificat datele firmei.
* `tax_id` e codul fiscal al dezvoltatorului. Apare doar când firma e verificată și e persoană juridică. Codul fiscal al unei persoane fizice autorizate sau al unei întreprinderi individuale ține de un om, așa că la ele câmpul e `null`.
* `url` e pagina firmei pe Housera. La dezvoltator e `null` când firma nu are cont pe Housera.

## Mandatul de comercializare

La ansamblul unei agenții, `GET /account/listings/{code}` întoarce și mandatul agenției pe proiect, în `mandate`. Îl citești doar: mandatul se cere, se confirmă și se încheie numai în portal, iar `mandate`, `developer` și `marketer` trimise la o scriere primesc avertismentul `unknown_field`. La ansamblul pe care îl comercializează chiar dezvoltatorul și la celelalte tipuri de anunț, `mandate` e `null`.

```json theme={null}
"mandate": {
  "status": "confirmed",
  "decided_via": "developer",
  "valid_until": "2027-12-31"
}
```

* `status` e `requested` (cererea așteaptă decizia), `confirmed`, `refused`, `withdrawn` (agenția și-a retras cererea), `revoked` sau `expired`. Ansamblul e public doar cu mandatul `confirmed`.
* `decided_via` spune cine a decis: `developer` (dezvoltatorul, din contul lui), `moderator` (un moderator Housera) sau `legacy` (mandat fără o decizie înregistrată). E `null` cât timp nu s-a decis.
* `valid_until` e data de sfârșit a contractului. E `null` când contractul nu are una.

Dezvoltatorul poate prelua ansamblul din portal după ce mandatul a fost decis. Din acel moment ansamblul e al lui: cheile agenției primesc `404` pe el, iar unitățile agenției rămân legate ca ale unei partenere sau ies din ansamblu, după cum alege dezvoltatorul. Fiecare pas îl afli din evenimentele `complex.mandate_confirmed`, `complex.mandate_ended` și `complex.taken_over`. Vezi [Webhook-uri](https://api.housera.ro/ro/webhooks.md).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.