Skip to main content
Use this guide to operate a local copy of the classified data selected by your Immoteur filters. It combines a full export for the first snapshot, live notifications for prompt updates, and delta exports to reconcile changes over time. These are separate delivery modes, configured on separate compatible services. This is not an unfiltered copy of every Immoteur resource. It contains the public-exportable classifieds that currently match your configured service filters. The generated API reference remains the source of truth for payload schemas.

Start the receiver before the baseline

Configure an HTTPS receiver and make it ready before requesting or scheduling the first export. Create a classified service for live notifications and a separate, compatible classifieds service for full and delta exports. They may use the same receiver URL, but they cannot be the same service. Set onlyNew to false on the live classified service so it receives eligible updates as well as creations. If your receiver restricts source IPs, allowlist Immoteur egress IPs before testing. Keep the HTTP handler small: persist or enqueue the request, return 2xx, then process it in your own worker. See Webhook delivery, retries, and idempotency for the receiver, timeout, header, and retry contract.

Establish the first snapshot with a full export

Choose a Full export to establish the baseline. It delivers every currently matching public-exportable listing in one or more chunks, followed by a terminal completion message with an empty items array. Each item is a full public Classified snapshot. Every message for this export has exportType set to full.
The terminal completion message keeps the same exportId and exportType:
These simplified examples illustrate exportType and isComplete. Every export message also requires batchId, itemCount, and batchCount; the terminal completion message has batchId: null. See webhooks.classifieds-export in the generated API reference for the complete schema. exportType identifies the effective type delivered for the entire export and has the same value on every data batch and terminal completion message. It does not include the requested mode or a fallback reason. Do not assume a fixed chunk size, delivery order, or number of deliveries. Treat isComplete: true with an empty items array as the terminal completion signal for that export.

Process live classified notifications

Use the classified payload type for live notifications. They give your local copy prompt updates when a classified is created or when an eligible normalized field changes. A meta.lastSeenAt-only revisit is retained in export and delta ledgers only; it never produces a live notification, and Immoteur does not send periodic keep-alives. Persist a delivery ledger keyed by X-Immoteur-Service-Id and X-Immoteur-Event-Id before acknowledging a live notification. Delivery is at least once and unordered, so use the ledger to make processing idempotent. The classified-notification event ID is retained across retries and is the idempotency key. X-Immoteur-Delivery-Id identifies an HTTP attempt only, so record it for diagnostics but do not use it as the idempotency key. Do not promise replay, exactly-once delivery, or arrival order in your integration; export chunks do not promise event-ID stability. Use meta.lastModifiedAt for normalized source changes and meta.lastSeenAt to retain the most recent observed revisit.

Reconcile with delta exports

Use a Full export for the first baseline and whenever you deliberately need a new snapshot of the current filter scope. It selects every currently matching public-exportable classified.
If no compatible successful baseline exists, the baseline is older than 7 days, or the selection filters have changed, a requested Delta export falls back to a Full export. Every fallback uses exportType: "full" for each data batch and the terminal completion message. Changing the destination URL alone does not invalidate a compatible baseline. The receiver payload exposes the effective exportType, but not the requested mode or fallback reason.

Make local writes safe for duplicates and late delivery

Store each source snapshot by classified identifier, retain the raw payload, and keep your own enrichment in separate fields or tables. Do not let arrival order, chunk position, delivery ID, or retry count decide which source snapshot wins. Use the full or delta export to reconcile after retries are exhausted or a service circuit recovers. When applying a snapshot, prefer the newer meta.lastModifiedAt. When the modified timestamp is equal, you may retain the later meta.lastSeenAt without overwriting newer normalized data. status.current is a lifecycle field; do not infer deletion solely because an item is absent from a later export. A changed filter creates a new selection scope and is not an automatic instruction to remove records from your database.

Use the local copy for analysis and enrichment

Once source snapshots are stored, run your own analysis, joins, scoring, CRM sync, or enrichment against your database. Keep those derived values separate from the Immoteur snapshot so an incoming source update remains a straightforward upsert rather than a conflict with your local work.

Questions developers ask

Does this mirror all Immoteur data?

No. It mirrors the public-exportable classified data that currently matches the filters configured for your service. Use the API reference and your service configuration to understand the exact payload and selection.

Can I rely on arrival order or receive each event once?

No. Webhook deliveries can be retried and exports can use several chunks. Persist an idempotency ledger for live notifications and upsert snapshots by classified identifier.

When should I choose a Full export or a Delta export?

Start with a Full export. Keep live notifications running for prompt updates, then use Delta exports for regular reconciliation. When a requested Delta export falls back, its exportType is full.

Should I delete a local record missing from a later export?

Not automatically. An export reflects its current filter scope. Keep lifecycle decisions explicit and use the classified snapshot, including status.current, instead of treating absence as a deletion command.