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

# Zendesk V1

> The Zendesk connector uses the Zendesk REST API to retrieve tickets and their associated comments and attachments from a Zendesk repository.

export const schema = {
  "type": "object",
  "title": "Zendesk",
  "description": "Connector to index Zendesk tickets, ticket attachments, and ticket comments.",
  "required": ["id", "connector", "type", "pipeline", "properties"],
  "properties": {
    "category": {
      "type": "string",
      "title": "Category",
      "default": "Repository",
      "hints": ["hidden", "readonly"]
    },
    "parserId": {
      "type": "string",
      "title": "Parser",
      "description": "Parser used when parsing raw content. For some connectors, a configuration to 'retry' parsing if an error occurs is available as an advanced setting",
      "default": "_system"
    },
    "id": {
      "type": "string",
      "title": "Datasource ID",
      "description": "Unique name for this datasource.",
      "minLength": 1,
      "pattern": "^[a-zA-Z0-9_-]+$"
    },
    "connector": {
      "type": "string",
      "title": "Connector Type",
      "description": "Connector Type.",
      "hints": ["hidden"],
      "minLength": 1
    },
    "type": {
      "type": "string",
      "title": "Datasource Type",
      "description": "Datasource type supported by the selected connector type.",
      "hints": ["hidden"],
      "minLength": 1
    },
    "pipeline": {
      "type": "string",
      "title": "Pipeline ID",
      "description": "Name of an existing index pipeline for processing documents.",
      "minLength": 1
    },
    "description": {
      "type": "string",
      "title": "Description",
      "description": "Optional description for this datasource."
    },
    "type_description": {
      "type": "string",
      "title": "Type Description",
      "default": "Connector to index Zendesk tickets, ticket attachments, and ticket comments.",
      "hints": ["hidden", "readonly"]
    },
    "properties": {
      "type": "object",
      "title": "Properties",
      "description": "Datasource configuration properties",
      "required": ["base_url", "use_token_auth", "auth_key", "auth_value"],
      "properties": {
        "collection": {
          "type": "string",
          "title": "Collection",
          "description": "Collection documents will be indexed to.",
          "hints": ["hidden"],
          "pattern": "^[a-zA-Z0-9_-]+$"
        },
        "db": {
          "type": "object",
          "title": "Connector DB",
          "description": "Type and properties for a ConnectorDB implementation to use with this datasource.",
          "required": ["type"],
          "properties": {
            "type": {
              "type": "string",
              "title": "Implementation Class Name",
              "description": "Fully qualified class name of ConnectorDb implementation.",
              "default": "com.lucidworks.connectors.db.impl.MapDbConnectorDb",
              "minLength": 1
            },
            "inlinks": {
              "type": "boolean",
              "title": "Process Inlinks?",
              "description": "Keep track of incoming links. This negatively impacts performance and size of DB.",
              "default": false
            },
            "aliases": {
              "type": "boolean",
              "title": "Process Aliases?",
              "description": "Keep track of original URI-s that resolved to the current URI. This negatively impacts performance and size of DB.",
              "default": false
            },
            "inv_aliases": {
              "type": "boolean",
              "title": "Process Inverted Aliases?",
              "description": "Keep track of target URI-s that the current URI resolves to. This negatively impacts performance and size of DB.",
              "default": false
            }
          },
          "hints": ["hidden"]
        },
        "article_containers": {
          "type": "array",
          "title": "Article Containers",
          "description": "Specify the Category or Section Id to retrieve articles from. Don't add entries to index all articles from all categories",
          "items": {
            "type": "object",
            "required": ["container_type", "container_id"],
            "properties": {
              "container_type": {
                "type": "string",
                "title": "Container Type",
                "description": "Container type can be a Category or a Section",
                "enum": ["Category", "Section"]
              },
              "container_id": {
                "type": "string",
                "title": "Container Id",
                "description": "The Category or Section ID",
                "minLength": 1
              }
            }
          }
        },
        "initial_mapping": {
          "type": "object",
          "title": "Initial field mapping",
          "description": "Provides mapping of fields before documents are sent to an index pipeline.",
          "properties": {
            "skip": {
              "type": "boolean",
              "title": "Skip This Stage",
              "description": "Set to true to skip this stage.",
              "default": false,
              "hints": ["advanced"]
            },
            "label": {
              "type": "string",
              "title": "Label",
              "description": "A unique label for this stage.",
              "hints": ["advanced"],
              "maxLength": 255
            },
            "condition": {
              "type": "string",
              "title": "Condition",
              "description": "Define a conditional script that must result in true or false. This can be used to determine if the stage should process or not.",
              "hints": ["code", "code/javascript", "advanced"]
            },
            "reservedFieldsMappingAllowed": {
              "type": "boolean",
              "title": "Allow System Fields Mapping?",
              "default": false,
              "hints": ["advanced"]
            },
            "retentionMappings": {
              "type": "array",
              "title": "Field Retention",
              "description": "Fields that should be kept or deleted",
              "hints": ["advanced"],
              "items": {
                "type": "object",
                "required": ["field"],
                "properties": {
                  "field": {
                    "type": "string",
                    "title": "Field",
                    "description": "The name of the field to operate on.",
                    "hints": ["advanced"]
                  },
                  "operation": {
                    "type": "string",
                    "title": "Operation",
                    "description": "The type of operation to perform: keep (default) or delete",
                    "enum": ["keep", "delete"],
                    "default": "keep",
                    "hints": ["advanced"]
                  }
                }
              }
            },
            "updateMappings": {
              "type": "array",
              "title": "Field Value Updates",
              "description": "Values that should be added to or set on a field. When a value is added, any values previously on the field will be retained. When a value is set, any values previously on the field will be overwritten.",
              "hints": ["advanced"],
              "items": {
                "type": "object",
                "required": ["field", "value"],
                "properties": {
                  "field": {
                    "type": "string",
                    "title": "Field",
                    "description": "The name of the field to operate on.",
                    "hints": ["advanced"]
                  },
                  "value": {
                    "type": "string",
                    "title": "Value",
                    "description": "The value to add to or set on the field.",
                    "hints": ["advanced"]
                  },
                  "operation": {
                    "type": "string",
                    "title": "Operation",
                    "description": "The type of operation to perform: add (default) or set.",
                    "enum": ["add", "set"],
                    "default": "add",
                    "hints": ["advanced"]
                  }
                }
              }
            },
            "translationMappings": {
              "type": "array",
              "title": "Field Translations",
              "description": "Fields that should be moved or copied to another field. When a field is moved, the values from the source field are moved over to the target field and the source field is removed. When a field is copied, the values from the source field are copied over to the target field and the source field is retained.",
              "hints": ["advanced"],
              "items": {
                "type": "object",
                "required": ["source", "target"],
                "properties": {
                  "source": {
                    "type": "string",
                    "title": "Source Field",
                    "description": "The name of the field to operate on.",
                    "hints": ["advanced"]
                  },
                  "target": {
                    "type": "string",
                    "title": "Target Field",
                    "description": "The name of the target field.",
                    "hints": ["advanced"]
                  },
                  "operation": {
                    "type": "string",
                    "title": "Operation",
                    "description": "The type of operation to perform: copy (default) or move.",
                    "enum": ["copy", "move"],
                    "default": "copy",
                    "hints": ["advanced"]
                  }
                }
              }
            },
            "unmappedRule": {
              "type": "object",
              "title": "Unmapped Fields",
              "description": "Fields not mapped by the above rules. By default, any remaining fields will be kept on the document.",
              "properties": {
                "keep": {
                  "type": "boolean",
                  "title": "Keep",
                  "description": "Keep all unmapped fields",
                  "default": true,
                  "hints": ["advanced"]
                },
                "delete": {
                  "type": "boolean",
                  "title": "Delete",
                  "description": "Delete all unmapped fields",
                  "default": false,
                  "hints": ["advanced"]
                },
                "fieldToMoveValuesTo": {
                  "type": "string",
                  "title": "Move",
                  "description": "Move all unmapped field values to this field",
                  "hints": ["advanced"]
                },
                "fieldToCopyValuesTo": {
                  "type": "string",
                  "title": "Copy",
                  "description": "Copy all unmapped field values to this field",
                  "hints": ["advanced"]
                },
                "valueToAddToUnmappedFields": {
                  "type": "string",
                  "title": "Add",
                  "description": "Add this value to all unmapped fields",
                  "hints": ["advanced"]
                },
                "valueToSetOnUnmappedFields": {
                  "type": "string",
                  "title": "Set",
                  "description": "Set this value on all unmapped fields",
                  "hints": ["advanced"]
                }
              }
            }
          },
          "category": "Field Transformation",
          "categoryPriority": 7,
          "hints": ["advanced"],
          "unsafe": false
        },
        "enable_security_trimming": {
          "type": "object",
          "title": "Enable Security Trimming",
          "description": "Enable indexing and query-time security-trimming of Zendesk articles. Zendesk tickets and ticket comments don't support security trimming, these will be public by default",
          "properties": {}
        },
        "base_url": {
          "type": "string",
          "title": "Base API URL",
          "description": "A properly formatted v2 Zendesk API URL. Example: https://yourcompany.zendesk.com/api/v2"
        },
        "use_token_auth": {
          "type": "boolean",
          "title": "Token Auth",
          "description": "Used to determine how the authentication credentials will be formatted. If set to true, the auth_key value will be formatted according to the Zendesk token auth specifications (<email>/<token>).",
          "default": true
        },
        "auth_key": {
          "type": "string",
          "title": "Authentication Key",
          "description": "An email address of a valid Zendesk user which must have an admin role.",
          "minLength": 1
        },
        "auth_value": {
          "type": "string",
          "title": "Authentication Value",
          "description": "This value can be a user password, or an API token. If an API token is used, the Token Auth must be set to true.",
          "hints": ["secret"]
        },
        "organization_id": {
          "type": "string",
          "title": "Organization ID",
          "description": "The ID of a Zendesk Organization. This optional setting will allow the Connector to skip records that don't have the same Organization ID."
        },
        "proxy_url": {
          "type": "string",
          "title": "Proxy URL",
          "description": "HTTP(S) proxy server URL."
        },
        "proxy_username": {
          "type": "string",
          "title": "Proxy username",
          "description": "Proxy server username/login."
        },
        "proxy_password": {
          "type": "string",
          "title": "Proxy password",
          "description": "Proxy server password.",
          "hints": ["secret"]
        },
        "index_tickets": {
          "type": "boolean",
          "title": "Index Tickets",
          "description": "If enabled, tickets will be indexed",
          "default": true
        },
        "index_articles": {
          "type": "boolean",
          "title": "Index Articles",
          "description": "If enabled, Help Center articles will be indexed using settings on Article Container section",
          "default": false
        },
        "page_size": {
          "type": "integer",
          "title": "Page size",
          "description": "The number of items to be retrieved on each call. Maximum value is 100",
          "default": 100,
          "maximum": 100,
          "exclusiveMaximum": false,
          "minimum": 1,
          "exclusiveMinimum": false
        },
        "zendesk_account_plan": {
          "type": "string",
          "title": "Zendesk Account Plan",
          "description": "Zendesk applies plan-specific rate limits to API requests. Check https://developer.zendesk.com/rest_api/docs/core/introduction#rate-limits for more information.",
          "enum": ["essential", "team", "professional", "enterprise", "high_volume"],
          "default": "essential"
        },
        "index_article_attachments": {
          "type": "boolean",
          "title": "Index article attachments",
          "description": "If enabled, article attachments will be retrieved",
          "default": false
        },
        "security_trimming_cache_timeout": {
          "type": "integer",
          "title": "Security trimming cache timeout",
          "description": "Security trimming cache timeout in seconds.",
          "default": 3600
        }
      },
      "propertyGroups": [{
        "label": "Crawl Performance",
        "properties": ["page_size", "zendesk_account_plan"]
      }, {
        "label": "Limit Articles Documents",
        "properties": ["index_articles", "index_article_attachments", "article_containers"]
      }, {
        "label": "Security Trimming",
        "properties": ["enable_security_trimming", "security_trimming_cache_timeout"]
      }, {
        "label": "Limit Tickets Documents",
        "properties": ["index_tickets"]
      }, {
        "label": "Field Mapping",
        "properties": ["initial_mapping"]
      }]
    }
  },
  "category": "Other",
  "categoryPriority": 1,
  "unsafe": false
};

