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

# Pylon as a data source

> Bring issues, messages, accounts, contacts, users, teams, tasks, projects, surveys, knowledge base articles and more from Pylon to Nekt.

Pylon is a B2B customer support platform: it brings conversations from Slack, Microsoft Teams, email, chat and other channels into issues, and adds accounts, SLAs, surveys, a knowledge base and customer projects around them. This connector reads your Pylon workspace through its public API and brings your issues and every message on them, your accounts and contacts, users and teams, tasks, projects and milestones, survey responses, knowledge base articles, the configuration around them (tags, statuses, custom fields, ticket forms, macros) and the audit log.

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

## Configuring Pylon 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 Pylon 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 Pylon **API token**. Only Admins can create one: in Pylon, go to **Settings > Integrations & dev > API tokens** and click **Create API Token**. Give it a name and either pick a **Role** that can read the data you want to sync, or select a user or bot for it to act as (it then uses that user's role). Leave the **IP allowlist** empty. Copy the token when it is shown, since Pylon shows it only once. See [Pylon's guide to API tokens](https://docs.usepylon.com/pylon-docs/developer/api/authentication).

> [!WARNING]
>
> Pylon deletes a token when the user who created it, or the user it acts as, is deactivated. Create the token from an account that will stay active, or with its own identity.

The following configurations are available:

* **API Token**: The Pylon API token.
* **Region**: Where your Pylon workspace is hosted, **US** or **EU**. Tokens that start with `pylon_api_eu_` belong to the EU region, and tokens that start with `pylon_api_` (without `eu`) belong to the US region.
* **Start Date**: Earliest update date read by the incremental streams (issues, issue messages, tasks, projects, milestones and audit logs) on the first sync and on full syncs. The other streams are always read in full.

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]
>
> Pylon limits how many requests your workspace can make per minute, shared by every integration that uses your Pylon tokens. Issue messages are read with one request per issue, so the first sync of a workspace with many issues can take several hours. A recent **Start Date** makes it shorter.

# Streams and Fields

## Available streams

The table below lists every stream, its **slug** (the exact identifier to pass when creating the source via API) and a short description.

| Stream | Slug | Sync | Description |
| - | - | - | - |
| Issues | `issues` | Incremental | Support issues (conversations and tickets) with their state, requester, assignee, team, tags, custom fields, SLA timings and CSAT. |
| Issue Messages | `issue_messages` | Incremental | Every message of each issue read in the sync: customer messages, replies and internal notes, oldest first. |
| Surveys | `surveys` | Full table | CSAT, NPS and custom surveys. |
| Survey Responses | `survey_responses` | Full table | Responses to every survey, with their answers. |
| Accounts | `accounts` | Full table | Customer accounts (companies), with domains, owner, tags, channels and custom fields. |
| Contacts | `contacts` | Full table | Contacts (people at your customer accounts). |
| Users | `users` | Full table | Users (agents) of your Pylon workspace, deactivated ones included. |
| Teams | `teams` | Full table | Teams, their members and how they assign issues. |
| User Roles | `user_roles` | Full table | Roles users can have. |
| Tasks | `tasks` | Incremental | Tasks of your projects and customer onboardings. |
| Projects | `projects` | Incremental | Projects, with status and progress. |
| Milestones | `milestones` | Incremental | Project milestones (milestones of projects not launched yet are not returned by Pylon). |
| Tags | `tags` | Full table | Tags for issues, accounts and articles. |
| Issue Statuses | `issue_statuses` | Full table | Issue statuses, built-in and custom. |
| Task Statuses | `task_statuses` | Full table | Task statuses, built-in and custom. |
| Custom Fields | `custom_fields` | Full table | Custom field definitions of accounts, issues, contacts, tasks, projects, meetings and opportunities. |
| Ticket Forms | `ticket_forms` | Full table | Ticket forms and their fields. |
| Macros | `macros` | Full table | Macros (saved replies, notes and actions). |
| Knowledge Bases | `knowledge_bases` | Full table | Knowledge bases (help centers). |
| Knowledge Base Articles | `knowledge_base_articles` | Full table | Articles of every knowledge base, in its default language, with draft and published content. |
| Audit Logs | `audit_logs` | Incremental | Audit log of actions taken in your workspace. |

> [!NOTE]
>
> Nested information (custom fields, SLA details, authors, channels, answers and similar) comes as JSON text. The IDs most used in joins are also copied into their own columns: `account_id`, `requester_id`, `assignee_id`, `team_id`, `owner_id`, `project_id` and `milestone_id`.

