Integration reporting and search
Read call reports and viewings, and discover leads from indexed CRM history with scoped integration keys.
These routes use the Fondaro API integration credential from Organization → Integrations → n8n. Send Authorization: Bearer <integration-key> to https://api.fondaro.com. Integration keys have organization-wide CRM authority bounded by their stored scopes, expiry and revocation. MCP keys and OAuth tokens use their separate authentication plane. Disabled organizations cannot use these reads.
Calls and activities
GET /integrations/v1/leads/:id/calls requires leads:read, with integer limit 1–100 (20 default) and nonnegative integer offset (0 default). Response: {calls,total,hasMore,nextOffset}. Each summary contains the recorded ownerId: string | null, call identity, direction/outcome/state, duration, timestamps and recording availability. It omits recording URLs, provider credentials and heavy bodies. Call-only totals are exact.
curl 'https://api.fondaro.com/integrations/v1/leads/10132/calls?limit=20&offset=0' \
-H 'Authorization: Bearer <integration-key>'GET /integrations/v1/leads/:id/activities?types=call remains supported under the same scope and uses the same eligible call selection. Supported comma-separated types are call, email, note, task-created, task-completed, status-change, deal-stage-change, deal-won, deal-lost, assignee-change, viewing, document-attached, and lead-created. Filtering runs before paging. Response: {entries,total,totalIsExact,hasMore,nextOffset}. General totals can be lower bounds; never use timeline totals for KPI counts.
Continue with nextOffset until hasMore is false. Ordering uses effective activity time, event type and source ID; the origin event appears once at the oldest position. Offsets traverse unchanged history deterministically, but concurrent inserts can shift them. No multi-request snapshot is guaranteed.
Outbound owner IDs identify the recorded calling rep; inbound IDs identify an internal owner only when recorded. Empty/system ownership is null. Lead reassignment and shared numbers are never fallback calling identities. Resolve labels through GET /integrations/v1/users or /users/:id under users:read; retain historical owner IDs if team lookup no longer resolves them. call.logged and call.analyzed carry the same ownership field.
Call ownership versus lead assignment: ownerId identifies the recorded internal user for that call. A lead's assigneeIds identifies its current assignment set; the singular assigneeId in lead-list filters selects leads assigned to that user. Those fields describe different relationships. If Alice calls a lead and it is later reassigned to Bob, the call retains Alice's ownerId, while the lead's assigneeIds reflects Bob. Label ownerId as Recorded calling user in reports.
Viewings
GET /integrations/v1/viewings and GET /integrations/v1/viewings/:id require an explicitly granted viewings:read. Existing keys do not acquire this permission; omitted scopes on key creation preserve legacy defaults.
| Filter | Validation and meaning |
|---|---|
propertyListingId, dealId | UUID |
leadId, collaboratorLeadId | Positive integer |
agentUserId | Nonempty hosting-agent ID |
status | scheduled, completed, cancelled, no_show |
kind | in_person, virtual |
from, to | ISO timestamp bounds on viewingAt; inclusive from, exclusive to; ordered range |
limit, offset | Integer 1–100 (20 default); nonnegative offset (0 default) |
Filters intersect before counting/paging. Response: {viewings,total,hasMore,nextOffset}, with exact totals and (viewingAt DESC,id DESC) ordering. Rows include relationship IDs, agentUserId, createdBy, status/kind/source, viewing/created/updated timestamps, notes and notesTruncated. List notes are previews; authorized REST detail notes are complete.
curl 'https://api.fondaro.com/integrations/v1/viewings?leadId=10132&status=scheduled&limit=20' \
-H 'Authorization: Bearer <integration-key>'This release reads registered own-listing viewings. Records are organization-visible; relationship IDs do not expose linked contact details. The host and registering user have distinct identities. MCP/Assistant callers with explicit lead filters must pass canonical CRM visibility checks. Deleted optional links do not prevent reading the registered viewing. There are no viewing write adapters or new viewing webhooks in this release.
Semantic discovery
Both POST routes require leads:read and use the existing RAG facade:
curl 'https://api.fondaro.com/integrations/v1/leads/semantic-search' \
-H 'Authorization: Bearer <integration-key>' \
-H 'Content-Type: application/json' \
-d '{"query":"buyers who mentioned a garden near the beach","maxResults":10}'
curl 'https://api.fondaro.com/integrations/v1/leads/listing-match' \
-H 'Authorization: Bearer <integration-key>' \
-H 'Content-Type: application/json' \
-d '{"listingRef":{"source":"resales_online","id":"R123456"},"maxResults":10}'Semantic search accepts trimmed nonempty query up to 500 characters, optional positive integer leadId, valid ordered ISO occurredFrom/occurredTo, and maxResults 1–30 (10 default). Listing matching requires exactly one UUID propertyListingId or {source,id} listingRef. Listing identity is resolved through the source catalog; URLs and caller-supplied org/user/admin authority are not accepted.
Response: {matches,tookMs,reranked}. Matches retain ranked lead IDs/names, evidence snippets, source identities/counts and occurrence times. No vectors, confidence percentage or Return All pagination is exposed. Reranker degradation returns reranked:false; embedding errors remain errors.
These operations share a 30-request/minute limit per organization and per key, using existing shared throttle storage, alongside ordinary integration limits. A 429 includes standard Retry-After seconds. The existing storage outage behavior remains fail-open. No new customer billing meter is introduced.
The corpus is asynchronously indexed eligible notes, call transcript chunks/summaries, human-written emails and lead memory over a 24-month window. No relevant indexed match does not prove a lead does not exist. Evidence counts are not ledger totals. Occurrence-date bounds refer to when the source activity happened, including inclusive upper search bounds; they do not refer to future travel dates mentioned in text. Ordinary GET /integrations/v1/leads/search stays unchanged.