Salt la conținutul principal
Când un client trimite un mesaj despre un anunț, cere să fie sunat sau cere o vizionare, cererea ajunge în căsuța din portalul Housera. Cu dreptul leads:read o citești și prin API, cu datele de contact ale clientului, și o aduci în CRM-ul tău.

Cine are acces

Cheia API vede cererile pe care contul le vede în portal, în firma cheii, plus cererile lui de pe anunțurile publicate în afara unei firme:
  • titularul și administratorii văd cererile întregii firme;
  • un manager de punct de lucru vede cererile punctului său (la un dezvoltator imobiliar, ale proiectelor sale);
  • un agent vede cererile pe care le are în grijă;
  • un cont fără firmă își vede cererile proprii.
Cererile altei firme nu apar, nici pentru cineva care lucrează în amândouă. Cât timp firma e suspendată, cheia vede doar cererile pe care contul le are în grijă, ca în portal. Cererile colegilor nu mai apar și nici evenimentele despre ele, iar după reactivare revin. Când firma se închide, cheia rămâne doar cu cererile contului din afara firmei. Pe cheia proprie, leads:read îl bifezi singur, în Setări → API. Un integrator îl primește doar dacă Housera i l-a aprobat, iar pagina de acord îi spune contului că integratorul va primi datele de contact ale clienților. Fără acest drept, apelurile la /leads primesc 403 missing_ability.

Lista cererilor

GET /leads întoarce cererile de la cea mai veche la cea mai nouă, cu paginare prin cursor.
Un cod sau un id pe care Housera nu îl găsește întoarce o listă goală. Filtrele se pot combina între ele și cu inbox=true, iar o valoare care nu e în listă (de exemplu status=unassigned) primește 422. since se compară cu updated_at, așa că o cerere deja importată poate apărea din nou. După id știi că o ai deja.

O cerere

GET /leads/{id} întoarce o singură cerere. Pentru o cerere la care cheia nu are acces, API-ul răspunde 404, ca pentru una care nu există.
Valorile lui inbox.reason sunt cele din portal:
  • no_listing: clientul a scris de pe pagina firmei, deci cererea nu are anunț;
  • left: agentul care avea cererea sau anunțul a plecat din firmă ori a fost dezactivat, iar munca lui a ajuns în „De preluat”;
  • no_agent: anunțul nu are un agent activ.

Lucrul cu cererile

Cu dreptul leads:write faci prin API ce faci cu o cerere în portal: îi schimbi etapa, nota și suma, o ștergi, adaugi contacte de mână și preiei cererile care nu au încă responsabil. Regulile sunt aceleași ca în portal, iar schimbarea se vede imediat acolo. leads:write merge doar împreună cu leads:read, fiindcă fiecare răspuns conține datele de contact ale clientului. Pe cheia proprie îl bifezi în Setări → API. Un integrator îl primește doar dacă Housera i l-a aprobat, iar contul îl acceptă separat pe pagina de acord. O cheie sau o legătură care are doar leads:read nu poate scrie: primește 403 missing_ability.

Etapa, nota și datele de contact

PATCH /leads/{id} schimbă câmpurile pe care le trimiți și le lasă pe celelalte cum sunt. Un câmp trimis cu null se golește, în afară de nume și etapă, care nu pot rămâne goale.
Răspunsul conține cererea, cu valorile noi. Dacă alt contact al aceluiași client pe același anunț are deja telefonul sau emailul trimis, primești 422, cu codul lead_duplicate pe /phone. DELETE /leads/{id} șterge cererea, ca din portal. Răspunsul e 204, iar cererea dispare din liste și din GET /leads/{id}. O cerere pe care cheia nu o vede, a unui coleg sau a altei firme, primește 404, ca una care nu există.

Un contact adăugat de mână

POST /leads adaugă un contact, ca butonul „Adaugă” din portal, cu tine ca responsabil. Doar name e obligatoriu, iar fără status contactul pornește din etapa new. Trimite un Idempotency-Key diferit pentru fiecare contact nou și același la reîncercarea unei cereri: în 10 minute, aceeași valoare întoarce contactul adăugat prima dată, cu 200 și cu același meta.possible_duplicate, fără să adauge altul. Titularul, administratorii și managerii adaugă contactul în cererile firmei. Dacă vrei să rămână doar în cererile tale, trimiți "board": "personal". La un agent, contactul ajunge mereu în cererile lui, iar "board": "firm" primește 403.

Contactul există deja?