> [!NOTE]
>
> Pylon does not report deleted records. In incremental tables (issues, tasks, projects, milestones), a record deleted in Pylon stays in your table; full-table streams drop it on the next sync.

## Fields by stream

### Support

> [accordion] Issues
>
> Support issues (conversations and tickets) with their state, requester, assignee, team, tags, custom fields, SLA timings and CSAT. Synced incrementally by last update; an issue with new messages is read again too.
>
> Table: `issues` · Primary key: `id` · Sync: Incremental · Replication key: `updated_at`
>
> | Field | Type | Description |
> | :- | :- | :- |
> | `id` | String | The ID of the issue. |
> | `account_id` | String | ID of the account the issue belongs to (copied from account.id). |
> | `assignee_id` | String | ID of the user the issue is assigned to (copied from assignee.id). |
> | `requester_id` | String | ID of the contact who requested the issue (copied from requester.id). |
> | `team_id` | String | ID of the team the issue is assigned to (copied from team.id). |
> | `account` | String (JSON) | Account the issue belongs to. JSON object with: id, external\_ids. |
> | `active_time_by_user` | String (JSON) | Active time spent on the issue broken down per user, if any. JSON array of objects with: active\_time\_seconds, business\_hours\_active\_time\_seconds, user\_id. |
> | `active_time_seconds` | Integer | The total active time spent on the issue in seconds, if any. Equals the sum of the per-user active time. |
> | `assignee` | String (JSON) | User the issue is assigned to. JSON object with: id, email. |
> | `attachment_urls` | Array of strings | The attachment URLs attached to this issue, if any. Signed download URLs. Fetch with a plain GET, no Authorization header. |
> | `author_unverified` | Boolean | Whether any message on the issue has an unverified author identity. True if any message author's identity has NOT been verified (e.g., from public forms). |
> | `body_html` | String | The body of the issue in HTML format. |
> | `business_hours_active_time_seconds` | Integer | The total business-hours active time spent on the issue in seconds, if any. Equals the sum of the per-user business-hours active time. |
> | `business_hours_first_response_seconds` | Integer | The business hours time in seconds it took for the first response to the issue, if any. |
> | `business_hours_resolution_seconds` | Integer | The business hours time in seconds it took for the issue to be resolved, if any. |
> | `business_hours_time_in_status_seconds` | String (JSON) | A map of status slug to the business hours time in seconds the issue has spent in that status. Includes both base statuses (e.g. "new", "waiting\_on\_you") and custom statuses. JSON object. |
> | `chat_widget_info` | String (JSON) | Chat widget details, for issues started in the chat widget. JSON object with: page\_url. |
> | `child_issues` | String (JSON) | The child issues in this group, if this issue is an issue group. JSON array of objects with: id, number, title. |
> | `created_at` | Datetime | The time the issue was created. |
> | `csat_responses` | String (JSON) | The CSAT responses of the issue, if any. JSON array of objects with: comment, score. |
> | `custom_fields` | String (JSON) | Custom field values associated with the issue. JSON object. |
> | `customer_portal_visible` | Boolean | Whether the issue is visible in the customer portal. |
> | `external_incidents` | String (JSON) | Incidents from incident.io or Rootly linked to this issue. JSON array of objects with: external\_id, link, reference, source. |
> | `external_issues` | String (JSON) | The external issues associated with the issue, if any. JSON array of objects with: external\_id, key, link, source, state. |
> | `first_resolution_time` | Datetime | The time of the first resolution of the issue, if any. Frozen at the issue's first resolution and never updated on reopen/re-resolve. |
> | `first_response_assignee_id_at_breach` | String | The ID of the user the issue was assigned to when its first response SLA breached, if it breached. |
> | `first_response_breach_time` | Datetime | The time by which the issue's first response SLA will breach, if any. Only present for issues with an active first response SLA. |
> | `first_response_resolving_user_id` | String | The ID of the user whose action resolved the issue's first response SLA. Absent when resolved by a contact or automation. |
> | `first_response_seconds` | Integer | The time in seconds it took for the first response to the issue, if any. |
> | `first_response_time` | Datetime | The time of the first response to the issue, if any. |
> | `follow_up` | String (JSON) | Follow-up SLA of the issue. JSON object with: time, seconds, business\_hours\_seconds, breach\_time, assignee\_id\_at\_breach, resolving\_user\_id. |
> | `is_issue_group` | Boolean | Whether this issue is an issue group. |
> | `latest_message_time` | Datetime | The time of the latest message in the issue, if any. |
> | `link` | String | The link to the issue in Pylon. |
> | `next_reply` | String (JSON) | Next-reply SLA of the issue. JSON object with: time, seconds, business\_hours\_seconds, breach\_time, assignee\_id\_at\_breach, resolving\_user\_id. |
> | `number` | Integer | The number of the issue. |
> | `number_of_touches` | Integer | The number of times the issue has been touched. |
> | `parent_issue_group` | String (JSON) | Issue group this issue belongs to, if any. JSON object with: id, number, title. |
> | `requester` | String (JSON) | Contact who requested the issue. JSON object with: id, email. |
> | `resolution_assignee_id_at_breach` | String | The ID of the user the issue was assigned to when its resolution SLA breached, if it breached. |
> | `resolution_breach_time` | Datetime | The time by which the issue's resolution SLA will breach, if any. Only present for open issues with an active resolution SLA. |
> | `resolution_resolving_user_id` | String | The ID of the user whose action resolved the issue's resolution SLA. Absent when resolved by a contact or automation. |
> | `resolution_seconds` | Integer | The time in seconds it took for the issue to be resolved, if any. |
> | `resolution_time` | Datetime | The time of the resolution of the issue, if any. |
> | `slack` | String (JSON) | Slack origin of the issue. JSON object with: channel\_id, message\_ts, workspace\_id. |
> | `snoozed_until_time` | Datetime | The time the issue was snoozed until in RFC3339 format, if any. |
> | `source` | String | The source of the issue. Known values: `slack`, `microsoft_teams`, `microsoft_teams_chat`, `chat_widget`, `customer_portal`, `email`, `manual`, `form`, `discord`, `google_chat`, `whatsapp`, `sms`, `telegram`, `phone`. This list is not exhaustive. |
> | `state` | String | The state of the issue. Standard values are `new`, `waiting_on_you`, `waiting_on_customer`, `on_hold`, and `closed`; custom status slugs are also supported. |
> | `tags` | Array of strings | Tags associated with the issue. |
> | `team` | String (JSON) | Team the issue is assigned to. JSON object with: id. |
> | `team_slas` | String (JSON) | The team-scoped SLAs on the issue, if any. One entry per team, mirroring the issue-level first response and resolution SLA fields. JSON array of objects with: first\_resolution, first\_response, follow\_up, next\_reply, resolution, team\_id. |
> | `time_in_status_seconds` | String (JSON) | A map of status slug to the time in seconds the issue has spent in that status. Includes both base statuses (e.g. "new", "waiting\_on\_you") and custom statuses. JSON object. |
> | `title` | String | The title of the issue. |
> | `type` | String | The type of the issue. Known values: `conversation`, `ticket`. This list is not exhaustive. |
> | `updated_at` | Datetime | The time the issue was last updated, used as the incremental replication key. |
> | `workspace_email` | String | The email address connected to the Pylon workspace through which the issue's email conversation is routed. For inbound issues, this is the address that received the original email. |
> | `workspace_phone_number` | String | The WhatsApp, SMS, or voice phone number connected to the Pylon workspace through which the issue's conversation is routed. For inbound issues, this is the number the customer messaged or called. |

