# Zendesk

Zendesk is a customer service platform that provides support ticketing, knowledge management, and customer communication tools. The Sling Zendesk connector extracts data from the Zendesk REST API, supporting tickets, users, organizations, satisfaction ratings, and configuration data.

{% hint style="success" %}
**CLI Pro Required**: APIs require a [CLI Pro token](https://docs.slingdata.io/sling-cli/cli-pro) or [Platform Plan](https://docs.slingdata.io/sling-platform/platform).
{% endhint %}

## Setup

The following credentials and inputs are accepted:

**Secrets:**

* `subdomain` **(required)** -> Your Zendesk subdomain (the first part of your Zendesk URL, e.g., `mycompany` from `mycompany.zendesk.com`)
* `oauth_token` (optional) -> OAuth Bearer token for authentication (starts with `Bearer` )
* `email` (optional) -> Email address for Basic Auth (required if using API token instead of OAuth)
* `api_token` (optional) -> API token for Basic Auth (required if using email instead of OAuth)

**Inputs:**

* `anchor_date` (optional) -> The starting date for historical data extraction on first sync (default: 1 year ago). Format: `YYYY-MM-DD`

{% hint style="info" %}
**Authentication Methods:** You can authenticate using either OAuth Bearer token OR Basic Auth (email + api\_token). At least one method must be configured.
{% endhint %}

### Getting Your Credentials

#### OAuth Bearer Token (Recommended)

OAuth is the recommended authentication method for Zendesk:

1. Log in to your [Zendesk Admin Center](https://support.zendesk.com/hc/en-us/articles/203663216)
2. Go to **Apps and integrations** > **OAuth clients**
3. Click **Create OAuth client** (or use an existing one)
4. Under **Authorized redirect URIs**, add your application's redirect URI
5. Copy your **OAuth token** from the client details
6. Format it as: `Bearer <your_token>`

#### Basic Auth with API Token

For Basic Auth using an API token:

1. Log in to your [Zendesk Admin Center](https://support.zendesk.com/hc/en-us/articles/203663216)
2. Go to **Settings** > **API and webhooks** > **API tokens**
3. Click **+ Add API token** to create a new token
4. Copy the **API token** (you'll only see it once)
5. Use your account email address and the API token for authentication

{% hint style="warning" %}
**Important:** Store your API token securely. It provides full access to your Zendesk account data. Never commit tokens to version control.
{% endhint %}

### Using `sling conns`

Here are examples of setting a connection named `ZENDESK`. We must provide the `type=api` property:

**With OAuth Bearer token:**

{% code overflow="wrap" %}

```bash
sling conns set ZENDESK type=api spec=zendesk secrets='{ subdomain: mycompany, oauth_token: "Bearer xxxxxxxxxxxxxxxx" }'
```

{% endcode %}

**With Basic Auth (email + API token):**

{% code overflow="wrap" %}

```bash
sling conns set ZENDESK type=api spec=zendesk secrets='{ subdomain: mycompany, email: user@example.com, api_token: xxxxxxxxxxxxxxxx }'
```

{% endcode %}

### Environment Variable

See [here](https://docs.slingdata.io/sling-cli/environment#dot-env-file-.env.sling) to learn more about the `.env.sling` file.

**With OAuth:**

{% code overflow="wrap" %}

```bash
export ZENDESK='{ type: api, spec: zendesk, secrets: { subdomain: "mycompany", oauth_token: "Bearer xxxxxxxxxxxxxxxx" } }'
```

{% endcode %}

**With Basic Auth:**

{% code overflow="wrap" %}

```bash
export ZENDESK='{ type: api, spec: zendesk, secrets: { subdomain: "mycompany", email: "user@example.com", api_token: "xxxxxxxxxxxxxxxx" } }'
```

{% endcode %}

### Sling Env File YAML

See [here](https://docs.slingdata.io/sling-cli/environment#sling-env-file-env.yaml) to learn more about the sling `env.yaml` file.

**With OAuth Bearer token:**

```yaml
connections:
  ZENDESK:
    type: api
    spec: zendesk
    secrets:
      subdomain: "mycompany"
      oauth_token: "Bearer xxxxxxxxxxxxxxxx"
```

**With Basic Auth (email + API token):**

```yaml
connections:
  ZENDESK:
    type: api
    spec: zendesk
    secrets:
      subdomain: "mycompany"
      email: "user@example.com"
      api_token: "xxxxxxxxxxxxxxxx"
```

**With anchor date for historical data:**

```yaml
connections:
  ZENDESK:
    type: api
    spec: zendesk
    secrets:
      subdomain: "mycompany"
      oauth_token: "Bearer xxxxxxxxxxxxxxxx"
    inputs:
      anchor_date: "2020-01-01"
```

## Replication

Here's an example replication configuration to sync Zendesk data to a PostgreSQL database:

```yaml
source: ZENDESK
target: MY_POSTGRES

defaults:
  mode: incremental
  object: zendesk.{stream_name}

streams:
  # Core support data
  tickets:
  ticket_comments:
  users:
  organizations:

  # Reference data (full-refresh only)
  groups:
    mode: full-refresh
  ticket_fields:
    mode: full-refresh
  ticket_forms:
    mode: full-refresh
  brands:
    mode: full-refresh
  tags:
    mode: full-refresh
```

**Sync all endpoints:**

```yaml
source: ZENDESK
target: MY_POSTGRES

defaults:
  mode: incremental
  object: zendesk.{stream_name}

streams:
  # Sync all available endpoints
  '*':
```

**Full refresh example for configuration data:**

```yaml
source: ZENDESK
target: MY_POSTGRES

defaults:
  mode: full-refresh
  object: zendesk_config.{stream_name}

streams:
  groups:
  ticket_fields:
  ticket_forms:
  brands:
  custom_roles:
  tags:
  views:
  sla_policies:
  schedules:
```

## Endpoints

### Core Support Data

| Endpoint               | Description                          | Incremental        |
| ---------------------- | ------------------------------------ | ------------------ |
| `tickets`              | Support tickets                      | Yes (cursor-based) |
| `ticket_comments`      | Comments on tickets (child endpoint) | No                 |
| `satisfaction_ratings` | Customer satisfaction ratings        | Yes (time-based)   |

### Users & Organizations

| Endpoint                   | Description                          | Incremental        |
| -------------------------- | ------------------------------------ | ------------------ |
| `users`                    | Support agents and end-users         | Yes (cursor-based) |
| `organizations`            | Customer organizations               | Yes (time-based)   |
| `group_memberships`        | Membership of users in groups        | No                 |
| `organization_memberships` | Membership of users in organizations | No                 |

### Ticket Configuration

| Endpoint         | Description                     | Incremental |
| ---------------- | ------------------------------- | ----------- |
| `ticket_fields`  | Custom ticket field definitions | No          |
| `ticket_forms`   | Ticket form configurations      | No          |
| `ticket_metrics` | Ticket statistics and metrics   | No          |

### Groups & Routing

| Endpoint | Description                | Incremental |
| -------- | -------------------------- | ----------- |
| `groups` | Support agent groups       | No          |
| `views`  | Saved ticket views/filters | No          |

### Organization Configuration

| Endpoint       | Description             | Incremental |
| -------------- | ----------------------- | ----------- |
| `brands`       | Account brands          | No          |
| `custom_roles` | Custom role definitions | No          |

### SLAs & Schedules

| Endpoint       | Description              | Incremental |
| -------------- | ------------------------ | ----------- |
| `sla_policies` | Service level agreements | No          |
| `schedules`    | Business hour schedules  | No          |

### Automation

| Endpoint      | Description          | Incremental |
| ------------- | -------------------- | ----------- |
| `triggers`    | Automation triggers  | No          |
| `automations` | Automation workflows | No          |
| `macros`      | Quick action macros  | No          |

### Tags & Metadata

| Endpoint | Description    | Incremental |
| -------- | -------------- | ----------- |
| `tags`   | Available tags | No          |

To discover available endpoints:

```bash
sling conns discover ZENDESK
```

## Incremental Sync

The Zendesk connector supports incremental sync for the following endpoints:

### Cursor-based Incremental Sync

* **tickets** - Uses cursor pagination for large result sets
* **users** - Uses cursor pagination for large result sets

First run fetches all records, subsequent runs only fetch records created or modified after the last sync.

### Time-based Incremental Sync

* **organizations** - Filters by `updated_at` timestamp
* **satisfaction\_ratings** - Filters by `created_at` timestamp

### Anchor Date

On the first sync, incremental endpoints use the `anchor_date` input (default: 1 year ago) as the starting point. Subsequent syncs only fetch records modified after the last sync timestamp.

### Child Endpoints

The `ticket_comments` endpoint uses a queue-based pattern:

1. First, the `tickets` endpoint runs and collects ticket IDs
2. Then, the `ticket_comments` endpoint iterates through the queue to fetch comments for each ticket

This means you should run the `tickets` endpoint before `ticket_comments` in your replication.

## Rate Limiting

The Zendesk API has rate limits:

* **Standard accounts:** 10 requests per second
* **Enterprise accounts:** May have higher limits

The connector automatically:

* Uses conservative rate limiting (5 requests/second)
* Retries with exponential backoff on rate limit responses

To check your rate limits, refer to the [Zendesk Rate Limiting documentation](https://developer.zendesk.com/documentation/ticketing/managing-pagination/handling-overload/).

## Common Use Cases

### Sync Core Support Tickets

```yaml
source: ZENDESK
target: MY_POSTGRES

defaults:
  mode: incremental
  object: support.{stream_name}

streams:
  tickets:
  ticket_comments:
  users:
  satisfaction_ratings:
```

### Sync Users and Organizations

```yaml
source: ZENDESK
target: MY_POSTGRES

defaults:
  mode: incremental
  object: zendesk.{stream_name}

streams:
  users:
  organizations:
  group_memberships:
  organization_memberships:
```

### Configuration and Reference Data

```yaml
source: ZENDESK
target: MY_POSTGRES

defaults:
  mode: full-refresh
  object: zendesk_config.{stream_name}

streams:
  groups:
  ticket_fields:
  ticket_forms:
  brands:
  custom_roles:
  views:
  sla_policies:
  schedules:
  triggers:
  automations:
  macros:
```

### Support Analytics with SLA Tracking

```yaml
source: ZENDESK
target: MY_POSTGRES

defaults:
  mode: incremental
  object: analytics.{stream_name}

streams:
  tickets:
  ticket_comments:
  ticket_metrics:
  satisfaction_ratings:
  sla_policies:
    mode: full-refresh
```

If you are facing issues connecting, please reach out to us at <support@slingdata.io>, on [discord](https://discord.gg/q5xtaSNDvp) or open a Github Issue [here](https://github.com/slingdata-io/sling-cli/issues).


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.slingdata.io/connections/api-connections/zendesk.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
