Tenere allineata una copia
La maggior parte delle integrazioni finisce per tenere una copia di una parte del catalogo. Farlo male è l'errore più costoso che questa API metta a disposizione, e ha tre forme riconoscibili: rileggere tutto a intervalli regolari, paginare per scostamento e trattare una scheda assente come una scheda cancellata.
La forma che funziona
- Fai un riempimento iniziale. Percorri il filtro che ti interessa dal primo cursore all'ultimo, salvando le schede man mano.
- Annota il livello di guardia. Tieni l'
updated_atpiù recente che hai visto, non l'ora in cui è girato il tuo processo. Sono cose diverse, ed è in quella differenza che le schede si perdono. - Interroga le modifiche. Chiedi
updated_sincequalche minuto prima di quel riferimento. - Oppure smetti di interrogare. I webhook eliminano del tutto questo ciclo, e non costano quota.
import { Skautik } from "@skautik/sdk";
const skautik = new Skautik({ apiKey: process.env.SKAUTIK_API_KEY! });
async function backfill(city: string) {
let newest = "";
for await (const property of skautik.properties.listAll({ city })) {
await upsert(property);
if (property.updatedAt > newest) {
newest = property.updatedAt;
}
}
return newest;
}L'iteratore segue il cursore al posto tuo e si ferma su has_more, che è l'unica
condizione corretta. Scrivere il ciclo a mano è il punto in cui ci si ferma su una pagina
corta, mentre una pagina piena può comunque essere l'ultima.
Fai sovrapporre la finestra
Chiedi qualche minuto prima del tuo livello di guardia, non il riferimento stesso:
GET /v1/api/properties?city=Berlin&updated_since=2026-08-11T03:55:00ZLe schede vengono scritte in modo concorrente. Un confine rigido perde tutto ciò che è stato confermato un istante dopo il tuo taglio ma datato un istante prima, e quella scheda resta mancante finché non capita che cambi di nuovo. Trattare due volte la stessa scheda non costa nulla se la tua scrittura è un upsert; perderne una ti costa una risposta sbagliata per un tempo indefinito.
L'assenza non è una cancellazione
Una scheda che smette di comparire in un elenco filtrato non è necessariamente sparita. Può
essere cambiata in un modo che la porta fuori dal tuo filtro: un rialzo di prezzo oltre il
tuo max_price, un cambio di quartiere, un ritiro.
Il ritiro è esplicito. Un immobile ritirato mantiene il suo identificatore e resta
leggibile per id; lo stato del suo annuncio dice archived oppure sold. Esce
dall'elenco predefinito perché il predefinito sono gli annunci attivi, non perché abbia smesso
di esistere.
Quindi: non dedurre mai una cancellazione da un'assenza. O ti iscrivi a property.withdrawn,
oppure chiedi lo stato esplicitamente quando hai bisogno di saperlo:
GET /v1/api/properties?city=Berlin&status=archivedSe la tua copia cancella tutto ciò che esce da una pagina filtrata, una sola variazione di prezzo cancellerà un immobile che è ancora sul mercato.
Cosa memorizzare
Memorizza come minimo l'identificatore e l'updated_at. L'identificatore è opaco
e stabile; la marca temporale è ciò che rende economica la sincronizzazione successiva.
Memorizza anche l'external_id se sei tu la fonte della scheda. È il tuo
identificatore restituito indietro, ed è ciò che ti permette di riconciliare senza tenere una
tabella di corrispondenza fra i nostri id e i tuoi.
Costo
| Approccio | Richieste al giorno, 20.000 immobili |
|---|---|
| Rilettura ogni ora, 200 per pagina | 2.400 |
updated_since ogni ora | da 24 a 50, a seconda del ricambio |
| Webhook | 0 |
La prima riga è il motivo per cui esistono le quote. La terza è il motivo per cui esistono i webhook.
Quando un riempimento è lo strumento sbagliato
Letture continue e ad alto volume dell'intero catalogo si servono meglio con un'esportazione che con una scansione più rapida. Un'esportazione è una sola richiesta, produce un solo file e non compete con il tuo traffico di produzione per il limite di picco. Chiedici prima di costruire qualcosa che pagini l'intero mercato ogni notte.