> [accordion] Issue Messages
>
> Every message of each issue read in the sync: customer messages, replies and internal notes, oldest first. All messages of an issue are read again whenever the issue changes.
>
> Table: `issue_messages` · Primary key: `issue_id`, `id` · Sync: Incremental · Replication key: `issue_updated_at`
>
> | Field | Type | Description |
> | :- | :- | :- |
> | `issue_id` | String | ID of the issue the message belongs to. |
> | `id` | String | The top-level Pylon message ID. Use this value as message\_id when replying or when targeting an internal note's thread. |
> | `author` | String (JSON) | Author of the message. JSON object with: name, avatar\_url, user (id, email), contact (id, email). |
> | `author_unverified` | Boolean | Whether this message's author identity has NOT been verified. True for public form submissions, unverified chat widget visitors, and emails that failed sender authentication. For emails, read email\_info.sender\_authentication\_status to tell an authentication failure apart from the other cases. |
> | `email_info` | String (JSON) | Email details of the message, for messages sent by email. JSON object with: from\_email, to\_emails, cc\_emails, bcc\_emails, message\_id, opens, sender\_authentication\_status. |
> | `file_urls` | Array of strings | The URLs of the files in the message, if any. Signed download URLs. Fetch with a plain GET, no Authorization header. |
> | `is_private` | Boolean | Whether the message is an internal note. If true, the message is not visible to the requester; if false, it is customer-visible. |
> | `issue_updated_at` | Datetime | Last update time of the issue when the message was read, used as the incremental replication key. |
> | `message_html` | String | The HTML body of the message. |
> | `reactions` | String (JSON) | The emoji reactions currently on the message, grouped by emoji. JSON array of objects with: count, name. |
> | `slack_info` | String (JSON) | Slack details of the message, for messages from Slack. JSON object with: channel\_id, message\_ts, thread\_ts, permalink. |
> | `source` | String | The source of the message. |
> | `thread_id` | String | The Pylon internal thread ID. This is set only for internal notes and can be passed as thread\_id when creating an internal note. |
> | `timestamp` | Datetime | The time at which the message was created. |

