Realtor Leads Webhook

Test the Realtor leads webhook endpoint. This shows the default expected payload shape - the endpoint accepts any shape as long as a field mapping targets it.

Endpoint

Pushes the contact to GHL inline and responds with the result.

API Config

Contact

Property Address

Listing Agent

Listing Office

Request

Endpoint:
POST /api/v1/test-location-123/webhook/realtor/leads
Headers:
{
  "Content-Type": "application/json",
  "m4-connect-key": "[your-api-key]"
}
Body (Editable):

API Reference

Payload shape:

The nested shape above is the default expected shape (a realtor.com "Connections Plus" lead notification) and is what the built-in fallback field mapping targets. Every field is optional, and the endpoint isn't limited to this shape - the fields actually used to build the contact (name, email, phone, etc.) are whatever the resolved field mapping (configured in the configurator, or this default) points at. A location can be configured with a mapping that targets a completely different payload shape with no code changes.

Default Field Mapping:

  • lead_info.lead_id realtor_lead_id (also the default external_id)
  • lead_info.lead_type / lead_info.message realtor_lead_type / realtor_lead_message
  • contact.first_name / contact.last_name contact.first_name / contact.last_name
  • contact.email contact.email (fallback external_id if lead_info.lead_id doesn't resolve)
  • contact.phone contact.phone
  • property_details.address.* contact.address1 / contact.city / contact.state / contact.postal_code
  • property_details.mls_id / property_details.realtor_listing_url realtor_mls_id / realtor_listing_url
  • representation.listing_agent.name realtor_agent_assigned
  • representation.listing_office.broker_name realtor_broker_assigned

Processing:

  • Field mapping is resolved via ConfigurationClient.getMappings for the "realtor" sub-feature, falling back to the default mapping above.
  • Name/email/phone for the contact record are read back out of the resolved mapping output, checked against known aliases (e.g. contact.email then email) - not fixed payload fields - so a differently-shaped payload works as long as a mapping targets it.
  • external_id is built from the mapping response's uniqueIdentifier field list when configured (joining resolved values with _). When no mapping is configured, the default uniqueIdentifier is realtor_lead_id (i.e. lead_info.lead_id), falling back to the resolved email if that doesn't resolve.
  • If the mapping response includes tags, they're added to sync_data.tags.
  • A pending ContactSyncRecord is upserted with sync_source: "Realtor" and sync_direction: "In".
  • The existing GHL contact sync workflow picks up the pending record asynchronously.

Sync vs Async:

/api/v1/[locationId]/webhook/realtor/leads (synchronous, default) pushes the contact to GHL inline and reflects the result in the response. /api/v1/[locationId]/webhook/realtor/async/leads shares the same validation and field-mapping logic but only inserts a PENDING record and returns immediately - the existing GHL contact sync workflow (~2-minute cron) delivers it later. Use the toggle above to test either.

Full Documentation:

See docs/API_REALTOR_LEADS.md for the complete field mapping table, error codes, and cURL examples for both endpoints.