Partner API (HTTP) & MCP server — 73 operations (44 Partner API, 64 MCP).
Generated from the operations registry. Concept chapters are hand-written. Regenerate with npm run docs:api.
Authentication
Partner API — API key
Create a key in the avendo CRM under Settings → API Keys (type API,
not Widget). Keys look like av_pk_… and are shown once.
Send it on every request:
X-API-Key: av_pk_<your-api-key>
Use the key server-side only. A key is scoped: a request to an operation whose scope the key
lacks is rejected with FORBIDDEN. The key acts for the whole company.
MCP — personal access token
Each staff member issues a personal av_mcp_… token from the CRM
(OAuth is planned). MCP operations run as that user, so the CRM’s own role and access scoping
applies unchanged; sensitive tools additionally require a per-user switch (see below).
Webhooks
Subscribe an HTTPS endpoint to events with the webhooks scope (see the
webhooks.* operations below). Each delivery is a signed POST; verify the HMAC
signature with the subscription secret returned once on create / rotate. Failed deliveries are
retried with backoff and land in a dead-letter state you can inspect via
webhooks.deliveries.
| Event | When it fires |
|---|
| contact.created | A contact was created (via Partner API, MCP or the CRM). |
| inquiry.received | An inquiry came in for a listing. |
| searchProfile.created | A search profile was created for a contact. |
| searchProfile.match | A newly-activated listing matched a contact’s search profile. |
| valuation.lead | A valuation funnel produced a seller lead (contact, lead object and — unless the category has none — its value). |
Delivery format
Each event is an HTTPS POST carrying a JSON envelope and three headers:
X-Avendo-Event: contact.created
X-Avendo-Delivery: <unique delivery id>
X-Avendo-Signature: t=<unix-timestamp>,v1=<hmac-hex>
Content-Type: application/json
{ "id": "<delivery id>", "type": "contact.created",
"createdAt": "<ISO 8601>", "companyId": "<id>", "data": { … } }
Verifying the signature
Compute HMAC-SHA256(secret, "<t>.<raw request body>") as lowercase hex and
compare it in constant time to the v1 value from X-Avendo-Signature.
Reject deliveries whose t lies outside your acceptance window (replay protection). The
secret is the subscription signing secret, shown in full only on create and rotate-secret.
Contacts & leads 9
A contact with its timeline: recent emails, logbook entries, search profiles and valuation requests. Read-only.
read contacts
Request
| Field | Type | | Description |
| contactId |
string |
required |
Contact id |
Response
The contact plus a bounded timeline (max 25 rows per kind). timeline.valuations carries the newest valuation per object the contact owns; valuations.list has the full picture.
| Field | Type | Description |
| contact.id |
string |
Contact id |
| contact.contactType |
string |
'person' or 'company' |
| contact.emailAddresses |
string[] |
Email addresses; the first one is the primary |
| contact.firstname |
string |
First name |
| contact.lastname |
string |
Last name |
| contact.gender |
string |
'male' or 'female' when known |
| contact.salutation |
string |
Salutation |
| contact.company |
string |
Company name |
| contact.phoneNumbers |
object |
Phone numbers as [{ lbl, nr }] |
| contact.title |
string |
Title |
| contact.profession |
string |
Profession |
| contact.dateOfBirth |
date |
Date of birth |
| contact.address |
object |
Postal address (street, housenumber, postal, place, country) |
| contact.notes |
string |
Notes |
| contact.tags |
string[] |
Tags |
| contact.source |
string |
Lead origin the contact was created with |
| contact.language |
string |
Correspondence language |
| contact.createDate |
date |
When the contact was created |
| timeline.emails[] |
object |
Recent emails as { id, subject, date, outgoing, inquiry, source, immoId } |
| timeline.logbook[] |
object |
Recent logbook entries as { id, subject, key, date, immoId } |
| timeline.searchProfiles[] |
object |
Search profiles as { id, title, marketingType, origin, createDate } |
| timeline.valuationRequests[] |
object |
Homeowner-platform requests as { id, type, createDate, immoId } |
| timeline.valuations[].immoId |
string |
Object id |
| timeline.valuations[].visualReferenceId |
string |
Human-readable reference number |
| timeline.valuations[].address |
object |
street, housenumber, postal, place, country |
| timeline.valuations[].objectCategory |
string |
Fine-grained object category key |
| timeline.valuations[].status |
string |
Marketing status |
| timeline.valuations[].id |
string |
Estimation id |
| timeline.valuations[].kind |
string |
'crm' (agent-run) or 'platform' (funnel/homeowner) |
| timeline.valuations[].createDate |
date |
When the valuation was produced |
| timeline.valuations[].date |
string |
Valuation date of the current value (YYYY-MM-DD) |
| timeline.valuations[].salePrice |
number |
Estimated sale price |
| timeline.valuations[].salePriceRange |
object |
Confidence interval { lower, upper } |
| timeline.valuations[].confidence |
string |
poor | medium | good |
| timeline.valuations[].history |
object |
Only with includeHistory: the full series as [{ date, salePrice, salePriceRange, confidence }] |
contacts.export
MCP contacts_export
Export the company's contacts (optionally filtered) as CSV. Requires the contact-export permission.
read contacts switch · contactExport
Request
| Field | Type | | Description |
| query |
string |
optional |
Free-text filter |
| tags |
string[] |
optional |
Filter by tags |
| contactType |
string |
optional |
'person' or 'company' (default: persons only) |
Response
| Field | Type | Description |
| format |
string |
Always 'csv' |
| rowCount |
number |
Number of exported contacts (excluding the header row) |
| csv |
string |
The CSV document itself, header row first |
contacts.merge
MCP contacts_merge
Merge two or more contacts into one (secondary contacts are removed, their history reassigned). Requires the delete/merge permission and confirmation.
write contacts switch · deleteMerge confirmation
Request
| Field | Type | | Description |
| contactIds |
string[] |
required |
The contact ids to merge (>=2); the merge result is a single new contact |
| firstname |
string |
optional |
Override first name on the merged contact |
| lastname |
string |
optional |
Override last name on the merged contact |
| company |
string |
optional |
Override company on the merged contact |
| force |
boolean |
optional |
Force merge (default false; a platform-user conflict still blocks) |
Response
| Field | Type | Description |
| mergedContactId |
string |
The surviving contact that now carries the merged history |
List the company's unresolved contact mutations (conflicting field proposals awaiting review). Read-only.
read contacts
No input parameters.
Response
Unresolved mutations; an empty array means nothing awaits review.
| Field | Type | Description |
| [].id |
string |
Contact mutation id (pass to contacts.resolveMutation) |
| [].contactId |
string |
The contact the proposal belongs to |
| [].source |
string |
Where the conflicting values came from |
| [].createDate |
date |
When the conflict was recorded |
| [].proposed |
object |
The proposed field values (firstname, lastname, gender, salutation, company, phoneNumbers, title, profession, dateOfBirth, address, notes, tags) |
Resolve a contact mutation: apply=true takes the proposed fields onto the contact, apply=false just dismisses it. Either way it is marked handled.
write contacts
Request
| Field | Type | | Description |
| contactMutationId |
string |
required |
Contact mutation id |
| apply |
boolean |
optional |
true = apply proposed fields to the contact; false = dismiss (default false) |
Response
| Field | Type | Description |
| id |
string |
The resolved mutation id |
| applied |
boolean |
Whether the proposed fields were written onto the contact |
| resolvedAt |
date |
When it was marked handled |
Search the company's contacts by name/email/phone, optionally filtered by tags. Answers "does this contact already exist?". Read-only.
read contacts
Request
| Field | Type | | Description |
| query |
string |
optional |
Free-text (name / email / phone) |
| tags |
string[] |
optional |
Filter by tags |
| tagFilterType |
string |
optional |
'and' or 'or' (default 'or') |
| onlyWithEmail |
boolean |
optional |
Only contacts that have an email |
| contactType |
string |
optional |
'person' or 'company' (default: persons only) |
| skip |
number |
optional |
Rows to skip (default 0) |
| limit |
number |
optional |
Page size (default 10) |
Response
Matching contacts, newest first.
| Field | Type | Description |
| items[].id |
string |
Contact id |
| items[].contactType |
string |
'person' or 'company' |
| items[].emailAddresses |
string[] |
Email addresses; the first one is the primary |
| items[].firstname |
string |
First name |
| items[].lastname |
string |
Last name |
| items[].gender |
string |
'male' or 'female' when known |
| items[].salutation |
string |
Salutation |
| items[].company |
string |
Company name |
| items[].phoneNumbers |
object |
Phone numbers as [{ lbl, nr }] |
| items[].title |
string |
Title |
| items[].profession |
string |
Profession |
| items[].dateOfBirth |
date |
Date of birth |
| items[].address |
object |
Postal address (street, housenumber, postal, place, country) |
| items[].notes |
string |
Notes |
| items[].tags |
string[] |
Tags |
| items[].source |
string |
Lead origin the contact was created with |
| items[].language |
string |
Correspondence language |
| items[].createDate |
date |
When the contact was created |
| total_count |
number |
Total number of matching rows (not the page size) |
Replace a contact's tags with the given set.
write contacts
Request
| Field | Type | | Description |
| contactId |
string |
required |
Contact id |
| tags |
string[] |
required |
The full tag set to store on the contact |
Response
| Field | Type | Description |
| id |
string |
The affected contact id |
| tags |
string[] |
The tag set now stored on the contact |
Update a contact's identity fields. New emails are rejected if they collide with another contact in the company.
write contacts
Request
| Field | Type | | Description |
| contactId |
string |
required |
Contact id |
| emails |
string[] |
optional |
Email addresses |
| firstname |
string |
optional |
First name |
| lastname |
string |
optional |
Last name |
| phone |
string |
optional |
Phone number |
| company |
string |
optional |
Company name |
| title |
string |
optional |
Title |
| notes |
string |
optional |
Notes |
Response
| Field | Type | Description |
| id |
string |
The affected contact id |
| status |
string |
What the service did (e.g. updated, or a mutation was recorded instead) |
Create or match a contact by email (dedup within the company, with source). Returns the resulting contact; a field conflict is recorded as a contact mutation for review rather than overwriting.
write contacts
Request
| Field | Type | | Description |
| email |
string |
required |
Primary email (dedup key within the company) |
| firstname |
string |
optional |
First name |
| lastname |
string |
optional |
Last name |
| source |
string |
optional |
Lead source / origin (default: mcp) |
| phone |
string |
optional |
Phone number |
| company |
string |
optional |
Company name |
| title |
string |
optional |
Title |
| notes |
string |
optional |
Notes |
| tags |
string[] |
optional |
Tags |
Response
The created or matched contact. On a match with conflicting values the contact is returned unchanged and the proposal is recorded as a contact mutation (contacts.mutations).
| Field | Type | Description |
| id |
string |
Contact id |
| contactType |
string |
'person' or 'company' |
| emailAddresses |
string[] |
Email addresses; the first one is the primary |
| firstname |
string |
First name |
| lastname |
string |
Last name |
| gender |
string |
'male' or 'female' when known |
| salutation |
string |
Salutation |
| company |
string |
Company name |
| phoneNumbers |
object |
Phone numbers as [{ lbl, nr }] |
| title |
string |
Title |
| profession |
string |
Profession |
| dateOfBirth |
date |
Date of birth |
| address |
object |
Postal address (street, housenumber, postal, place, country) |
| notes |
string |
Notes |
| tags |
string[] |
Tags |
| source |
string |
Lead origin the contact was created with |
| language |
string |
Correspondence language |
| createDate |
date |
When the contact was created |
Search profiles & matching 5
Delete a search profile. Requires confirmation.
write search-profiles-write confirmation
Request
| Field | Type | | Description |
| searchProfileId |
string |
required |
The search profile to delete |
Response
| Field | Type | Description |
| deleted |
boolean |
Always true on success |
| id |
string |
The deleted search profile id |
List a contact's search profiles (criteria, marketing type, origin). Read-only.
read search-profiles
Request
| Field | Type | | Description |
| contactId |
string |
required |
The contact whose search profiles to list |
| skip |
number |
optional |
Rows to skip (default 0) |
| limit |
number |
optional |
Page size (default 10) |
| origin |
string |
optional |
Filter by origin: manual | auto-inquiry | public-submission |
Response
The contact's search profiles, newest first (a bare array, no paging envelope).
| Field | Type | Description |
| [].id |
string |
Search profile id |
| [].title |
string |
Profile title |
| [].notes |
string |
Internal notes |
| [].marketingType |
string |
'SELL' or 'RENT' |
| [].origin |
string |
manual | auto-inquiry | public-submission |
| [].contactId |
string |
The contact the profile belongs to |
| [].propertyTypes |
string[] |
Wanted property types |
| [].rooms |
object |
Range { min, max } |
| [].price |
object |
Range { min, max } |
| [].propertyArea |
object |
Range { min, max } in m² |
| [].netLivingArea |
object |
Range { min, max } in m² |
| [].flatsInBuilding |
object |
Range { min, max } |
| [].searchAreas |
object |
Search areas as [{ name, type, bfsNr }] — the polygon geometry is never returned |
| [].confirmedAt |
date |
When the contact confirmed the profile (double opt-in) |
Interested contacts whose search profile matches a given object — usable as a recipient list. Read-only.
read search-profiles
Request
| Field | Type | | Description |
| objectId |
string |
required |
The object (immo) to find matching contacts for |
| origin |
string |
optional |
Filter matching profiles by origin: manual | auto-inquiry | public-submission |
Response
One row per matching contact (a bare array, no paging envelope) — usable as a recipient list for emails.bulkSend.
| Field | Type | Description |
| [].contactId |
string |
The matching contact |
| [].contact |
object |
Contact preview as { id, firstName, lastName, email } |
| [].searchProfiles |
object |
The profiles that matched as [{ id, title }] |
Objects (listings) that match a given search profile. Read-only.
read search-profiles
Request
| Field | Type | | Description |
| searchProfileId |
string |
required |
The search profile to match objects against |
| skip |
number |
optional |
Rows to skip (default 0) |
| limit |
number |
optional |
Page size (default 20) |
Response
Objects matching the profile criteria.
| Field | Type | Description |
| items[].id |
string |
Object id |
| items[].place |
string |
Town/city |
| items[].objectCategory |
string |
Fine-grained object category key |
| items[].marketingType |
string |
'SELL' or 'RENT' |
| items[].price |
number |
Price |
| items[].rooms |
number |
Number of rooms |
| items[].netLivingArea |
number |
Net living area in m² |
| total_count |
number |
Total number of matching rows (not the page size) |
Update a search profile's criteria (title, notes, marketing type, property types, and rooms/price/area/units ranges). Geographic areas are not editable here.
write search-profiles-write
Request
| Field | Type | | Description |
| searchProfileId |
string |
required |
The search profile to update |
| title |
string |
optional |
Profile title |
| notes |
string |
optional |
Internal notes |
| marketingType |
string |
optional |
Marketing type (e.g. SELL, RENT) |
| propertyTypes |
string[] |
optional |
Property type keys |
| roomsMin |
number |
optional |
rooms lower bound (send with roomsMax) |
| roomsMax |
number |
optional |
rooms upper bound (send with roomsMin) |
| priceMin |
number |
optional |
price lower bound (send with priceMax) |
| priceMax |
number |
optional |
price upper bound (send with priceMin) |
| propertyAreaMin |
number |
optional |
propertyArea lower bound (send with propertyAreaMax) |
| propertyAreaMax |
number |
optional |
propertyArea upper bound (send with propertyAreaMin) |
| netLivingAreaMin |
number |
optional |
netLivingArea lower bound (send with netLivingAreaMax) |
| netLivingAreaMax |
number |
optional |
netLivingArea upper bound (send with netLivingAreaMin) |
| flatsInBuildingMin |
number |
optional |
flatsInBuilding lower bound (send with flatsInBuildingMax) |
| flatsInBuildingMax |
number |
optional |
flatsInBuilding upper bound (send with flatsInBuildingMin) |
Response
The updated search profile.
| Field | Type | Description |
| id |
string |
Search profile id |
| title |
string |
Profile title |
| notes |
string |
Internal notes |
| marketingType |
string |
'SELL' or 'RENT' |
| origin |
string |
manual | auto-inquiry | public-submission |
| contactId |
string |
The contact the profile belongs to |
| propertyTypes |
string[] |
Wanted property types |
| rooms |
object |
Range { min, max } |
| price |
object |
Range { min, max } |
| propertyArea |
object |
Range { min, max } in m² |
| netLivingArea |
object |
Range { min, max } in m² |
| flatsInBuilding |
object |
Range { min, max } |
| searchAreas |
object |
Search areas as [{ name, type, bfsNr }] — the polygon geometry is never returned |
| confirmedAt |
date |
When the contact confirmed the profile (double opt-in) |
Newsletter & consent 2
Subscribe or unsubscribe a contact to the newsletter. A consent source is mandatory (recorded with the timestamp). Unsubscribe is global (Linie DEV-1228).
write newsletter
Request
| Field | Type | | Description |
| contactId |
string |
required |
Contact id |
| subscribe |
boolean |
required |
true = subscribe, false = unsubscribe (global) |
| source |
string |
required |
Consent source (where/how the decision was given) — recorded with the timestamp |
Response
The consent state after the change.
| Field | Type | Description |
| subscribed |
boolean |
True when consent was given and not withdrawn |
| enlistDate |
date |
When consent was given |
| enlistSource |
string |
Where/how consent was given |
| unsubscribeDate |
date |
When the contact unsubscribed |
| unsubscribeSource |
string |
Where the unsubscribe came from |
A contact's newsletter consent state (subscribed, enlist/unsubscribe dates and sources). Read-only.
read newsletter
Request
| Field | Type | | Description |
| contactId |
string |
required |
Contact id |
Response
| Field | Type | Description |
| subscribed |
boolean |
True when consent was given and not withdrawn |
| enlistDate |
date |
When consent was given |
| enlistSource |
string |
Where/how consent was given |
| unsubscribeDate |
date |
When the contact unsubscribed |
| unsubscribeSource |
string |
Where the unsubscribe came from |
Contact lists 6
Add contacts to a list ("befüllen").
write newsletter
Request
| Field | Type | | Description |
| listId |
string |
required |
Contact list id |
| contactIds |
string[] |
required |
Contact ids to add |
Response
| Field | Type | Description |
| ok |
boolean |
Always true on success |
Create a contact list, optionally pre-filled with contacts.
write newsletter
Request
| Field | Type | | Description |
| name |
string |
required |
List name (unique per company) |
| contactIds |
string[] |
optional |
Initial member contact ids |
Response
| Field | Type | Description |
| id |
string |
The new contact list id |
Remove all members from a list ("leeren") without deleting the list.
write newsletter
Request
| Field | Type | | Description |
| listId |
string |
required |
Contact list id |
Response
| Field | Type | Description |
| removed |
number |
How many members were removed |
Get one contact list with its members. Read-only.
read newsletter
Request
| Field | Type | | Description |
| listId |
string |
required |
Contact list id |
| query |
string |
optional |
Member name filter (starts-with) |
| skip |
number |
optional |
Member rows to skip (default 0) |
| limit |
number |
optional |
Member page size (default 10) |
Response
The list itself plus a page of resolved members under _contacts.
| Field | Type | Description |
| _id |
string |
Contact list id |
| name |
string |
List name (unique per company) |
| contacts |
object |
Members as [{ contactId, notes }] |
| createdBy |
string |
User who created the list |
| createDate |
date |
When the list was created |
| lastModifiedDate |
date |
Last change |
| _contacts.items[]._id |
string |
Member contact id |
| _contacts.items[].firstname |
string |
First name |
| _contacts.items[].lastname |
string |
Last name |
| _contacts.items[].company |
string |
Company name |
| _contacts.items[].salutation |
string |
Salutation |
| _contacts.items[].gender |
string |
'male' or 'female' when known |
| _contacts.items[].emailAddresses |
string[] |
Email addresses |
| _contacts.items[].phoneNumbers |
object |
Phone numbers as [{ lbl, nr }] |
| _contacts.items[].notes |
string |
Notes |
| _contacts.items[].settings |
object |
Contact settings incl. newsletter consent entries |
| _contacts.total_count |
number |
Total number of members (not the page size) |
List the company's contact lists (optionally filtered by name). Read-only.
read newsletter
Request
| Field | Type | | Description |
| query |
string |
optional |
Name filter (starts-with) |
| skip |
number |
optional |
Rows to skip (default 0) |
| limit |
number |
optional |
Page size (default 10) |
Response
The company's contact lists.
| Field | Type | Description |
| items[]._id |
string |
Contact list id |
| items[].name |
string |
List name (unique per company) |
| items[].contacts |
object |
Members as [{ contactId, notes }] |
| items[].createdBy |
string |
User who created the list |
| items[].createDate |
date |
When the list was created |
| items[].lastModifiedDate |
date |
Last change |
| total_count |
number |
Total number of matching rows (not the page size) |
Remove one contact from a list.
write newsletter
Request
| Field | Type | | Description |
| listId |
string |
required |
Contact list id |
| contactId |
string |
required |
Contact id to remove |
Response
| Field | Type | Description |
| ok |
boolean |
Always true on success |
Objects & marketing 9
Create a CRM object from title, address and object category. Optional catalog fields (see objects.fieldCatalog) are applied in the same call. Returns the new object id and reference id. Partner API: an Idempotency-Key request header is required so repeated syncs never create duplicates.
write listings-write
Request
| Field | Type | | Description |
| title |
string |
required |
Object title |
| objectCategory |
string |
required |
Fine-grained object category key (objects.fieldCatalog lists them, e.g. floor-apartment, villa, plot) |
| postal |
number |
required |
Postal code |
| place |
string |
required |
Town/city |
| street |
string |
optional |
Street name |
| housenumber |
string |
optional |
House number |
| country |
string |
optional |
Country code (default 'CH') |
| marketingType |
string |
optional |
'SELL' (default) or 'RENT' |
| status |
string |
optional |
Initial status (default 'unclassified'): dummy, inactive, cancelled-mandate, no-mandate, lead, interested-object, cold, hot, unclassified, in-acquisition, in-progress, review, published, paused, reservation-contract-signed, reserved, sold |
| fields |
object |
optional |
Optional catalog fields to set right away, keyed by field path (e.g. {"properties.rooms": 3.5}) |
Response
On an Idempotency-Key replay the stored first response is returned and nothing is created.
| Field | Type | Description |
| id |
string |
The new object id |
| visualReferenceId |
string |
Generated human-readable reference number |
| title |
string |
The stored title |
| appliedFields |
string[] |
Field paths that were set from fields |
The full exposé data package for an object (by its visual reference id): object and smart-listing data, agent and company identity, POIs, taxes and socio-economic context. Large response; read-only.
read listings
Request
| Field | Type | | Description |
| visualReferenceId |
string |
required |
The object's visual reference id (e.g. from objects.get) |
Response
The exposé data package as the documentation pipeline consumes it — identical to the v1 endpoint GET /listings/:visualReferenceId/documentation-data. Large response.
| Field | Type | Description |
| immo |
object |
Object master data (address, properties, dimensions, finance, custom fields) |
| smartListing |
object |
Smart-listing content: texts, characteristics, features, macro location, virtual tour, images |
| documentation |
object |
Documentation content: title, descriptions, images, title-image config, community data, attached PDFs |
| agent |
object |
Responsible contact agent (publication identity) |
| company |
object |
Company/office identity: name, logo, address, phone, domain |
| pois |
object |
Points of interest grouped by category as [{ category, markers[] }] |
| groundViewUrl |
string |
Ground-view image URL, null when none exists |
Machine-readable object field schema per property type: field paths, labels, types, required/optional level, enum values, units and dependencies. Optionally scope to one propertyType or objectCategory; otherwise every property type is returned. Use it to generate object-create/update payloads and know which fields a category needs.
read listings
Request
| Field | Type | | Description |
| propertyType |
string |
optional |
Limit to one property type: apartment, house, multiFamilyHouse, commercial, plot, parking. |
| objectCategory |
string |
optional |
Limit to the property type of a fine-grained object category (e.g. villa, studio, gastronomy). |
Response
Fields hidden for a property type are absent from the catalog — writing them is rejected.
| Field | Type | Description |
| propertyTypes[].propertyType |
string |
apartment | house | multiFamilyHouse | commercial | plot | parking |
| propertyTypes[].objectCategories |
string[] |
The fine-grained categories that resolve to this property type |
| propertyTypes[].sections[].section |
string |
Field-config section (properties, dimensions, financeAndMarket, heatingAndEnergy, condition, quality, amenities) |
| propertyTypes[].sections[].fields[].path |
string |
Dot path to use when writing the field (objects.create / objects.updateFields) |
| propertyTypes[].sections[].fields[].label |
string |
Human-readable field label |
| propertyTypes[].sections[].fields[].type |
string |
number | text | boolean | enum | date |
| propertyTypes[].sections[].fields[].required |
boolean |
Whether the field is mandatory for this property type |
| propertyTypes[].sections[].fields[].requirement |
string |
mandatory | suggested | optional |
| propertyTypes[].sections[].fields[].custom |
boolean |
True for company-specific custom fields |
| propertyTypes[].sections[].fields[].enumValues |
string[] |
Allowed values for enum fields |
| propertyTypes[].sections[].fields[].unit |
string |
Unit of the value (m², m³, CHF, %, Jahr) when it has one |
| propertyTypes[].sections[].fields[].dependsOn |
object |
Field this one only applies to under a condition |
| objectCategories[] |
object |
Lookup table { key, title, propertyType } for every fine-grained category |
One CRM object in full detail: address, all field-catalog sections, custom fields, images, document names and lastModifiedDate (needed for the objects.updateFields conflict check). Read-only.
read objects-read
Request
| Field | Type | | Description |
| immoId |
string |
required |
Object id |
Response
| Field | Type | Description |
| id |
string |
Object id |
| visualReferenceId |
string |
Human-readable reference number |
| title |
string |
Object title |
| address |
object |
street, housenumber, postal, place, region, country |
| objectCategory |
string |
Fine-grained object category key |
| status |
string |
Marketing status |
| marketingType |
string |
'SELL' or 'RENT' |
| price |
number |
Sale price |
| netRent |
number |
Net rent |
| grossRent |
number |
Gross rent |
| rooms |
number |
Number of rooms |
| imageCount |
number |
Number of images |
| createDate |
date |
When the object was created |
| lastModifiedDate |
date |
Last change (pass as expectedLastModified to objects.updateFields) |
| properties |
object |
Properties section (category, rooms, build year, …) |
| dimensions |
object |
Dimensions section (areas, volume, …) |
| financeAndMarket |
object |
Finance & market section (prices, status, dates, …) |
| heatingAndEnergy |
object |
Heating & energy section |
| condition |
object |
Condition per building part |
| quality |
object |
Quality per building part |
| amenities |
object |
Amenities section |
| customFields |
object |
Company-specific custom field values |
| tags |
string[] |
Object tags |
| languages |
string[] |
Content languages |
| images |
object |
Images in display order (first = title image) |
| documents |
object |
Document names/types only as [{ name, type }] — files come from objectDocuments.* |
| agent |
object |
Responsible agent as { firstname, lastname, email } |
| projectId |
string |
Project the object belongs to |
Search the company's CRM objects (properties) by free text, status and marketing type. Covers the whole inventory including unpublished objects (listings.list only sees published ones). Read-only.
read objects-read
Request
| Field | Type | | Description |
| query |
string |
optional |
Free text (title / street / place / reference id / postal) |
| statuses |
string[] |
optional |
Filter by object status: dummy, inactive, cancelled-mandate, no-mandate, lead, interested-object, cold, hot, unclassified, in-acquisition, in-progress, review, published, paused, reservation-contract-signed, reserved, sold |
| marketingType |
string |
optional |
'SELL' or 'RENT' |
| skip |
number |
optional |
Rows to skip (default 0) |
| limit |
number |
optional |
Page size (default 10) |
Response
Matching objects, newest first. objects.get returns the full detail of one.
| Field | Type | Description |
| items[].id |
string |
Object id |
| items[].visualReferenceId |
string |
Human-readable reference number |
| items[].title |
string |
Object title |
| items[].address |
object |
street, housenumber, postal, place, region, country |
| items[].objectCategory |
string |
Fine-grained object category key |
| items[].status |
string |
Marketing status |
| items[].marketingType |
string |
'SELL' or 'RENT' |
| items[].price |
number |
Sale price |
| items[].netRent |
number |
Net rent |
| items[].grossRent |
number |
Gross rent |
| items[].rooms |
number |
Number of rooms |
| items[].imageCount |
number |
Number of images |
| items[].createDate |
date |
When the object was created |
| items[].lastModifiedDate |
date |
Last change (pass as expectedLastModified to objects.updateFields) |
| total_count |
number |
Total number of matching rows (not the page size) |
Move an image within a CRM object's image order (position = array index, 0-based; the first image is the title image).
write listings-write
Request
| Field | Type | | Description |
| immoId |
string |
required |
Object id |
| fromIndex |
number |
required |
Current position of the image (0-based) |
| toIndex |
number |
required |
Target position (0-based) |
Response
| Field | Type | Description |
| id |
string |
Object id |
| images |
object |
The image list in its new order |
Change a CRM object's marketing status. The transition is validated server-side (an illegal from→to change is rejected); no other field is touched. Statuses: dummy, inactive, cancelled-mandate, no-mandate, lead, interested-object, cold, hot, unclassified, in-acquisition, in-progress, review, published, paused, reservation-contract-signed, reserved, sold.
write listings-write
Request
| Field | Type | | Description |
| immoId |
string |
required |
Object id |
| status |
string |
required |
Target status: dummy, inactive, cancelled-mandate, no-mandate, lead, interested-object, cold, hot, unclassified, in-acquisition, in-progress, review, published, paused, reservation-contract-signed, reserved, sold |
Response
| Field | Type | Description |
| id |
string |
Object id |
| status |
string |
The status now stored |
| lastModifiedDate |
date |
New change marker |
Update catalog fields on a CRM object (partial update; only the given paths change). Fields are validated against objects.fieldCatalog. Pass expectedLastModified (from objects.get) to fail with CONFLICT instead of overwriting changes made in the meantime.
write listings-write
Request
| Field | Type | | Description |
| immoId |
string |
required |
Object id |
| fields |
object |
required |
Catalog fields keyed by field path (e.g. {"properties.rooms": 3.5, "financeAndMarket.price": 950000}) |
| expectedLastModified |
string |
optional |
The object's lastModifiedDate as last read (ISO 8601); mismatch aborts with CONFLICT |
Response
| Field | Type | Description |
| id |
string |
Object id |
| appliedFields |
string[] |
The field paths that were written |
| lastModifiedDate |
date |
New change marker — pass it as expectedLastModified on the next update |
Add an image to a CRM object by downloading it from an https URL. The image lands at the end of the image order (objects.reorderImages to sort).
write listings-write
Request
| Field | Type | | Description |
| immoId |
string |
required |
Object id |
| url |
string |
required |
Public https URL of the image (jpeg/png/webp/gif, max 30 MB) |
| filename |
string |
optional |
Filename override (default: derived from the URL) |
Response
| Field | Type | Description |
| id |
string |
Object id |
| imageCount |
number |
Number of images after the upload |
| images |
object |
The full image list in display order |
Object documents 3
The download URL of an uploaded object document. Requires the document-retrieval permission (document contents are sensitive).
read listings switch · documentRetrieval
Request
| Field | Type | | Description |
| documentId |
string |
required |
Object document id (from objectDocuments.list) |
Response
NOT_FOUND when the document slot has no file yet.
| Field | Type | Description |
| id |
string |
Document id |
| name |
string |
File name |
| type |
string |
Document type |
| url |
string |
Download URL of the stored file |
List/search the object documents (contracts, land-register extracts, ...) of one object or the whole company, filtered by name or document type. Returns metadata only; the file itself is fetched via objectDocuments.downloadLink. Read-only.
read objects-read
Request
| Field | Type | | Description |
| immoId |
string |
optional |
Limit to one object |
| name |
string |
optional |
Filter by document name (case-insensitive substring) |
| type |
string |
optional |
Filter by document type: documentation, ownership-certificate, building-insurance, brokerage-agreement, reservation-contract, sales-agreement, information-warrant, renovation-list, ground-view, additional-document, profile, condominium-substantiation-apartment, condominium-regulations-apartment, condominium-substantiation-garage, condominium-regulations-garage, share-renewal-fund, imputed-rental-value, stweg-protocols, utilities-statement, construction-specification, tipgiver-form, rent-index, flyer, other |
Response
Metadata only, newest upload first, max 200 rows (total_count is the number of returned rows). The file URL comes from objectDocuments.downloadLink.
| Field | Type | Description |
| items[].id |
string |
Document id |
| items[].immoId |
string |
Object the document belongs to |
| items[].name |
string |
File name |
| items[].type |
string |
Document type |
| items[].description |
string |
Description |
| items[].optional |
boolean |
Whether the document slot is optional |
| items[].hasFile |
boolean |
False for an empty slot that is still waiting for its file |
| items[].uploadedAt |
date |
Upload timestamp |
| items[].verifiedAt |
date |
When an agent verified the document |
| total_count |
number |
Total number of matching rows (not the page size) |
Upload an object document by downloading it from an https URL and attaching it to an object. Fills an existing empty document slot of the same type when one exists, otherwise creates a new one.
write listings-write
Request
| Field | Type | | Description |
| immoId |
string |
required |
Object id the document belongs to |
| type |
string |
required |
Document type: documentation, ownership-certificate, building-insurance, brokerage-agreement, reservation-contract, sales-agreement, information-warrant, renovation-list, ground-view, additional-document, profile, condominium-substantiation-apartment, condominium-regulations-apartment, condominium-substantiation-garage, condominium-regulations-garage, share-renewal-fund, imputed-rental-value, stweg-protocols, utilities-statement, construction-specification, tipgiver-form, rent-index, flyer, other |
| url |
string |
required |
Public https URL of the file (max 30 MB) |
| name |
string |
optional |
Filename override (default: derived from the URL) |
| description |
string |
optional |
Optional description |
Response
| Field | Type | Description |
| id |
string |
Document id |
| immoId |
string |
Object the document belongs to |
| name |
string |
Stored file name |
| type |
string |
Document type |
| filledExistingSlot |
boolean |
True when an empty document slot of the same type was filled instead of creating a new one |
Object relations 3
objectRelations.list
MCP objectRelations_list
List the relations (prospect pipeline) of an object, project or contact: who is linked in which role and, for prospects, which phase they are in. Read-only.
read listings
Request
| Field | Type | | Description |
| immoId |
string |
optional |
Limit to one object |
| projectId |
string |
optional |
Limit to one project |
| contactId |
string |
optional |
Limit to one contact |
| category |
string |
optional |
Filter by relation category: interested-person, buyer, search-hit-ignored, manager, marketer, architect, craftsman, renter, fiscal-agent, notary, owner, builder-owner, employer, tip-giver |
| phase |
string |
optional |
Filter by prospect phase: search-hit-contact, request-received, request-answered, accesslink-sent, first-viewing, second-viewing, sales-negotiation, reservation, buy-promise, proof-of-funding, draft-contract, land-register-meeting, contract-signing, canceled |
| skip |
number |
optional |
Rows to skip (default 0) |
| limit |
number |
optional |
Page size (default 10) |
Response
Matching relations, newest first.
| Field | Type | Description |
| items[].id |
string |
Relation id |
| items[].contactId |
string |
The linked contact |
| items[].immoId |
string |
The linked object |
| items[].projectId |
string |
The linked project |
| items[].category |
string |
Relation category (owner, interested-person, buyer, …) |
| items[].phase |
string |
Prospect phase (interested-person relations) |
| items[].phaseLabel |
string |
Human-readable phase label |
| items[].source |
string |
Where the relation came from |
| items[].contact |
object |
Contact preview as { firstname, lastname, email } |
| items[].createDate |
date |
When the relation was created |
| total_count |
number |
Total number of matching rows (not the page size) |
Remove a relation: unlink a contact from an object/project (e.g. delist a prospect). Requires confirmation.
write listings confirmation
Request
| Field | Type | | Description |
| relationId |
string |
required |
The relation to remove (id from objectRelations.list) |
Response
| Field | Type | Description |
| removed |
boolean |
Always true on success |
| id |
string |
The removed relation id |
Link a contact to an object/project or move a prospect through the pipeline. For category 'interested-person' a phase is required; calling again with a new phase records the phase change (e.g. Suchtreffer angeschrieben = search-hit-contact, Zugangslink versendet = accesslink-sent, Absage = canceled). The change is logged on the object's logbook.
write listings
Request
| Field | Type | | Description |
| contactId |
string |
required |
The contact to link |
| immoId |
string |
optional |
The object (alternative to projectId) |
| projectId |
string |
optional |
The project (alternative to immoId) |
| category |
string |
optional |
Relation category (default 'interested-person'): interested-person, buyer, search-hit-ignored, manager, marketer, architect, craftsman, renter, fiscal-agent, notary, owner, builder-owner, employer, tip-giver |
| phase |
string |
optional |
Prospect phase, required for 'interested-person': search-hit-contact, request-received, request-answered, accesslink-sent, first-viewing, second-viewing, sales-negotiation, reservation, buy-promise, proof-of-funding, draft-contract, land-register-meeting, contract-signing, canceled |
Response
| Field | Type | Description |
| id |
string |
Relation id |
| contactId |
string |
The linked contact |
| immoId |
string |
The linked object |
| projectId |
string |
The linked project |
| category |
string |
Relation category (owner, interested-person, buyer, …) |
| phase |
string |
Prospect phase (interested-person relations) |
| phaseLabel |
string |
Human-readable phase label |
| source |
string |
Where the relation came from |
| contact |
object |
Contact preview as { firstname, lastname, email } |
| createDate |
date |
When the relation was created |
| isNew |
boolean |
True when the relation was created, false when an existing one was moved to the given phase |
Publications 4
publications.create
MCP publications_create
Create a new publication for an object from its smart listing (the object must have one). The new publication becomes the object's current publication.
write listings
Request
| Field | Type | | Description |
| immoId |
string |
required |
Object id |
Response
| Field | Type | Description |
| publicationId |
string |
The new publication |
| immoId |
string |
Object id |
publications.end
MCP publications_end
End (withdraw) the running publication campaign of an object on a channel. Ending the avendo channel also ends the apex campaign. Requires the end-publications permission and confirmation.
write listings switch · endPublications confirmation
Request
| Field | Type | | Description |
| immoId |
string |
required |
Object id |
| channel |
string |
required |
Publication channel: platform, avendo, immoscout, homegate, urbanhome, smg, newhome, properstar, comparis, dreamo, flatfox, neubauprojekte, lookmove, beyonity, realadvisor, immobilier-ch, homepage, custom, avendo-publications |
Response
| Field | Type | Description |
| immoId |
string |
Object id |
| channel |
string |
The channel that was ended |
| ended |
boolean |
Always true on success |
publications.publish
MCP publications_publish
Start publishing an object on a channel (starts the channel campaign after validating the publish state). Fails with the validation report when required content is missing.
write listings
Request
| Field | Type | | Description |
| immoId |
string |
required |
Object id |
| channel |
string |
required |
Publication channel: platform, avendo, immoscout, homegate, urbanhome, smg, newhome, properstar, comparis, dreamo, flatfox, neubauprojekte, lookmove, beyonity, realadvisor, immobilier-ch, homepage, custom, avendo-publications |
Response
A missing-content publish attempt fails with VALIDATION_ERROR carrying the validation report instead.
| Field | Type | Description |
| campaignId |
string |
The started channel campaign |
| immoId |
string |
Object id |
| channel |
string |
The channel that was started |
| startDate |
date |
When publishing started |
publications.status
MCP publications_status
An object's publication state: the current publication, archived count, and every channel campaign with start/end dates. Read-only.
read listings
Request
| Field | Type | | Description |
| immoId |
string |
required |
Object id |
Response
| Field | Type | Description |
| immoId |
string |
Object id |
| currentPublication |
object |
{ id, title, createDate }, or null when the object has no publication yet |
| archivedCount |
number |
Number of superseded publications |
| campaigns[].channel |
string |
Publication channel |
| campaigns[].startDate |
date |
When publishing on that channel started |
| campaigns[].endDate |
date |
When it ended; null while running |
| campaigns[].active |
boolean |
Whether the campaign is currently running |
Valuations 4
valuations.create
MCP valuations_create
Run a fresh valuation for an existing CRM object using its current master data (the CRM's Bewertung/Schnellschätzung action). Returns the new value with its range and confidence. Update the object first (objects.updateFields) to valuate changed facts. Not available for plots.
write valuations
Request
| Field | Type | | Description |
| immoId |
string |
required |
Object id |
Response
kind is always 'crm' here (an agent-run estimation).
| Field | Type | Description |
| immoId |
string |
The valuated object |
| id |
string |
Estimation id |
| kind |
string |
'crm' (agent-run) or 'platform' (funnel/homeowner) |
| createDate |
date |
When the valuation was produced |
| date |
string |
Valuation date of the current value (YYYY-MM-DD) |
| salePrice |
number |
Estimated sale price |
| salePriceRange |
object |
Confidence interval { lower, upper } |
| confidence |
string |
poor | medium | good |
The download URL of a generated valuation-dossier PDF (from valuations.list). Requires the document-retrieval permission (the dossier contains the owner's property data).
read valuations switch · documentRetrieval
Request
| Field | Type | | Description |
| dossierId |
string |
required |
Valuation dossier id (from valuations.list) |
Response
NOT_FOUND while no PDF has been generated yet (including a dossier still processing).
| Field | Type | Description |
| id |
string |
Dossier id |
| immoId |
string |
The object the dossier belongs to |
| processingStatus |
string |
PDF generation state |
| url |
string |
Download URL of the generated PDF |
The valuations of one object, or of every object a contact owns: agent-run CRM quick estimations, homeowner/funnel platform estimations and the full valuation dossiers (with hybrid value and whether a PDF exists). Pass exactly one of immoId or contactId. Read-only.
read valuations
Request
| Field | Type | | Description |
| immoId |
string |
optional |
One object |
| contactId |
string |
optional |
A contact — returns the valuations of every object the contact owns (max 25) |
| includeHistory |
boolean |
optional |
Include the full value series per estimation (default false: current value only) |
Response
One row per object (exactly one when immoId was given), each with its newest 5 estimations and up to 10 dossiers. total_count is the number of rows.
| Field | Type | Description |
| items[].immoId |
string |
Object id |
| items[].visualReferenceId |
string |
Human-readable reference number |
| items[].address |
object |
street, housenumber, postal, place, country |
| items[].objectCategory |
string |
Fine-grained object category key |
| items[].status |
string |
Marketing status |
| items[].estimations[].id |
string |
Estimation id |
| items[].estimations[].kind |
string |
'crm' (agent-run) or 'platform' (funnel/homeowner) |
| items[].estimations[].createDate |
date |
When the valuation was produced |
| items[].estimations[].date |
string |
Valuation date of the current value (YYYY-MM-DD) |
| items[].estimations[].salePrice |
number |
Estimated sale price |
| items[].estimations[].salePriceRange |
object |
Confidence interval { lower, upper } |
| items[].estimations[].confidence |
string |
poor | medium | good |
| items[].estimations[].history |
object |
Only with includeHistory: the full series as [{ date, salePrice, salePriceRange, confidence }] |
| items[].dossiers[].id |
string |
Dossier id (pass to valuations.dossierDownloadLink) |
| items[].dossiers[].createDate |
date |
When the dossier was created |
| items[].dossiers[].processingStatus |
string |
PDF generation state (e.g. processing, finished, failed) |
| items[].dossiers[].valuationSource |
string |
'iazi' or 'custom' |
| items[].dossiers[].hybridEstimation |
number |
The hybrid (agent-adjusted) value |
| items[].dossiers[].customHedonicValuation |
number |
Manual hedonic value when valuationSource is custom |
| items[].dossiers[].bigDataEstimation |
object |
Model value as { min, max, value } |
| items[].dossiers[].confidence1to3 |
number |
Confidence on a 1–3 scale |
| items[].dossiers[].criticalFactors |
string[] |
Factors flagged as critical for the valuation |
| items[].dossiers[].agentId |
string |
The agent the dossier is authored for |
| items[].dossiers[].hasPdf |
boolean |
Whether a generated PDF exists |
| total_count |
number |
Total number of matching rows (not the page size) |
Valuation funnel: submit a property (address + facts) and the homeowner's contact details, get the property value back, and create the seller lead in the CRM (contact, lead object, owner relation, agent notification). This is the API behind a partner's own "what is my property worth" form. Requires an Idempotency-Key request header so a resubmitted form never creates a duplicate lead. Plots get a lead but no value (no automated plot valuation exists).
write valuations
Request
| Field | Type | | Description |
| email |
string |
required |
Homeowner's email (dedup key within the company) |
| objectCategory |
string |
required |
Fine-grained object category key (objects.fieldCatalog lists them, e.g. floor-apartment, villa, plot) |
| postal |
number |
required |
Postal code of the property |
| place |
string |
required |
Town/city of the property |
| firstname |
string |
optional |
First name |
| lastname |
string |
optional |
Last name |
| phone |
string |
optional |
Phone number |
| gender |
string |
optional |
'male' or 'female' (drives the salutation) |
| street |
string |
optional |
Street name |
| housenumber |
string |
optional |
House number |
| country |
string |
optional |
Country code (default 'CH') |
| buildYear |
number |
optional |
Year built |
| renovationYear |
number |
optional |
Year of the last renovation |
| rooms |
number |
optional |
Number of rooms |
| bathrooms |
number |
optional |
Number of bathrooms |
| flats |
number |
optional |
Number of flats (multi-family houses) |
| separateGarages |
number |
optional |
Number of separate garages |
| netLivingArea |
number |
optional |
Net living area in m² |
| propertyArea |
number |
optional |
Plot area in m² (houses and plots) |
| balconyArea |
number |
optional |
Balcony area in m² |
| netRentPA |
number |
optional |
Net rent per year (multi-family houses) |
| objectCondition |
string |
optional |
General condition applied to all condition fields: renovation_needed, intact, renovated, new |
| source |
string |
optional |
Lead origin recorded in the CRM (default 'homepage') |
| tags |
string[] |
optional |
Tags for the created contact |
| notes |
string |
optional |
Notes for the created contact |
Response
On an Idempotency-Key replay the stored first response is returned and no second lead is created.
| Field | Type | Description |
| contactId |
string |
The created or matched contact |
| immoId |
string |
The created lead object |
| visualReferenceId |
string |
Reference number of the new object |
| valuation.date |
string |
Valuation date (YYYY-MM-DD) |
| valuation.salePrice |
number |
Estimated sale price; the whole valuation object is null when none was produced |
| valuation.salePriceRange |
object |
Confidence interval { lower, upper } |
| valuation.confidence |
string |
poor | medium | good |
| valuationStatus |
string |
'valuated' | 'unsupportedCategory' (e.g. a plot) | 'failed' (the lead exists either way) |
Listings (published) 1
List the company's published listings with filtering, sorting and skip/limit paging.
read listings
Request
| Field | Type | | Description |
| marketingType |
string |
optional |
Marketing type filter (e.g. SELL, RENT) |
| propertyTypes |
string[] |
optional |
Property type keys |
| postal |
number |
optional |
Postal code filter |
| priceFrom |
number |
optional |
Minimum price |
| priceTo |
number |
optional |
Maximum price |
| roomsFrom |
number |
optional |
Minimum number of rooms |
| roomsTo |
number |
optional |
Maximum number of rooms |
| skip |
number |
optional |
Rows to skip (default 0) |
| limit |
number |
optional |
Page size (default 10) |
| sort |
string |
optional |
Sort field (default createDate) |
| order |
string |
optional |
'asc' or 'desc' (default desc) |
| status |
string |
optional |
'open' or 'sold/leased' |
| projectVisualReferenceId |
string |
optional |
Limit results to one project |
Response
Published listings only. The response is byte-identical to the pre-operations-layer v1 endpoint — this is the one operation kept on the legacy error format.
| Field | Type | Description |
| items[]._id |
string |
Publication id of the listing |
| items[].title |
string |
Listing title |
| items[].address |
object |
postal and place always; street, housenumber and location only when the object does not mask its address |
| items[].dimensions |
object |
netLivingArea, grossLivingArea, propertyArea |
| items[].properties |
object |
Listing properties (category, rooms, …) |
| items[].financeAndMarket |
object |
price, netRent, grossRent (all null once sold) and marketingType |
| items[].images |
object |
Listing images in display order |
| items[]._immo |
object |
Object reference data: visualReferenceId, address, status/marketingType, publish and sold dates, projectId, selected properties |
| items[]._publicationIdentity |
object |
Resolved presentation identity as { logoUrl, agencyName } (override → office → company) |
| total_count |
number |
Total number of matching rows (not the page size) |
Master data 3
The company profile (name, address, contact, branding, language/currency). Read-only.
read master-data
No input parameters.
Response
Null when the company record is missing.
| Field | Type | Description |
| id |
string |
Company id |
| name |
string |
Company name |
| key |
string |
Company key (used as partner referral ref) |
| phone |
string |
Main phone number |
| address |
object |
Company address |
| domain |
string |
Primary domain |
| websiteUrl |
string |
Website URL |
| logoUrl |
string |
Logo URL |
| faviconUrl |
string |
Favicon URL |
| language |
string |
Default language |
| currency |
string |
Default currency |
| whiteLabeled |
boolean |
Whether the company runs white-labelled |
| isActive |
boolean |
Whether the company is active |
The company's offices / branches (name, address, contact, default flag). Read-only.
read master-data
No input parameters.
Response
Default office first, then alphabetical (a bare array).
| Field | Type | Description |
| [].id |
string |
Office id |
| [].name |
string |
Office name |
| [].name2 |
string |
Second name line |
| [].address |
object |
Office address |
| [].phone |
string |
Phone number |
| [].email |
string |
Email address |
| [].logoUrl |
string |
Office logo URL |
| [].isDefault |
boolean |
Whether this is the default office |
| [].defaultContactAgentId |
string |
Default contact agent of the office |
The company's team / broker profiles (active admins and agents): name, contact, role, photo. Read-only.
read master-data
No input parameters.
Response
Active admins and agents, sorted by last then first name (a bare array).
| Field | Type | Description |
| [].id |
string |
User id |
| [].firstName |
string |
First name |
| [].lastName |
string |
Last name |
| [].name |
string |
Display/sender name |
| [].email |
string |
Email address |
| [].phone |
string |
Phone number |
| [].role |
string |
CRM role (admin, agent) |
| [].photoUrl |
string |
Portrait URL |
| [].active |
boolean |
Whether the account is active |
Insights & reporting 5
insights.activity
MCP insights_activity
Activity report: agent-activity logbook entries in the window, grouped by user. Read-only.
read listings
Request
| Field | Type | | Description |
| days |
number |
optional |
Look-back window in days (default 30, seller-leads 90; clamped 1–365) |
Response
| Field | Type | Description |
| windowDays |
number |
The look-back window actually used |
| byUser[] |
object |
Activities per user as { userId, name, count }, busiest first |
| total |
number |
All agent activities in the window |
Lead statistics: contacts created in the window grouped by source (channel/portal). Read-only.
read listings
Request
| Field | Type | | Description |
| days |
number |
optional |
Look-back window in days (default 30, seller-leads 90; clamped 1–365) |
Response
| Field | Type | Description |
| windowDays |
number |
The look-back window actually used |
| bySource[] |
object |
Contacts per source as { source, count }, largest first ("unknown" = no source set) |
| total |
number |
All contacts created in the window |
| definition |
string |
How the numbers are derived |
Marketing performance: active listings and inquiries per channel, viewing totals, and the top objects by inquiries in the window. Read-only.
read listings
Request
| Field | Type | | Description |
| days |
number |
optional |
Look-back window in days (default 30, seller-leads 90; clamped 1–365) |
Response
| Field | Type | Description |
| windowDays |
number |
The look-back window actually used |
| channels[].channel |
string |
Publication channel |
| channels[].activeListings |
number |
Objects with a running campaign on that channel |
| channels[].inquiries |
number |
Inbound inquiries attributed to that channel in the window |
| totals.activeListings |
number |
Distinct objects with a running publication |
| totals.inquiries |
number |
All inquiries in the window |
| totals.viewings |
number |
Viewing appointments in the window |
| topObjectsByInquiries[] |
object |
Top 10 objects as { immoId, referenceId, place, inquiries } |
| definition |
string |
How each number is derived (read it before comparing to CRM screens) |
insights.pipeline
MCP insights_pipeline
Pipeline overview: the company's objects grouped by status (Lead → In Bearbeitung → Publiziert → Verkauft …). Read-only.
read listings
No input parameters.
Response
Current snapshot — no time window.
| Field | Type | Description |
| byStatus[] |
object |
Objects per status as { status, title, count }, largest first (demo and reference objects excluded) |
| total |
number |
Total number of objects counted |
insights.sellerLeads
MCP insights_sellerLeads
Seller-lead overview: valuations, homeowner-platform requests, open seller leads, and the valuation→mandate conversion. Read-only.
read listings
Request
| Field | Type | | Description |
| days |
number |
optional |
Look-back window in days (default 30, seller-leads 90; clamped 1–365) |
Response
| Field | Type | Description |
| windowDays |
number |
The look-back window actually used (default 90 here) |
| valuations |
number |
Distinct objects valued in the window (dossiers, CRM and platform estimations) |
| platformRequests.total |
number |
Homeowner-platform requests in the window |
| platformRequests.byType[] |
object |
Requests per type as { type, count } |
| openSellerLeads |
number |
Request objects without an active mandate |
| mandateConversion.valued |
number |
Objects valued in the window |
| mandateConversion.converted |
number |
Of those, how many now have an active mandate |
| mandateConversion.rate |
number |
converted / valued, rounded to three decimals |
| definition |
string |
How each number is derived |
Logbook 2
logbook.list
MCP logbook_list
Read the company's logbook (activity history), filterable by contact, object, activity key and date range. Read-only.
read contacts
Request
| Field | Type | | Description |
| contactId |
string |
optional |
Limit to one contact |
| immoId |
string |
optional |
Limit to one object |
| key |
string |
optional |
Limit to one activity key: not-reached, phone-incoming, phone-outgoing, email, meeting, sms-whatsapp, note, lead-referred |
| fromDate |
string |
optional |
Entries created at/after this ISO date |
| toDate |
string |
optional |
Entries created at/before this ISO date |
| skip |
number |
optional |
Rows to skip (default 0) |
| limit |
number |
optional |
Page size (default 10) |
Response
Entries newest first.
| Field | Type | Description |
| items[].id |
string |
Logbook entry id |
| items[].key |
string |
Activity key |
| items[].actionType |
string |
Action type label |
| items[].subject |
string |
Subject line |
| items[].message |
string |
Entry text |
| items[].contactId |
string |
Linked contact |
| items[].immoId |
string |
Linked object |
| items[].projectId |
string |
Linked project |
| items[].userId |
string |
Acting user |
| items[].isAgentActivity |
boolean |
Whether it counts as agent-to-contact activity |
| items[].isMcpAction |
boolean |
Whether the entry was produced through MCP |
| items[].isPartnerApiAction |
boolean |
Whether the entry was produced through the Partner API |
| items[].createDate |
date |
When the entry was written |
| total_count |
number |
Total number of matching rows (not the page size) |
logbook.record
MCP logbook_record
Record a manual activity in the logbook (call, meeting, note, ...), optionally linked to a contact and/or object. Renders like a CRM quick-action entry; MCP attribution is stamped automatically.
write contacts
Request
| Field | Type | | Description |
| key |
string |
required |
Activity kind: not-reached, phone-incoming, phone-outgoing, email, meeting, sms-whatsapp, note |
| message |
string |
required |
The activity text |
| contactId |
string |
optional |
Link to a contact |
| immoId |
string |
optional |
Link to an object |
Response
| Field | Type | Description |
| id |
string |
The new logbook entry |
| key |
string |
The recorded activity key |
| createDate |
date |
When it was written |
Tasks 3
tasks.complete
MCP tasks_complete
Mark a task as done (stamps the completion date and completing user).
write contacts
Request
| Field | Type | | Description |
| taskId |
string |
required |
Task id |
Response
The task with its completion date set.
| Field | Type | Description |
| id |
string |
Task id |
| description |
string |
What is to be done |
| dueDate |
date |
Due date |
| status |
string |
Workflow status the task belongs to |
| done |
date |
Completion date; null while the task is open |
| assigneeUserId |
string |
Assignee |
| contactId |
string |
Linked contact |
| immoId |
string |
Linked object |
| projectId |
string |
Linked project |
| optional |
boolean |
Whether the task is optional |
| createDate |
date |
When the task was created |
tasks.create
MCP tasks_create
Create a task, optionally linked to a contact/object and with a due date (a due date makes it a reminder task). Default assignee is the acting user.
write contacts
Request
| Field | Type | | Description |
| description |
string |
required |
What is to be done |
| assigneeUserId |
string |
optional |
Assignee user id (default: the acting user) |
| contactId |
string |
optional |
Link to a contact |
| immoId |
string |
optional |
Link to an object |
| dueDate |
string |
optional |
Due date (ISO 8601) |
Response
The created task.
| Field | Type | Description |
| id |
string |
Task id |
| description |
string |
What is to be done |
| dueDate |
date |
Due date |
| status |
string |
Workflow status the task belongs to |
| done |
date |
Completion date; null while the task is open |
| assigneeUserId |
string |
Assignee |
| contactId |
string |
Linked contact |
| immoId |
string |
Linked object |
| projectId |
string |
Linked project |
| optional |
boolean |
Whether the task is optional |
| createDate |
date |
When the task was created |
tasks.list
MCP tasks_list
List the company's tasks, filterable by open/done, assignee, contact, object and due-date range. Read-only.
read contacts
Request
| Field | Type | | Description |
| query |
string |
optional |
Description filter (starts-with) |
| done |
boolean |
optional |
true = completed tasks, false = open tasks (default: both) |
| assigneeUserId |
string |
optional |
Limit to one assignee |
| contactId |
string |
optional |
Limit to one contact |
| immoId |
string |
optional |
Limit to one object |
| dueFrom |
string |
optional |
Due at/after this ISO date (switches the date filter to dueDate) |
| dueTo |
string |
optional |
Due at/before this ISO date (switches the date filter to dueDate) |
| skip |
number |
optional |
Rows to skip (default 0) |
| limit |
number |
optional |
Page size (default 10) |
Response
Matching tasks, newest first.
| Field | Type | Description |
| items[].id |
string |
Task id |
| items[].description |
string |
What is to be done |
| items[].dueDate |
date |
Due date |
| items[].status |
string |
Workflow status the task belongs to |
| items[].done |
date |
Completion date; null while the task is open |
| items[].assigneeUserId |
string |
Assignee |
| items[].contactId |
string |
Linked contact |
| items[].immoId |
string |
Linked object |
| items[].projectId |
string |
Linked project |
| items[].optional |
boolean |
Whether the task is optional |
| items[].createDate |
date |
When the task was created |
| total_count |
number |
Total number of matching rows (not the page size) |
Appointments 2
appointments.create
MCP appointments_create
Create an appointment. Non-'free' types (viewings) require an object. No confirmation email is sent to the contact - use emails.send for that. Syncs to the owner's default push calendar.
write contacts
Request
| Field | Type | | Description |
| startTime |
string |
required |
Start (ISO 8601) |
| endTime |
string |
required |
End (ISO 8601) |
| title |
string |
optional |
Title |
| description |
string |
optional |
Description |
| type |
string |
optional |
Appointment type (default 'free'): free, singular, group |
| immoId |
string |
optional |
Linked object (required for non-'free' types) |
| contactId |
string |
optional |
Attending contact |
| ownerUserId |
string |
optional |
Calendar owner (default: the acting user) |
| allDay |
boolean |
optional |
All-day event (default false) |
Response
The created appointment.
| Field | Type | Description |
| id |
string |
Appointment id |
| title |
string |
Title |
| description |
string |
Description |
| startTime |
date |
Start |
| endTime |
date |
End |
| allDay |
boolean |
All-day event |
| timeZone |
string |
Time zone |
| type |
string |
Appointment type |
| visibility |
string |
Visibility (private events of other users are redacted) |
| ownerUserId |
string |
Calendar owner |
| immoId |
string |
Linked object |
| contactId |
string |
Linked contact |
| attendees |
object |
Attending contacts as [{ contactId, attending }] |
appointments.list
MCP appointments_list
List appointments in a date range, filterable by object, owner and type. Private events of other users are redacted. Read-only.
read contacts
Request
| Field | Type | | Description |
| fromDate |
string |
optional |
Appointments starting at/after this ISO date |
| toDate |
string |
optional |
Appointments starting at/before this ISO date |
| immoId |
string |
optional |
Limit to one object |
| ownerUserId |
string |
optional |
Limit to one calendar owner |
| type |
string |
optional |
Appointment type: free, singular, group |
Response
Appointments in the range; total_count is the number of returned rows (this read is not paged).
| Field | Type | Description |
| items[].id |
string |
Appointment id |
| items[].title |
string |
Title |
| items[].description |
string |
Description |
| items[].startTime |
date |
Start |
| items[].endTime |
date |
End |
| items[].allDay |
boolean |
All-day event |
| items[].timeZone |
string |
Time zone |
| items[].type |
string |
Appointment type |
| items[].visibility |
string |
Visibility (private events of other users are redacted) |
| items[].ownerUserId |
string |
Calendar owner |
| items[].immoId |
string |
Linked object |
| items[].contactId |
string |
Linked contact |
| items[].attendees |
object |
Attending contacts as [{ contactId, attending }] |
| total_count |
number |
Total number of matching rows (not the page size) |
Email 3
emails.bulkSend
MCP emails_bulkSend
Serial send: one email (with placeholders) to a selected set of contacts or a contact list, max 100 recipients per send. Requires the serial-send permission; the confirmation preview shows the resolved recipient list and count before anything is sent. Every recipient gets an email record and a logbook entry.
write contacts switch · bulkSend confirmation
Request
| Field | Type | | Description |
| subject |
string |
required |
Subject (placeholders allowed) |
| body |
string |
required |
Body as HTML or plain text (placeholders allowed) |
| contactIds |
string[] |
optional |
Recipient contact ids (alternative to listId, max 100) |
| listId |
string |
optional |
Contact list to send to (alternative to contactIds) |
| immoId |
string |
optional |
Linked object (enables object placeholders and timeline linkage) |
Response
The preview call instead returns { subject, recipientCount, recipients[], skippedWithoutEmail } plus the confirmation token.
| Field | Type | Description |
| draftId |
string |
The draft that was created and sent |
| recipientCount |
number |
How many contacts were sent to |
| skippedWithoutEmail |
string[] |
Resolved recipients that were skipped for lack of an email address |
| jobId |
string |
Id of the queued send job |
| queuedCount |
number |
How many recipient emails were queued |
| provider |
string |
Sending path used: 'mailersend' (verified domain) or 'nylas' (mailbox) |
emails.draft
MCP emails_draft
Create an email draft for one or more contacts (always allowed - nothing is sent). The draft is visible in the CRM for review; sending it needs emails.send (one recipient) or emails.bulkSend. Subject/body support the CRM placeholders.
write contacts
Request
| Field | Type | | Description |
| subject |
string |
required |
Subject (placeholders allowed) |
| body |
string |
required |
Body as HTML or plain text (placeholders allowed) |
| contactIds |
string[] |
required |
Recipient contact ids |
| immoId |
string |
optional |
Linked object (enables object placeholders and timeline linkage) |
Response
Nothing is sent by this operation.
| Field | Type | Description |
| draftId |
string |
The created draft (pass to emails.send) |
| recipientCount |
number |
Number of recipients on the draft |
emails.send
MCP emails_send
Send a single-recipient email draft as the acting user (sending path: verified MailerSend domain, else the user mailbox, else the company mailbox). Requires the send-email permission and confirmation. Multi-recipient drafts are refused - see emails.bulkSend.
write contacts switch · emailSend confirmation
Request
| Field | Type | | Description |
| draftId |
string |
required |
The draft to send (from emails.draft) |
Response
The preview call instead returns { subject, recipient } plus the confirmation token.
| Field | Type | Description |
| draftId |
string |
The sent draft |
| jobId |
string |
Id of the queued send job |
| queuedCount |
number |
How many recipient emails were queued |
| provider |
string |
Sending path used: 'mailersend' (verified domain) or 'nylas' (mailbox) |
SMS 1
Send an SMS to a contact's primary phone number (sender: the company's SMS sender name). Requires the send-SMS permission. The send is recorded in the contact's logbook.
write contacts switch · sms
Request
| Field | Type | | Description |
| contactId |
string |
required |
Contact id (must have a phone number) |
| message |
string |
required |
The SMS text |
Response
| Field | Type | Description |
| contactId |
string |
The contact the SMS went to |
| sent |
boolean |
Always true on success (out of SMS credits fails with VALIDATION_ERROR) |
Webhooks 8
Create a webhook subscription. The full signing secret is returned once in the response.
write webhooks
Request
| Field | Type | | Description |
| url |
string |
required |
HTTPS endpoint the signed event POST is delivered to |
| events |
string[] |
required |
A non-empty subset of: contact.created, inquiry.received, searchProfile.created, searchProfile.match, valuation.lead |
| description |
string |
optional |
Optional label |
Response
The only response that carries the full signing secret (besides webhooks.rotateSecret).
| Field | Type | Description |
| subscription._id |
string |
Subscription id |
| subscription.url |
string |
Delivery endpoint |
| subscription.events |
string[] |
Subscribed event types |
| subscription.secret |
string |
Signing secret, masked (full value only from webhooks.create / rotateSecret) |
| subscription.description |
string |
Label |
| subscription.active |
boolean |
Whether deliveries are enabled |
| subscription.createDate |
date |
When the subscription was created |
| subscription.lastModifiedDate |
date |
Last change |
| secret |
string |
The full signing secret — shown only here, store it securely |
| warning |
string |
Reminder that the secret cannot be retrieved again |
Delete a webhook subscription. Deliveries stop immediately.
write webhooks
Request
| Field | Type | | Description |
| id |
string |
required |
Webhook subscription id |
Response
| Field | Type | Description |
| deleted |
boolean |
Always true on success |
| id |
string |
The deleted subscription id |
Recent delivery attempts (status, response code, timestamps), optionally for one subscription. Read-only.
read webhooks
Request
| Field | Type | | Description |
| subscriptionId |
string |
optional |
Filter to one subscription |
| limit |
number |
optional |
Max rows (default 50, capped at 200) |
Response
Delivery attempts newest first (a bare array).
| Field | Type | Description |
| []._id |
string |
Delivery id |
| [].subscriptionId |
string |
The subscription it was delivered for |
| [].eventType |
string |
Event type |
| [].eventId |
string |
Event id (also sent as the X-Avendo-Delivery header) |
| [].url |
string |
Endpoint the attempt went to |
| [].payload |
object |
The event data that was sent |
| [].status |
string |
pending | delivered | failed | dead |
| [].attempts |
number |
Number of attempts so far |
| [].responseStatus |
number |
HTTP status of the last attempt |
| [].lastError |
string |
Error of the last failed attempt |
| [].createDate |
date |
When the event was recorded |
The catalog of subscribable webhook event types. Read-only.
read webhooks
No input parameters.
Response
| Field | Type | Description |
| events |
string[] |
Every event type that can be subscribed to |
Get one webhook subscription (signing secret masked). Read-only.
read webhooks
Request
| Field | Type | | Description |
| id |
string |
required |
Webhook subscription id |
Response
| Field | Type | Description |
| _id |
string |
Subscription id |
| url |
string |
Delivery endpoint |
| events |
string[] |
Subscribed event types |
| secret |
string |
Signing secret, masked (full value only from webhooks.create / rotateSecret) |
| description |
string |
Label |
| active |
boolean |
Whether deliveries are enabled |
| createDate |
date |
When the subscription was created |
| lastModifiedDate |
date |
Last change |
List the company's webhook subscriptions (signing secret masked). Read-only.
read webhooks
No input parameters.
Response
All subscriptions of the company, newest first (a bare array).
| Field | Type | Description |
| []._id |
string |
Subscription id |
| [].url |
string |
Delivery endpoint |
| [].events |
string[] |
Subscribed event types |
| [].secret |
string |
Signing secret, masked (full value only from webhooks.create / rotateSecret) |
| [].description |
string |
Label |
| [].active |
boolean |
Whether deliveries are enabled |
| [].createDate |
date |
When the subscription was created |
| [].lastModifiedDate |
date |
Last change |
Rotate a subscription's signing secret. The new full secret is returned once in the response.
write webhooks
Request
| Field | Type | | Description |
| id |
string |
required |
Webhook subscription id |
Response
The new secret takes effect immediately — deliveries signed with the old one stop.
| Field | Type | Description |
| subscription._id |
string |
Subscription id |
| subscription.url |
string |
Delivery endpoint |
| subscription.events |
string[] |
Subscribed event types |
| subscription.secret |
string |
Signing secret, masked (full value only from webhooks.create / rotateSecret) |
| subscription.description |
string |
Label |
| subscription.active |
boolean |
Whether deliveries are enabled |
| subscription.createDate |
date |
When the subscription was created |
| subscription.lastModifiedDate |
date |
Last change |
| secret |
string |
The full signing secret — shown only here, store it securely |
| warning |
string |
Reminder that the secret cannot be retrieved again |
Update a webhook subscription's url, events, description or active flag (signing secret masked).
write webhooks
Request
| Field | Type | | Description |
| id |
string |
required |
Webhook subscription id |
| url |
string |
optional |
New HTTPS endpoint |
| events |
string[] |
optional |
A non-empty subset of: contact.created, inquiry.received, searchProfile.created, searchProfile.match, valuation.lead |
| description |
string |
optional |
New label |
| active |
boolean |
optional |
Enable/disable delivery without deleting |
Response
The updated subscription.
| Field | Type | Description |
| _id |
string |
Subscription id |
| url |
string |
Delivery endpoint |
| events |
string[] |
Subscribed event types |
| secret |
string |
Signing secret, masked (full value only from webhooks.create / rotateSecret) |
| description |
string |
Label |
| active |
boolean |
Whether deliveries are enabled |
| createDate |
date |
When the subscription was created |
| lastModifiedDate |
date |
Last change |