> [accordion] Surveys
>
> CSAT, NPS and custom surveys. Read in full on every sync.
>
> Table: `surveys` · Primary key: `id` · Sync: Full table
>
> | Field | Type | Description |
> | :- | :- | :- |
> | `id` | String | The unique identifier of the survey. |
> | `name` | String | The name of the survey. |
> | `type` | String | The type of the survey. Known values: `nps`, `csat`, `custom`. This list is not exhaustive. |
> | `updated_at` | Datetime | When the survey was last updated (RFC3339 format). |

> [accordion] Survey Responses
>
> Responses to every survey, with their answers. Read in full on every sync, so responses later excluded from analytics are updated.
>
> Table: `survey_responses` · Primary key: `id` · Sync: Full table
>
> | Field | Type | Description |
> | :- | :- | :- |
> | `id` | String | The unique identifier of the survey response. |
> | `account_id` | String | The ID of the account associated with the response. |
> | `answers` | String (JSON) | The answers submitted in this response. JSON array of objects with: prompt, question\_id, question\_type, value. |
> | `contact_id` | String | The ID of the contact who submitted the response. |
> | `excluded_at` | Datetime | When the response was excluded from analytics. |
> | `issue_id` | String | The ID of the issue associated with this response, when applicable. |
> | `submitted_at` | Datetime | When the response was submitted. |
> | `survey_id` | String | The ID of the survey template associated with this response. |
> | `survey_instance_id` | String | The ID of the individual survey delivery that produced this response. |
> | `survey_type` | String | The type of survey associated with this response. Known values: `nps`, `csat`, `custom`. This list is not exhaustive. |

### Customers and team

> [accordion] Accounts
>
> Customer accounts (companies), with domains, owner, tags, channels and custom fields. Read in full on every sync.
>
> Table: `accounts` · Primary key: `id` · Sync: Full table
>
> | Field | Type | Description |
> | :- | :- | :- |
> | `id` | String | The ID of the account. |
> | `owner_id` | String | ID of the user who owns the account (copied from owner.id). |
> | `associated_account_ids` | Array of strings | The IDs of accounts associated with this partner that the caller can read. Present only for partner accounts; an empty array indicates no visible associated accounts. |
> | `channels` | String (JSON) | Channels associated with the account. JSON array of objects with: channel\_id, channel\_name, channel\_url, is\_internal, is\_primary, mirror\_to, source. |
> | `created_at` | Datetime | The creation time of the account. |
> | `crm_settings` | String (JSON) | CRM details linked to the account. JSON object with: details. |
> | `custom_fields` | String (JSON) | Custom fields associated with the account. JSON object. |
> | `domain` | String | The primary domain of the account. |
> | `domains` | Array of strings | The list of domains associated with the account. |
> | `external_ids` | String (JSON) | External IDs associated with the account. JSON array of objects with: external\_id, label. |
> | `is_disabled` | Boolean | Whether the account is disabled. |
> | `latest_customer_activity_time` | String | The time of the latest customer activity. |
> | `latest_vendor_activity_time` | String | The time of the latest vendor activity. |
> | `logo_url` | String | The logo URL of the account. |
> | `name` | String | The name of the account. |
> | `owner` | String (JSON) | User who owns the account. JSON object with: id, email. |
> | `parent_account_id` | String | The ID of this account's parent account, or null if it has no parent. |
> | `primary_domain` | String | The primary domain of the account. |
> | `subaccount_ids` | Array of strings | The IDs of the subaccounts belonging to this account. |
> | `tags` | Array of strings | Tags associated with the account. |
> | `type` | String | The type of the account. Known values: `customer`, `internal`, `community`, `partner`. This list is not exhaustive. |
> | `updated_at` | Datetime | The time the account was last updated. |

