> ## 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.

# Hub ConsultIA as a data source

> Bring CRM deals, contacts, companies and tasks, service conversations and messages, and Dashboard reports (attendances, satisfaction surveys, commercial results) from Hub ConsultIA to Nekt.

Hub ConsultIA is ConsultIA's platform that combines a CRM with omnichannel customer service (WhatsApp, e-mail and chat), AI agents and dashboards. This connector reads your Hub ConsultIA account through its public API and brings your pipelines and deals, contacts, companies and tasks, the CRM catalogs (loss reasons, deal origins, task categories, custom fields and tags), your service conversations with their messages and history, and the numbers of the Dashboard: attendances, satisfaction surveys (CSAT) and commercial results.

> [!NOTE]
>
> The connector only reads data. It never creates, changes or deletes anything in Hub ConsultIA.

## Configuring Hub ConsultIA 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 Hub ConsultIA option from the list of connectors.

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

### 1. Add account access

The connector signs in with a Hub ConsultIA **API key**. In Hub ConsultIA, open **Integrações** in the side menu, go to the **Chaves de API** tab and click **Nova chave**. Name the key (for example, "Nekt") and give it **Leitura** (read) access to every module you want to sync: **CRM**, **Catálogo**, **Conversas**, **Conexões**, **Manuais** and **Relatórios**. Copy the key when it is shown.

> [!WARNING]
>
> Hub ConsultIA allows 100 requests per minute per API key. Create a key used only by Nekt, so that other integrations don't slow down your syncs (or the other way around).

The following configurations are available:

* **API Key**: The Hub ConsultIA API key.
* **Start Date**: Earliest date read by the incremental streams (conversation messages, history and linked cards, attendances, survey answers and the daily reports) on the first sync and on full syncs. CRM lists and the conversation list are always read in full.
* **Account Time Zone** (advanced, optional): The time zone of your Hub ConsultIA account (for example, America/Sao\_Paulo or America/Manaus), used to cut report days. Leave it empty and the connector reads it from Hub ConsultIA; if it cannot, it uses America/Sao\_Paulo and says so in the sync log.
* **Deal Details Full Read Interval (days)** (advanced): Only used by the Deal Details stream. Between full reads it reads only the deals updated since the last sync; every this many days it reads every deal again, to catch contacts or tasks linked to a deal without changing it. 0 reads every deal on every sync. Default: 7.

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.

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**: you can choose between INCREMENTAL and FULL\_TABLE.
  * Incremental: every time the extraction happens, we'll get only the new data, which is good if, for example, you want to keep every record ever fetched.
  * Full table: every time the extraction happens, we'll get the current state of the data, which is good if, for example, you don't want to have deleted data in your catalog.

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/runs/scheduling-and-triggers.md), 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).
* Determine when to execute an **Additional [Full Sync](https://docs.nekt.com/get-started/core-concepts/types-of-sync#additional-full-sync)**. This will complement the incremental data extractions, ensuring that your data is completely synchronized with your source every once in a while.

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.

> [!NOTE]
>
> Because of the limit of 100 requests per minute, streams that read one record at a time take longer, so they are **not selected by default**: **Deal Tag Assignments** makes one request per deal and **Person Tags** one per contact on every sync (with 10,000 deals, about two hours), and **Deal Details** one per deal on the first sync and every 7 days (configurable), and in between only for deals updated since the last sync. Conversation history and linked cards are read only for conversations with recent activity or still open, so after the first sync they are fast. As a rough estimate based on the number of requests (not a measurement), an account with 10,000 deals, 50,000 contacts and 20,000 conversations needs about 2,350 requests a day for the default selection, around 30 minutes at the allowed pace plus the API's response time.

> [!WARNING]
>
> When Hub ConsultIA lists the messages of a conversation, it transcribes on the spot every audio message that does not have a transcription yet, and **this uses your Hub ConsultIA credits**. The first sync of **Conversation Messages** can trigger many transcriptions. That is why this stream is not selected by default: select it only if you want the messages, preferably with a recent **Start Date**.

## Fields by stream

### CRM

> [accordion] Pipelines
>
> Sales and task pipelines (funnels) of the account, with their stages as listed with them.
>
> Table: `pipelines` · Primary key: `id` · Sync: Full table
>
> | Field | Type | Description |
> | :- | :- | :- |
> | `id` | String | Unique identifier of the record. |
> | `name` | String | Display name. |
> | `color` | String | Color shown in Hub ConsultIA (hex). |
> | `type` | String | Pipeline type: commercial (deals), task\_management or support (tasks). |
> | `position` | Integer | Display order. |
> | `stages` | String (JSON) | Stages (columns) of the pipeline as listed with it. |
> | `extra_fields` | String (JSON) | Fields the API returned that this connector does not map to a column yet, keyed by their original names. |

> [accordion] Pipeline Stages
>
> Stages (columns) of every pipeline, with the status a deal gets when it enters each one.
>
> Table: `pipeline_stages` · Primary key: `id` · Sync: Full table
>
> | Field | Type | Description |
> | :- | :- | :- |
> | `id` | String | Unique identifier of the stage. |
> | `pipeline_id` | String | Pipeline the stage belongs to. |
> | `name` | String | Display name. |
> | `color` | String | Color shown in Hub ConsultIA (hex). |
> | `position` | Integer | Order of the stage in the pipeline. |
> | `default_deal_status` | String | Status a deal gets when it enters this stage (OPEN, WON, LOST...). |
> | `required_fields` | String (JSON) | Fields required before a card can enter this stage. |
> | `extra_fields` | String (JSON) | Fields the API returned that this connector does not map to a column yet, keyed by their original names. |

> [accordion] Pipeline Task Categories
>
> Task categories enabled on each task pipeline (kanban).
>
> Table: `pipeline_task_categories` · Primary key: `pipeline_id`, `id` · Sync: Full table
>
> | Field | Type | Description |
> | :- | :- | :- |
> | `pipeline_id` | String | Pipeline (task kanban) the category is enabled on. |
> | `id` | String | Task category identifier. |
> | `name` | String | Display name. |
> | `color` | String | Color shown in Hub ConsultIA (hex). |
> | `parent_id` | String | Parent category, for subcategories. |
> | `extra_fields` | String (JSON) | Fields the API returned that this connector does not map to a column yet, keyed by their original names. |

> [accordion] Deals
>
> Deals (negócios) with their value, status, pipeline, stage, company, owner and supervisor.
>
> Table: `deals` · Primary key: `id` · Sync: Full table
>
> | Field | Type | Description |
> | :- | :- | :- |
> | `id` | String | Unique identifier of the deal. |
> | `name` | String | Name of the deal. |
> | `description` | String | Description of the deal. |
> | `status` | String | Deal status: OPEN, WON, LOST, FINISHED or ARCHIVED. |
> | `amount` | Number | Deal value. |
> | `currency` | String | Currency of the amount (e.g. BRL). |
> | `probability` | Number | Probability of closing the deal. |
> | `pipeline_id` | String | Pipeline the deal is in. |
> | `pipeline_name` | String | Name of the pipeline. |
> | `stage_id` | String | Stage (column) the deal is in. |
> | `stage_name` | String | Name of the stage. |
> | `stage_color` | String | Color of the stage. |
> | `company_id` | String | Company linked to the deal. |
> | `company_name` | String | Name of the company. |
> | `owner_id` | String | User responsible for the deal. |
> | `owner_name` | String | Name of the user responsible for the deal. |
> | `supervisor_id` | String | Supervisor of the deal. |
> | `supervisor_name` | String | Name of the supervisor. |
> | `lost_reason_id` | String | Reason the deal was lost (see lost\_reasons). |
> | `lost_reason_text` | String | Free-text reason the deal was lost. |
> | `source_id` | String | Origin of the deal (see deal\_sources). |
> | `source_text` | String | Free-text origin of the deal. |
> | `source_deal_id` | String | Deal this one originated from. |
> | `close_date` | Datetime | Expected or actual close date of the deal. |
> | `close_time` | String | Close time of the deal (HH:MM). |
> | `closed_at` | Datetime | When the deal was actually closed (won or lost). |
> | `custom_fields` | String (JSON) | Custom field values keyed by slug (see custom\_fields). |
> | `pipeline` | String (JSON) | Pipeline object as returned by the API. |
> | `stage` | String (JSON) | Stage object as returned by the API. |
> | `company` | String (JSON) | Company object as returned by the API. |
> | `created_at` | Datetime | When the record was created. |
> | `updated_at` | Datetime | When the record was last updated. |
> | `extra_fields` | String (JSON) | Fields the API returned that this connector does not map to a column yet, keyed by their original names. |

> [accordion] Deal Details
>
> Every deal read one by one, with its linked people, tasks, products and the history of its moves between stages. After the first sync, only deals updated since the last sync are read again. Not selected by default.
>
> Table: `deal_details` · Primary key: `id` · Sync: Incremental · Replication key: `updated_at`
>
> | Field | Type | Description |
> | :- | :- | :- |
> | `id` | String | Unique identifier of the deal. |
> | `name` | String | Name of the deal. |
> | `description` | String | Description of the deal. |
> | `status` | String | Deal status: OPEN, WON, LOST, FINISHED or ARCHIVED. |
> | `amount` | Number | Deal value. |
> | `currency` | String | Currency of the amount (e.g. BRL). |
> | `probability` | Number | Probability of closing the deal. |
> | `pipeline_id` | String | Pipeline the deal is in. |
> | `pipeline_name` | String | Name of the pipeline. |
> | `stage_id` | String | Stage (column) the deal is in. |
> | `stage_name` | String | Name of the stage. |
> | `stage_color` | String | Color of the stage. |
> | `company_id` | String | Company linked to the deal. |
> | `company_name` | String | Name of the company. |
> | `owner_id` | String | User responsible for the deal. |
> | `owner_name` | String | Name of the user responsible for the deal. |
> | `supervisor_id` | String | Supervisor of the deal. |
> | `supervisor_name` | String | Name of the supervisor. |
> | `lost_reason_id` | String | Reason the deal was lost (see lost\_reasons). |
> | `lost_reason_text` | String | Free-text reason the deal was lost. |
> | `source_id` | String | Origin of the deal (see deal\_sources). |
> | `source_text` | String | Free-text origin of the deal. |
> | `source_deal_id` | String | Deal this one originated from. |
> | `close_date` | Datetime | Expected or actual close date of the deal. |
> | `close_time` | String | Close time of the deal (HH:MM). |
> | `closed_at` | Datetime | When the deal was actually closed (won or lost). |
> | `custom_fields` | String (JSON) | Custom field values keyed by slug (see custom\_fields). |
> | `pipeline` | String (JSON) | Pipeline object as returned by the API. |
> | `stage` | String (JSON) | Stage object as returned by the API. |
> | `company` | String (JSON) | Company object as returned by the API. |
> | `created_at` | Datetime | When the record was created. |
> | `updated_at` | Datetime | When the record was last updated. |
> | `persons` | String (JSON) | People (contacts) linked to the deal. |
> | `tasks` | String (JSON) | Tasks linked to the deal. |
> | `stage_history` | String (JSON) | Movements of the deal between stages (stage, entered\_at, exited\_at). |
> | `products` | String (JSON) | Products of the deal (unit price, quantity, discount, total, billing type), when returned. |
> | `extra_fields` | String (JSON) | Fields the API returned that this connector does not map to a column yet, keyed by their original names. |

> [accordion] Deal Tag Assignments
>
> Which tags are on which deal. One request per deal on every sync. Not selected by default.
>
> Table: `deal_tag_assignments` · Primary key: `deal_id`, `tag_id` · Sync: Full table
>
> | Field | Type | Description |
> | :- | :- | :- |
> | `deal_id` | String | Deal the tag is on. |
> | `tag_id` | String | Tag identifier (see deal\_tags). |
> | `tag_name` | String | Name of the tag. |
> | `tag_color` | String | Color of the tag. |
> | `extra_fields` | String (JSON) | Fields the API returned that this connector does not map to a column yet, keyed by their original names. |

> [accordion] Deal Tags
>
> Catalog of deal tags.
>
> Table: `deal_tags` · Primary key: `id` · Sync: Full table
>
> | Field | Type | Description |
> | :- | :- | :- |
> | `id` | String | Unique identifier of the record. |
> | `name` | String | Display name. |
> | `color` | String | Color shown in Hub ConsultIA (hex). |
> | `extra_fields` | String (JSON) | Fields the API returned that this connector does not map to a column yet, keyed by their original names. |

> [accordion] Persons
>
> Contacts with phones, e-mails, CPF and company.
>
> Table: `persons` · Primary key: `id` · Sync: Full table
>
> | Field | Type | Description |
> | :- | :- | :- |
> | `id` | String | Unique identifier of the contact. |
> | `first_name` | String | First name. |
> | `last_name` | String | Last name. |
> | `phones` | String (JSON) | Phone numbers (E.164) with the primary flag. |
> | `emails` | String (JSON) | E-mail addresses. |
> | `cpf` | String | CPF (digits only). |
> | `job_title` | String | Job title. |
> | `city` | String | City. |
> | `birth_date` | String | Birth date. |
> | `avatar_url` | String | URL of the contact's picture. |
> | `linkedin_url` | String | LinkedIn profile URL. |
> | `x_url` | String | X (Twitter) profile URL. |
> | `origin` | String | Origin of the contact. |
> | `company_id` | String | Company the contact belongs to. |
> | `company_name` | String | Trade name of the company. |
> | `company_legal_name` | String | Legal name of the company. |
> | `company_cnpj` | String | CNPJ of the company (digits only). |
> | `company` | String (JSON) | Company object as returned by the API. |
> | `owner_id` | String | User responsible for the contact. |
> | `created_by_id` | String | User who created the contact (null when created by the API). |
> | `blocked` | Boolean | Whether the contact is blocked. |
> | `blocked_reason` | String | Why the contact is blocked. |
> | `custom_fields` | String (JSON) | Custom field values keyed by slug (see custom\_fields). |
> | `created_at` | Datetime | When the record was created. |
> | `updated_at` | Datetime | When the record was last updated. |
> | `extra_fields` | String (JSON) | Fields the API returned that this connector does not map to a column yet, keyed by their original names. |

> [accordion] Person Tags
>
> Which tags are on which contact. One request per contact on every sync. Not selected by default.
>
> Table: `person_tags` · Primary key: `person_id`, `tag_id` · Sync: Full table
>
> | Field | Type | Description |
> | :- | :- | :- |
> | `person_id` | String | Contact the tag is on. |
> | `tag_id` | String | Tag identifier. |
> | `tag_name` | String | Name of the tag. |
> | `tag_color` | String | Color of the tag. |
> | `extra_fields` | String (JSON) | Fields the API returned that this connector does not map to a column yet, keyed by their original names. |

> [accordion] Companies
>
> Companies with legal name, CNPJ, domain and ICP flag.
>
> Table: `companies` · Primary key: `id` · Sync: Full table
>
> | Field | Type | Description |
> | :- | :- | :- |
> | `id` | String | Unique identifier of the company. |
> | `name` | String | Trade name. |
> | `legal_name` | String | Legal name (razão social). |
> | `cnpj` | String | CNPJ (digits only). |
> | `domain_name` | String | Website domain. |
> | `employees` | Integer | Number of employees. |
> | `annual_revenue` | Number | Annual revenue. |
> | `ideal_customer_profile` | Boolean | Whether the company matches the ideal customer profile (ICP). |
> | `account_owner_id` | String | User responsible for the company. |
> | `created_by_id` | String | User who created the company (null when created by the API). |
> | `blocked` | Boolean | Whether the company is blocked. |
> | `blocked_reason` | String | Why the company is blocked. |
> | `address` | String (JSON) | Address of the company. |
> | `linkedin_url` | String | LinkedIn page URL. |
> | `x_url` | String | X (Twitter) profile URL. |
> | `persons_count` | Integer | Number of contacts of the company (when returned). |
> | `persons` | String (JSON) | Contacts of the company (when returned). |
> | `custom_fields` | String (JSON) | Custom field values keyed by slug (see custom\_fields). |
> | `created_at` | Datetime | When the record was created. |
> | `updated_at` | Datetime | When the record was last updated. |
> | `extra_fields` | String (JSON) | Fields the API returned that this connector does not map to a column yet, keyed by their original names. |

> [accordion] Tasks
>
> Tasks with status, priority, due date and what they are linked to.
>
> Table: `tasks` · Primary key: `id` · Sync: Full table
>
> | Field | Type | Description |
> | :- | :- | :- |
> | `id` | String | Unique identifier of the task. |
> | `title` | String | Title of the task. |
> | `description` | String | Description of the task. |
> | `status` | String | Task status: TODO, IN\_PROGRESS or DONE. |
> | `priority` | String | Priority: LOW, MEDIUM, HIGH or URGENT. |
> | `due_date` | Datetime | Due date. |
> | `pipeline_id` | String | Task pipeline (kanban) the task is in. |
> | `stage_id` | String | Stage of the task in its pipeline. |
> | `category_id` | String | Task category (see task\_categories). |
> | `type_id` | String | Task type. |
> | `assignee_id` | String | User responsible for the task. |
> | `supervisor_id` | String | Supervisor of the task. |
> | `parent_task_id` | String | Parent task, for subtasks. |
> | `person_id` | String | Contact linked to the task. |
> | `company_id` | String | Company linked to the task. |
> | `deal_id` | String | Deal linked to the task. |
> | `conversation_id` | String | Conversation linked to the task. |
> | `created_by_id` | String | User who created the task (null when created by the API). |
> | `custom_fields` | String (JSON) | Custom field values keyed by slug (see custom\_fields). |
> | `created_at` | Datetime | When the record was created. |
> | `updated_at` | Datetime | When the record was last updated. |
> | `extra_fields` | String (JSON) | Fields the API returned that this connector does not map to a column yet, keyed by their original names. |

> [accordion] Lost Reasons
>
> Reasons a deal can be lost.
>
> Table: `lost_reasons` · Primary key: `id` · Sync: Full table
>
> | Field | Type | Description |
> | :- | :- | :- |
> | `id` | String | Unique identifier of the record. |
> | `name` | String | Display name. |
> | `color` | String | Color shown in Hub ConsultIA (hex). |
> | `position` | Integer | Display order. |
> | `is_active` | Boolean | Whether the record is active (inactive ones were soft-deleted). |
> | `extra_fields` | String (JSON) | Fields the API returned that this connector does not map to a column yet, keyed by their original names. |

> [accordion] Deal Sources
>
> Origins of deals.
>
> Table: `deal_sources` · Primary key: `id` · Sync: Full table
>
> | Field | Type | Description |
> | :- | :- | :- |
> | `id` | String | Unique identifier of the record. |
> | `name` | String | Display name. |
> | `color` | String | Color shown in Hub ConsultIA (hex). |
> | `position` | Integer | Display order. |
> | `is_active` | Boolean | Whether the record is active (inactive ones were soft-deleted). |
> | `extra_fields` | String (JSON) | Fields the API returned that this connector does not map to a column yet, keyed by their original names. |

> [accordion] Task Categories
>
> Tree of task categories.
>
> Table: `task_categories` · Primary key: `id` · Sync: Full table
>
> | Field | Type | Description |
> | :- | :- | :- |
> | `id` | String | Unique identifier of the record. |
> | `name` | String | Display name. |
> | `description` | String | Description of the category. |
> | `color` | String | Color shown in Hub ConsultIA (hex). |
> | `position` | Integer | Display order. |
> | `parent_id` | String | Parent category (null for a root category). |
> | `extra_fields` | String (JSON) | Fields the API returned that this connector does not map to a column yet, keyed by their original names. |

> [accordion] Custom Fields
>
> Definitions of the custom fields of deals, contacts, companies and tasks. Their values are in the custom\_fields column of each entity, keyed by slug.
>
> Table: `custom_fields` · Primary key: `id` · Sync: Full table
>
> | Field | Type | Description |
> | :- | :- | :- |
> | `id` | String | Unique identifier of the record. |
> | `entity_type` | String | Entity the field belongs to: DEAL, PERSON, COMPANY or TASK. |
> | `name` | String | Display name. |
> | `slug` | String | Key of the field inside the custom\_fields column of its entity. |
> | `field_type` | String | Field type (text, number, select, multi\_select, date...). |
> | `is_required` | Boolean | Whether the field is required. |
> | `display_order` | Integer | Display order. |
> | `options` | String (JSON) | Options of select and multi\_select fields. |
> | `is_active` | Boolean | Whether the record is active (inactive ones were soft-deleted). |
> | `extra_fields` | String (JSON) | Fields the API returned that this connector does not map to a column yet, keyed by their original names. |

### Conversations

> [accordion] Conversations
>
> Service conversations (WhatsApp, e-mail, chat) with status, priority, responsible user, department and current attendance.
>
> Table: `conversations` · Primary key: `id` · Sync: Full table
>
> | Field | Type | Description |
> | :- | :- | :- |
> | `id` | String | Unique identifier of the conversation. |
> | `code` | String | Short code of the conversation shown in Hub ConsultIA. |
> | `status` | String | Status of the conversation: open, finished or awaiting\_csat. |
> | `priority` | String | Priority: urgent, high, medium or low. |
> | `assigned_user_id` | String | User responsible for the conversation. |
> | `department_id` | String | Department the conversation is in. |
> | `person_id` | String | CRM contact of the conversation. |
> | `contact_id` | String | Channel contact of the conversation. |
> | `pipeline_id` | String | Ticket pipeline of the conversation. |
> | `stage_id` | String | Ticket stage of the conversation. |
> | `is_flagged` | Boolean | Whether the conversation is flagged. |
> | `is_group` | Boolean | Whether the conversation is a group chat. |
> | `last_message_at` | Datetime | When the last message was sent or received. |
> | `attendance_sequence` | Integer | Number of the current (or last) attendance inside the conversation; grows on each reopening. |
> | `attendance_number` | String | Attendance number shown in Hub ConsultIA: conversation code, a dash and the sequence. |
> | `conversation_code` | Integer | Numeric code of the conversation. |
> | `attendance_protocol` | String | Protocol of the current (or last) attendance. |
> | `current_attendance` | String (JSON) | Current (or last) attendance of the conversation. |
> | `extra_fields` | String (JSON) | Fields the API returned that this connector does not map to a column yet, keyed by their original names. |

> [accordion] Conversation Messages
>
> Messages of each conversation, including internal notes and audio transcriptions. Not selected by default (see the warning about transcription credits).
>
> Table: `conversation_messages` · Primary key: `id` · Sync: Incremental · Replication key: `created_at`
>
> | Field | Type | Description |
> | :- | :- | :- |
> | `id` | String | Unique identifier of the message. |
> | `conversation_id` | String | Conversation the message belongs to. |
> | `sequence` | Integer | Order of the message inside the conversation. |
> | `direction` | String | inbound (from the contact) or outbound (from the account). |
> | `content_type` | String | Content type (text, audio, image, document...). |
> | `text` | String | Text of the message. |
> | `transcription` | String (JSON) | Transcription of audio messages: status (done, pending, failed) and text. |
> | `is_private` | Boolean | Whether the message is an internal note. |
> | `attendance_sequence` | Integer | Attendance (inside the conversation) the message belongs to. |
> | `attendance_number` | String | Attendance number: conversation code, a dash and the sequence. |
> | `attendance_protocol` | String | Protocol of the attendance. |
> | `attendance_estimated` | Boolean | True when the attendance was deduced from the time (message older than attendance numbering). |
> | `attendance` | String (JSON) | Attendance the message belongs to. |
> | `created_at` | Datetime | When the message was sent or received; used as the incremental replication key. |
> | `extra_fields` | String (JSON) | Fields the API returned that this connector does not map to a column yet, keyed by their original names. |

> [accordion] Conversation History
>
> Events of each conversation: assignments, transfers, stage and status changes, tags.
>
> Table: `conversation_history` · Primary key: `id` · Sync: Incremental · Replication key: `created_at`
>
> | Field | Type | Description |
> | :- | :- | :- |
> | `id` | String | Unique identifier of the event. |
> | `conversation_id` | String | Conversation the event belongs to. |
> | `event_type` | String | Kind of event (assignment, transfer, stage, status, tags...). |
> | `actor_type` | String | Who caused the event (user, automation, external...). |
> | `created_at` | Datetime | When the event happened; used as the incremental replication key. |
> | `extra_fields` | String (JSON) | Fields the API returned that this connector does not map to a column yet, keyed by their original names. |

> [accordion] Conversation Linked Cards
>
> Deals and tasks linked to each conversation. A card later unlinked keeps its row.
>
> Table: `conversation_linked_cards` · Primary key: `conversation_id`, `type`, `id` · Sync: Incremental · Replication key: `conversation_activity_at`
>
> | Field | Type | Description |
> | :- | :- | :- |
> | `conversation_id` | String | Conversation the card is linked to. |
> | `type` | String | Card type: deal or task. |
> | `id` | String | Identifier of the deal or task. |
> | `name` | String | Name of the deal or title of the task. |
> | `pipeline_id` | String | Pipeline of the card. |
> | `pipeline_name` | String | Name of the pipeline. |
> | `stage_id` | String | Stage of the card. |
> | `stage_name` | String | Name of the stage. |
> | `conversation_activity_at` | Datetime | Latest activity of the conversation when the links were read; used as the incremental replication key. |
> | `extra_fields` | String (JSON) | Fields the API returned that this connector does not map to a column yet, keyed by their original names. |

> [accordion] Connections
>
> Active channels (connections) of the account. Never includes credentials or phone numbers.
>
> Table: `connections` · Primary key: `id` · Sync: Full table
>
> | Field | Type | Description |
> | :- | :- | :- |
> | `id` | String | Unique identifier of the channel (connection). |
> | `name` | String | Name of the channel. |
> | `provider` | String | Provider of the channel (wasender, whatsapp\_cloud, webhook...). |
> | `channel_type` | String | Channel type (whatsapp...). |
> | `status` | String | Connection status (connected...). |
> | `extra_fields` | String (JSON) | Fields the API returned that this connector does not map to a column yet, keyed by their original names. |

> [accordion] Manuals
>
> Published manuals indexed in the AI memory, with their indexing status.
>
> Table: `manuals` · Primary key: `manual_id` · Sync: Full table
>
> | Field | Type | Description |
> | :- | :- | :- |
> | `manual_id` | String | Unique identifier of the manual. |
> | `title` | String | Title of the manual. |
> | `status` | String | Publication status (only published manuals are listed). |
> | `chunk_count` | Integer | Number of indexed passages of the manual. |
> | `last_vectorized_at` | Datetime | When the manual was last indexed. |
> | `embedding_model` | String | Embedding model used to index the manual. |
> | `extra_fields` | String (JSON) | Fields the API returned that this connector does not map to a column yet, keyed by their original names. |

### Reports

> [accordion] Attendance Cycles
>
> Every attendance (each reopening of a conversation is a new attendance) with responsible user, department, inbox and its times, in business hours and elapsed. Attendances that finish later are updated whenever they finish.
>
> Table: `attendance_cycles` · Primary key: `id` · Sync: Incremental · Replication key: `started_at`
>
> | Field | Type | Description |
> | :- | :- | :- |
> | `id` | String | Unique identifier of the attendance. |
> | `conversation_id` | String | Conversation the attendance belongs to. |
> | `attendance_sequence` | Integer | Order of the attendance inside the conversation. |
> | `attendance_number` | String | Attendance number: conversation code, a dash and the sequence. |
> | `conversation_code` | Integer | Code of the conversation. |
> | `attendance_protocol` | String | Protocol of the attendance. |
> | `attendance` | String (JSON) | Attendance identification as returned by the API. |
> | `started_at` | Datetime | When the attendance started; used as the incremental replication key. |
> | `finished_at` | Datetime | When the attendance finished (null while in progress). |
> | `closure_reason` | String | How the attendance was closed (manual...). |
> | `assigned_user_id` | String | User responsible for the attendance. |
> | `assigned_user_name` | String | Name of the user responsible for the attendance. |
> | `department_id` | String | Department of the attendance. |
> | `department_name` | String | Name of the department. |
> | `inbox_id` | String | Inbox of the attendance. |
> | `inbox_name` | String | Name of the inbox. |
> | `business_frt_seconds` | Integer | First response time in seconds, counting only business hours. |
> | `business_tmpi_seconds` | Integer | Time to first interaction (TMPI) in seconds, business hours. |
> | `business_aht_seconds` | Integer | Handle time in seconds, business hours. |
> | `business_waiting_seconds` | Integer | Waiting time in seconds, business hours. |
> | `elapsed_frt_seconds` | Integer | First response time in seconds, elapsed (24x7). |
> | `elapsed_tmpi_seconds` | Integer | Time to first interaction (TMPI) in seconds, elapsed (24x7). |
> | `elapsed_aht_seconds` | Integer | Handle time in seconds, elapsed (24x7). |
> | `elapsed_waiting_seconds` | Integer | Waiting time in seconds, elapsed (24x7). |
> | `times` | String (JSON) | All times of the attendance as returned by the API. |
> | `transfers` | Integer | Number of transfers during the attendance. |
> | `metrics_formula_version` | Integer | Version of the formula used to compute the times. |
> | `extra_fields` | String (JSON) | Fields the API returned that this connector does not map to a column yet, keyed by their original names. |

> [accordion] Attendance Summary (daily)
>
> The Dashboard's attendance numbers, one row per day.
>
> Table: `attendance_summary_daily` · Primary key: `report_date` · Sync: Incremental · Replication key: `report_date`
>
> | Field | Type | Description |
> | :- | :- | :- |
> | `report_date` | Date | Day of the report (account time zone); used as the incremental replication key. |
> | `time_base` | String | Time base of the times: elapsed (24x7). |
> | `conversations_started` | Integer | Conversations started on the day. |
> | `new_conversations` | Integer | New conversations on the day. |
> | `attendances` | Integer | Attendances on the day (each reopening counts as a new attendance). |
> | `attendances_finished` | Integer | Attendances finished. |
> | `attendances_in_progress_assigned` | Integer | Attendances in progress with a responsible user. |
> | `attendances_in_progress_unassigned` | Integer | Attendances in progress without a responsible user. |
> | `started_by_customer` | Integer | Conversations started by the customer. |
> | `started_by_automation` | Integer | Conversations started by an automation. |
> | `started_by_internal` | Integer | Conversations started by a user of the account. |
> | `avg_first_response_seconds` | Number | Average first response time in seconds. |
> | `avg_tmpi_seconds` | Number | Average time to first interaction (TMPI) in seconds. |
> | `avg_handle_seconds` | Number | Average handle time (TMA) in seconds. |
> | `avg_full_handle_seconds` | Number | Average full handle time in seconds. |
> | `avg_waiting_seconds` | Number | Average waiting time in seconds. |
> | `avg_first_resolution_seconds` | Number | Average time to first resolution in seconds. |
> | `avg_transfers` | Number | Average number of transfers per attendance. |
> | `sample_sizes` | String (JSON) | Number of attendances behind each average. |
> | `legacy_formula_attendances` | Integer | Attendances measured with the legacy formula. |
> | `extra_fields` | String (JSON) | Fields the API returned that this connector does not map to a column yet, keyed by their original names. |

> [accordion] Attendance by Agent (daily)
>
> Attendance volume and times per agent, one row per agent per day. A row the report no longer has on a re-read is kept with removed = true and empty figures.
>
> Table: `attendance_by_agent_daily` · Primary key: `report_date`, `agent_key` · Sync: Incremental · Replication key: `report_date`
>
> | Field | Type | Description |
> | :- | :- | :- |
> | `report_date` | Date | Day of the report (account time zone); used as the incremental replication key. |
> | `removed` | Boolean | True when this row no longer appears in the report for this day (a re-read replaced it); its figures are then null. |
> | `agent_key` | String | Agent identifier, or 'none' for attendances without a responsible user. |
> | `agent_id` | String | User (agent) identifier. |
> | `agent_name` | String | Name of the agent. |
> | `time_base` | String | Time base of the times: elapsed (24x7). |
> | `attendances` | Integer | Attendances of the agent on the day. |
> | `attendances_finished` | Integer | Attendances the agent finished. |
> | `avg_first_response_seconds` | Number | Average first response time in seconds. |
> | `avg_tmpi_seconds` | Number | Average time to first interaction (TMPI) in seconds. |
> | `avg_handle_seconds` | Number | Average handle time (TMA) in seconds. |
> | `avg_waiting_seconds` | Number | Average waiting time in seconds. |
> | `avg_customer_reply_seconds` | Number | Average time the customer took to reply, in seconds. |
> | `avg_agent_reply_seconds` | Number | Average time the agent took to reply, in seconds. |
> | `legacy_formula_attendances` | Integer | Attendances measured with the legacy formula. |
> | `extra_fields` | String (JSON) | Fields the API returned that this connector does not map to a column yet, keyed by their original names. |

> [accordion] Attendance by Department (daily)
>
> Average times per department, one row per department per day. A row the report no longer has on a re-read is kept with removed = true and empty figures.
>
> Table: `attendance_by_department_daily` · Primary key: `report_date`, `department_key` · Sync: Incremental · Replication key: `report_date`
>
> | Field | Type | Description |
> | :- | :- | :- |
> | `report_date` | Date | Day of the report (account time zone); used as the incremental replication key. |
> | `removed` | Boolean | True when this row no longer appears in the report for this day (a re-read replaced it); its figures are then null. |
> | `department_key` | String | Department identifier, or 'none' for attendances without a department. |
> | `department_id` | String | Department identifier. |
> | `department_name` | String | Name of the department. |
> | `time_base` | String | Time base of the times: elapsed (24x7). |
> | `avg_first_response_seconds` | Number | Average first response time in seconds. |
> | `avg_tmpi_seconds` | Number | Average time to first interaction (TMPI) in seconds. |
> | `avg_handle_seconds` | Number | Average handle time (TMA) in seconds. |
> | `sample_size` | Integer | Number of attendances behind the averages. |
> | `extra_fields` | String (JSON) | Fields the API returned that this connector does not map to a column yet, keyed by their original names. |

> [accordion] Attendance Queue Snapshots
>
> The queue at the moment of each sync: open conversations with and without a responsible user. One row per sync; a full sync replaces the table and loses that history.
>
> Table: `attendance_queue_snapshots` · Primary key: `snapshot_at` · Sync: Incremental · Replication key: `snapshot_at`
>
> | Field | Type | Description |
> | :- | :- | :- |
> | `snapshot_at` | Datetime | When the queue was read (start of the sync); used as the incremental replication key. |
> | `open_now` | Integer | Conversations open at that moment. |
> | `open_assigned` | Integer | Open conversations with a responsible user. |
> | `open_unassigned` | Integer | Open conversations without a responsible user. |
> | `new_in_period` | Integer | Conversations that arrived today (account time zone). |
> | `extra_fields` | String (JSON) | Fields the API returned that this connector does not map to a column yet, keyed by their original names. |

> [accordion] CSAT Responses
>
> Satisfaction survey answers, one per row.
>
> Table: `csat_responses` · Primary key: `id` · Sync: Incremental · Replication key: `sent_at`
>
> | Field | Type | Description |
> | :- | :- | :- |
> | `id` | String | Unique identifier of the survey answer. |
> | `conversation_id` | String | Conversation of the rated attendance. |
> | `attendance_sequence` | Integer | Order of the rated attendance inside the conversation. |
> | `attendance_number` | String | Number of the rated attendance: conversation code, a dash and the sequence. |
> | `conversation_code` | Integer | Code of the conversation. |
> | `attendance_protocol` | String | Protocol of the rated attendance. |
> | `attendance` | String (JSON) | Rated attendance as returned by the API. |
> | `score` | Integer | Score given (after any correction). |
> | `original_score` | Integer | Score originally given, when it was corrected. |
> | `scale` | Integer | Maximum of the score scale. |
> | `score_category_id` | String | Reason chosen for the score. |
> | `score_category_name` | String | Name of the reason chosen for the score. |
> | `score_category_counts_in_average` | Boolean | Whether answers with this reason count in the average. |
> | `score_category` | String (JSON) | Reason chosen for the score as returned by the API. |
> | `comment` | String | Comment left with the score. |
> | `status` | String | Survey status (responded, pending...). |
> | `sent_at` | Datetime | When the survey was sent; used as the incremental replication key. |
> | `responded_at` | Datetime | When the survey was answered. |
> | `agent_id` | String | User who handled the rated attendance. |
> | `agent_name` | String | Name of the user who handled the rated attendance. |
> | `department_id` | String | Department of the rated attendance. |
> | `department_name` | String | Name of the department. |
> | `ai_handled` | Boolean | Whether the attendance was handled by AI. |
> | `disregarded` | Boolean | Whether the answer is disregarded (never counts in the metrics). |
> | `extra_fields` | String (JSON) | Fields the API returned that this connector does not map to a column yet, keyed by their original names. |

> [accordion] CSAT Summary (daily)
>
> Survey summary (sent, answered, average, satisfaction), one row per day.
>
> Table: `csat_summary_daily` · Primary key: `report_date` · Sync: Incremental · Replication key: `report_date`
>
> | Field | Type | Description |
> | :- | :- | :- |
> | `report_date` | Date | Day of the report (account time zone); used as the incremental replication key. |
> | `surveys_sent` | Integer | Surveys sent. |
> | `surveys_responded` | Integer | Surveys answered. |
> | `response_rate` | Number | Share of surveys answered (0 to 1). |
> | `average_score` | Number | Average score. |
> | `satisfaction_pct` | Number | Satisfaction percentage. |
> | `finished_attendances` | Integer | Attendances finished. |
> | `pending` | Integer | Surveys waiting for an answer. |
> | `no_response` | Integer | Surveys never answered. |
> | `low_scores` | Integer | Low scores. |
> | `excluded_from_average` | Integer | Answers whose reason is kept out of the average. |
> | `disregarded` | Integer | Answers disregarded. |
> | `extra_fields` | String (JSON) | Fields the API returned that this connector does not map to a column yet, keyed by their original names. |

> [accordion] CSAT by Agent (daily)
>
> Survey results per agent, one row per agent per day. A row the report no longer has on a re-read is kept with removed = true and empty figures.
>
> Table: `csat_by_agent_daily` · Primary key: `report_date`, `agent_key` · Sync: Incremental · Replication key: `report_date`
>
> | Field | Type | Description |
> | :- | :- | :- |
> | `report_date` | Date | Day of the report (account time zone); used as the incremental replication key. |
> | `removed` | Boolean | True when this row no longer appears in the report for this day (a re-read replaced it); its figures are then null. |
> | `agent_key` | String | Agent identifier, or 'none' for answers without an agent. |
> | `agent_id` | String | User (agent) identifier. |
> | `agent_name` | String | Name of the agent. |
> | `responded` | Integer | Surveys answered. |
> | `average_score` | Number | Average score. |
> | `score_counts` | String (JSON) | Number of answers per score. |
> | `extra_fields` | String (JSON) | Fields the API returned that this connector does not map to a column yet, keyed by their original names. |

> [accordion] CSAT by Department (daily)
>
> Survey results per department, one row per department per day. A row the report no longer has on a re-read is kept with removed = true and empty figures.
>
> Table: `csat_by_department_daily` · Primary key: `report_date`, `department_key` · Sync: Incremental · Replication key: `report_date`
>
> | Field | Type | Description |
> | :- | :- | :- |
> | `report_date` | Date | Day of the report (account time zone); used as the incremental replication key. |
> | `removed` | Boolean | True when this row no longer appears in the report for this day (a re-read replaced it); its figures are then null. |
> | `department_key` | String | Department identifier, or 'none' for answers without a department. |
> | `department_id` | String | Department identifier. |
> | `department_name` | String | Name of the department. |
> | `responded` | Integer | Surveys answered. |
> | `average_score` | Number | Average score. |
> | `score_counts` | String (JSON) | Number of answers per score. |
> | `extra_fields` | String (JSON) | Fields the API returned that this connector does not map to a column yet, keyed by their original names. |

> [accordion] Commercial Summary (daily)
>
> The Dashboard's commercial numbers (deals created, won, lost, values, funnel, sales per seller), one row per day.
>
> Table: `commercial_summary_daily` · Primary key: `report_date` · Sync: Incremental · Replication key: `report_date`
>
> | Field | Type | Description |
> | :- | :- | :- |
> | `report_date` | Date | Day of the report (account time zone); used as the incremental replication key. |
> | `created_count` | Integer | Deals created. |
> | `created_value` | Number | Value of the deals created (BRL). |
> | `won_count` | Integer | Deals won. |
> | `won_value` | Number | Value of the deals won (BRL). |
> | `lost_count` | Integer | Deals lost. |
> | `lost_value` | Number | Value of the deals lost (BRL). |
> | `open_count` | Integer | Deals open. |
> | `open_value` | Number | Value of the deals open (BRL). |
> | `conversion_rate` | Number | Conversion rate (0 to 1). |
> | `average_ticket` | Number | Average ticket (BRL). |
> | `average_ticket_per_client` | Number | Average ticket per client (BRL). |
> | `ticket_sales_count` | Integer | Sales counted in the average ticket. |
> | `ticket_client_count` | Integer | Clients counted in the average ticket per client. |
> | `previous_period` | String (JSON) | Same figures for the previous period. |
> | `pipeline_funnel` | String (JSON) | Funnel of each pipeline: deals per stage and conversion. |
> | `average_time_per_stage` | String (JSON) | Average hours per stage of each pipeline. |
> | `sales_by_owner` | String (JSON) | Sales per seller. |
> | `lost_by_reason` | String (JSON) | Losses per reason. |
> | `sales_by_day` | String (JSON) | Sales per day. |
> | `extra_fields` | String (JSON) | Fields the API returned that this connector does not map to a column yet, keyed by their original names. |

> [accordion] Commercial Origins (daily)
>
> Deals per origin, stage and status, one row per combination per day and commercial pipeline. When a deal moves, the combination it left is kept with removed = true and empty figures, so filter on removed = false.
>
> Table: `commercial_origins_daily` · Primary key: `report_date`, `pipeline_id`, `row_key` · Sync: Incremental · Replication key: `report_date`
>
> | Field | Type | Description |
> | :- | :- | :- |
> | `report_date` | Date | Day of the report (account time zone); used as the incremental replication key. |
> | `removed` | Boolean | True when this row no longer appears in the report for this day (a re-read replaced it); its figures are then null. |
> | `pipeline_id` | String | Commercial pipeline of the figures. |
> | `row_key` | String | Origin, stage and status of the row joined by '/' (unique per day and pipeline). |
> | `source_id` | String | Origin of the deals (see deal\_sources). |
> | `source_text` | String | Name of the origin. |
> | `stage_id` | String | Stage of the deals. |
> | `status` | String | Status of the deals (OPEN, WON, LOST...). |
> | `count` | Integer | Number of deals. |
> | `amount` | Number | Value of the deals (BRL). |
> | `extra_fields` | String (JSON) | Fields the API returned that this connector does not map to a column yet, keyed by their original names. |

## Implementation notes

* **Full table streams.** Hub ConsultIA's CRM lists have no "updated since" filter, so pipelines, deals, contacts, companies, tasks, the catalogs and the conversation list are read in full on every sync. If one that had records suddenly comes back empty, that stream fails instead of emptying your table, and its table keeps its data; run a full sync of the source if the data really was removed in Hub ConsultIA. If one comes back with far fewer records than the previous sync, the sync loads it and shows a warning.
* **Deal details.** After the first sync, only deals whose last update moved are read again, and every deal is read again every 7 days (see **Deal Details Full Read Interval**), so a contact or task linked to a deal without changing it shows up within a week. You don't need an **Additional Full Sync** for this; a full sync of the source also erases the **Attendance Queue Snapshots** history.
* **Conversations.** Messages, history and linked cards are read for conversations with activity since the last sync (re-reading the last 3 days), and for every conversation that is still open (with activity in the last 30 days) or was open at the previous sync, so the events of closing a conversation are not missed. Finished conversations count as closed; conversations awaiting the satisfaction survey still count as open. A deal or task unlinked from a conversation keeps its row in **Conversation Linked Cards**.
* **Daily reports.** Each daily report is asked for one day at a time, in your account's time zone (the connector reads it from Hub ConsultIA at the start of each sync, or uses **Account Time Zone** when set, and warns you if it changes between syncs), and every sync asks the last 7 days again because recent days still change. The summaries have one row per day; the reports by agent, by department and by origin have one row per day and agent, department or origin/stage/status. When a re-read day no longer has a row (an attendance reassigned to another agent, a deal that moved to another stage), that row is kept with **removed** set to true and empty figures, so filter on `removed = false`. Daily averages cannot be summed: to get the average of a longer period, weight each day by its sample size.
* **Report days older than 7 days are frozen.** Days before the 7-day re-read are never asked again, so records imported later with past dates do not change them. The commercial reports also group deals by the day they were created but show each deal's stage when the day was read, so an old day does not follow later moves. For the current state of your funnel, use the **Deals** table.
* **Attendances** are read twice for the re-read days: the ones that finished in those days, however long ago they started, and the ones that started in them, including those still in progress. An attendance therefore gets its end time on the sync after it finishes.
* **Survey answers** are read up to yesterday (today's answers come on the next sync) and from 7 days before the latest one already read. A survey answered more than 7 days after it was sent is only picked up by a full sync.
* **Attendance queue snapshots** keep one row per sync. A full sync replaces the table and loses the earlier snapshots.
* **Permissions.** Before reading anything, the connector checks that the API key can read every module of the streams you selected; if not, the sync stops with a message naming the missing permissions. A report your account or key cannot read (for example, when the CSAT module is not enabled) is skipped with a warning, and the other streams still load.
* **Deleted records.** Hub ConsultIA does not report deleted records. Full table streams drop them on the next sync; in incremental tables (messages, history, attendances, survey answers, deal details) a deleted record stays.
* **Fields.** Columns follow every field Hub ConsultIA documents for each record. Any other field the API returns is kept in the **extra\_fields** column of the table, as JSON with the original field names.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.