export const SchemaParamFields = ({schema}) => {
  const sanitize = str => {
    if (typeof str !== "string") return str;
    return str.replace(/^"(.*)"$/s, "$1").replace(/\\/g, "").replace(/"/g, "'");
  };
  const formatDescription = str => {
    const s = sanitize(str);
    return (/[.!?]\)*$/).test(s) ? s : `${s}.`;
  };
  const {description, properties = {}, required: requiredProps = []} = schema;
  const visibleProps = useMemo(() => Object.entries(properties).filter(([, prop]) => !prop.hints?.includes("hidden")), [properties]);
  return <div>
      {description && <p>{formatDescription(description)}</p>}

      {visibleProps.map(([name, prop]) => {
    const isRequired = requiredProps.includes(name);
    const hasDefault = prop.default !== undefined;
    const rawDefault = prop.default;
    const isComplexDefault = hasDefault && (typeof rawDefault === "object" || typeof rawDefault === "string" && (rawDefault.length > 20 || rawDefault.includes('"')));
    const fieldProps = {
      key: name,
      body: prop.title || name,
      type: prop.type,
      ...prop.title && ({
        post: [<><span className="text-stone-400 dark:text-stone-500">API property: </span>{name}</>]
      }),
      ...isRequired && ({
        required: true
      }),
      ...!isComplexDefault && hasDefault ? {
        default: sanitize(String(rawDefault))
      } : {}
    };
    const isObject = prop.type === "object" && prop.properties;
    const isArrayOfObjects = prop.type === "array" && prop.items?.type === "object" && prop.items.properties;
    return <ParamField {...fieldProps}>
            {prop.description && <p>{formatDescription(prop.description)}</p>}

            {isComplexDefault && <div className="flex">
                <p>
                  <strong>Default:</strong>
                </p>
                <pre className="!my-0">
                  <code>
                    {JSON.stringify(rawDefault, null, 2)}
                  </code>
                </pre>
              </div>}

            {isArrayOfObjects && <div className="flex">
              <p>
                <strong>Object attributes:</strong>
              </p>
              <pre className="!my-0">
                <code>
                  {'{\n'}
                  {Object.entries(prop.items.properties).map(([iname, iprop]) => <>
                      {`  ${iname}`}
                      {prop.items?.required?.includes(iname) && <span style={{
      color: 'red'
    }}> required</span>}
                      {`: {\n    display name: ${sanitize(iprop.title || '')}\n    type: ${iprop.type}\n  }\n`}
                    </>)}
                  {'}'}
                </code>
              </pre>
              </div>}

            {isObject && <Expandable title="properties">
                <SchemaParamFields schema={{
      properties: prop.properties,
      required: prop.required
    }} />
              </Expandable>}
          </ParamField>;
  })}
    </div>;
};