> [accordion] Contacts
>
> Contacts (people at your customer accounts). Read in full on every sync.
>
> Table: `contacts` · Primary key: `id` · Sync: Full table
>
> | Field | Type | Description |
> | :- | :- | :- |
> | `id` | String | The ID of the contact. |
> | `account_id` | String | ID of the account the contact belongs to (copied from account.id). |
> | `account` | String (JSON) | Account the contact belongs to. JSON object with: id, external\_ids. |
> | `avatar_url` | String | Avatar URL of the contact. |
> | `custom_fields` | String (JSON) | Custom field values associated with the contact. JSON object. |
> | `email` | String | The primary email of the contact, if it exists. |
> | `emails` | Array of strings | The list of all emails of the contact. |
> | `external_ids` | String (JSON) | External IDs associated with the contact. JSON array of objects with: external\_id, label. |
> | `integration_user_ids` | String (JSON) | Integration user IDs linking this contact to external systems. JSON array of objects with: id, source. |
> | `name` | String | The name of the contact. |
> | `phone_numbers` | Array of strings | The list of all phone numbers of the contact. |
> | `portal_role` | String | Portal role slug assigned to the contact. For backwards compatibility. Known values: `no_access`, `member`, `admin`. This list is not exhaustive. |
> | `portal_role_id` | String | The ID of the custom portal role assigned to the contact. |
> | `primary_phone_number` | String | The primary phone number of the contact, if it exists. |

> [accordion] Users
>
> Users (agents) of your Pylon workspace, deactivated ones included. Read in full on every sync.
>
> Table: `users` · Primary key: `id` · Sync: Full table
>
> | Field | Type | Description |
> | :- | :- | :- |
> | `id` | String | The ID of the user. |
> | `avatar_url` | String | The avatar URL of the user. |
> | `email` | String | The primary email of the user. |
> | `emails` | Array of strings | The list of all emails of the user. |
> | `is_deactivated` | Boolean | Whether the user is deactivated. |
> | `name` | String | The name of the user. |
> | `role` | String (JSON) | Deprecated by Pylon in favour of roles: one role assignment of the user. JSON object. |
> | `role_id` | String | Deprecated: Use role\_ids to retrieve all assigned roles. This field returns only one assignment for backwards compatibility, not a primary role. |
> | `role_ids` | Array of strings | All assigned role IDs, sorted by ID. The order does not imply precedence. |
> | `roles` | String (JSON) | All assigned roles, including SCIM-derived roles, sorted by ID. Empty when no roles are assigned. JSON array of objects with: id, name, slug. |
> | `skills` | String (JSON) | The user's routing skills. Null when the caller lacks permission to read team settings. JSON array of objects with: attribute, attribute\_type, values. |
> | `status` | String | The status of the user. Standard values are `active`, `away`, and `out_of_office`; custom status slugs are also supported. See GET /user-statuses for each status's category. |

> [accordion] Teams
>
> Teams, their members and how they assign issues. Read in full on every sync.
>
> Table: `teams` · Primary key: `id` · Sync: Full table
>
> | Field | Type | Description |
> | :- | :- | :- |
> | `id` | String | The ID of the team. |
> | `assignment_configuration` | String (JSON) | How the team assigns issues. JSON object with: assignment\_method, assignable\_user\_statuses, only\_assign\_if\_user\_active, override\_existing\_assignee, . |
> | `name` | String | The name of the team. |
> | `schedule` | String (JSON) | Recurring assignment schedule of the team, if any. JSON object with: id, timezone, blocks. |
> | `users` | String (JSON) | The users in the team. JSON array of objects with: email, id. |

> [accordion] User Roles
>
> Roles users can have. Read in full on every sync.
>
> Table: `user_roles` · Primary key: `id` · Sync: Full table
>
> | Field | Type | Description |
> | :- | :- | :- |
> | `id` | String | The ID of the role. |
> | `name` | String | The name of the role. |
> | `slug` | String | The slug of the role. |

### Projects and tasks

