Skip to main content
The agenda gathers the viewings, requests and open houses of every listing you run, like the agenda in your account. Through the API you read it and work with each viewing. Reading needs the listings:read ability. The clients’ details also need leads:read.

What the agenda holds

A key’s agenda is its account’s agenda in the portal:
  • the account’s active listings;
  • the listings whose viewings a colleague gave to it;
  • for the owner, the admins and the managers, the team’s listings (a manager sees their team);
  • for a developer’s consultant, the projects they work on, and there only the clients who came to them and the open days.
A listing that is not public does not appear. A key bound to a firm sees only that firm’s listings and the account’s listings without a firm.

Reading the agenda

GET /account/viewings returns the hours of a range, one page at a time, in order of time:
meta.pending_requests counts every request waiting for your answer in the agenda, not only those in the range. A request you answered with another time waits for the client and is not counted, as in the portal. meta.next_at is the next viewing or request. GET /viewings/{id} returns one hour, in the same shape. An hour outside the agenda answers 404.

The states

  • available: a free hour.
  • pending: a request waiting for your answer, until request_expires_at.
  • booked: a booked viewing that has not passed.
  • completed: a booked viewing whose hour has ended. The state is worked out when you read it: a viewing becomes completed as soon as its hour ends.
completed appears only here and in GET /viewings/{id}. A listing’s agenda (GET /account/listings/{code}/viewings) shows only the hours that have not passed, with the states available, pending and booked.

The client and their details

visitor and outcome_note come only to a key with the leads:read ability. For other keys they are null, while outcome and outcome_at stay.
  • account: true: the client has a Housera account, with a name, an email and a phone.
  • account: false: a client without an account, added by hand. They have a name and, if you entered it, a phone, but no email. A listing’s agenda does not name them (visitor: null).
Housera keeps these details no longer than in the portal. The name and phone of a client added by hand are erased 90 days after the viewing, and visitor is then null. The note from “How did it go?” is erased after 24 months.

Free hours

  • source: schedule for the hours generated by the weekly schedule, manual for those put in by hand.
  • held: the hour is kept for a short while for someone signing in to book it.
  • bookable: whether a client can book the hour now. It is false when the hour is too close (the notice), when whoever runs the viewings is busy at the same time at another listing (with the break between viewings), or when the hour is kept. On hours that are not free it is null.

Developers’ projects

On a project with several consultants, each hour has one row per consultant, with the same starts_at and a different seat. The rows are not duplicates: they are the hour’s places. Once booked, agent is the consultant who meets the client, and place says where: office (the sales office), show_flat (the show flat) or unit (a finished flat, with place_rooms rooms). Elsewhere, agent is whoever runs the listing’s viewings. agent.email goes to the keys of the holder, the admins and the manager who has that person on their team, and to the person’s own key; any other key gets null, as on the Team page in the portal.

A listing’s agenda

GET /account/listings/{code}/viewings gets the same new fields on each hour (source, duration_min, held, bookable, booked_at, proposed_starts_at, attendance_confirmed_at, reminded_day_at, reminded_soon_at, outcome, outcome_at, agent, place, place_rooms, seat), plus timezone and schedule_mode on the listing.

The client who called

POST /listings/{code}/viewings/clients puts in the agenda a client without an account with whom you agreed a time on the phone, as „Adaugă în agendă” does in the portal. It needs listings:write, leads:read and leads:write, since it adds a contact.
  • starts_at is read as for published times: without a time zone, on the clock of the listing’s place. duration_min is 15, 30, 45, 60 or 90. name has at most 120 characters, and phone is optional.
  • The time is booked at once, under the same overlap rules as a time published on the listing. The free times under it go.
  • The client lands in the contacts with the source other. With a phone, the contact moves to the Viewing stage.
  • The answer is 201, with the time (visitor with account: false).
  • With the Idempotency-Key header, the same request again within 10 minutes adds nothing and returns the time added the first time, as it is now, with 200. The same key with another body is refused on /idempotency_key. Without a key, a second request for the same time gets 409 listing_action_refused, since the time is no longer free.
  • A time that overlaps another viewing or an open house, one in the past or one that does not exist at a clock change is refused on /starts_at.
The viewing of such a client is moved directly, with PATCH /viewings/{id}.

Another hour for a client with an account

POST /viewings/{id}/proposal with {"starts_at": "2026-11-15T10:00"} proposes another time to the client. The viewing keeps its time until they answer, and the answer now has proposed_starts_at. The client gets the message as from the portal. When they accept, starts_at becomes the proposed time and proposed_starts_at is null again. An open house, a viewing without a client with an account and one that is over get 409 listing_action_refused. A time that overlaps another, or at which whoever runs the viewings is not free (with the break between viewings, at all their listings), is refused on /starts_at.

Cancelling with a note

POST /viewings/{id}/cancel optionally takes note, at most 300 characters, which goes into the message to the client with an account (a client added by hand gets no messages from Housera). note is optional.

“How did it go?”

PUT /viewings/{id}/outcome says what came of a viewing that took place:
  • outcome is offer (wants to make an offer), again (comes back), not_interested or no_show. note has at most 500 characters.
  • The answer can be changed at any time, and a new request without note clears the note.
  • On offer, the client’s contact on the listing moves to the Offer stage, if it had not gone that far. The answer has meta.lead_moved_to_offer.
  • It needs listings:write and leads:write, since it moves a contact between stages.
  • A viewing that has not taken place yet gets 409 listing_action_refused.

The line of viewings in “My listings”

GET /account/listings?include=viewings adds the viewings field to each listing:
next_at and next_kind are the next appointment (a viewing or an open house), more how many follow it, bookable whether it has free hours to book, on_request whether it is “On request”. Without include, the answer doesn’t have these fields, and the listing’s etag does not change. GET /account/listings?viewings=none returns only the active listings with no schedule: no free hours, nothing scheduled, and not “On request”.

What the CRM learns without asking

From the day we announce to you, every change to a viewing also goes out as an event, the same from the portal and from the API. That way you also learn what a colleague did in the portal, without reading the agenda every minute. The events carry slot_id and the time, with no client details. With slot_id you read the viewing through GET /viewings/{id}, and only a key with leads:read sees the client’s name and phone. When a client with an account moves their own viewing to another free time, you get viewing.cancelled and then viewing.booked, with a new id. When the listing comes off the market (you pause it, mark it sold or withdraw it, or it is rejected), its upcoming viewings are released without an event for each one. You learn it from the listing’s event, for example listing.paused or listing.sold, and clients with an account hear it from Housera. viewing.completed can arrive up to an hour late. The state in GET /account/viewings is completed as soon as the time is over: if you need it right away, read it. The full list, with each event’s fields and who receives it, is in Webhooks.