API pentru agenții și CRM-uri

Orice agenție din România își poate conecta propriul CRM la PrimulAnunț.ro: trimiți anunțurile automat, adaugi fotografii și le poți urca pe primul loc, fără să intri pe site.

1. Cheia de acces

Generezi cheia din contul tău, secțiunea „Integrare CRM”. O trimiți la fiecare cerere în antetul Authorization. Cheia se afișează o singură dată și poate fi revocată oricând.

Authorization: Bearer pa_live_xxxxxxxxxxxxxxxx
Content-Type: application/json

Testezi conexiunea cu: GET https://www.primulanunt.ro/api/public/v1/ping

2. Publicare anunț

POST /api/public/v1/listings. Dacă trimiți external_id (identificatorul din CRM-ul tău), a doua trimitere actualizează același anunț în loc să creeze unul nou. Agențiile verificate publică direct; restul conturilor trec prin moderare.

{
  "external_id": "CRM-10245",
  "title": "Apartament 3 camere, bloc nou, Cluj-Napoca",
  "description": "Text descriptiv...",
  "purpose": "sale",
  "property_type": "apartament",
  "price": 145000,
  "currency": "EUR",
  "rooms": 3,
  "bathrooms": 2,
  "surface_m2": 78,
  "county": "Cluj",
  "city": "Cluj-Napoca",
  "area": "Bună Ziua",
  "features": ["Balcon", "Parcare", "Lift"]
}

3. Fotografii

POST /api/public/v1/listings/{id}/media — încărcare directă de fișiere, multipart/form-data, câmpul file (până la 20 imagini, maximum 10 MB fiecare). Prima imagine devine automat coperta anunțului. La {id} poți folosi fie identificatorul nostru, fie external_id-ul tău.

curl -X POST https://www.primulanunt.ro/api/public/v1/listings/CRM-10245/media \
  -H "Authorization: Bearer pa_live_..." \
  -F "file=@foto1.jpg" -F "file=@foto2.jpg"

GET /api/public/v1/listings/{id}/media listează fotografiile (fiecare cu id, url și position). DELETE /api/public/v1/listings/{id}/media/{mediaId} șterge o fotografie. Cu ?replace=true la încărcare înlocuiești tot setul dintr-un singur apel — util când agentul schimbă pozele în CRM.

curl -X POST "https://www.primulanunt.ro/api/public/v1/listings/CRM-10245/media?replace=true" \
  -H "Authorization: Bearer pa_live_..." \
  -F "file=@nou1.jpg" -F "file=@nou2.jpg"

Câmpuri suplimentare acceptate

Pe lângă datele de bază, poți trimite: agent_name, agent_phone, agent_email (agentul responsabil, afișat la anunț), lat, lng și location_precision (exact sau approximate), postal_code, floor și floors_total, video_url.

is_private înseamnă anunț nelistat public (vizibil doar prin link direct). Pentru anunțurile de agenție trimite false.

Răspunsul conține câmpul url cu linkul public complet, în forma https://www.primulanunt.ro/anunturi/{slug}.

Notificări de moderare (webhook)

Pentru conturile fără publicare directă, configurează în Cont → Integrare CRM adresa care primește evenimentele listing.approved și listing.rejected. Trimitem un POST JSON cu antetul x-primulanunt-signature: sha256=… (HMAC-SHA256 peste corpul cererii, cu secretul afișat la salvare).

{
  "event": "listing.rejected",
  "listing": {
    "id": "…", "external_id": "LK-992978", "slug": null,
    "status": "rejected", "rejection_reason": "Fotografii insuficiente", "url": null
  }
}

Limite de trafic

Nu impunem o limită fixă pe cheie. Pentru sincronizarea inițială a câtorva sute de anunțuri recomandăm maximum 2–3 cereri pe secundă și reluarea cererii după câteva secunde dacă primești o eroare temporară.

4. Actualizare și retragere

PATCH /api/public/v1/listings/{id} modifică doar câmpurile trimise (preț, descriere, status). DELETE pe aceeași adresă arhivează anunțul. GET /api/public/v1/listings îți listează toate anunțurile.

5. Promovare în timp real

POST /api/public/v1/listings/{id}/boost alocă credite anunțului (active 24 de ore). Cu {"to_top": true} anunțul urcă direct pe locul #1, cu costul minim calculat în acel moment.

{ "points": 25 }
// sau
{ "to_top": true }

Fiecare cont nou primește 200 de credite incluse, ca să poți testa imediat.

Răspunsuri și erori

Toate răspunsurile sunt JSON. 401 — cheie lipsă sau revocată; 404 — anunț inexistent; 422 — date invalide (primești lista câmpurilor); 400 — eroare de procesare, cu mesaj explicit în română.