Për portalet, CRM-të dhe ndërtuesit

Listimi Partner API

Publikoni dhe sinkronizoni automatikisht pronat nga çdo portal ose sistem i brendshëm. Çdo integrim merr një përdorues API dhe një çelës privat të lidhur me agjencinë ose agjentin, me kuotë dhe leje të veçanta.

REST + JSON Çelës privat i ruajtur me SHA-256 Upsert me external_id Leje sipas scope

URL bazë: https://www.listimi360.al/api/v1

1. Krijimi i kredencialeve

  1. Hyni në Panel → API & Integrime (pronari i agjencisë, agjenti i pavarur ose administratori).
  2. Shtypni “Krijo përdorues API”, jepini një emër (p.sh. “Portali XYZ”) dhe zgjidhni lejet.
  3. Ruani API User (p.sh. lst_8f2a…) dhe Private Key (sk_live_…). Çelësi privat shfaqet vetëm një herë; mund ta rigjeneroni në çdo kohë.

Administratori mund të krijojë kredenciale për çdo agjenci ose agjent dhe t’i çaktivizojë menjëherë.

2. Autentikimi

Dërgoni kredencialet në çdo kërkesë me njërën nga mënyrat:

http
X-API-User: lst_xxxxxxxxxxxxxxxx
X-API-Key: sk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
http
Authorization: Basic base64("lst_xxxxxxxxxxxxxxxx:sk_live_xxxx…")

Përdorni gjithmonë HTTPS dhe mos e ekspozoni çelësin privat në shfletues ose aplikacione mobile.

3. Endpoints

MetodaRrugaLejaPërshkrimi
GET/api/v1/meproperties:readInformacion për çelësin, planin dhe kuotën
GET/api/v1/reference—Llojet, qytetet, veçoritë dhe vlerat e lejuara
GET/api/v1/propertiesproperties:readLista e pronave (page, per_page, status, updated_since, external_id)
POST/api/v1/propertiesproperties:writeKrijo ose përditëso (upsert sipas external_id)
POST/api/v1/properties/bulkproperties:writeDeri në 25 prona për kërkesë
GET/api/v1/properties/{id}properties:readNjë pronë sipas ID ose ext:{external_id}
PUT/api/v1/properties/{id}properties:writeZëvendëso të gjitha fushat
PATCH/api/v1/properties/{id}properties:writeNdrysho vetëm fushat e dërguara (p.sh. çmimin ose statusin)
DELETE/api/v1/properties/{id}properties:writeArkivo (ose ?hard=1 për fshirje përfundimtare)
POST/api/v1/mediaproperties:writeNgarko një foto (multipart “file” ose JSON { url })
GET/api/v1/leadsleads:readMesazhet e klientëve për pronat tuaja (?since=ISO)

4. Publikimi dhe përditësimi

POST /api/v1/properties krijon pronën (201). Nëse external_id ekziston tashmë për këtë çelës, prona përditësohet (200) — kështu mund ta dërgoni feed-in sa herë të doni pa krijuar dublikime.

bash
curl -X POST https://www.listimi360.al/api/v1/properties \
  -H "X-API-User: $LISTIMI_USER" \
  -H "X-API-Key: $LISTIMI_KEY" \
  -H "Content-Type: application/json" \
  -d @prona.json
json
{
  "external_id": "CRM-10045",
  "title": "Apartament 2+1 me pamje nga liqeni",
  "description": "Apartament i rikonstruktuar, kati 6 me ashensor.",
  "purpose": "sale",
  "type": "Apartament",
  "price": 189000,
  "area": 104,
  "beds": 2,
  "baths": 2,
  "balconies": 2,
  "garage": 1,
  "floor": 6,
  "layout": "2+1",
  "furnished": "partial",
  "location": { "city": "Tiranë", "zone": "Liqeni i Thatë", "address": "Rruga Herman Gmeiner", "lat": 41.3155, "lng": 19.8213 },
  "features": ["Ashensor", "Parkim", "Kondicioner"],
  "images": ["https://cdn.portali-juaj.al/foto/10045-1.jpg", "https://cdn.portali-juaj.al/foto/10045-2.jpg"]
}

Përgjigja:

json
{
  "data": {
    "id": "6c1f2e9a-…",
    "external_id": "CRM-10045",
    "url": "https://www.listimi360.al/prona/6c1f2e9a-…",
    "status": "published",
    "price": 189000,
    "currency": "EUR",
    "images": ["https://www.listimi360.al/api/media/…"],
    …
  },
  "created": true,
  "warnings": []
}

Ndryshim i shpejtë i çmimit:

bash
curl -X PATCH https://www.listimi360.al/api/v1/properties/ext:CRM-10045 \
  -u "$LISTIMI_USER:$LISTIMI_KEY" \
  -H "Content-Type: application/json" \
  -d '{"price": 179000}'

5. Import masiv

Dërgoni deri në 25 prona në një kërkesë. Çdo pronë përpunohet veçmas; gabimi në njërën nuk ndalon të tjerat.

json
POST /api/v1/properties/bulk
{ "items": [ { "external_id": "A-1", … }, { "external_id": "A-2", … } ] }

→ { "data": [ { "index": 0, "ok": true, "created": true, "id": "…" },
             { "index": 1, "ok": false, "error": { "code": "validation_error", "message": "…" } } ],
    "meta": { "received": 2, "succeeded": 1, "failed": 1 } }

6. Fushat e pronës

