---
title: "tawk.to to Helpshift Migration: A Technical Guide"
slug: tawkto-to-helpshift-migration-a-technical-guide
date: 2026-08-13
author: Roopi
categories: [Migration Guide, Help Desk]
excerpt: "A technical guide to migrating from tawk.to to Helpshift — covering data extraction, API mechanics, identity mapping, edge cases, and billing impact."
tldr: "No native migration path exists. Extract from tawk.to's gated API, transform chats into Helpshift Issues with correct identity, and plan for issue-based billing impact on every migrated record."
canonical: https://clonepartner.com/blog/tawkto-to-helpshift-migration-a-technical-guide/
---

# tawk.to to Helpshift Migration: A Technical Guide


# tawk.to to Helpshift Migration: A Technical Guide

> [!NOTE]
> **TL;DR:** Migrating from tawk.to to Helpshift means moving from a session-based web chat tool to a mobile-first, issue-centric customer service platform. There is no native migration path. You must extract data from tawk.to (manual export capped at 50 messages per batch, REST API available by request only), transform flat chat transcripts into Helpshift's Issue/Message hierarchy with proper user identity, and load via Helpshift's REST API. The hard parts: tawk.to API access is not guaranteed, anonymous visitor identity mapping, attachment re-hosting, historical timestamp fidelity is unproven, and Helpshift's issue-based billing charges for every migrated record.

Migrating from tawk.to to Helpshift is not a widget swap. It is a data model transformation — session-based, often anonymous web chats into persistent, identified, stateful issues on a mobile-first platform. There is no vendor-built connector, no shared data format, and no one-click import. Every tawk.to-to-Helpshift migration is a custom ETL project.

This guide covers the full technical path: data model differences, extraction methods and their real limitations, transformation logic, Helpshift import mechanics, edge cases, validation, and honest guidance on when full historical migration is not worth the cost.

*API behaviors and pricing change. Confirm against current vendor documentation before starting your migration.*

> **Disclosure:** ClonePartner offers managed migration services. This guide is written to be useful even if you execute the move in-house.