> [accordion] Tasks
>
> Tasks of your projects and customer onboardings. Synced incrementally by last update.
>
> Table: `tasks` · Primary key: `id` · Sync: Incremental · Replication key: `updated_at`
>
> | Field | Type | Description |
> | :- | :- | :- |
> | `id` | String | The ID of the task. |
> | `account_id` | String | ID of the account the task belongs to (copied from account.id). |
> | `milestone_id` | String | ID of the milestone the task belongs to (copied from milestone.id). |
> | `project_id` | String | ID of the project the task belongs to (copied from project.id). |
> | `account` | String (JSON) | Account the task belongs to. JSON object with: id, external\_ids. |
> | `ai_instructions` | String | Instructions the AI follows when evaluating this task in a smart project. |
> | `assignee` | String (JSON) | Who the task is assigned to. JSON object with: user, contact. |
> | `blocked_by_task_ids` | Array of strings | The IDs of tasks that block this task. |
> | `blocks_task_ids` | Array of strings | The IDs of tasks that this task blocks. |
> | `body_html` | String | The body of the task in HTML format. |
> | `completed_at` | Datetime | The completion time of the task in RFC3339 format. |
> | `created_at` | Datetime | The created at time of the task. |
> | `custom_fields` | String (JSON) | Custom field values associated with the task, keyed by custom field slug. JSON object. |
> | `customer_portal_visible` | Boolean | The customer portal visible of the task. |
> | `due_date` | Datetime | The due date of the task in RFC3339 format. |
> | `external_issues` | String (JSON) | The external product issues associated with the task, if any. JSON array of objects with: external\_id, key, link, source, state. |
> | `linked_issues` | String (JSON) | The Pylon issues linked to the task that the current user can access, if any. JSON array of objects with: id, number, title. |
> | `milestone` | String (JSON) | Milestone the task belongs to. JSON object with: id. |
> | `parent_task_id` | String | The ID of the parent task, if this is a subtask. |
> | `project` | String (JSON) | Project the task belongs to. JSON object with: id. |
> | `status` | String | The status of the task: not\_started, in\_progress or completed, or a custom task status slug. |
> | `subtask_ids` | Array of strings | The IDs of subtasks belonging to this task. |
> | `title` | String | The title of the task. |
> | `updated_at` | Datetime | The updated at time of the task, used as the incremental replication key. |

> [accordion] Projects
>
> Projects, with status and progress. Synced incrementally by last update.
>
> Table: `projects` · Primary key: `id` · Sync: Incremental · Replication key: `updated_at`
>
> | Field | Type | Description |
> | :- | :- | :- |
> | `id` | String | The ID of the project. |
> | `account_id` | String | ID of the account the project belongs to (copied from account.id). |
> | `account` | String (JSON) | Account the project belongs to. JSON object with: id, external\_ids. |
> | `ai_instructions` | String | Instructions the AI follows when keeping this smart project up to date. |
> | `archived_at` | Datetime | The archived at time of the project in RFC3339 format. |
> | `created_at` | Datetime | The created at time of the project. |
> | `custom_fields` | String (JSON) | Custom fields for this project, keyed by slug. JSON object. |
> | `customer_portal_visible` | Boolean | The customer portal visible of the project. |
> | `description_html` | String | The description of the project in HTML format. |
> | `end_date` | Datetime | The end date of the project in RFC3339 format. |
> | `is_archived` | Boolean | Whether the project is archived. |
> | `name` | String | The name of the project. |
> | `owner_id` | String | The owner ID of the project. |
> | `progress` | Number | The fraction of completed tasks, from 0 to 1. |
> | `project_template` | String (JSON) | Template the project was created from. JSON object with: id. |
> | `start_date` | Datetime | The start date of the project in RFC3339 format. |
> | `status` | String | The status of the project. One of not\_started, in\_progress, or completed. Known values: `not_started`, `in_progress`, `completed`. This list is not exhaustive. |
> | `updated_at` | Datetime | The updated at time of the project, used as the incremental replication key. |

> [accordion] Milestones
>
> Project milestones (milestones of projects not launched yet are not returned by Pylon). Synced incrementally by last update.
>
> Table: `milestones` · Primary key: `id` · Sync: Incremental · Replication key: `updated_at`
>
> | Field | Type | Description |
> | :- | :- | :- |
> | `id` | String | The ID of the milestone. |
> | `account_id` | String | ID of the account the milestone belongs to (copied from account.id). |
> | `project_id` | String | ID of the project the milestone belongs to (copied from project.id). |
> | `account` | String (JSON) | Account the milestone belongs to. JSON object with: id, external\_ids. |
> | `created_at` | Datetime | The time the milestone was created. |
> | `due_date` | Datetime | The due date of the milestone. |
> | `name` | String | The name of the milestone. |
> | `project` | String (JSON) | Project the milestone belongs to. JSON object with: id. |
> | `updated_at` | Datetime | The time the milestone was last updated, used as the incremental replication key. |

### Configuration and content

> [accordion] Tags
>
> Tags for issues, accounts and articles. Read in full on every sync.
>
> Table: `tags` · Primary key: `id` · Sync: Full table
>
> | Field | Type | Description |
> | :- | :- | :- |
> | `id` | String | The ID of the tag. |
> | `hex_color` | String | The hex code of the tag's color. |
> | `object_type` | String | The object type of the tagged object. Known values: `account`, `article`, `issue`. This list is not exhaustive. |
> | `value` | String | The value of the Tag. |

