Ta strona nie została jeszcze przetłumaczona na Twój język. Wyświetlamy wersję angielski (Wielka Brytania).
Integration reporting
Read a lead's calls and activity, viewings and meaning-based lead search, and receive signed webhooks, with a scoped integration key.
The integrations API (/integrations/v1) lets your own automation read and write your organization's CRM: leads, deals, tasks, notes and tags, call and activity history, viewings, and webhooks for what changes. It is the API behind the n8n node, and any HTTP client can call it. For access as one person, use the REST API with an API key; this API stays for agency-wide automation and webhooks.
Authenticate
Send an integration key as a Bearer token:
An integration key starts with fdr_n8n_. An organization admin creates it in Settings > Integrations > n8n; the full key is shown once. It acts for the whole organization within its scopes, and works until it is revoked or expires. A disabled organization's keys stop working. Property API keys (fondaro_pk_) and MCP credentials do not open these routes, and an integration key opens nothing else. See Authentication.
Scopes
| Scope | Allows |
|---|---|
leads:read | Read, find, search and list leads, their calls and activities, the option lists, and meaning-based lead search |
leads:write | Create leads, change contact details and status, add assignees |
deals:read | Read deals and a lead's deals |
deals:write | Create deals, change stage, mark won or lost |
tasks:write | Create a task on a lead |
notes:write | Create a note on a lead |
tags:read | Read a lead's tags and a tag |
tags:write | Add tags to a lead |
triggers:subscribe | Manage webhook subscriptions and poll for new leads |
users:read | Resolve a team member's id to their name, email and role |
viewings:read | Read viewings. Only granted when chosen explicitly |
A key created without a scope list gets every scope except viewings:read. A request without the scope its route needs returns 403.
Endpoints
| Method and path | Scope | Purpose |
|---|---|---|
GET /integrations/v1/whoami | none | The key's organization, name and scopes |
POST /integrations/v1/leads | leads:write | Create a lead |
GET /integrations/v1/leads | leads:read | List leads |
GET /integrations/v1/leads/find | leads:read | Find one lead by email, phone or externalId |
GET /integrations/v1/leads/search | leads:read | Search leads by text (q, limit, offset) |
GET /integrations/v1/leads/:id | leads:read | Read a lead |
GET /integrations/v1/leads/:id/calls | leads:read | A lead's calls |
GET /integrations/v1/leads/:id/activities | leads:read | A lead's activity history |
PATCH /integrations/v1/leads/:id/contact | leads:write | Change contact details and companyName |
PATCH /integrations/v1/leads/:id/status | leads:write | Change the lead status |
POST /integrations/v1/leads/:id/assignees | leads:write | Add assignees, people or teams |
POST /integrations/v1/leads/semantic-search | leads:read | Find leads by what they said |
POST /integrations/v1/leads/listing-match | leads:read | Find leads that fit a listing |
POST /integrations/v1/deals | deals:write | Create a deal |
GET /integrations/v1/deals/:id | deals:read | Read a deal |
PATCH /integrations/v1/deals/:id/stage | deals:write | Move a deal to another stage |
POST /integrations/v1/deals/:id/won | deals:write | Mark a deal won |
POST /integrations/v1/deals/:id/lost | deals:write | Mark a deal lost |
GET /integrations/v1/leads/:leadId/deals | deals:read | A lead's deals |
POST /integrations/v1/leads/:leadId/tasks | tasks:write | Create a task |
POST /integrations/v1/leads/:leadId/notes | notes:write | Create a note |
GET /integrations/v1/leads/:leadId/tags | tags:read | A lead's tags |
POST /integrations/v1/leads/:leadId/tags | tags:write | Add tags to a lead |
GET /integrations/v1/tags/:tagId | tags:read | Read a tag |
GET /integrations/v1/options/{tags,assignees,deal-stages,lead-statuses,lead-types,lead-sources} | leads:read | Values for pickers |
GET /integrations/v1/users, GET /integrations/v1/users/:id | users:read | Team members |
GET /integrations/v1/viewings, GET /integrations/v1/viewings/:id | viewings:read | Viewings |
GET /integrations/v1/triggers/leads/new | triggers:subscribe | Poll for new leads |
POST /integrations/v1/subscriptions | triggers:subscribe | Subscribe a webhook |
GET /integrations/v1/subscriptions/:id | triggers:subscribe | Read a subscription |
DELETE /integrations/v1/subscriptions/:id | triggers:subscribe | Remove a subscription |
Every lead payload carries companyName (string or null). POST /integrations/v1/leads accepts it; PATCH /integrations/v1/leads/:id/contact sets it, or clears it with null or an empty string (at most 255 characters).
The lead, deal, task and assignee writes accept an optional teamIds list (up to 20 team ids) next to their user ids. Each team becomes its current members when the request runs. One request assigns at most 50 people; past that it returns 400 with code: "ASSIGNEE_LIMIT_EXCEEDED" and writes nothing. See Teams.
List a lead's calls
GET /integrations/v1/leads/:id/calls
Returns the lead's calls, newest first, without recordings or transcripts.
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
id | Path | integer | Yes | Lead id |
limit | Query | integer | No | 1 to 100, default 20 |
offset | Query | integer | No | 0 or more, default 0 |
outcome is the call result (success, no_answer, busy, failed, invalid_number and similar), null when none was set. ownerId is the team member recorded as making or taking the call, and null when none was recorded. It is not the lead's current assignee: a lead reassigned after the call keeps the call's ownerId. Resolve it with GET /integrations/v1/users/:id.
List a lead's activity
GET /integrations/v1/leads/:id/activities
Returns the lead's history as typed entries, newest first. Each entry has type, occurredAt and one object named for its kind (call, note, task, email, statusChange, dealStageChange, deal, assigneeChange, document, viewing). Entries carry ids and short previews, never email bodies, note HTML or transcripts.
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
id | Path | integer | Yes | Lead id |
types | Query | string | No | Comma-separated: call, email, note, task-created, task-completed, status-change, deal-stage-change, deal-won, deal-lost, assignee-change, viewing, document-attached, lead-created |
limit | Query | integer | No | 1 to 100, default 20 |
offset | Query | integer | No | 0 or more, default 0 |
The type filter applies before paging. Page with nextOffset until hasMore is false. When totalIsExact is false, total is a lower bound: count calls with the calls endpoint, not this one. A viewing appears on each of its client leads and on the collaborator lead that brought them.
List viewings
GET /integrations/v1/viewings
Returns viewings registered on your organization's listings, newest first (viewingAt, then id). Needs viewings:read. A viewing can have several clients: leadId is the viewing's lead and otherLeadIds lists the others, empty when there are none.
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
propertyListingId | Query | UUID | No | One listing |
leadId | Query | integer | No | A client lead: the viewing's lead or one of its other clients |
collaboratorLeadId | Query | integer | No | The collaborator lead |
agentUserId | Query | string | No | The hosting agent |
dealId | Query | UUID | No | One deal |
status | Query | string | No | scheduled, completed, cancelled, no_show |
kind | Query | string | No | in_person, virtual |
from | Query | ISO 8601 | No | viewingAt on or after |
to | Query | ISO 8601 | No | viewingAt before |
limit | Query | integer | No | 1 to 100, default 20 |
offset | Query | integer | No | 0 or more, default 0 |
In the list, notes is the first 500 characters and notesTruncated says whether there is more. GET /integrations/v1/viewings/:id returns one viewing with its full notes, or 404.
Find leads by what they said
POST /integrations/v1/leads/semantic-search
Ranks leads by meaning across their notes, call transcripts and summaries, emails and messages.
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
query | Body | string | Yes | 1 to 500 characters |
leadId | Body | integer | No | Search one lead's records only |
occurredFrom | Body | ISO 8601 | No | Evidence written on or after |
occurredTo | Body | ISO 8601 | No | Evidence written on or before; after occurredFrom |
maxResults | Body | integer | No | 1 to 30, default 10 |
sourceType is note, call_transcript, call_summary, email, message or lead_memory. reranked: false means the final ranking step was unavailable and the first-pass order was returned. The index covers about the last 24 months and fills shortly after records are written, so no match does not prove a lead does not exist.
Find leads for a listing
POST /integrations/v1/leads/listing-match
Ranks leads whose wishes fit a listing. Send exactly one of propertyListingId or listingRef.
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
propertyListingId | Body | UUID | One of | A Fondaro listing id |
listingRef.source | Body | string | One of | A property source id, such as resales_online |
listingRef.id | Body | string | One of | The listing's id in that source |
listingRef.country | Body | string | No | The country the source returned with the listing, when it gave one |
maxResults | Body | integer | No | 1 to 30, default 10 |
The response has the same shape as meaning-based search.
Webhooks
Subscribe
POST /integrations/v1/subscriptions
Sends the events you choose to an HTTPS URL. Subscribing the same events to the same URL again returns the existing subscription and reactivates it.
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
eventTypes | Body | string[] | Yes | 1 to 20 event names from the table below |
targetUrl | Body | string | Yes | An https URL on port 443 that resolves to a public address |
Store secret: it signs every delivery. GET /integrations/v1/subscriptions/:id returns id, eventTypes, targetUrl and isActive; DELETE /integrations/v1/subscriptions/:id removes it and returns { "success": true }. An organization can hold 25 subscriptions.
Events
| Event | Fires when |
|---|---|
lead.created | A lead is created |
lead.statusChanged | A lead's status changes |
lead.assigned | Assignees are added to a lead |
lead.tagged, lead.untagged | A tag is added to or removed from a lead, one delivery per tag |
deal.created, deal.stageChanged, deal.won, deal.lost | A deal is created, moves stage, or closes |
task.created, task.completed | A task is created or completed |
note.created | A note is created |
call.logged | A call is recorded on a lead |
call.analyzed | A call's analysis is saved. This one carries a written summary of the call |
message.received | An email or chat message (WhatsApp, Instagram, LinkedIn, Telegram) from a lead is stored on the lead |
message.sent | An email or chat message to a lead is sent from Fondaro, or from the agent's own connected mailbox or phone, and stored on the lead |
message.updated | A chat message on a lead is edited after it was sent, in Fondaro or on the phone |
message.deleted | A chat message on a lead is deleted for everyone, in Fondaro or on the phone |
meeting.created | A meeting, a viewing included, is created on the Fondaro calendar, or an event gains an invitee. A lead event that invites nobody outside the team fires task.created instead |
meeting.responded | An invitee accepts, declines or tentatively accepts, once per changed answer |
Payloads carry ids and times, not message bodies, subjects or addresses (call.analyzed excepted). Read details back with the endpoints above. A message from someone who is not a lead yet fires nothing, and neither does mail brought in when a mailbox is first connected.
Deliveries
Each delivery is a POST with a JSON body and three headers:
| Header | Value |
|---|---|
X-Fondaro-Event | The event name |
X-Fondaro-Timestamp | Unix seconds when it was sent |
X-Fondaro-Signature | sha256= followed by the hex HMAC-SHA256 of <timestamp>.<raw body>, keyed with the subscription secret |
Verify the signature over the raw body and reject old timestamps (for example older than 5 minutes). Answer with any 2xx within 10 seconds; anything else is retried with backoff, up to 8 attempts. A subscription that fails 20 times in a row is deactivated; subscribe again to turn it back on. Delivery is at least once, so deduplicate on deliveryId.
For message.received, message.sent, message.updated and message.deleted, messageType is email or message, channel is email, whatsapp, linkedin, instagram or telegram, and userId is the member who pressed Send in Fondaro (null for inbound messages and for messages sent from the agent's own phone or mail app). On message.updated and message.deleted, occurredAt is when the message was changed, and you read its current text back from the lead's timeline (a deleted message has none).
meeting.created carries organizationId, eventId, leadId, leadIds (every lead and collaborator on the meeting, its own lead first), viewingId, ownerId, startsAt, endsAt and occurredAt. meeting.responded carries organizationId, eventId, leadId, ownerId, response (accepted, declined or tentative) and occurredAt.
Errors and limits
| Status | When |
|---|---|
400 | Invalid parameters, for example an unknown event type or a limit above 100 |
401 | Missing, unknown, revoked or expired key |
403 | The key lacks the route's scope, or the organization is disabled |
404 | The lead, deal, viewing or subscription is not in your organization |
409 | The organization already has 25 webhook subscriptions |
429 | Rate limit reached; wait Retry-After seconds |
Each key may make 120 requests per minute. The two meaning-based search routes also share 30 requests per minute per key and per organization.