export const LwTemplate = ({title = "Key questions to get you started", icon = "sparkles", cta = "Powered by Agent Studio", linkHref = "https://lucidworks.com/demo/?utm_source=docs&utm_medium=referral&utm_campaign=docs_cta_ai"}) => {
  const [isLoaded, setIsLoaded] = useState(false);
  useEffect(() => {
    const timer = setTimeout(() => {
      setIsLoaded(true);
    }, 500);
    return () => clearTimeout(timer);
  }, []);
  return <div className="lw-template-container">
      <Card title={title} icon={icon}>
        {isLoaded && <span dangerouslySetInnerHTML={{
    __html: `<lw-template id="a029c1a9-28be-427e-b0e1-5d918920246a"></lw-template
            >`
  }} />}
        <Link href={linkHref} className="agent-studio-link text-left text-gray-600 gap-2 dark:text-gray-400 text-sm font-medium flex flex-row items-center hover:text-primary dark:hover:text-primary-light group-hover:text-primary group-hover:dark:text-primary-light">Powered by Lucidworks Agent Studio</Link>
      </Card>
    </div>;
};

[localhost link]: http://localhost:3000/docs/fusion-connectors/connectors/v1/zendesk

[mintlify link]: https://doc.lucidworks.com/docs/fusion-connectors/connectors/v1/zendesk