> [accordion] Issue Statuses
>
> Issue statuses, built-in and custom. Read in full on every sync.
>
> Table: `issue_statuses` · Primary key: `slug` · Sync: Full table
>
> | Field | Type | Description |
> | :- | :- | :- |
> | `slug` | String | The slug of the issue status. |
> | `category` | String | The category of the issue status. |
> | `is_archived` | Boolean | Indicates if the issue status is archived. |
> | `is_default_status` | Boolean | Indicates if the issue status is a default status. |
> | `label` | String | The label of the issue status. |

> [accordion] Task Statuses
>
> Task statuses, built-in and custom. Read in full on every sync.
>
> Table: `task_statuses` · Primary key: `slug` · Sync: Full table
>
> | Field | Type | Description |
> | :- | :- | :- |
> | `slug` | String | The slug of the task status. |
> | `category` | String | The category of the task status. |
> | `is_archived` | Boolean | Indicates if the task status is archived. |
> | `is_default_status` | Boolean | Indicates if the task status is a default status. |
> | `label` | String | The label of the task status. |

> [accordion] Custom Fields
>
> Custom field definitions of accounts, issues, contacts, tasks, projects, meetings and opportunities. Read in full on every sync.
>
> Table: `custom_fields` · Primary key: `id` · Sync: Full table
>
> | Field | Type | Description |
> | :- | :- | :- |
> | `id` | String | The ID of the custom field. |
> | `created_at` | Datetime | When the custom field was created. |
> | `default_value` | String | The default value for single-valued custom fields. |
> | `default_values` | Array of strings | The default values for multi-valued custom fields. |
> | `description` | String | The description of the custom field. |
> | `is_read_only` | Boolean | Whether the custom field is read only. Fields synced from apps and integrations are read-only. |
> | `label` | String | The label of the custom field. |
> | `number_metadata` | String (JSON) | Display settings of number fields. JSON object with: format, currency, decimal\_places, duration\_display\_format, duration\_input\_unit. |
> | `object_type` | String | The type of object this custom field is for. This can be a built-in or custom object type. |
> | `select_metadata` | String (JSON) | Options of select and multi-select fields. JSON object with: options (label, slug, ...). |
> | `slug` | String | The slug of the custom field. |
> | `source` | String | The source of the custom field. |
> | `type` | String | The type of the custom field. |
> | `updated_at` | Datetime | When the custom field was last updated. |

> [accordion] Ticket Forms
>
> Ticket forms and their fields. Read in full on every sync.
>
> Table: `ticket_forms` · Primary key: `id` · Sync: Full table
>
> | Field | Type | Description |
> | :- | :- | :- |
> | `id` | String | The ID of the ticket form. |
> | `description_html` | String | The description of the ticket form in HTML. |
> | `fields` | String (JSON) | The layout of the ticket form. JSON array of objects with: custom\_field\_id, description\_html, hidden, name, required, slug, type, visibility\_conditions. |
> | `is_public` | Boolean | Indicates if the ticket form is public. |
> | `name` | String | The name of the ticket form. |
> | `slug` | String | The slug of the ticket form. |
> | `url` | String | The URL of the ticket form. |

> [accordion] Macros
>
> Macros (saved replies, notes and actions). Read in full on every sync.
>
> Table: `macros` · Primary key: `id` · Sync: Full table
>
> | Field | Type | Description |
> | :- | :- | :- |
> | `id` | String | The ID of the macro. |
> | `actions` | String (JSON) | The actions that execute when this macro is applied. JSON array of objects with: type. |
> | `created_at` | Datetime | The time the macro was created. |
> | `edit_visibility` | String (JSON) | Visibility represents the visibility settings of a resource in responses. JSON object with: team\_ids, type, user\_ids. |
> | `has_actions` | Boolean | Whether this macro has actions that execute when applied. |
> | `macro_group_id` | String | The ID of the macro group this macro belongs to. |
> | `name` | String | The name of the macro. |
> | `text_html` | String | The HTML content of the macro. |
> | `text_type` | String | The type of text: "reply", "note", or "email". |
> | `updated_at` | Datetime | The time the macro was last updated. |
> | `visibility` | String (JSON) | Visibility represents the visibility settings of a resource in responses. JSON object with: team\_ids, type, user\_ids. |