Înainte să salveze, portalul verifică dacă ai deja contactul: caută în aceleași cereri (ale firmei sau ale tale) ultimul contact cu același telefon sau cu exact același nume. Prin API faci aceeași verificare, între cererile pe care cheia le vede, cu POST /leads/duplicate-check, cu name, phone și, opțional, board, ca la POST /leads:
Dacă găsește contactul, primești cererea în data, ca la GET /leads/{id}, iar în meta.matched_on ce s-a potrivit: phone, name sau amândouă. Dacă nu, primești "data": null și meta.matched_on gol. Verificarea nu schimbă nimic și cere aceleași drepturi ca adăugarea, leads:read și leads:write. Doi oameni pot avea același telefon, de exemplu linia unei agenții, așa că verificarea doar te avertizează. Tu decizi dacă adaugi contactul. POST /leads îl adaugă oricum și îți spune în meta.possible_duplicate contactul pe care îl găsește aceeași verificare, cu id și matched_on, sau null.

Cererile fără responsabil

Când un anunț al firmei nu are un agent activ, sau clientul scrie de pe pagina agenției, cererea ajunge la „De preluat” și o poate lua oricine din punctul de lucru. Prin API:
  • GET /leads?inbox=true întoarce cererile din „De preluat” pe care contul le poate prelua. Un agent le vede doar pe cele ale punctului său de lucru, iar titularul și administratorii, pe toate. GET /leads/{id} le citește și pe ele.
  • POST /leads/{id}/take îți dă cererea. Dacă un coleg a preluat-o înainte, primești 409 lead_already_taken. Dacă ai deja un contact cu același client, fără anunț, cererea se unește cu el, ca în portal: răspunsul e contactul tău, iar meta.merged_from e id-ul cererii unite, care nu mai există.
  • POST /leads/{id}/assign, cu {"agent_email": "coleg@agentia.ro"}, dă cererea unui coleg din echipa ta. Merge pentru titular, administratori și manageri, iar colegul primește notificarea din portal. Un email care nu e al unui coleg din echipă primește 422 agent_not_member, iar un coleg dezactivat, 422 agent_deactivated.
După ce o cerere e preluată, apare în GET /leads al responsabilului, cu agent completat.

Conversația cu clientul

Când clientul îți scrie pe un anunț, cererea are o conversație, aceeași pe care o vezi în Mesaje în portal. Prin API o citești și îi răspunzi clientului, ca din portal. Conversația o citește și îi răspunde doar contul care se ocupă de anunț, ca în portal. Titularul sau managerul care vede cererea unui agent primește 403 conversation_not_held la conversația ei. O cerere fără conversație (o cerere de apel, un contact adăugat de mână, un mesaj de pe pagina agenției) întoarce o listă goală.

Mesajele

GET /leads/{id}/messages întoarce mesajele de la cel mai vechi, cu paginare prin cursor. Cu after primești doar mesajele de după unul pe care îl ai deja. Citirea prin API nu marchează mesajele ca citite, deci nu le ascunde de cel care lucrează în portal.

Răspunsul

POST /leads/{id}/messages trimite un mesaj clientului, ca din portal. Clientul îl vede în conversație și primește aceleași notificări ca la un mesaj scris în portal.
Răspunsul e 201, cu mesajul. Trimite un Idempotency-Key diferit pentru fiecare mesaj nou și același la reîncercarea unui mesaj: în 10 minute, o cerere cu aceeași valoare întoarce mesajul trimis prima dată, cu 200, și nu trimite altul. Textul are cel mult 2.000 de caractere. Răspunsul e refuzat cu 409 când cererea nu are conversație (no_conversation), când conversația e doar de citit, fiindcă anunțul sau contul clientului a fost șters (conversation_closed), și când una dintre părți a blocat-o pe cealaltă (conversation_blocked). Răspunsurile prin API și cele din portal au aceeași limită, 20 pe minut și 200 pe oră pe cont.

Editarea, ștergerea și citirea

  • PATCH /leads/{id}/messages/{message}, cu {"body": "…"}, schimbă textul unui mesaj scris de tine, în primele 15 minute și cât timp conversația e deschisă. După 15 minute primești 409 edit_window_closed. Clientul vede mesajul marcat ca editat.
  • DELETE /leads/{id}/messages/{message} șterge un mesaj scris de tine, oricând. Mesajul rămâne în conversație ca „Mesaj șters”, fără text.
  • Un mesaj al clientului nu se editează și nu se șterge: primești 403 message_not_yours.
  • POST /leads/{id}/messages/read marchează mesajele clientului ca citite, ca atunci când deschizi conversația în portal. Clientul nu află nimic.

Evenimentul lead.message_received

Când clientul scrie din nou în conversație, contul care se ocupă de anunț primește evenimentul lead.message_received, pe webhook și în GET /events, dacă are o cheie cu leads:read. Evenimentul are lead_id și message_id, fără textul mesajului, pe care îl citești cu GET /leads/{id}/messages?after=…. Primul mesaj al clientului, cel care deschide conversația, vine ca lead.created sau, dacă clientul avea deja o cerere pe anunț, ca lead.updated, deci nu produce și lead.message_received.
Mesajele clienților sunt date personale, ca datele lor de contact. Păstrează-le doar cât îți trebuie pentru a răspunde cererii.