[old doc.lw link]: https://doc.lucidworks.com/fusion-connectors/46

<Callout icon="plug" color="#A4C6F7" iconType="solid">
  **Compatible with Fusion version:** 4.0.0 through 5.12.0
</Callout>

<Tip>
  V1 deprecation and removal notice

  All V1 connectors are deprecated in Fusion 5.18.0 and later. This means they are no longer being actively developed and will be removed in Fusion 6. V1 connectors were also previously deprecated in Fusion 5.12.0 but remained available in all versions between 5.12.0 and 5.18.0, including the Fusion 5.9.x long-term support release line, to support customers on those versions.

  The replacement for this connector is in active development at this time and will be released at a future date.

  If you are using this connector, you must migrate to the replacement connector or a supported alternative before upgrading to Fusion 6. Migrate to the replacement connector as soon as possible to avoid any disruption to your workflows.
</Tip>

It retrieves all tickets with all fields (such as customer, assignee, priority, status, and so on) as well as access restrictions for users and groups. ACLs can be used for security trimming at query time.
The types of items retrieved are:

* tickets and their associated metrics: for example, time elapsed until first response, time to close.
* ticket comment counts, comment IDs
* ticket comment attachment URLs

Items retrieved are returned as individual Solr documents, therefore, for a given Zendesk ticket, there will be multiple documents:

* the Zendesk ticket itself
* one document per comment
* one document per comment attachment

Documents have fields for Zendesk type and reference field to parent documents. For example, a comment document will have field `ticket_id` pointing back to the Zendesk ticket.

Incremental recrawls allow updates to the Fusion collection to add new tickets and record further changes to existing tickets without having
to retrieve the entire Zendesk repository contents.

<LwTemplate />

## Prerequisites

The Zendesk user must have administrator privileges to retrieve all tickets and associated information.
All communication with the Zendesk API is encrypted with SSL.

A Zendesk data source must be configured with the following properties:

* **Authentication Key.** The username or email.
* **Authentication Value.** The password or API token.
* **Token Auth.** A flag to indicate whether the auth key/value should be treated as username/password or email/token
* **Base URL.** The API URL to an instance of the Zendesk API
* **Organization ID.** Set to restrict indexing to only tickets that belong to the Organization

## Description

It retrieves all tickets with all fields (such as customer, assignee, priority, status, and so on) as well as access restrictions for users and groups. ACLs can be used for security trimming at query time.
The types of items retrieved are:

* tickets and their associated metrics: for example, time elapsed until first response, time to close.
* ticket comment counts, comment IDs
* ticket comment attachment URLs

Items retrieved are returned as individual Solr documents, therefore, for a given Zendesk ticket, there will be multiple documents:

* the Zendesk ticket itself
* one document per comment
* one document per comment attachment

Documents have fields for Zendesk type and reference field to parent documents. For example, a comment document will have field `ticket_id` pointing back to the Zendesk ticket.

Incremental recrawls allow updates to the Fusion collection to add new tickets and record further changes to existing tickets without having
to retrieve the entire Zendesk repository contents.

## Configuration Properties

<Tip>
  When entering configuration values in the UI, use *unescaped* characters, such as `\t` for the tab character. When entering configuration values in the API, use *escaped* characters, such as `\\t` for the tab character.
</Tip>

<SchemaParamFields schema={schema} />