If you are evaluating other targets, see our [tawk.to to Zendesk guide](https://clonepartner.com/blog/blog/tawkto-to-zendesk-migration-a-technical-guide/) and [tawk.to to Freshchat guide](https://clonepartner.com/blog/blog/tawkto-to-freshchat-migration-a-technical-guide/).

## tawk.to vs. Helpshift: Data Model Differences

Understanding the structural gap is the foundation of any migration plan. The two platforms differ not just in features but in their fundamental data model.

**tawk.to** is a free live chat tool for websites. Its data model centers on **Properties** (sites), discrete **chat sessions**, **tickets**, and **contacts** (visitors). The free plan includes live chat, email ticketing, a hosted knowledge base, unlimited agents, and unlimited chat volume.

**Helpshift** is a mobile-first customer service platform built for apps and games using **issue-based pricing** — the Starter plan begins at $150/month and includes 250 issues, with each additional issue costing approximately $0.45. It organizes data around **Issues**, **Users**, **Apps**, **Custom Issue Fields (CIFs)**, **Tags**, and device **Metadata**.

| Concept | tawk.to | Helpshift |
|---|---|---|
| **Primary unit** | Chat session / Ticket | Issue |
| **User identity** | Visitor (often anonymous, cookie-based) | User Profile (identified via SDK uid or email) |
| **Grouping** | Properties (sites) | Apps |
| **Organization** | Tags | Tags + Custom Issue Fields (CIFs) |
| **Status model** | Open / Closed | 7 states: New Issue, New Issue for Agent, Waiting for Agent, Agent Replied, Pending Reassignment, Resolved, Rejected |
| **Attachments** | File URLs in chat messages | Attachments on Issues and Messages |
| **Custom fields** | Not natively supported (pre-chat form data only) | CIFs with typed values |
| **Knowledge base** | Hosted KB articles | FAQs organized in FAQ Sections |
| **Channels** | Web chat, email | In-app (iOS/Android/Unity), web chat, email |
| **Metadata** | IP, location, browser, OS | Device metadata (OS, app version, battery, device type) + Custom Data |

The biggest structural shift: tawk.to chats are ephemeral conversations tied to a browser session. Helpshift Issues are persistent, stateful objects with a rich lifecycle. Each tawk.to chat becomes a Helpshift Issue, but you need to decide how to map status, assign metadata, and bridge the identity gap.

**CIF limits worth knowing:** single-line text tops out at **255 characters**, multiline at **100,000**, the combined active+archived CIF count caps at **250**, and dropdown CIFs allow up to **1,000** options. ([support.helpshift.com](https://support.helpshift.com/hc/en/13-helpshift-technical-support/faq/979-custom-issue-fields-how-do-i-create-a-new-custom-issue-field/))

**Multi-property accounts:** tawk.to allows multiple Properties under one account. The natural Helpshift mapping is one App per Property. In practice, organizations with 10+ Properties frequently consolidate into fewer Helpshift Apps (grouping by product line or region) to reduce CIF duplication and simplify Smart View configuration. Decide this mapping before importing anything — changing it later requires re-creating all affected issues.

## Extracting Data from tawk.to

Getting data out of tawk.to is the first bottleneck. There are three extraction paths, each with real limitations.

### Method 1: Manual Dashboard Export

tawk.to's Inbox allows admins to select and export conversations. The export is delivered as a ZIP file containing JSON, sent to an email address.

**Constraints:**
- Limited to **50 messages per export batch** ([help.tawk.to](https://help.tawk.to/article/exporting-messages))
- Requires Admin access to the property
- Disabled properties must be re-enabled before exporting
- The download link in the email is accessible to anyone who has it — handle with care
- No programmatic access; purely manual, click-and-wait

This works for small datasets (hundreds of chats). For anything larger, it is operationally impractical.

Tickets can also be exported from the Inbox as JSON files delivered by email, with download links valid for **30 days**. ([help.tawk.to](https://help.tawk.to/article/exporting-tickets))

**tawk.to export JSON structure** (representative schema from manual exports):

```json
{
  "id": "chat-abc123",
  "status": "closed",
  "startedAt": "2023-11-14T09:22:11.000Z",
  "endedAt": "2023-11-14T09:35:47.000Z",
  "property": { "id": "prop-xyz", "name": "My Website" },
  "visitor": {
    "name": "Jane Doe",
    "email": "jane@example.com",
    "city": "Austin",
    "country": "US",
    "browser": "Chrome",
    "ip": "203.0.113.45"
  },
  "agents": [
    { "id": "agent-001", "name": "Alex", "email": "alex@company.com" }
  ],
  "tags": ["billing", "refund"],
  "messages": [
    {
      "id": "msg-001",
      "type": "msg",
      "sender": "visitor",
      "text": "Hi, I need help with my invoice.",
      "timestamp": "2023-11-14T09:22:30.000Z"
    },
    {
      "id": "msg-002",
      "type": "msg",
      "sender": "agent",
      "text": "Happy to help. What is the invoice number?",
      "timestamp": "2023-11-14T09:23:05.000Z"
    }
  ],
  "attachments": [
    {
      "id": "att-001",
      "name": "invoice.pdf",
      "mimeType": "application/pdf",
      "size": 45231,
      "url": "https://files.tawk.to/..."
    }
  ],
  "rating": { "value": 5, "comment": "Very helpful" }
}
```

Field notes for transformer authors:
- `messages [].type` includes `"msg"` (human), `"sys"` (system/trigger), and `"file"` (attachment notification)
- `messages [].sender` is either `"visitor"`, `"agent"`, or `"system"`
- Automated trigger messages have `sender: "system"` and often contain navigation events like `"Visitor navigated to /pricing"`
- The `visitor.email` field is absent entirely (not null) when the visitor is anonymous
- Timestamps are ISO 8601 in UTC

### Method 2: tawk.to REST API

tawk.to offers a REST API, but it is currently in **private beta** and requires explicit access approval. Once approved, you receive credentials and access to documentation that is not publicly available.

**What is known:**
- Uses HTTP Basic Authentication or OAuth2 (authorization code and implicit grant flows)
- All requests over HTTPS, responses in JSON
- Supports reading conversation history, managing properties, webhooks, and more
- Endpoint structure follows `https://api.tawk.to/v1/...`

**What is not publicly documented:**
- Rate limits
- Pagination behavior
- Full endpoint inventory
- Attachment download mechanics

> [!WARNING]
> **Access is not guaranteed.** tawk.to describes the REST API as available to partners. If your request is denied or delayed, you fall back to manual export or webhook capture. Plan for this.

### Method 3: Webhook-Based Capture (Forward-Looking Only)

tawk.to supports webhooks that fire on chat events — including `chat:end` and transcript delivery. The webhook payload includes chat details, visitor info, message history, and attachment metadata (file URL, name, MIME type, size). ([developer.tawk.to](https://developer.tawk.to/webhooks/))

**Representative webhook payload for `chat:end`:**

```json
{
  "event": "chat:end",
  "time": "2023-11-14T09:35:47.000Z",
  "property": { "id": "prop-xyz", "name": "My Website" },
  "chat": {
    "id": "chat-abc123",
    "status": "closed",
    "messages": [
      {
        "sender": { "type": "visitor" },
        "type": "msg",
        "text": "Hi, I need help with my invoice.",
        "timestamp": "2023-11-14T09:22:30.000Z"
      }
    ],
    "attachments": [
      {
        "name": "invoice.pdf",
        "mimeType": "application/pdf",
        "size": 45231,
        "url": "https://files.tawk.to/..."
      }
    ],
    "visitor": {
      "name": "Jane Doe",
      "email": "jane@example.com",
      "city": "Austin",
      "country": "US",
      "browser": "Chrome"
    }
  }
}
```

**Constraints:**
- **Forward-looking only** — captures new events, not historical data
- Signed with HMAC-SHA1 via the `X-Tawk-Signature` header
- 30-second timeout; retries for up to 12 hours on failure
- Your endpoint must be idempotent to handle duplicate deliveries

Webhooks are essential for **delta capture during migration** — catching new chats while you process historical data — but they cannot backfill anything.

### Contacts Export

Contacts can be exported separately as CSV via the tawk.to Dashboard (**Contacts → People → Export**). The CSV includes name, email, phone, location, IP address, and any custom fields from pre-chat forms. ([help.tawk.to](https://help.tawk.to/article/how-to-add-export-and-delete-contacts))

> [!TIP]
> **Practical approach:** Request REST API access immediately. While waiting for approval, manually export a representative sample to understand the JSON structure. If API access is denied, you are looking at manual export in batches of 50 or engaging a migration service with existing API access.

## Importing Data into Helpshift

Helpshift exposes a REST API at `https://api.helpshift.com/v1/{domain}/`. Authentication is HTTP Basic with your API key.

> [!WARNING]
> **The integrations feature is not enabled by default.** If you do not see the API section in your Helpshift dashboard, contact Helpshift support to enable it before starting any migration work. ([developers.helpshift.com](https://developers.helpshift.com/rest-api/getting-started/))

### Helpshift Sandbox Environment

Helpshift does not offer a self-serve sandbox. Test environments must be requested through your Helpshift Account Manager or implementation contact. If you are on a trial or paid plan, ask explicitly for a test App within your account — create a separate App (e.g., "Migration Test") and run all validation loads against it before touching your production App. Delete test issues after validation.

### User Import via User Hub Bulk APIs

Helpshift's **User Hub Bulk APIs** support importing end-user profile data asynchronously, with up to **10,000 payloads per request** and JSONL file upload recommended for larger jobs. ([developers.helpshift.com](https://developers.helpshift.com/rest-api/user-hub-bulk-apis/))

Loading user profiles before creating issues gives you better odds of correct history linkage than creating issues against half-formed profiles.

### Create Issue API

The primary import endpoint is `POST /v1/{domain}/issues`. Key parameters:

- `email` — end-user email (required for identity)
- `message-body` — initial message text
- `title` — issue title
- `app-id` — the Helpshift App to associate with (retrieve via `GET /apps`)
- `platform-type` — `"web"`, `"ios"`, `"android"`, etc.
- `tags` — JSON array of tag strings
- `meta` — JSON object of metadata key-value pairs
- `custom_issue_fields` — stringified JSON of CIF values
- `attachment` — file upload (multipart form data)

```python
import requests
import json

DOMAIN = "your-domain"
API_KEY = "your-api-key"

cifs = json.dumps({
    "legacy_tawk_id": {"type": "singleline", "value": "chat-12345"},
    "browser_type": {"type": "singleline", "value": "Chrome"}
})

payload = {
    "email": "user@example.com",
    "message-body": "Original chat message content",
    "title": "Migrated from tawk.to — Chat #12345",
    "app-id": "your_app_id",
    "platform-type": "web",
    "tags": json.dumps(["migrated", "tawkto"]),
    "meta": json.dumps({"source": "tawk.to", "original_chat_id": "12345"}),
    "custom_issue_fields": cifs,
    "author-name": "Jane Doe"
}

response = requests.post(
    f"https://api.helpshift.com/v1/{DOMAIN}/issues",
    auth=(API_KEY, ""),
    data=payload
)
print(response.status_code, response.json())
```

Helpshift's documentation states there is **currently no hard rate limit on the Create Issue API**, but you should estimate your requests-per-minute and share the number with your Helpshift Account Manager. Issue-based pricing means every created issue counts toward your monthly allotment and affects billing.

**Observed throughput note:** The absence of a documented rate limit does not mean unlimited throughput. Implement exponential backoff on any 429 or 503 response. A conservative starting point is 2–4 requests per second; increase gradually while monitoring for throttling signals.

### Set Issue Status

After creating an issue, you set its status in a separate call. To mark a migrated historical conversation as resolved:

```python
status_payload = {
    "state": "resolved"
}

response = requests.put(
    f"https://api.helpshift.com/v1/{DOMAIN}/issues/{issue_id}",
    auth=(API_KEY, ""),
    data=status_payload
)
print(response.status_code, response.json())
```

Valid state values: `new`, `in-progress`, `resolved`, `rejected`. Apply `resolved` to all historically closed tawk.to chats. Apply `new` or `in-progress` to any conversations that were open at cutover.

### Add Message API

For multi-message conversations, create the Issue first, then append messages using the returned `issue_id`:

```python
message_payload = {
    "message-body": "Follow-up message from agent",
    "message-type": "Text"
}

response = requests.post(
    f"https://api.helpshift.com/v1/{DOMAIN}/issues/{issue_id}/messages",
    auth=(API_KEY, ""),
    data=message_payload
)
```

Attachments can be included as multipart form data on both Create Issue and Add Message calls.

### FAQ Import

If you are moving tawk.to KB articles to Helpshift, the REST API supports creating **FAQs** and **FAQ Sections** programmatically via `POST /v1/{domain}/faqs` and `POST /v1/{domain}/faq-sections`. Map your tawk.to KB structure to Helpshift Sections before importing. Treat this as a separate workstream from conversation migration.

## Data Mapping: tawk.to → Helpshift

This is where migrations succeed or fail. Every field needs a deliberate mapping decision.

### Chat / Ticket → Issue Mapping

| tawk.to Field | Helpshift Field | Notes |
|---|---|---|
| Chat/Ticket ID | `meta.original_chat_id` | Store as metadata for audit trail and deduplication |
| Visitor name | `author-name` | Fall back to "Visitor" if anonymous |
| Visitor email | `email` | Required. Fabricate placeholder if missing (e.g., `visitor-{id}@migrated.tawkto`) |
| Chat messages (`type: "msg"`) | Issue messages | First message → Create Issue `message-body`. Subsequent → Add Message calls in chronological order |
| System messages (`type: "sys"`) | Omit or `meta` | Navigation events and trigger messages; strip or log to metadata |
| Chat status (Open) | State: `new` | Default for migrated active issues; set via status update call |
| Chat status (Closed) | State: `resolved` | Set via `PUT /issues/{id}` after creation |
| Tags | `tags` | Direct 1:1 mapping after lowercase/spacing cleanup |
| `startedAt` timestamp | `meta.original_timestamp` | Helpshift sets its own `created_at`; store original as metadata |
| Agent name | `meta.original_agent` | Agent assignment requires a valid Helpshift agent ID; name-only storage is the fallback |
| Attachments | `attachment` | Must be re-uploaded; tawk.to file URLs may expire |
| Visitor IP / Location | `meta` or CIF | Map to metadata or Custom Issue Fields |
| Rating | CIF (dropdown) or tag | Map to a dropdown CIF (e.g., values: 1–5) or tag (e.g., `rating-5`) |
| Pre-chat form data | CIF or `meta` | Use CIFs for routing-relevant data; metadata for everything else |
| Department | Queue, tag, or dropdown CIF | Pick one target and standardize before load |
| `visitor.browser` | CIF `browser_type` | Useful for debugging; map to singleline CIF |

### Identity Decision Tree for Each Visitor Record

```
Does visitor.email exist in tawk.to data?
├── YES → Use as Helpshift email primary key
│         Does a Helpshift user with that email already exist?
│         ├── YES → Issue will attach to existing user profile
│         └── NO  → New user profile created on first issue
└── NO  → Was pre-chat form data captured with an email field?
          ├── YES → Use that email value
          └── NO  → Is the visitor ID (cookie-based) stable and known?
                    ├── YES → Fabricate: visitor-{tawk_visitor_id}@migrated.tawkto
                    └── NO  → Fabricate: anonymous-{tawk_chat_id}@migrated.tawkto
                              Flag record in idempotency store as anonymous=true
                              for post-migration reporting exclusions
```

Document the fabrication pattern you choose. Agents who see `anonymous-abc123@migrated.tawkto` in their queue need to understand it is a placeholder, not a real user.

### Contact → User Mapping

Helpshift user profiles are created implicitly when an Issue is created with an `email` parameter. There is no standalone "create user" endpoint in the way traditional helpdesks work. The user record is built from the email, author-name, and metadata passed at issue creation time.

For bulk profile loading before issue creation, use the **User Hub Bulk APIs** described above.

Key implications:
- tawk.to contacts with **no email** require a fabricated email to create a Helpshift issue
- Duplicate contacts in tawk.to will be deduplicated by email in Helpshift automatically
- Contact custom fields from pre-chat forms should map to CIFs or metadata on the first issue

### The CIF Stringification Requirement

Helpshift requires Custom Issue Fields to be passed as a **stringified JSON object** in the API payload. Fields must be created in the Helpshift dashboard first, and the keys must match exactly.

```json
"custom_issue_fields": "{\"browser_type\":{\"type\":\"singleline\",\"value\":\"Chrome\"},\"is_premium\":{\"type\":\"boolean\",\"value\":\"true\"}}"
```

This double-encoding is a common source of import failures. Test it against a dedicated test App before running at scale. Specific failure modes to watch for:
- Key name mismatch (CIF key in dashboard vs. key in payload) → silently drops the field, no error returned
- Value exceeding 255 characters for singleline type → API error
- Boolean sent as `true` instead of string `"true"` → type mismatch rejection

### Encoding and Character Set Edge Cases

tawk.to chat transcripts frequently contain content that breaks naive JSON handling:
- **Emoji and Unicode:** Ensure your pipeline uses UTF-8 throughout. Python 3 handles this by default; verify your file I/O and HTTP client encoding explicitly.
- **Right-to-left text (Arabic, Hebrew):** Preserves correctly in UTF-8 JSON but may render oddly in Helpshift's agent UI depending on browser settings.
- **Newlines in message text:** tawk.to may encode these as `\n` or as literal line breaks. Normalize to `\n` before loading into Helpshift message bodies.
- **HTML entities:** Some tawk.to exports encode `<`, `>`, `&` as `&lt;`, `&gt;`, `&amp;`. Run all message text through an HTML entity decoder before loading.

## The Hard Part: Historical Replay Fidelity

Helpshift's public docs confirm `POST /issues` and `POST /issues/{issue-id}/messages`, but they do **not** describe a dedicated historical import mode with explicit controls for preserving original actor roles, original sent timestamps, or attachment replay semantics. ([developers.helpshift.com](https://developers.helpshift.com/rest-api/getting-started/))

There is a second wrinkle: Helpshift's "create an issue on behalf of a user" flow treats the first message as the user's issue details, and the user does **not** see that first message until your next reply in the thread. If your migration depends on replaying old transcripts as native historical threads, validate this behavior in both the agent UI and end-user UI before making promises. ([support.helpshift.com](https://support.helpshift.com/hc/en/13-helpshift-technical-support/faq/913-for-admin-how-do-i-create-an-issue-on-behalf-of-a-user/))

Because of these constraints, most tawk.to-to-Helpshift migrations fall into one of three patterns:

**Pattern 1: Live cutover only.**
Switch the widget and email routing. Keep tawk.to as a read-only archive for old history. Zero engineering on historical import. Appropriate when tawk.to data is mostly anonymous or has no ongoing operational value.

**Pattern 2: Summary import.**
Create one Helpshift issue per legacy chat or customer with a structured summary — original chat ID, date range, agent name, topic summary, source URLs to tawk.to archive, and any structured metadata (rating, tags, pre-chat form answers). Agents get context without full transcript replay. Issue count is lower than a full replay, which reduces billing impact. This is the most common choice for migrations where historical context matters but exact transcript fidelity does not.

**Pattern 3: Full replay.**
Re-create complete message threads in Helpshift via sequential Create Issue + Add Message calls. Only viable after sandbox tests confirm acceptable behavior for timestamps, authors, attachments, closed-state handling, and end-user visibility. The timestamp limitation is real: Helpshift sets `created_at` to the import time, not the original chat time. If timestamp ordering matters for compliance or SLA reporting, full replay requires storing original timestamps in metadata and accepting that Helpshift's native time fields will not reflect history accurately.

The summary import is often the best trade-off between engineering cost, billing cost, and operational value. That is an engineering judgment, not a vendor guarantee.

> [!WARNING]
> If you import resolved legacy conversations into user-visible history, review Helpshift's **Re-open Time Window** first. Helpshift documents a default **one-year** reopen window for resolved or rejected email/web issues. Old imported threads that look closed to your team may still be reopenable by end users. ([support.helpshift.com](https://support.helpshift.com/hc/en/13-helpshift-technical-support/faq/1168-what-is-re-open-time-window-and-how-do-i-use-it/))

## Edge Cases and Failure Modes

These are the issues that surface during real migrations.

### Anonymous Visitors

tawk.to allows fully anonymous chats — no name, no email. Helpshift requires an email to create an issue. Use the identity decision tree above. If you fabricate emails, document the pattern. You will need it for cleanup, reporting exclusions, and to avoid confusing agents who see phantom users in their queues.

### Attachment Re-hosting

tawk.to attachment URLs in export JSON or webhook payloads may be time-limited or require authentication. You must:

1. Download each attachment during extraction
2. Store locally or in cloud storage (S3, GCS) with original filenames and MIME types
3. Re-upload as multipart form data when creating the Helpshift Issue or Message

Do not assume tawk.to URLs will remain accessible after migration. If a download returns `404` or `403`, log the failure, append the broken URL as text to the message body, and continue. Track attachment failures separately for post-migration review.

### HTML vs. Plain Text

tawk.to transcripts may contain raw HTML or HTML entities. Helpshift's agent dashboard expects plain text or specific formatting. Raw HTML in a Helpshift message body renders as code. Run all messages through an HTML sanitizer (Python's `bleach` or `html.unescape()` for entity decoding, `BeautifulSoup` for tag stripping) before loading.

### Bot and Automated Messages

tawk.to captures all messages in a chat, including automated triggers, pre-chat form responses, and navigation tracking (e.g., `"Visitor navigated to /pricing"`). These appear in export JSON as `messages` entries with `sender: "system"` or `type: "sys"`.

Decide in advance:
- **Strip system messages entirely:** Cleanest agent view, loses some context
- **Import as metadata:** Append all system messages as a single `meta.system_events` JSON array on the issue, not as individual messages
- **Tag automated messages:** Include in message thread but prefix with `[AUTO]` for agent visibility

Pushing every system/bot message into Helpshift as individual messages clutters the agent view and, under issue-based billing, has a real cost if it inflates your issue count through confusion.

### Idempotency and Crash Recovery

If your script crashes halfway through 50,000 chats, restarting from the beginning creates duplicates. Maintain a local state store mapping `tawk_chat_id` to `helpshift_issue_id`.

Minimal SQLite schema:

```sql
CREATE TABLE migration_state (
    tawk_chat_id TEXT PRIMARY KEY,
    helpshift_issue_id TEXT,
    status TEXT,          -- 'created', 'messages_loaded', 'resolved', 'failed'
    is_anonymous INTEGER, -- 1 if fabricated email was used
    error_message TEXT,
    created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
    updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
```

Before creating each Issue, query the state store. If a row exists with `status = 'created'` or higher, skip to the next step. On completion of each stage, update the status. On failure, record the error and continue to the next record rather than halting the entire job.

### Issue-Based Billing Impact

Every issue created via the API counts toward your Helpshift bill. For a migration of 10,000 historical conversations, that is 10,000 issues. At ~$0.45 per overage issue on the Starter plan, that could add $4,500 in a single billing cycle. **Discuss migration-specific billing with your Helpshift Account Manager before starting.** Some accounts negotiate a migration window or bulk import exemption.

The summary import pattern (one issue per customer rather than one issue per chat) is one lever for reducing billing impact. If a single customer had 40 short chats over two years, a summary import creates one issue with context rather than 40 issues at $0.45 each.

### Helpshift's 50,000-Row Pagination Ceiling

Relevant if you are pulling data from Helpshift to verify imports: the `GET /issues` API enforces a ceiling where `page × page-size` must not exceed 50,000. With `page-size` of 1,000, you get 50 pages maximum. For datasets larger than 50K issues, use `created_since` and `created_until` time-range parameters to window your queries (a technique we also detail in our [Helpshift to Plain migration guide](https://clonepartner.com/blog/blog/helpshift-to-plain-migration-the-complete-technical-guide/)).

### Archived Issue Behavior

Helpshift automatically archives resolved or rejected issues after one year. Archived issues do not appear in Smart Views or Advanced Search and cannot be accessed through the regular Helpshift API. If legacy history must remain broadly searchable, keep a warehouse copy outside Helpshift. ([support.helpshift.com](https://support.helpshift.com/hc/ar/13-helpshift-technical-support/faq/932-for-admin-what-are-archived-issues-and-how-do-i-access-them/))

### CIF Not Populating (Silent Failure)

Helpshift does not return an error if a CIF key in your payload does not match a CIF defined in the dashboard — it silently drops the field. If your CIF values are not appearing on imported issues:
1. Confirm the CIF exists in the Helpshift dashboard (not archived)
2. Confirm the key in your payload exactly matches the CIF key (case-sensitive)
3. Confirm the type declaration in the payload (`"type": "singleline"`) matches the CIF type configured in the dashboard
4. Test the stringified JSON encoding against a single issue before batch loading

### Messages Out of Order

The Add Message API appends messages in the order you call it. There is no timestamp parameter to override insertion order. If your extraction produces messages out of chronological order (possible with concurrent webhook captures or unsorted batch exports), sort by `timestamp` ascending before building your API call sequence. Validate order on spot-checked issues after loading.

## Migration Sequence: Step by Step

### Step 1: Audit Your tawk.to Data

Before writing any code:

- Count total chats, tickets, and contacts per property
- Identify the percentage of anonymous vs. identified visitors
- Catalog tags in use
- Document pre-chat form fields and custom attributes
- Note attachment volume and average file sizes
- Determine which properties are being migrated and their target Helpshift App mapping

### Step 2: Choose the Identity Strategy

Use the identity decision tree above. Pick a stable primary key before loading anything. If your site has authenticated users, use that user ID as the primary key and keep email as secondary. If your tawk.to data is mostly anonymous visitor names and partial emails, be honest about the result: Helpshift will not magically deduplicate or connect history that the source never identified cleanly. ([support.helpshift.com](https://support.helpshift.com/hc/en/13-helpshift-technical-support/faq/906-for-admin-how-are-other-issues-identified-within-helpshift/))

### Step 3: Set Up Helpshift

- Create Helpshift Apps (one per tawk.to Property, or consolidated by product line)
- Enable the integrations feature and generate API keys
- Create a dedicated test App for validation runs
- Define Custom Issue Fields for structured data you want to carry over
- Set up tags that map to your tawk.to tag taxonomy
- Configure Web Chat and/or email forwarding
- Create FAQ Sections if migrating knowledge base content
- Confirm identity verification approach: Helpshift documents both a newer **User Hub JWT** flow for SDK X 10.4+/Web Chat and an older **HMAC-based** flow for legacy implementations ([support.helpshift.com](https://support.helpshift.com/hc/en/13-helpshift-technical-support/faq/887-web-chat-guide/))
- Discuss migration billing with your Account Manager before loading any records

### Step 4: Extract from tawk.to and Start Delta Capture

- Request REST API access or execute manual exports
- Export contacts as CSV
- Download all attachments and store locally or in cloud storage with original filenames
- Enable webhooks to capture new chats during the migration window
- Normalize exported data into a consistent intermediate format (recommended: JSONL, one record per line)
- Sort messages within each chat by timestamp ascending

### Step 5: Transform and Load (Against Test App First)

- Load user profiles via User Hub Bulk APIs first
- Run a sample of 50–100 records against your test App
- Validate CIF population, message ordering, attachment accessibility, and status assignment in the test App
- Fix encoding issues, CIF key mismatches, and HTML stripping before scaling up
- Create Issues via `POST /v1/{domain}/issues` with the first human message
- Append subsequent human messages via Add Message endpoint, in chronological order
- Upload attachments as multipart form data; log failures without halting
- Import FAQs and FAQ Sections if applicable
- Set issue state to Resolved via `PUT /issues/{id}` for historical closed conversations
- Track all operations in your idempotency store with status progression

### Step 6: Validate and Cut Over

- Compare total issue counts against source data
- Spot-check 5–10% of migrated issues for message completeness and ordering
- Run a specific check: filter `migration_state` for `is_anonymous = 1` and confirm those records are handled correctly in the agent UI
- Verify attachment accessibility in Helpshift
- Confirm CIF values populated correctly using a sample query
- Check that tags transferred accurately
- Validate user profiles for all identified contacts
- **Test from the end-user perspective** — not just the agent dashboard — paying attention to the "first message not visible until reply" behavior
- Run a final delta load from webhook-captured events
- Switch the website widget and email routing to Helpshift

## Realistic Timelines

| Migration Size | Estimated Duration | Notes |
|---|---|---|
| < 1,000 chats | 2–4 days | Manual export feasible; simple scripting |
| 1,000–10,000 chats | 1–2 weeks | API access strongly preferred; automation essential |
| 10,000–50,000 chats | 2–4 weeks | Requires batching, error handling, billing negotiation |
| 50,000+ chats | 4–8 weeks | Time-windowed extraction, staged loading, extensive validation |

These estimates assume a dedicated engineer and include extraction, transformation, loading, and validation. They do not include tawk.to API access approval wait time, which is unpredictable.

## When Not to Migrate Historical Data

Use this decision framework rather than defaulting to full migration:

```
Is more than 50% of your tawk.to chat volume anonymous (no email)?
├── YES → Skip full replay. Summary import or archive only.
└── NO  → Continue.

Is your Helpshift use case primarily mobile in-app, and your tawk.to 
data primarily web chat with no mobile context (device, app version)?
├── YES → Historical data has low operational value in Helpshift. Archive only.
└── NO  → Continue.

Will the billing cost of importing all historical issues (volume × $0.45 
overage) exceed 3 months of your current tawk.to spend?
├── YES → Consider summary import (one issue per customer) to reduce count.
└── NO  → Full import may be viable. Confirm with Account Manager.

Do you need more than 90 days of history for compliance?
├── NO  → Set a 90-day cutoff. Archive the rest in tawk.to or a data warehouse.
└── YES → Proceed with full import for the compliance window; archive the rest.
```

A common pattern: migrate only contacts and open conversations, set a cutoff date, and maintain tawk.to data separately for reference access.

## DIY vs. Managed Migration

**Build it yourself** if:
- You have a senior engineer with 1–2 weeks of availability
- Your dataset is small (< 5,000 chats)
- You have tawk.to REST API access already approved
- You are comfortable with Helpshift's API documentation and billing model
- Your anonymous visitor percentage is low (< 20%)

**Consider a managed service** if:
- You do not have tawk.to API access and cannot afford the delay
- Your dataset exceeds 10,000 conversations
- You need zero data loss guarantees
- You have complex CIF mapping or identity normalization requirements
- You cannot afford to have engineers tied up for weeks on migration plumbing

## What to Get Right

The tawk.to-to-Helpshift migration is fundamentally a data model transformation. Success depends on three things: getting tawk.to data out (not guaranteed to be easy), mapping identity correctly (especially for anonymous visitors), and having an honest conversation about how much historical fidelity you actually need versus what it will cost in Helpshift billing.

The five most common failure modes, in order of frequency:
1. **Anonymous visitor identity** — no email means no clean Helpshift user, and fabricated emails require ongoing documentation discipline
2. **CIF silent failures** — key mismatches drop data without errors; always validate on a test App before batch loading
3. **Message ordering** — unsorted extraction produces transcripts that read backward in the agent UI
4. **Attachment URL expiry** — tawk.to file URLs accessed weeks after export may return 403; download during extraction, not during loading
5. **Billing surprise** — 10,000 historical issues at $0.45 each is $4,500; negotiate before loading, not after

Get the identity mapping, message ordering, and billing agreement right, and the rest is engineering. Get any of them wrong, and you spend weeks cleaning up phantom users, unreadable transcripts, and unexpected invoices.

For Helpshift-specific export strategies, see our guide on [how to export data from Helpshift](https://clonepartner.com/blog/blog/how-to-export-data-from-helpshift-api-limits-methods-portability/).

> Need help migrating from tawk.to to Helpshift? ClonePartner handles the full migration — extraction, transformation, loading, and validation. Book a free technical consultation.
>
> [Talk to us](https://cal.com/clonepartner/meet?duration=30)

## Frequently asked questions

### Can I migrate from tawk.to to Helpshift automatically?

No. There is no native migration path, vendor-built connector, or one-click import between tawk.to and Helpshift. Every migration requires custom scripting to extract data from tawk.to, transform it to match Helpshift's data model, and load it via Helpshift's REST API.

### How do I export chat history from tawk.to?

Three methods: manual dashboard export (limited to 50 chats per batch, delivered as JSON via email), tawk.to's REST API (private beta, requires access approval), or webhooks (forward-looking only, cannot backfill historical data). For bulk migration, REST API access is recommended but not guaranteed.

### Does Helpshift charge for migrated issues?

Yes. Helpshift uses issue-based pricing, so every issue created via the API counts toward your monthly allotment. At approximately $0.45 per overage issue on the Starter plan, migrating 10,000 historical conversations could cost $4,500. Negotiate a migration window with your Helpshift Account Manager before starting.

### How do I handle anonymous tawk.to visitors in Helpshift?

Helpshift requires an email to create an issue. For anonymous tawk.to visitors, you can fabricate placeholder emails (e.g., anonymous-{visitor_id}@migrated.local), skip anonymous chats entirely, or use a single catch-all email. Document whatever pattern you use for later cleanup and reporting exclusions.

### Will Helpshift preserve original timestamps from tawk.to chats?

Helpshift's public API docs do not describe a dedicated historical import mode that preserves original sent timestamps or actor roles. Helpshift sets its own created_at on issues and messages. Store original timestamps in metadata for audit purposes and validate the behavior in a sandbox before committing to full replay.
