---
name: "import_from_zendesk"
area: "imports"
title: "Import from Zendesk"
price: "$0.001 per record imported (created or updated)"
method: "POST"
url: "https://api.conecto.chat/v1/tools/import_from_zendesk"
mcp_server: "https://api.conecto.chat/mcp/imports"
auth: "Authorization: Bearer <conecto_sk_ key>"
docs_url: "https://conecto.chat/tools/imports/import_from_zendesk"
---

# Import from Zendesk (`import_from_zendesk`)

Imports Zendesk Support tickets in the background, with their public replies, and each requester as a contact; nobody is emailed.

Import a Zendesk Support account's tickets, with their public replies as the conversation, and each requester as a contact (matched to existing contacts by email). Status new/open becomes open, pending/on-hold pending, solved/closed resolved; priority, subject and dates are kept. Nobody is emailed. Needs the subdomain (acme for acme.zendesk.com), and an agent's or admin's email with an API token from Zendesk Admin Center > Apps and integrations > APIs > API tokens. With an admin's email every ticket comes over, archived ones included; with an agent's, Zendesk leaves out archived tickets. Wrong credentials are refused before anything is reserved or charged; the token is kept only encrypted while the import runs, then erased. A ticket and its requester count as records; replies come with their ticket. Runs in the background for up to 15 minutes and imports up to max_records records; when more remain, the result has next_cursor: call again with the same arguments plus next_cursor to continue. Running it again never duplicates anything: changed records are updated, unchanged ones skipped. Unchanged records are free, and 1,000 imported records cost $1. max_records x $0.001 is reserved while it runs and only what was imported is charged; lower max_records if your balance is smaller.

Price: $0.001 per record imported (created or updated). A call that fails costs nothing.

## Use it when

The business moves its help desk from Zendesk.

- For the contacts and companies of a CRM, use [import_from_hubspot](https://conecto.chat/tools/imports/import_from_hubspot.md).

## Say this to your agent

> Bring our old Zendesk tickets over so we keep the history. Tom made an API token.

## Inputs

| Name | Type | Required | Description | Allowed values | Default |
|---|---|---|---|---|---|
| `subdomain` | string | yes | The "acme" in acme.zendesk.com. 1 to 120 characters. |  |  |
| `email` | string | yes | The email of the agent or admin the API token is used as. 3 to 254 characters. |  |  |
| `api_token` | string | yes | A Zendesk API token. 10 to 200 characters. Stored encrypted and shown only as [redacted]. |  |  |
| `max_records` | integer | no | The most records this run may create or update (and reserve $0.001 each for). 1 to 100,000. |  | `10000` |
| `next_cursor` | string | no | The next_cursor a previous run of this import returned, to continue where it stopped. Up to 2,000 characters. |  |  |

## Example

Written for Hansen & Voss, a restaurant-equipment wholesaler in Hamburg with 60 staff.

MCP: call `import_from_zendesk` on the MCP server `https://api.conecto.chat/mcp/imports` with these arguments:

```json
{
  "subdomain": "hansenvoss",
  "email": "tom.okafor@hansenvoss.example",
  "api_token": "0000000000000000000000000000000000000000"
}
```

REST:

```bash
curl https://api.conecto.chat/v1/tools/import_from_zendesk \
  -H "Authorization: Bearer $CONECTO_KEY" \
  -H "Content-Type: application/json" \
  -d '{"subdomain": "hansenvoss", "email": "tom.okafor@hansenvoss.example", "api_token": "0000000000000000000000000000000000000000"}'
```

## Response

This tool runs in the background. The first reply has status `202`:

```json
{
  "call_id": "5f0c8a2e-3b7d-4c1e-9a64-2d8e1f7b0c93",
  "tool": "import_from_zendesk",
  "status": "running",
  "reserved_usd": "$10.00",
  "poll": "GET /v1/calls/5f0c8a2e-3b7d-4c1e-9a64-2d8e1f7b0c93 (or the account_get_call tool) until status is succeeded or failed. You are charged only when it succeeds."
}
```

Poll `GET https://api.conecto.chat/v1/calls/<call_id>` (or call `account_get_call`) until `status` is `succeeded` or `failed`. When it succeeds, `output` holds the result:

```json
{
  "call_id": "5f0c8a2e-3b7d-4c1e-9a64-2d8e1f7b0c93",
  "tool": "import_from_zendesk",
  "area": "imports",
  "status": "succeeded",
  "cost_usd": "$0.004",
  "error": null,
  "message": null,
  "latency_ms": 4210,
  "at": "2026-10-14T08:00:00+00:00",
  "bot": "Pip",
  "person": null,
  "input": {
    "subdomain": "hansenvoss",
    "email": "tom.okafor@hansenvoss.example",
    "api_token": "[redacted]"
  },
  "output": {
    "source": "zendesk:hansenvoss",
    "done": true,
    "records_imported": 4,
    "imported": {
      "contacts": {
        "created": 2,
        "updated": 0,
        "unchanged": 0,
        "skipped": 0
      },
      "tickets": {
        "created": 2,
        "updated": 0,
        "unchanged": 0,
        "skipped": 0
      },
      "replies": {
        "created": 2,
        "updated": 0,
        "unchanged": 0,
        "skipped": 0
      }
    }
  }
}
```

`output`: When it finishes: source, done, records_imported, imported (per kind: created, updated, unchanged, skipped), and when more remain next_cursor, stopped_because and how to continue.

## Errors

| Code | Status | When | Fix |
|---|---|---|---|
| `credentials_refused` | 422 | Zendesk refused the email and token, they are not an agent's, or no Zendesk account answers at the subdomain. | Use an agent's or admin's email with an API token from the Admin Center, and check subdomain. |
| `invalid_input` | 400 | subdomain is not the name before .zendesk.com. | Send it like hansenvoss for hansenvoss.zendesk.com. |
| `vendor_unavailable` | 502 | The other service did not answer. | Try again in a few minutes, with the same next_cursor if you passed one; nothing was charged. |
| `in_progress` | 409 | An import from the same tool is running already. | Wait for it (account_get_call), then continue with the next_cursor it returns. |
| `invalid_cursor` | 400 | next_cursor is not one this import returned. | Pass back exactly the next_cursor of the last run, or leave it out to start again (nothing is duplicated). |

The refusals every tool can give (401 key, 402 balance, 429 limits) are on the errors page: https://conecto.chat/docs/errors.md

## Related

- [import_csv](https://conecto.chat/tools/imports/import_csv.md): Imports contacts or companies from a CSV, as text or a link, matching columns by their names; importing it again updates instead of duplicating. $0.001 per record imported (created or updated).
- [import_from_hubspot](https://conecto.chat/tools/imports/import_from_hubspot.md): Imports a HubSpot account in the background: companies, contacts, deals and notes, linked as they were. $0.001 per record imported (created or updated).
- [import_from_pipedrive](https://conecto.chat/tools/imports/import_from_pipedrive.md): Imports a Pipedrive account in the background: organizations, persons, deals, notes and activities, linked as they were. $0.001 per record imported (created or updated).
- [import_status](https://conecto.chat/tools/imports/import_status.md): What imports brought in so far, per source, and the last 10 import runs with their status, cost and next_cursor. Free up to 1,000,000 reads a month.