Evenimentul lead.created

Când un client îți trimite prima cerere pe un anunț, primești evenimentul lead.created, pe webhook și în GET /events. Evenimentul nu conține datele clientului: are lead_id și source, iar datele le citești cu GET /leads/{id}. În GET /events îl vezi cu orice cheie care are leads:read, chiar dacă nu are listings:read. Evenimentul ajunge doar la conturile care văd cererea în căsuță și au o cheie cu leads:read. Din ziua pe care ți-o anunțăm, o cerere care ajunge la „De preluat” produce lead.created și pentru cei care o pot prelua, adică pentru toți cei din punctul de lucru pe care îi anunță și portalul, agenții inclusiv. Un webhook îl primește doar dacă are în spate dreptul leads:read. Detaliile sunt în Webhook-uri.

Evenimentele lead.assigned și lead.removed

Din ziua pe care ți-o anunțăm, afli și ce se întâmplă cu o cerere după ce a venit. lead.assigned vine când cererea are un responsabil nou. by spune cum: take (cineva a preluat-o din „De preluat”), assign (titularul, un administrator sau un manager a dat-o unui coleg) sau handover (a trecut la un coleg odată cu munca cuiva care a plecat din firmă sau a fost dezactivat, ori cu un anunț mutat la alt agent). agent e noul responsabil, iar previous_agent cel de dinainte, fiecare cu name și email; previous_agent e null când cererea aștepta în „De preluat” sau când contul colegului de dinainte a fost șters. Îl primesc cei care văd cererea acum. lead.removed vine când cererea nu mai e a ta, cu reason:
  • deleted: cererea a fost ștearsă, din portal sau prin API;
  • merged: cererea s-a adăugat la cererea aceluiași client pe care o avea deja colegul care a preluat-o;
  • out_of_reach: cererea nu mai e în raza ta, de exemplu a preluat-o un coleg din „De preluat” sau ai predat-o.
Îl primesc cei care primeau până atunci evenimentele cererii. După lead.removed, GET /leads/{id} răspunde 404, dar evenimentul rămâne în GET /events. Ștergi cererea din sistemul tău sau o marchezi ca ieșită din raza ta. Ambele evenimente au lead_id, ca lead.created, și cer dreptul leads:read. Orice webhook care primește lead.created le primește și pe ele, fără să le bifezi.

Evenimentul lead.updated

Când același client revine pe același anunț cu o cerere nouă, de exemplu îți cere să-l suni după ce ți-a scris, cererea nouă se adaugă la cea pe care o ai deja. Nu apare o cerere separată, dar primești evenimentul lead.updated, cu același lead_id. source din eveniment spune pe ce canal a venit cererea nouă (aici phone), iar source din GET /leads/{id} rămâne canalul primei cereri. Momentul cererii noi e created_at al evenimentului. updated_at al cererii devine momentul cererii noi, deci GET /leads?since= o aduce din nou. La fel primești lead.updated când clientul scrie din nou de pe pagina firmei după ce un coleg i-a preluat cererea, și când o cerere din „De preluat” se unește, la preluare, cu contactul pe care îl ai deja cu același client. lead.updated ajunge la aceleași conturi și webhook-uri ca lead.created și cere tot dreptul leads:read. Pe un webhook din Setări → API îl bifezi separat.
Datele de contact ale clienților sunt date personale. Păstrează-le doar cât îți trebuie pentru a răspunde cererii și nu le folosi în alt scop.

Ștergerea datelor clientului

Housera șterge datele unui client în două cazuri, iar tu trebuie să le ștergi și din sistemul tău. Când clientul își șterge contul, cererile lui rămân în portal, dar fără datele lui: numele devine anonim, iar telefonul, emailul, mesajul și nota se golesc. Cererea primește erased: true, iar updated_at devine momentul ștergerii, așa că GET /leads?since= o aduce din nou. Primești și evenimentul lead.erased, cu reason: account_deleted, chiar și pentru o cerere pe care ai șters-o deja din portal. O cerere fără nicio activitate de 24 de luni, sau una ștearsă din portal de mai mult de 30 de zile, se șterge definitiv. Chiar înainte primești lead.erased, cu reason: retention. După aceea GET /leads/{id} răspunde 404, iar evenimentul rămâne în GET /events 35 de zile. lead.erased ajunge la aceleași conturi ca lead.created și cere tot dreptul leads:read. Orice webhook care primește lead.created îl primește și pe el; nu apare în lista de evenimente a webhook-ului și nu se bifează.
Când primești lead.erased sau vezi o cerere cu erased: true, ștergi din sistemul tău numele, telefonul, emailul, mesajul și nota clientului din cererea respectivă. Ai primit datele de la Housera, deci ștergerea lor la noi te privește și pe tine (GDPR, art. 17 alin. 2 și art. 19).