> ## 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.

# Developer projects

> How you read your company's projects, change a project's sales office and team, and take a partner agency's unit out of a project.

For a developer company, every residential development is a project, with its own sales office and team. Through the API you read the projects and their units, change their sales office and team, and take partners' units out of a project, under the rules of the Projects page in the company account. Reading needs the `listings:read` permission, and changes need `listings:write`. The units and the development itself are edited like any listing, with `PATCH /listings/{code}`.

What the key sees depends on the account's role in the company:

| Role | What it can do |
| - | - |
| the owner or an administrator | sees every project, changes their sales offices, chooses the team and takes partner agencies' units out |
| a project's manager | sees the projects they work on, changes their sales offices and takes partners' units out |
| an agent | sees the projects they work on |

A project the account can't see answers `404`, just like one that doesn't exist. An agency has projects only when it markets developments under a mandate (see [An agency's projects](#an-agency-s-projects)); otherwise the list comes back empty.

## Projects

`GET /account/projects` returns the projects the key sees, with cursor pagination. As in the portal's list, `q` searches the title, the street and the area, and `stage` keeps only one stage. `GET /account/projects/{code}` returns one project by the development's code:

```json theme={null}
{
  "data": {
    "code": "HEWPUTA8",
    "title": "Copou Park",
    "url": "https://housera.ro/anunt/hewputa8/iasi/copou-park",
    "status": "active",
    "stage": "under_construction",
    "address": "Str. Copou 12, Copou, Iași",
    "delivery": { "quarter": 4, "year": 2027 },
    "price_from": { "amount": 89000, "currency": "EUR" },
    "partners": { "active": 3, "pending": 1 },
    "requests": { "total": 27, "unassigned": 4 },
    "manages": true,
    "sales_office": {
      "address": "Bd. Carol I 1, Iași",
      "phone": "+40740123456",
      "email": "vanzari@exemplu.ro",
      "opening_hours": { "mon": { "from": "09:00", "to": "18:00" } }
    },
    "team": [
      { "name": "Andrei Ionescu", "email": "andrei@exemplu.ro", "role": "owner", "all_projects": true },
      { "name": "Maria Popa", "email": "maria@exemplu.ro", "role": "manager", "all_projects": false }
    ],
    "units": { "available": 42, "reserved": 3, "sold": 12 }
  }
}
```

* `manages` says whether the key's account runs the project, that is, whether it can change the sales office and take partners' units out.
* `team` starts with the owner and the administrators, who are on every project (`all_projects: true`), then the colleagues chosen for the project.
* `team[].email` goes only to the keys of the owner, the administrators and the managers, as on the Team page in the portal. A manager gets the emails of the colleagues on their projects, not those of the owner and administrators. An agent's key gets only its own email; for colleagues, `email` is `null`.
* `units` counts the project's public units, as on the development's page.
* `partners` and `requests` are the columns of the Projects list: the active partnerships and the partnership requests waiting, then the client requests and how many of them nobody has taken. They are figures only; you read the requests with `leads:read` (see [Client requests](https://api.housera.ro/en/guides/leads.md)).

## An agency's projects

An agency that markets a development under a requested or confirmed mandate has it under Projects, as in the portal. Only the agency's owner and administrators see the list, and they run these projects. The key of one of the agency's managers or agents gets an empty list.

On an agency's project:

* `manages` is `true`: the owner and administrators change the sales office, read the units and take partners' units out, as a developer does;
* `mandate` shows the open mandate: `status` (`requested` or `confirmed`), `decided_via` (`developer`, `moderator` or `legacy`), `valid_until` (the end of the contract) and `renewal_pending` (a new contract is waiting for the developer to confirm it);
* `developer` is the development's developer, as on the listing;
* the developer chooses the project's team, so `PATCH /projects/{code}` with `team` gets `403 forbidden`;
* `viewings` is `null`.

On a developer's projects, `mandate` is `null`.

## The sales office and the team

`PATCH /projects/{code}` changes the fields you send. A field sent as `null` is cleared.

```json theme={null}
{
  "address": "Bd. Carol I 1, Iași",
  "phone": "0740123456",
  "email": "vanzari@exemplu.ro",
  "opening_hours": { "mon": { "from": "09:00", "to": "18:00" }, "sat": { "from": "10:00", "to": "14:00" } }
}
```

`opening_hours` has one interval per day, for the days from `mon` to `sun`. A missing day, or one set to `null`, is closed. `from` comes before `to`, and `24:00` means the end of the day. The phone number is saved in international format.

You choose the team by sending your colleagues' emails, only with the owner's or an administrator's key:

```json theme={null}
{ "team": ["maria@exemplu.ro", "dan@exemplu.ro"] }
```

The list replaces the project's team. An email that doesn't belong to a colleague who works at the company now gets `team_not_member`, at its position in the list (`/team/1`), and nothing is saved. A manager's key that sends `team` gets `403 forbidden`. The response holds the updated project.

## The project's units

`GET /account/projects/{code}/units` returns every listing linked to the project, only for whoever runs the project. Your company's units come in any status, and partner agencies' units once they leave draft. `publisher=firm` or `publisher=partner` narrows them by who published them, `publisher=<id>` to a single partner agency, and `status` by status.

```json theme={null}
{
  "data": [
    {
      "code": "K3TQ8WZA", "title": "Apartament 2 camere, B2-14", "type": "apartment", "transaction": "sale",
      "status": "active", "reserved": false, "unit_ref": "B2-14", "price": 96000, "currency": "EUR",
      "subtype": "standard", "rooms": 2, "unit_kind": "apartment",
      "linked_by": "partner", "publisher": { "own": false, "name": "Casa Bună", "agency_id": 318 },
      "url": "https://housera.ro/anunt/k3tq8wza/iasi/apartament-2-camere"
    }
  ]
}
```

`linked_by` says who linked the unit: `firm` (your company), `partner` (a partner agency) or `import` (a CRM's feed).

`unit_kind` is the unit's type in the development's matrix, with the same codes as `unit_types[].kind` on the development. `publisher.agency_id` is the id of the company that published the unit, the same as `agency.id` in `GET /account/partnerships`. A company's name can change and its id cannot, so group the units by agency with the id.

## Taking a unit out of the project

`POST /projects/{code}/units/{unit}/detach` takes a partner agency's unit out of the project, like the Remove from project button in the portal. `{unit}` is the listing's code. The response is `204`. The listing stays published as an ordinary listing and loses its `unit_ref`. The agency gets a notification and the `listing.complex_unlinked` event, with `reason: developer_removed`. While the partnership lasts, the agency can link the unit again.

Only units with `linked_by: partner` are taken out this way. On your company's own unit, or on one that is no longer in the project, you get `404`. You take your company's units out by editing the listing with `complex: null`. See [Partner agencies](https://api.housera.ro/en/guides/partners.md).

## Viewings on a project

Each project has a `viewings` field, `null` for a firm that isn't a developer:

```json theme={null}
"viewings": {
  "offer": { "places": [ { "place": "office", "rooms": null }, { "place": "show_flat", "rooms": null } ],
             "open_house": false, "site_visit": true, "flat_viewings": false, "needs_start": false },
  "flat_viewings_started_at": null,
  "consultants": [ { "name": "Maria Popa", "email": "maria@example.com", "role": "manager" } ],
  "next_viewing": "2026-11-13T08:00:00+00:00",
  "next_open_house": "2026-11-15T08:00:00+00:00"
}
```

The stage decides what clients can book (`offer`), as on the portal:

| Stage | Where clients are met (`places`) | Open house |
| - | - | - |
| Launch or no stage | at the sales office (`office`) | only a visit day with places (`site_visit: true`) |
| Under construction | at the office or the show flat (`show_flat`) | only a visit day with places (`site_visit: true`) |
| Finished | at the office until you start the viewings at the flats (`needs_start: true`); then at the flats (`unit`), one choice per number of rooms (`rooms`) | yes |
| Mixed | at the flats and at the office | yes |

A visit day with places is published with `POST /listings/{code}/open-house`, with `capacity` on the window. See [Open house](https://api.housera.ro/en/guides/open-house.md#visit-days-on-a-project).

`consultants` are the colleagues chosen for the project's team who work at the firm now, managers first. They meet the clients, and a free time has one place for each of them. You choose the team with `PATCH /projects/{code}` (`team`). When the list is empty, whoever runs the listing does the viewings.

`next_viewing` is the next booked or requested viewing at the development, and `next_open_house` the development's next open house that hasn't ended. You read the viewings at the flats on each unit.

### Starting the viewings at the flats

`POST /projects/{code}/flat-viewings` starts the viewings at the flats of a Finished project, like the Start viewings button on the portal. The flats get times from their schedule, and clients choose a flat to see instead of a meeting at the office. The answer is the project, with `viewings.flat_viewings_started_at` filled in. A second request changes nothing.

The owner, an admin or the project's manager can start them; for anyone else the project doesn't exist (`404`). A project that isn't Finished gets `422 stage_not_finished` on `/stage`.

### The project's report

`GET /account/projects/{code}/viewing-report` gives the viewing report for the last 14 days, for the development and its units together, only to whoever runs the project:

```json theme={null}
{ "data": { "from": "2026-10-29", "to": "2026-11-12",
  "funnel": { "bookings": 31, "came": 19, "again": 6, "offers": 2 },
  "consultants": [ { "name": "Maria Popa", "bookings": 18, "came": 12, "offers": 1 } ] } }
```

The report has no client names. Consultants appear with their team names. `open_houses` adds, as in the portal, the open houses and site visit days of the period, with `code` (the listing), `came` and `interested`; the funnel counts only booked viewings.


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