FushaTipiE detyrueshmePërshkrimi
external_idstringRekomandohetID e pronës në sistemin tuaj. Përdoret për sinkronizim pa dublikime (upsert).
titlestring ≤160PoTitulli i shpalljes.
descriptionstringPoPërshkrimi i plotë (lejohen rreshta të rinj).
purposeenumPosale (Në shitje), rent (Me qira), daily (Qira ditore)
typeenumPoApartament, Vilë, Duplex, Penthouse, Garsonierë, Shtëpi private, Zyrë, Njësi biznesi, Hotel, Magazinë, Post parkimi, Depo, Truall, Tokë bujqësore, Prona në bregdet
priceintegerPo*Çmimi në EUR. *Opsional kur price_on_request=true.
price_on_requestbooleanJoShfaq “Kontaktoni për çmim”.
areaintegerPoSipërfaqja në m².
beds / bathsintegerJoDhoma gjumi / tualete.
balconies / garageintegerJoNumri i ballkoneve / vendeve të parkimit.
floor / total_floorsintegerJoKati dhe numri total i kateve.
year_builtintegerJoViti i ndërtimit.
layoutstringJop.sh. 1+1, 2+1, 3+1.
furnishedenumJoyes (I mobiluar), partial (Pjesërisht i mobiluar), no (I pamobiluar)
citystringPoQyteti (normalizohet automatikisht: “Tirane” → “Tiranë”).
country / zone / addressstringJoShteti, zona/lagjja dhe adresa. Mund të dërgohen edhe brenda objektit "location".
lat / lngnumberJoKoordinatat e sakta. Pa to, prona vendoset pranë qendrës së qytetit.
featuresstring[]JoLista e veçorive, p.sh. Ashensor, Parkim, Garazh, Ballkon, Tarracë…
imagesstring[]JoURL publike të fotove (JPG/PNG/WebP ≤8 MB, maks. 20). Importohen automatikisht në serverin tonë.
video_urlhttps URLJoVideo ose tur virtual.
statusenumJopublished (parazgjedhje), draft, archived.
seo_titlestring ≤70JoTitull i personalizuar për Google. Bosh = gjenerohet automatikisht me llojin, zonën, qytetin dhe çmimin.
seo_descriptionstring ≤170JoMeta përshkrim i personalizuar. Bosh = gjenerohet nga të dhënat e pronës.

Pranohen edhe sinonimet: bedrooms, bathrooms, surface, latitude, longitude, neighborhood, property_type, transaction.

7. Fotot

Në fushën images dërgoni URL publike. Serveri i shkarkon dhe i ruan në hapësirën tuaj (1 GB për llogari). URL-të e importuara më parë ripërdoren, kështu që ridërgimi i të njëjtit feed nuk i dyfishon fotot. Fotot që dështojnë raportohen te warnings, pa e bllokuar publikimin. Kur dërgoni images, lista zëvendëson galerinë ekzistuese; nëse e lini jashtë, galeria mbetet e pandryshuar.

8. Arkivimi dhe fshirja

DELETE /api/v1/properties/ext:CRM-10045 e arkivon pronën (hiqet nga portali dhe liron kuotën). Me ?hard=1 fshihet përfundimisht. Për ta rikthyer një pronë të arkivuar dërgoni PATCH me {"status":"published"}.

9. Mesazhet nga klientët

Çdo mesazh që klientët dërgojnë nga faqja e pronës mund të tërhiqet në CRM-në tuaj:

bash
curl "https://www.listimi360.al/api/v1/leads?since=2026-10-01T00:00:00Z" -u "$LISTIMI_USER:$LISTIMI_KEY"

10. Gabimet & kufijtë

json
{ "error": { "code": "validation_error", "message": "Vlerë numerike e pavlefshme për \"price\" (1–1000000000).", "details": { "field": "price" } } }
HTTPcodeKuptimi
400invalid_jsonTrupi nuk është JSON i vlefshëm
401unauthorizedMungojnë ose janë të gabuara kredencialet
403forbidden / insufficient_scopeÇelës i çaktivizuar ose pa lejen e duhur
404not_foundProna nuk ekziston për këtë llogari
409quota_exceededËshtë arritur kufiri i pronave aktive të planit
422validation_errorFushë e munguar ose e pavlefshme (shih details.field)
429rate_limitedMë shumë se 120 kërkesa në minutë për çelës

11. Shembuj kodi

PHP

php
$ch = curl_init("https://www.listimi360.al/api/v1/properties");
curl_setopt_array($ch, [
  CURLOPT_POST => true,
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_USERPWD => getenv('LISTIMI_USER') . ':' . getenv('LISTIMI_KEY'),
  CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
  CURLOPT_POSTFIELDS => json_encode($property),
]);
$response = json_decode(curl_exec($ch), true);

JavaScript (Node.js)

js
const res = await fetch("https://www.listimi360.al/api/v1/properties", {
  method: "POST",
  headers: {
    "X-API-User": process.env.LISTIMI_USER,
    "X-API-Key": process.env.LISTIMI_KEY,
    "Content-Type": "application/json",
  },
  body: JSON.stringify(property),
});
const { data, warnings } = await res.json();

Python

python
import os, requests
r = requests.post("https://www.listimi360.al/api/v1/properties",
    auth=(os.environ["LISTIMI_USER"], os.environ["LISTIMI_KEY"]),
    json=property)
r.raise_for_status()
print(r.json()["data"]["url"])