> [accordion] Knowledge Bases
>
> Knowledge bases (help centers). Read in full on every sync.
>
> Table: `knowledge_bases` · Primary key: `id` · Sync: Full table
>
> | Field | Type | Description |
> | :- | :- | :- |
> | `id` | String | The ID of the knowledge base. |
> | `active_theme_id` | String | The ID of the theme currently used by the knowledge base. Omitted when the knowledge base uses a preset theme. |
> | `default_language` | String | The default language of the knowledge base. |
> | `slug` | String | The slug of the knowledge base. |
> | `supported_languages` | Array of strings | The list of supported languages for the knowledge base. |
> | `title` | String | The name of the knowledge base. |

> [accordion] Knowledge Base Articles
>
> Articles of every knowledge base, in its default language, with draft and published content. Read in full on every sync.
>
> Table: `knowledge_base_articles` · Primary key: `knowledge_base_id`, `id` · Sync: Full table
>
> | Field | Type | Description |
> | :- | :- | :- |
> | `knowledge_base_id` | String | ID of the knowledge base the article belongs to. |
> | `id` | String | The ID of the article. |
> | `approval_info` | String (JSON) | Approval status of the article. JSON object with: status, requested\_at, reviewed\_at, reviewed\_by\_user\_id. |
> | `author_user_id` | String | The ID of the user who authored the article. |
> | `collection_id` | String | The ID of the collection this article belongs to, if any. |
> | `created_at` | Datetime | The time the article was created. |
> | `current_draft_content_html` | String | The current draft content of the article in HTML. This is the latest version, which may differ from the published version. |
> | `current_draft_content_markdown` | String | The current draft content of the article in markdown. This is the latest version, which may differ from the published version. |
> | `current_published_content_html` | String | The current published content of the article in HTML. |
> | `current_published_content_markdown` | String | The current published content of the article in markdown. |
> | `identifier` | String | The identifier of the article. |
> | `is_published` | Boolean | IsPublished indicates if the article is published. |
> | `is_unlisted` | Boolean | Whether the article is accessible only via a direct link. |
> | `last_edited_at` | Datetime | The time the article content was last edited. |
> | `last_published_at` | Datetime | The last published at time of the article. |
> | `slug` | String | The slug of the article. |
> | `tags` | String (JSON) | Tags assigned to the article. JSON array of objects with: hex\_color, id, object\_type, value. |
> | `title` | String | The name of the article. |
> | `url` | String | The URL of the article. |
> | `visibility_config` | String (JSON) | Who can see the article. JSON object with: visibility, ai\_agent\_access, allowed\_agent\_ids, customer\_visibility\_condition, . |

> [accordion] Audit Logs
>
> Audit log of actions taken in your workspace. Synced incrementally by the time of the action.
>
> Table: `audit_logs` · Primary key: `id` · Sync: Incremental · Replication key: `action_happened_at`
>
> | Field | Type | Description |
> | :- | :- | :- |
> | `id` | String | The ID of the audit log. |
> | `action` | String | The action that was performed. |
> | `action_happened_at` | Datetime | The time at which the action happened, used as the incremental replication key. |
> | `actor_contact_id` | String | The ID of the contact who performed the action, if applicable. |
> | `actor_user_id` | String | The ID of the user who performed the action, if applicable. |
> | `attributes` | String (JSON) | Key-value attributes associated with the audit log. JSON object. |
> | `created_at` | Datetime | The time at which the audit log was created. |
> | `link` | String | The link associated with the audit log, if applicable. |
> | `metadata` | String (JSON) | Additional metadata associated with the audit log. The structure varies based on the action type. JSON object. |
> | `object_id` | String | The ID of the object that the audit log is for. |
> | `object_type` | String | The type of object that the audit log is for. |
> | `source` | String | The source of the audit log. |

## Implementation notes

* **Incremental sync.** Issues, tasks, projects and milestones are read by their last update time, audit logs by the time of the action. Each sync reads again from one hour before the latest update it saw, so late updates are not missed; records read twice are deduplicated.
* **Issue messages.** Whenever an issue changes or gets a new message, all of its messages are read again, so edits and reactions are kept current.
* **Full table streams** 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 Pylon.
* **Permissions.** If the token's role cannot read a stream you selected, that stream fails with a message naming it, and the other streams still load. Give the token a role with access, or deselect that stream.
* **Audit logs** are not selected by default, because reading them usually needs an Admin-level token. Entries Pylon records more than an hour after the action are only picked up by a full sync.
* **Deleted or edited messages.** Message changes are picked up when their issue is read again. A message deleted in Pylon stays in the `issue_messages` table.
* **File links.** `file_urls` and `attachment_urls` are signed links that do not expire and open without signing in. Treat these columns as sensitive.


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