> ## Documentation Index
> Fetch the complete documentation index at: https://docs.nekt.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Kenlo as a data source

> Bring data from Kenlo Imob to your Lakehouse.

Kenlo Imob is a Brazilian CRM for real estate agencies. The connector uses the Kenlo Open API v2 to extract your properties and the listings published on the channels, your customers, brokers and users, your leads with their proposals and history, your developments with their towers, units, attributes and combos, and the reference lists behind the property fields. With it you can analyze your portfolio, your funnel and your brokers' performance in your Lakehouse.

## Configuring Kenlo as a Source

In the [Sources](https://app.nekt.ai/sources) tab, click on the "Add source" button located on the top right of your screen. Then, select the Kenlo option from the list of connectors.

Click **Next** and you'll be prompted to add your access.

### 1. Add account access

Kenlo gives API access through the **Kenlo Marketplace**, and only to agencies on the **K2 plan**. When the integration is registered in the Marketplace, Kenlo issues two values that are used together:

* the **API key**;
* the **user info**, a long Base64 text that identifies your agency.

<Note>
  In the Marketplace, the agency also chooses which data the integration may read (consents). To extract leads, their proposals and history, and the list of brokers and users, the lead-reading consent (`lead_get_status_consent`) must be enabled. Prices, owner data and full addresses also depend on their own consents; without them those fields come back empty.
</Note>

The following configurations are available:

* **API Key**: the API key issued by Kenlo. Required.

* **User Info**: the user info issued together with the API key. Paste it exactly as you received it. Required.

* **Start Date**: the earliest last-update date of the properties and leads read on the first sync. Later syncs continue from where the previous one stopped. Leave it empty to read the whole history. Listings, customers, developments and the reference lists are always extracted in full.

* **Requests Per Minute** (advanced): how fast the connector may call Kenlo. The default is 60. The actual limit is set in your Kenlo contract; when Kenlo asks the connector to slow down, it waits and continues automatically.

Once you're done, click **Next**.

### 2. Select streams

Choose which data streams you want to sync. For faster extractions, select only the streams that are relevant to your analysis. You can select entire groups of streams or pick specific ones.

> Tip: The stream can be found more easily by typing its name.

<Note>
  Lead proposals and lead history take one request per lead each. On the first sync of an agency with many leads, they make the extraction noticeably longer; later syncs only visit the leads that changed.
</Note>

Select the streams and click **Next**.

### 3. Configure data streams

Customize how you want your data to appear in your catalog. Select the desired layer where the data will be placed, a folder to organize it inside the layer, a name for each table (which will effectively contain the fetched data) and the type of sync.

* **Layer**: choose between the existing layers on your catalog. This is where you will find your new extracted tables as the extraction runs successfully.
* **Folder**: a folder can be created inside the selected layer to group all tables being created from this new data source.
* **Table name**: we suggest a name, but feel free to customize it. You have the option to add a **prefix** to all tables at once and make this process faster!
* **Sync Type**: properties, leads, lead proposals and lead history are INCREMENTAL: each sync brings what changed since the previous one. The other streams are FULL\_TABLE: each sync replaces the table with what Kenlo currently holds. Read more about Sync Types [here](https://docs.nekt.com/get-started/core-concepts/types-of-sync).

Once you are done configuring, click **Next**.

### 4. Configure data source

Describe your data source for easy identification within your organization, not exceeding 140 characters.

To define your [Trigger](https://docs.nekt.com/get-started/core-concepts/triggers), consider how often you want data to be extracted from this source. This decision usually depends on how frequently you need the new table data updated (every day, once a week, or only at specific times).

Optionally, you can define some additional settings:

* Configure Delta Log Retention and determine for how long we should store old states of this table as it gets updated. Read more about this resource [here](https://docs.nekt.com/get-started/core-concepts/resource-control).

Once you are ready, click **Next** to finalize the setup.

### 5. Check your new source

You can view your new source on the [Sources](https://app.nekt.ai/sources) page. If needed, manually trigger the source extraction by clicking on the arrow button. Once executed, your data will appear in your Catalog.

<Warning>For you to be able to see it on your [Catalog](https://app.nekt.ai/catalog), you need at least one successful source run.</Warning>

# Streams and Fields

Below you'll find all available data streams from Kenlo and their corresponding fields. API reference: [Kenlo Open API v2](https://kenlo-open-api-prd.kenlo.io/docs/v2.html).

<Note>
  Every table has a `raw_payload` column with the whole record exactly as Kenlo returned it, so information without a column of its own is still available. Lists and objects are stored as JSON text, and timestamps are converted to UTC. During Kenlo's free period, Kenlo masks personal data (such as phone numbers and e-mails) and limits the number of records.
</Note>

<AccordionGroup>
  <Accordion title="Properties">
    Properties as registered in the agency's Kenlo CRM. Incremental: each sync reads the properties updated since the previous one (from one day before, as Kenlo filters by date).

    Table: `properties` · Primary key: `id` · Sync: Incremental

    | Field | Type | Description |
    | :- | :- | :- |
    | `id` | Integer | Identifier of the property in the Kenlo CRM. Not the listing id, which is text such as OPEN\_PROPERTY\_84499613. |
    | `property_code` | String | Business code of the property at the agency (e.g. AP-100). |
    | `title` | String | Title of the property. |
    | `description` | String | Description of the property. |
    | `property_type` | String | Property type by name (e.g. APARTMENT), when Kenlo sends it. |
    | `type_id` | Integer | Property type; see the 'type' catalog in property\_catalogs. |
    | `purpose` | String | Purpose by name (e.g. SALE), when Kenlo sends it. |
    | `purpose_id` | Integer | Purpose (sale, rent, seasonal); see the 'purpose' catalog. |
    | `status_id` | Integer | Status of the property (e.g. active, inactive); see the 'status' catalog. |
    | `owner_id` | Integer | Identifier of the owner (a customer). |
    | `sale_price` | Number | Sale price, in BRL. |
    | `rental_price` | Number | Monthly rent, in BRL. |
    | `condo_fee` | Number | Monthly condominium fee, in BRL. |
    | `iptu_value` | Number | IPTU (property tax), in BRL. |
    | `total_area` | Number | Total area, in square meters. |
    | `usable_area` | Number | Usable area, in square meters. |
    | `common_area` | Number | Common area, in square meters. |
    | `bedrooms` | Integer | Number of bedrooms. |
    | `suites` | Integer | Number of suites. |
    | `bathrooms` | Integer | Number of bathrooms. |
    | `garages` | Integer | Number of parking spaces. |
    | `full_address` | String | Full address in a single line (RESO unparsedAddress). |
    | `street_name` | String | Street name. |
    | `street_number` | String | Street number. |
    | `unit_number` | String | Unit or complement (apartment, suite). |
    | `neighborhood` | String | Neighborhood. |
    | `city` | String | City. |
    | `state` | String | State abbreviation (e.g. SP). |
    | `postal_code` | String | Postal code (CEP). |
    | `country` | String | Country code (e.g. BR). |
    | `latitude` | Number | Latitude of the address. |
    | `longitude` | Number | Longitude of the address. |
    | `features` | Array of strings | Features of the property (e.g. GYM, SWIMMING\_POOL). |
    | `photos` | String (JSON) | Photos of the property with their URLs (JSON array). |
    | `owners` | String (JSON) | Owners of the property (JSON array). Empty unless the agency granted the owner data consent. |
    | `captured_by` | String (JSON) | Broker who captured the property (JSON object). |
    | `created_at` | Datetime | When the property was registered in the CRM. |
    | `updated_at` | Datetime | When the property was last updated in the CRM, used as the incremental replication key. |
    | `raw_payload` | String (JSON) | The whole record exactly as Kenlo returned it (JSON object), including fields that have no column of their own. |
  </Accordion>

  <Accordion title="Listings">
    Listings published on the channels (portals and the agency website). A property can have zero or many listings. Extracted in full on every sync.

    Table: `listings` · Primary key: `id` · Sync: Full table

    | Field | Type | Description |
    | :- | :- | :- |
    | `id` | String | Identifier of the listing (text such as OPEN\_PROPERTY\_84499613). Not the property id of the CRM. |
    | `agency_id` | Integer | Identifier of the agency. |
    | `property_code` | String | Business code of the property at the agency (e.g. AP-100). |
    | `title` | String | Title of the listing. |
    | `description` | String | Description of the listing. |
    | `full_address` | String | Full address in a single line (RESO unparsedAddress). |
    | `street_name` | String | Street name. |
    | `street_number` | String | Street number. |
    | `unit_number` | String | Unit or complement (apartment, suite). |
    | `neighborhood` | String | Neighborhood. |
    | `city` | String | City. |
    | `state` | String | State abbreviation (e.g. SP). |
    | `postal_code` | String | Postal code (CEP). |
    | `country` | String | Country code (e.g. BR). |
    | `latitude` | Number | Latitude of the address. |
    | `longitude` | Number | Longitude of the address. |
    | `sale_price` | Number | Advertised sale price, in BRL. |
    | `rental_price` | Number | Advertised monthly rent, in BRL. |
    | `media` | String (JSON) | Media of the listing (JSON array). |
    | `created_at` | Datetime | When the listing was created. |
    | `updated_at` | Datetime | When the listing was last updated. |
    | `raw_payload` | String (JSON) | The whole record exactly as Kenlo returned it (JSON object), including fields that have no column of their own. |
  </Accordion>

  <Accordion title="Property Catalogs">
    Reference lists of the property fields, one row per option. Join `catalog = 'type'` and `value = properties.type_id` to get the name of a property type; the same works for usage, purpose, status and the other lists.

    Table: `property_catalogs` · Primary key: `catalog`, `value` · Sync: Full table

    | Field | Type | Description |
    | :- | :- | :- |
    | `catalog` | String | Which list the option belongs to: usage, type, purpose, status, property\_standard, location\_standard, commission\_type, rate\_type, face, position or iptu\_payment\_condition. |
    | `value` | Integer | Identifier of the option, as used in the property fields. |
    | `label` | String | Readable name of the option. |
    | `raw_payload` | String (JSON) | The whole record exactly as Kenlo returned it (JSON object), including fields that have no column of their own. |
  </Accordion>

  <Accordion title="Property Type Purposes">
    Combinations of property type and purpose the Kenlo CRM accepts.

    Table: `property_type_purposes` · Primary key: `type_id`, `purpose_id` · Sync: Full table

    | Field | Type | Description |
    | :- | :- | :- |
    | `type_id` | Integer | Property type; see the 'type' catalog in property\_catalogs. |
    | `purpose_id` | Integer | Purpose accepted for that type; see the 'purpose' catalog. |
    | `raw_payload` | String (JSON) | The whole record exactly as Kenlo returned it (JSON object), including fields that have no column of their own. |
  </Accordion>

  <Accordion title="Customers">
    People relevant to the agency: owners, clients, leads and brokers (see `role`). Extracted in full on every sync.

    Table: `customers` · Primary key: `id` · Sync: Full table

    | Field | Type | Description |
    | :- | :- | :- |
    | `id` | String | Identifier of the customer in the Kenlo CRM (digits, sent as text by this endpoint; the same number as client\_id in leads). |
    | `name` | String | Name of the customer. |
    | `person_type` | Integer | Type of person: 1 = individual (PF), 2 = company (PJ). |
    | `cpf` | String | CPF of an individual customer. |
    | `cnpj` | String | CNPJ of a company customer. |
    | `media_id` | Integer | Identifier of the media (origin) the customer came from. |
    | `email` | String | E-mail address of the customer. |
    | `phone` | String | Phone number of the customer. |
    | `role` | String | Role of the person for the agency: owner, client, lead or broker. |
    | `created_at` | Datetime | When the customer was registered in the CRM. |
    | `updated_at` | Datetime | When the customer was last updated in the CRM. |
    | `raw_payload` | String (JSON) | The whole record exactly as Kenlo returned it (JSON object), including fields that have no column of their own. |
  </Accordion>

  <Accordion title="Agents">
    Brokers and users of the agency, active and inactive. Requires the agency's lead-reading consent.

    Table: `agents` · Primary key: `user_id` · Sync: Full table

    | Field | Type | Description |
    | :- | :- | :- |
    | `user_id` | Integer | Identifier of the user in the Kenlo CRM (responsible\_user\_id in leads). |
    | `name` | String | Full name of the user. |
    | `email` | String | E-mail address of the user. |
    | `profile_id` | Integer | Profile of the user: 1 = admin, 2 = manager, 3 = broker, 4 = assistant, 5 = photographer. |
    | `profile_name` | String | Readable name of the profile. |
    | `active` | Boolean | Whether the user is active. |
    | `raw_payload` | String (JSON) | The whole record exactly as Kenlo returned it (JSON object), including fields that have no column of their own. |
  </Accordion>

  <Accordion title="Leads">
    Leads (atendimentos) of the agency's funnel. Incremental: each sync reads the leads updated since the previous one. Requires the agency's lead-reading consent.

    Table: `leads` · Primary key: `id` · Sync: Incremental

    | Field | Type | Description |
    | :- | :- | :- |
    | `id` | Integer | Identifier of the lead (clientAttendId), used by the lead routes. |
    | `agency_id` | Integer | Identifier of the agency. |
    | `client_id` | Integer | Identifier of the person behind the lead (a customer). |
    | `client_name` | String | Name of the person. |
    | `client_email` | String | E-mail address of the person (masked during Kenlo's free period). |
    | `client_phone` | String | Phone number of the person (masked during Kenlo's free period). |
    | `client_document` | String | CPF/CNPJ of the person. |
    | `client_external_id` | String | Identifier of the person in an external system, when sent. |
    | `stage` | String | Funnel stage: WITHOUT\_ATTENDANCE, ATTENDING, VISIT, PROPOSAL, GUARANTEE, CLOSURE or CONCLUDED. |
    | `stage_id` | Integer | Numeric id of the funnel stage. |
    | `operation` | String | Operation of interest: RENT, SALE or UNDEFINED. |
    | `operation_id` | Integer | Numeric id of the operation of interest. |
    | `responsible_user_id` | Integer | User (broker) responsible for the lead; see agents. |
    | `brokers` | String (JSON) | Brokers assigned to the lead (JSON array). |
    | `tags` | Array of strings | Tags of the lead (e.g. WhatsApp, Indicação). |
    | `origin_media` | String | Where the lead came from (e.g. portal-kenlo). |
    | `lead_scoring` | String | Qualification score of the lead, when scored. |
    | `active` | Boolean | Whether the lead is active. |
    | `is_archived` | Boolean | Whether the lead is archived. |
    | `archiving_reason` | String | Reason chosen by the broker when archiving the lead. |
    | `finished` | Boolean | Whether the lead's attendance is finished. |
    | `last_history_type` | String | Type of the latest history entry of the lead. |
    | `last_history_at` | Datetime | When the latest history entry of the lead was recorded. |
    | `interested_properties` | String (JSON) | Properties of interest linked to the lead (JSON array). Best effort on Kenlo's side: missing when its property lookup fails. |
    | `last_interaction_at` | Datetime | When the last interaction with the lead happened. |
    | `created_at` | Datetime | When the lead was created. |
    | `updated_at` | Datetime | When the lead was last updated, used as the incremental replication key. |
    | `raw_payload` | String (JSON) | The whole record exactly as Kenlo returned it (JSON object), including fields that have no column of their own. |
  </Accordion>

  <Accordion title="Lead Proposals">
    Proposals of each lead, read again whenever the lead changes. Kenlo does not document the fields of this list, so the columns follow the proposal fields Kenlo accepts and everything else is in `raw_payload`.

    Table: `lead_proposals` · Primary key: `lead_id`, `proposal_id` · Sync: Incremental

    | Field | Type | Description |
    | :- | :- | :- |
    | `lead_id` | Integer | Identifier of the lead. |
    | `lead_updated_at` | Datetime | Last update of the lead when its proposals were read, used as the incremental replication key. |
    | `proposal_id` | String | Identifier of the proposal (a hash of the record when Kenlo sends no id). |
    | `attend_property_id` | Integer | Identifier of the lead-property link the proposal is for. |
    | `property_id` | Integer | Identifier of the property the proposal is for. |
    | `status` | String | Status of the proposal. |
    | `price` | Number | Value of the proposal, in BRL. |
    | `operation` | String | Operation of the proposal (0 = sale, 1 = rent, 2 = both). |
    | `payment_type` | String | Payment method of the proposal. |
    | `tenant_id` | Integer | Identifier of the tenant or buyer (a customer). |
    | `site_origin` | String | Where the proposal was made (CMS, INGAIASITES or APP). |
    | `notes` | String | Notes of the proposal. |
    | `expire_at` | Datetime | When the proposal expires. |
    | `created_at` | Datetime | When the proposal was created. |
    | `updated_at` | Datetime | When the proposal was last updated. |
    | `raw_payload` | String (JSON) | The whole record exactly as Kenlo returned it (JSON object), including fields that have no column of their own. |
  </Accordion>

  <Accordion title="Lead History">
    History entries of each lead (stage changes, contacts, comments), read again whenever the lead changes. Kenlo does not document the fields of this list, so the columns follow the documented entry types and everything else is in `raw_payload`.

    Table: `lead_history` · Primary key: `lead_id`, `history_id` · Sync: Incremental

    | Field | Type | Description |
    | :- | :- | :- |
    | `lead_id` | Integer | Identifier of the lead. |
    | `lead_updated_at` | Datetime | Last update of the lead when its history was read, used as the incremental replication key. |
    | `history_id` | String | Identifier of the history entry (a hash of the record when Kenlo sends no id). |
    | `type` | String | Type of the entry (e.g. ATTEND\_CREATED, STEP\_CHANGED, CONTACT\_WHATSAPP, COMMENT\_ADDED). |
    | `description` | String | Text of the entry. |
    | `user_id` | Integer | User who recorded the entry, when sent; see agents. |
    | `operation_id` | Integer | Operation the entry refers to (1 = rent, 2 = sale). |
    | `created_at` | Datetime | When the entry was recorded. |
    | `raw_payload` | String (JSON) | The whole record exactly as Kenlo returned it (JSON object), including fields that have no column of their own. |
  </Accordion>

  <Accordion title="Developments">
    Real estate developments (empreendimentos). Extracted in full on every sync.

    Table: `developments` · Primary key: `id` · Sync: Full table

    | Field | Type | Description |
    | :- | :- | :- |
    | `id` | Integer | Identifier of the development. |
    | `name` | String | Name of the development. |
    | `description` | String | Description of the development. |
    | `full_address` | String | Full address in a single line (RESO unparsedAddress). |
    | `street_name` | String | Street name. |
    | `street_number` | String | Street number. |
    | `unit_number` | String | Unit or complement (apartment, suite). |
    | `neighborhood` | String | Neighborhood. |
    | `city` | String | City. |
    | `state` | String | State abbreviation (e.g. SP). |
    | `postal_code` | String | Postal code (CEP). |
    | `country` | String | Country code (e.g. BR). |
    | `latitude` | Number | Latitude of the address. |
    | `longitude` | Number | Longitude of the address. |
    | `status_id` | Integer | Status of the development. |
    | `phase_id` | Integer | Construction phase of the development. |
    | `facade_id` | Integer | Facade type of the development. |
    | `property_standard_id` | Integer | Construction standard of the development. |
    | `partner_id` | Integer | Partner (developer or builder) of the development. |
    | `created_at` | Datetime | When the development was registered. |
    | `updated_at` | Datetime | When the development was last updated. |
    | `raw_payload` | String (JSON) | The whole record exactly as Kenlo returned it (JSON object), including fields that have no column of their own. |
  </Accordion>

  <Accordion title="Development Towers">
    Towers of each development.

    Table: `development_towers` · Primary key: `id` · Sync: Full table

    | Field | Type | Description |
    | :- | :- | :- |
    | `id` | Integer | Identifier of the tower. |
    | `development_id` | Integer | Identifier of the development the tower belongs to. |
    | `name` | String | Name of the tower. |
    | `floors_count` | Integer | Number of floors. |
    | `units_per_floor` | Integer | Number of units per floor. |
    | `raw_payload` | String (JSON) | The whole record exactly as Kenlo returned it (JSON object), including fields that have no column of their own. |
  </Accordion>

  <Accordion title="Development Units">
    Units of each tower.

    Table: `development_units` · Primary key: `development_id`, `tower_id`, `id` · Sync: Full table

    | Field | Type | Description |
    | :- | :- | :- |
    | `id` | String | Identifier of the unit. |
    | `development_id` | Integer | Identifier of the development. |
    | `tower_id` | Integer | Identifier of the tower. |
    | `unit_type_id` | Integer | Unit type; see development\_unit\_types. |
    | `numbering` | String | Number of the unit (e.g. 1201). |
    | `floor` | Integer | Floor of the unit. |
    | `private_area` | Number | Private (usable) area, in square meters. |
    | `total_area` | Number | Total area, in square meters. |
    | `bedrooms` | Integer | Number of bedrooms. |
    | `suites` | Integer | Number of suites. |
    | `bathrooms` | Integer | Number of bathrooms. |
    | `parking_spots` | Integer | Number of parking spots. |
    | `sale_price` | Number | Sale price of the unit, in BRL. |
    | `rental_price` | Number | Monthly rent of the unit, in BRL. |
    | `is_sale` | Boolean | Whether the unit is for sale. |
    | `is_rental` | Boolean | Whether the unit is for rent. |
    | `raw_payload` | String (JSON) | The whole record exactly as Kenlo returned it (JSON object), including fields that have no column of their own. |
  </Accordion>

  <Accordion title="Development Details">
    Technical attributes of each development (parking, leisure, security and so on). Each value is either a boolean or a number, depending on `variable_type`.

    Table: `development_details` · Primary key: `development_id`, `detail_id` · Sync: Full table

    | Field | Type | Description |
    | :- | :- | :- |
    | `development_id` | Integer | Identifier of the development. |
    | `detail_id` | Integer | Identifier of the attribute. |
    | `name` | String | Name of the attribute. |
    | `variable_type` | String | Type of the value: Boolean, Decimal or Int32. |
    | `value` | String | Value of the attribute, as text. |
    | `value_boolean` | Boolean | Value of a Boolean attribute (empty for the other types). |
    | `value_number` | Number | Value of a Decimal or Int32 attribute (empty for Boolean ones). |
    | `raw_payload` | String (JSON) | The whole record exactly as Kenlo returned it (JSON object), including fields that have no column of their own. |
  </Accordion>

  <Accordion title="Development Combos">
    Combos (predefined sets of units) of each development.

    Table: `development_combos` · Primary key: `development_id`, `id`, `combo_item_id` · Sync: Full table

    | Field | Type | Description |
    | :- | :- | :- |
    | `development_id` | Integer | Identifier of the development. |
    | `id` | String | Identifier of the combo. |
    | `combo_item_id` | Integer | Identifier of the combo item, when Kenlo lists combos item by item. |
    | `name` | String | Name of the combo. |
    | `units_count` | Integer | Number of units in the combo. |
    | `raw_payload` | String (JSON) | The whole record exactly as Kenlo returned it (JSON object), including fields that have no column of their own. |
  </Accordion>

  <Accordion title="Development Sales Systems">
    Sales systems available for developments.

    Table: `development_sales_systems` · Primary key: `id` · Sync: Full table

    | Field | Type | Description |
    | :- | :- | :- |
    | `id` | String | Identifier of the sales system. |
    | `name` | String | Name of the sales system. |
    | `raw_payload` | String (JSON) | The whole record exactly as Kenlo returned it (JSON object), including fields that have no column of their own. |
  </Accordion>

  <Accordion title="Development Unit Types">
    Unit types available for development units.

    Table: `development_unit_types` · Primary key: `id` · Sync: Full table

    | Field | Type | Description |
    | :- | :- | :- |
    | `id` | Integer | Identifier of the unit type. |
    | `unit_type` | String | Name of the unit type. |
    | `is_vertical` | Boolean | Whether the type is vertical (in a building). |
    | `raw_payload` | String (JSON) | The whole record exactly as Kenlo returned it (JSON object), including fields that have no column of their own. |
  </Accordion>
</AccordionGroup>
