---
title: "How to Export Data from Close: Methods, API Limits & Formats"
slug: how-to-export-data-from-close-methods-api-limits-formats
date: 2026-07-31
author: Raaj
excerpt: "Complete guide to exporting data from Close CRM. Covers native CSV/JSON export, REST API endpoints, Export API, rate limits, pagination, attachments, and data portability."
tldr: "Close lets you export most CRM data via UI or API, but full activity history requires JSON, attachments need separate API calls, and call recordings expire by plan tier."
canonical: https://clonepartner.com/blog/how-to-export-data-from-close-methods-api-limits-formats/
---

# How to Export Data from Close: Methods, API Limits & Formats


## What Data Can You Export from Close?

Close is a **Lead-centric CRM**. Every object — Contacts, Opportunities, Tasks, Activities — lives inside a parent Lead. That hierarchy controls what you can export, how you export it, and what gets lost in the process.

If you flatten that structure too early (e.g., exporting to CSV), your export becomes easy to download and hard to migrate. Understanding what Close exposes — and through which channel — is the first step to planning any extraction.

**Smart Fields** are calculated fields that Close computes per lead, such as total call count, email count, days since last inbound email, or total revenue across opportunities. They are not stored as raw data but generated on request. They appear in the native UI export under "All Fields" and can be included in Export API calls via the `include_smart_fields: true` flag.

| Object | Native UI Export | API Export | Export Format | Known Limitations / Gaps |
|---|---|---|---|---|
| **Leads** | Yes | Yes (`GET /api/v1/lead/`) | CSV, JSON | JSON is the most complete route; activities excluded unless using the Export API with `include_activities=true`. ([developer.close.com](https://developer.close.com/api/resources/exports/create-lead)) |
| **Contacts** | Yes (via Leads export) | Yes (`GET /api/v1/contact/`) | CSV, JSON | CSV export starts from the Leads page only — Contact Smart Views have no export button. Lead-level custom fields not included in Contact exports. ([help.close.com](https://help.close.com/docs/exporting-data)) |
| **Opportunities** | Yes (Opportunities list view) | Yes (`GET /api/v1/opportunity/`) | CSV, JSON | Can filter by pipeline, status, date, assigned user. Historical stage change logs require API extraction. |
| **Tasks** | No | Yes (`GET /api/v1/task/`) | JSON | No native UI export; API only. |
| **Notes** | Partial (JSON Leads export only) | Yes (`GET /api/v1/activity/note/`) | JSON | Not available in CSV lead exports. Note attachments can be exported as a separate ZIP via support tools. |
| **Emails** | Partial (subject/preview in CSV) | Yes (`GET /api/v1/activity/email/`) | CSV (summary), JSON (full) | CSV gives subject and preview only, not full email body. Full body requires API or JSON export. |
| **Calls** | Partial (metadata in CSV) | Yes (`GET /api/v1/activity/call/`) | CSV (summary), JSON (full) | Call recordings are separate audio files with plan-dependent retention: 30 days (Solo/Essentials), 90 days (Growth), unlimited (Scale). |
| **SMS** | Yes (via support tools) | Yes (`GET /api/v1/activity/sms/`) | CSV, JSON | MMS media is separate; attachment URLs require an authenticated session and redirect to signed S3 URLs. |
| **WhatsApp Messages** | No | Yes (`GET /api/v1/activity/whatsapp/`) | JSON | API only. |
| **Meetings** | Yes (via support tools) | Yes (`GET /api/v1/activity/meeting/`) | CSV, JSON | Support tool provides CSV; can filter by Smart View and date range. |
| **Custom Activities** | Partial (JSON Leads export) | Yes (`GET /api/v1/activity/custom_activity/`) | JSON | Support tool exports one CSV per custom activity type. Not in CSV lead exports. |
| **Custom Objects** | No | Yes (`GET /api/v1/custom_object/`) | JSON | Growth plan and above only. Back references are not included in API responses — must be reconstructed via Custom Object Type metadata and Advanced Filtering. ([developer.close.com](https://developer.close.com/api/resources/custom-objects/list)) |
| **Files / Attachments** | No | Yes (via Activity API + file download) | Binary (signed S3 URL) | Requires separate download per file; not bundled in any native export. |
| **Email Templates** | Yes (via support tools) | Yes (`GET /api/v1/email_template/`) | CSV, JSON | Includes shared and own private templates; excludes other users' private templates. |
| **Smart Views** | Yes (via support tools) | Yes (`GET /api/v1/saved_search/`) | CSV, JSON | Includes shared and own private views; excludes other users' private views. ([help.close.com](https://help.close.com/docs/exporting-data)) |
| **Custom Fields** | Yes (via support tools) | Yes (`GET /api/v1/custom_field/`) | CSV, JSON | API exports return values as `custom.cf_XXXXX` keys — map to human-readable names via the Custom Fields API. |
| **Users** | No | Yes (`GET /api/v1/user/`) | JSON | API only. Does not include passwords or granular permission configurations. |
| **Roles** | No | Yes (`GET /api/v1/role/`) | JSON | API only. |
| **Sequences (Workflows)** | No | Yes (`GET /api/v1/sequence/`) | JSON | Step definitions and subscription data are readable; export is API-only. Conditional logic requires manual review. |
| **Event Log (Audit)** | No | Yes (`GET /api/v1/event/`) | JSON | Cursor-based pagination. Only the last 30 days are available; support-tool export capped at 100,000 events. ([developer.close.com](https://developer.close.com/resources/event-log/retrieve-events/)) |
| **Pipelines / Statuses** | No | Yes (`GET /api/v1/pipeline/`, `/status/lead/`, `/status/opportunity/`) | JSON | Configuration data, API only. |

[For engineering] When you fetch a Lead via the API, the response includes contacts, tasks, opportunities, and custom fields — but **activities are excluded and must be fetched separately** via the Activities endpoints. This is the most common source of incomplete exports.

[For customer success] The CSV export from the UI gives you a clean spreadsheet of leads and contacts with custom field values intact. But if you need the actual email thread content, call notes, or SMS messages, you need JSON or the API.

## How to Export Data from Close: Every Method Compared

There are multiple paths for getting data out of Close. The right choice depends on your data volume, coverage requirements, and whether you have developer resources.

| Method | Data Coverage | Volume Limit | Speed | Complexity | Best For |
|---|---|---|---|---|---|
| **Native UI Export** | Leads, Contacts, Opportunities | No hard limit; >100K may timeout | Minutes to hours | Low | Quick one-time pulls, spreadsheet analysis |
| **Support Tools** (help.close.com) | Emails, SMS, Templates, Smart Views, Custom Fields, Notes, Phone Numbers, Meetings | No published limit | Minutes | Low (requires API key) | Targeted exports of specific object types without code |
| **Export API** (`POST /export/lead/`) | Leads + nested data, Opportunities (async) | No published limit; GZIP compressed | Minutes to hours (async) | Medium | Programmatic bulk exports, scheduled backups |
| **REST API** (endpoint-by-endpoint) | All objects | 100 records/page; deep pagination via date windowing | Depends on rate limits | High | Full-fidelity extraction, migrations, attachment download |
| **Webhooks** (`POST /api/v1/webhook/`) | Real-time event notifications for creates, updates, deletes | N/A (event-driven) | Real-time | Medium | Continuous sync to external systems, streaming to data warehouses |
| **Third-Party ETL** (Coefficient, Zapier, Make) | Leads, Contacts, Opportunities, Activities | Varies by tool | Varies | Low–Medium | Recurring syncs, dashboard feeds |
| **Managed Export Service** | All objects + attachments | Unlimited | Days | Low (for you) | Full migrations, compliance exports |

### Webhooks as an Alternative Extraction Path

Close supports webhooks that send real-time HTTP POST notifications when objects are created, updated, or deleted. Register webhooks via `POST /api/v1/webhook/` specifying the target URL and event types. This is not a batch export method — it's a streaming alternative. Webhooks are useful for maintaining a continuously-synced mirror of Close data in an external warehouse, which eliminates the need for periodic bulk exports. The webhook payload includes the changed object's data, so your receiving endpoint can store it directly. Webhooks don't retroactively send historical data; they only capture events from the moment of registration forward. For a full historical export plus ongoing sync, combine a one-time REST API extraction with webhooks for incremental updates.

[For PMs] The native UI export and support tools require **zero engineering resources** — any admin with an API key can run them. The Export API needs a developer for initial setup but runs unattended after that. Full REST API extraction always requires a developer. Webhooks require a developer plus a receiving endpoint (e.g., a simple web server or serverless function).

## Native UI Export: Step-by-Step

Close's built-in exporter lives in the search/Smart View interface. It's the fastest path for anyone who doesn't write code.

1. Navigate to the **Leads** page in Close (the left sidebar).
2. Select or create a **Smart View** that filters the leads you want. Only Leads-based Smart Views support export — Contact-based Smart Views do not show the export button.
3. Click the **⋯ (more) > Export** button at the top right of the lead list.
4. Choose your **export type**: `leads` (one row per lead) or `contacts` (one row per contact).
5. Choose your **format**: CSV or JSON. JSON is recommended for raw backups or data migrations.
6. Choose your **field scope**: "Fields in current view," "Common fields," or "All fields."
7. Click **Export**. Close generates the file server-side and emails you a download link.
8. The download link **expires after 7 days**. The exported file is GZIP compressed.

> [!WARNING]
> **CSV exports cannot carry activity history.** Email bodies, call logs, SMS content, notes, and custom activities are only included in JSON exports. If you export as CSV, you get lead/contact metadata and opportunity data — not the communication history underneath.

**What "All Fields" includes:** Common fields plus address information, activity date summaries (last SMS, email, call, task dates), primary opportunity data, and Smart Fields (calculated fields like total call count, email count, days since last inbound email, or total revenue per lead). Smart Fields require the `include_smart_fields: true` flag when using the Export API.

**What native export misses:**
- Full email body content (CSV gives subject/preview only)
- Call recording audio files
- File attachments
- Custom Object instances
- Task details (no native export path)
- WhatsApp messages
- Relationship context between contacts and opportunities on the same lead

**Export timing:** Small exports (under 5,000 leads) typically complete in under 5 minutes. Exports over 100,000 records can be slow or occasionally timeout. The practical workaround is to split large exports into date-based batches of 20,000–30,000 records.

**Data freshness:** The native export reads from Close's live database. Records created or modified during a long-running export may or may not appear in the output, depending on where the export cursor was when the change occurred. There is no point-in-time snapshot guarantee. For consistency-critical extractions, pause CRM writes during the export window or validate post-export by comparing record counts and checking `date_updated` timestamps against the export start time.

**The CSV flattening problem:** Because Close nests Contacts under Leads, a CSV export forces a flat structure. If Lead A has Contact 1, Contact 2, and Contact 3, the CSV either generates three separate rows for Lead A (duplicating the company data) or appends secondary contacts into numbered columns (e.g., `Contact 2 Name`, `Contact 2 Email`). Before importing this data into a Contact-centric CRM like HubSpot or Salesforce, you must split the Leads and Contacts into separate relational tables.

### Exporting Opportunities from the UI

Opportunities have their own export path. Go to the **Opportunities List View** (not the Leads page), apply filters by pipeline, status, date, or assigned user, and use the Export button. This is the most reliable way to get a clean opportunity-level CSV without lead-level nesting.

## Close Support Tools: Zero-Code Gap Filling

Close provides a set of self-service support tools at help.close.com that cover data types the native UI exporter doesn't reach. These tools require an API key (generated at **Settings → Developer → API Keys**) but no programming — any admin can use them. ([help.close.com](https://help.close.com/docs/close-support-tools))

What you can export via support tools:

- **Email messages** as CSV (with date, direction, and status filters — but attachments are excluded)
- **SMS messages** as CSV with date, direction, and status filters
- **Notes** with an optional attachment ZIP download
- **Meeting data** as CSV
- **Email and SMS templates** (shared + your own private templates; other users' private templates excluded)
- **Smart View definitions** (shared + your own private views; other users' private views excluded)
- **Custom field definitions** with type filtering
- **Phone number configurations** with user info and forwarding details
- **Lead files** as a ZIP grouped by lead name and ID
- **Custom activities** — one CSV per custom activity type
- **Event log** — limited to the last 30 days and capped at 100,000 events

These tools are the fastest path for admin-led data extraction when the native exporter falls short. For many RevOps teams, the combination of UI export + support tools covers 80% of what they need without involving a developer.

## Export API: Async Bulk Export

Close provides an asynchronous Export API purpose-built for large-scale extractions. This is distinct from the regular REST list endpoints and is the officially recommended path for bulk exports and backups. ([developer.close.com](https://developer.close.com/api/resources/exports/create-lead))

Use `POST /api/v1/export/lead/` for lead-based exports and `POST /api/v1/export/opportunity/` for opportunity exports. The API returns an export job ID — you poll it until `status=done` and `download_url` is populated. Export files are GZIP compressed.

**Key configuration flags:**
- `format`: `json` (recommended) or `csv`
- `type`: `leads` or `contacts`
- `include_activities`: set to `true` to include activity data in the export — **this is not enabled by default**
- `include_smart_fields`: set to `true` for calculated fields
- `date_format`: use `iso8601` for timezone fidelity; `excel` forces UTC-style formatting and drops timezone context
- `send_done_email`: set to `false` if you're polling programmatically

**Snapshot behavior:** The Export API reads from Close's live database during generation. It does not create a consistent point-in-time snapshot. For large orgs, records may be created or updated between when the export starts and when it completes. If consistency is critical, compare `date_updated` timestamps in the export against the job creation time and re-fetch any records that changed during the export window.

```python
import gzip, io, json, time, requests

BASE = 'https://api.close.com/api/v1'
AUTH = ('your_api_key_here', '')

payload = {
    'format': 'json',
    'type': 'leads',
    'date_format': 'iso8601',
    'include_activities': True,
    'include_smart_fields': True,
    'send_done_email': False,
}

job = requests.post(f'{BASE}/export/lead/', json=payload, auth=AUTH).json()
export_id = job['id']

while True:
    r = requests.get(f'{BASE}/export/{export_id}/', auth=AUTH)
    if r.status_code == 429:
        time.sleep(float(r.headers.get('retry-after', '1')))
        continue
    meta = r.json()
    if meta['status'] == 'done' and meta['download_url']:
        blob = requests.get(meta['download_url'], auth=AUTH)
        export_data = json.load(gzip.GzipFile(fileobj=io.BytesIO(blob.content)))
        break
    time.sleep(2)
```

The Export API is the best single method for getting the most data with the least code. But it still doesn't include attachments, call recording audio files, custom object instances, or event log data — those require separate extraction via the REST API or support tools.

## REST API: Full-Fidelity Endpoint-by-Endpoint Extraction

[For engineering] When the Export API isn't enough — when you need attachments, custom objects, event logs, or granular control over every object type — you use the REST API directly. Every object in Close is accessible via `https://api.close.com/api/v1/`.

### Authentication

Close supports two authentication methods:
- **API Key** (HTTP Basic Auth): Best for internal scripts. Generate at **Settings → Developer → API Keys**. The API key goes in the username field; leave the password blank. API keys do not expire automatically, but they can be revoked by any admin at any time. For multi-hour extraction runs, verify the key is active before starting, and avoid sharing the key across concurrent processes that might trigger revocation alerts.
- **OAuth 2.0**: For public-facing applications. Provides scoped access on behalf of users. Tokens require periodic refresh.

### Core Endpoints

| Object | Endpoint | Method |
|---|---|---|
| Leads | `/api/v1/lead/` | GET |
| Contacts | `/api/v1/contact/` | GET |
| Opportunities | `/api/v1/opportunity/` | GET |
| Tasks | `/api/v1/task/` | GET |
| Notes | `/api/v1/activity/note/` | GET |
| Calls | `/api/v1/activity/call/` | GET |
| Emails | `/api/v1/activity/email/` | GET |
| Email Threads | `/api/v1/activity/emailthread/` | GET |
| SMS | `/api/v1/activity/sms/` | GET |
| WhatsApp | `/api/v1/activity/whatsapp/` | GET |
| Meetings | `/api/v1/activity/meeting/` | GET |
| Custom Activities | `/api/v1/activity/custom_activity/` | GET |
| Custom Objects | `/api/v1/custom_object/` | GET |
| Events (Audit Log) | `/api/v1/event/` | GET |
| Sequences | `/api/v1/sequence/` | GET |
| Users | `/api/v1/user/` | GET |
| Roles | `/api/v1/role/` | GET |
| Webhooks | `/api/v1/webhook/` | GET, POST |

### Pagination

Close uses two pagination strategies, and choosing the right one matters for large exports:

**Offset-based** (`_skip` / `_limit`): Used by most list endpoints. Maximum of **100 records per page**. The response includes a `has_more` boolean. There is a **maximum `_skip` value per resource** — exceed it and you get a 400 error. For deep pagination through large datasets, offset-based pagination eventually becomes impossible.

**Cursor-based**: Used by the Events API and Advanced Filtering API. Pass a `cursor` token from the previous response to fetch the next page. This avoids data-shift issues between requests. Advanced Filtering cursors expire after 30 seconds and have a hard 10,000-object limit per paginated query, so large jobs need to be split into smaller filter windows.

**Deep pagination workaround:** For large exports (all leads, contacts, or activities), Close's own documentation recommends using the `date_created` field as a sliding window. Make multiple requests while incrementing the date range. This avoids hitting the `_skip` ceiling that breaks naive offset loops. ([developer.close.com](https://developer.close.com/api/resources/leads/list))

### Rate Limits

Close enforces rate limits **per endpoint group**, not globally. The following figures are observed from API response headers and consistent with Close's documentation, though Close does not publish granular per-endpoint breakdowns:

- **Per API key**: ~20 requests per second (RPS) for a given endpoint group (observed via `RateLimit-Limit` response headers)
- **Per organization**: ~60 RPS (3× the per-key limit), meaning three API keys can hit max RPS simultaneously before the org limit kicks in
- **429 response**: Includes `RateLimit-Limit`, `RateLimit-Remaining`, and `RateLimit-Reset` headers, plus a `Retry-After` header specifying wait time in seconds
- **No published per-minute or per-day cap**: Close does not document cumulative daily limits, only per-second burst limits

Close does not publicly document whether rate limits vary by subscription plan. All observed rate limit values referenced here are from the Professional/Business tier. Solo or Startup plans may have lower thresholds. ([developer.close.com](https://developer.close.com/api/overview/rate-limits))

### Common API Error Codes During Export

| HTTP Code | Cause | Resolution |
|---|---|---|
| **400** | `_skip` value exceeds maximum for the resource, or malformed query parameters | Switch to date-windowing pagination; validate query syntax |
| **401** | Invalid or revoked API key | Regenerate key at Settings → Developer → API Keys |
| **403** | Insufficient permissions (e.g., accessing admin-only endpoints with a restricted key) | Use an admin-level API key or adjust role permissions |
| **404** | Resource ID doesn't exist or has been deleted | Skip and log; deleted records cannot be recovered |
| **422** | Validation error (e.g., invalid field name in query) | Check field names against the Custom Fields API response |
| **429** | Rate limit exceeded | Read `Retry-After` header; implement exponential backoff |
| **500 / 502 / 503** | Server-side error or temporary outage | Retry with exponential backoff; check [status.close.com](https://status.close.com) for incidents |

### Throughput Math

At a sustained, rate-limit-safe pace of ~15 RPS (leaving headroom below the ~20 RPS per-key limit) with 100 records per page:
- **~5,400 pages/hour → ~540,000 records/hour** for a single object type
- A 50,000-lead org with 200,000 activities across all types: roughly 1–2 hours for a complete API extraction, accounting for rate limit pauses and retries

API extraction is rarely the bottleneck. The bottleneck is normalizing the nested JSON into your destination data model.

### Sample REST API Export Script (Python)

```python
import requests
import time
from datetime import datetime, timedelta

API_KEY = "your_api_key_here"
BASE_URL = "https://api.close.com/api/v1"

def export_leads_by_date_window(start_date, end_date, limit=100):
    """Export all leads using date_created windowing for deep pagination.
    
    This avoids the _skip ceiling (400 error) that breaks naive offset loops
    on datasets larger than ~10,000 records per query.
    """
    all_leads = []
    current_start = start_date
    
    while current_start < end_date:
        current_end = current_start + timedelta(days=30)
        if current_end > end_date:
            current_end = end_date
        
        skip = 0
        has_more = True
        while has_more:
            params = {
                "_skip": skip,
                "_limit": limit,
                "date_created__gte": current_start.isoformat(),
                "date_created__lt": current_end.isoformat(),
            }
            resp = requests.get(
                f"{BASE_URL}/lead/",
                params=params,
                auth=(API_KEY, ""),
            )
            if resp.status_code == 429:
                wait = float(resp.headers.get("retry-after", 5))
                print(f"Rate limited. Waiting {wait}s...")
                time.sleep(wait)
                continue
            if resp.status_code >= 500:
                # Server error — retry with backoff
                time.sleep(10)
                continue
            resp.raise_for_status()
            data = resp.json()
            all_leads.extend(data["data"])
            has_more = data.get("has_more", False)
            skip += limit
            time.sleep(0.07)  # ~14 RPS with headroom
        
        current_start = current_end
    
    return all_leads
```

This pattern — date windowing + offset pagination within each window — is the standard approach recommended in Close's API docs and avoids the `_skip` ceiling that breaks naive offset loops.

## Does Close Export Include Attachments?

No. Close does not include file attachments in any native export — CSV, JSON, or Export API. Attachments must be extracted separately, and the path varies by attachment type.

**Email attachments:** Available in email activity API responses as URL references in the `attachments` array. Each file must be downloaded individually via an authenticated GET request. The email messages CSV export from support tools does not include attachments. ([help.close.com](https://help.close.com/technical-support/close-support-tools))

**Note attachments:** The Notes support tool can export note attachments as a separate ZIP file. The Note API also exposes an `attachments` array with URLs and thumbnails.

**Lead files:** The `Download Lead Files` support tool packages files into folders organized by lead name and ID — the simplest bulk path for lead-associated documents.

**SMS/MMS media:** Attachment URLs require an authenticated session and redirect to temporary signed S3 URLs. These URLs expire (typically within hours), so download promptly after retrieval.

**Call recordings:** Stored as audio files linked to call activity records. The recording URL appears in the call activity JSON, but the audio file itself has plan-dependent retention.

> [!CAUTION]
> **Call recording retention is a hard data-loss cliff.** Recordings are permanently deleted after the retention window: 30 days on Solo/Essentials, 90 days on Growth, unlimited on Scale. There's no archive or recycle bin. Export recording URLs and download the audio files before they expire. Transcript data may persist even after recordings are deleted.

**Inline images** in emails are typically stored as base64-encoded data within the email body HTML. They survive a JSON export but not a CSV export.

When running a bulk attachment download, ensure your script:
1. Handles network timeouts and retries with exponential backoff
2. Stores files with a naming convention that maps back to the original Lead ID and Activity ID (e.g., `{lead_id}_{activity_id}_{filename}`)
3. Logs successful downloads against a manifest for verification
4. Handles signed URL expiration by re-fetching the activity record for a fresh URL if the download fails

Without that mapping, downloaded files become orphaned and impossible to reassociate with their source records.

## What Data Cannot Be Exported from Close?

Every platform has export gaps. Here's what you cannot get out of Close through any official method:

| Data Type | Exportable? | Workaround |
|---|---|---|
| **Deleted records** | No | No API endpoint for soft-deleted data; once deleted, it's gone permanently. Mirror data to an external warehouse to preserve deletion history. |
| **Audit trail older than 30 days** | No | Mirror events to your own data warehouse on a daily schedule via the Event Log API |
| **Other users' private Smart Views** | No | Convert business-critical views to shared before export |
| **Other users' private templates** | No | Standardize on shared templates before migration |
| **Integration configurations** | No | Must be manually recreated in the target system |
| **Workflow/Sequence conditional logic** | Partially | Sequence definitions are readable via `GET /api/v1/sequence/`, but action templates and conditional branching require manual review and re-creation |
| **Dashboard/Report configurations** | No | Reports must be rebuilt manually; no export of saved report definitions |
| **Connected account credentials** | No | OAuth tokens and email sync configs can't be extracted (expected security boundary) |
| **Expired call recordings** | No | Once past retention (30/90 days depending on plan), permanently deleted |
| **Custom object back references** | No | `/custom_object/` responses omit back references; rebuild links using Custom Object Type metadata (`GET /api/v1/custom_object_type/`) and Advanced Filtering queries scoped to specific object types |

**What Close handles better than most CRMs:** Pipelines, lead statuses, opportunity statuses, custom field definitions, roles, groups, and sequence definitions are all readable via the API. The Event Log API (`GET /api/v1/event/`) captures most object-level changes (creates, updates, deletes) and serves as a partial audit trail. Close explicitly states that they believe customers should own their data — and the API access generally reflects that principle.

## Data Format, Encoding, and Cleanup After Export

**JSON vs. CSV:** Use JSON for backup or migration and CSV for flat analysis. JSON preserves nested relationships and is the only format that includes complete activity data in a lead export. CSV is convenient for spreadsheets but lossy for any relational data.

**Encoding:** Close exports use UTF-8 encoding. Custom field values with commas or newlines are properly quoted in CSV.

**Date formats:** Close uses ISO 8601 timestamps (`2026-07-15T14:30:00.000000+00:00`). All timestamps are UTC. Do not convert these in Excel — you risk shifting activity dates by a day depending on your local timezone. The Export API supports `iso8601`, `original`, and `excel` date formats for CSV output; use `iso8601` if timezone fidelity matters, because `excel` forces UTC-style spreadsheet formatting and drops timezone context.

**Custom field IDs:** API exports return custom field values as `custom.cf_XXXXX` keys. To map these to human-readable names, cross-reference with the Custom Fields API (`GET /api/v1/custom_field/lead/`, `/contact/`, `/opportunity/`). The old `custom` dict format in API responses is deprecated. ([developer.close.com](https://developer.close.com/resources/custom-fields/shared-custom-fields/))

**HTML in text fields:** Email activities contain raw HTML in the `body_html` field. Notes may contain HTML in `note_html`. If your destination CRM only accepts plain text, strip the HTML tags during the transformation phase. Keep the rich-text version if the target supports it — downgrade on purpose, not by accident.

**Lead-Contact relationships in CSV:** CSV exports flatten the Lead→Contact hierarchy. Each contact row includes a `lead_id` column as the only link back to the parent lead. If your destination expects a different hierarchy (which it almost certainly does), you'll need to reconstruct relationships post-export.

**Destination import format compatibility:** After export, the next question is what your target system accepts. HubSpot imports CSV with a 250MB file size limit per import and requires separate imports for Contacts, Companies, and Deals with association columns. Salesforce accepts CSV via Data Loader (up to 5 million records per batch) or JSON via the Bulk API 2.0. Pipedrive accepts CSV via its import wizard with a 50,000-row limit per file. GoHighLevel accepts CSV for contacts only and requires API integration for opportunities and activities. Plan your export file splits and column mappings based on the destination's constraints, not just Close's output format.

[For PMs] **Post-export validation checklist:**

- [ ] Verify row counts match expected record counts per object type (compare against Close's Smart View totals)
- [ ] Spot-check 5–10 records for complete custom field values
- [ ] Confirm email body content exists (JSON only) or is appropriately summarized (CSV)
- [ ] Validate that Lead→Contact→Opportunity relationships can be reconstructed via ID fields
- [ ] Check for encoding issues with special characters (accented names, CJK characters, emoji)
- [ ] Verify date/timezone handling matches destination system expectations
- [ ] Confirm attachment URLs are still accessible (signed URLs may expire within hours)
- [ ] Preserve every source ID: `lead_id`, `contact_id`, `opportunity_id`, user IDs, status IDs
- [ ] Compare `date_updated` timestamps against export start time to identify records that changed mid-export

## Export for Migration vs. Backup vs. Compliance

These are three different jobs with different requirements. Don't conflate them.

### Migration

If you're moving from Close to another CRM (HubSpot, Salesforce, GoHighLevel, Pipedrive), the JSON export is your starting point — but it's rarely sufficient on its own. Close's Lead-centric model creates structural mismatches with most destination CRMs.

A Close Lead acts as both a "lead" and an "account" in other CRMs. A single Lead with 3 contacts and 2 opportunities creates a many-to-many mapping problem that CSV imports can't resolve. Migrations to contact-centric CRMs usually fail at mapping time, not export time.

You'll need:
- JSON export of all leads (includes nested contacts and opportunities)
- Separate API extraction of all activity types (emails, calls, SMS, notes, meetings)
- Attachment downloads as a parallel workstream
- ID mapping table: Close internal IDs → destination system IDs
- Transformation logic to reshape the Lead-centric hierarchy into your target's data model

Build the target model first. Map the schema before you download anything. For a detailed walkthrough of the structural challenges, see our [Close to GoHighLevel migration guide](https://clonepartner.com/blog/blog/close-to-gohighlevel-migration-data-mapping-api-limits-methods/).

If you're considering a gradual transition instead of a hard cutover, running both systems in parallel during the migration window can reduce risk significantly. See [why running two CRMs in parallel beats a hard cutover](https://clonepartner.com/blog/blog/why-running-two-crms-in-parallel-beats-a-hard-cutover/) for the logic.

### Backup

For backup purposes, use the Export API (`POST /api/v1/export/lead/`) with JSON format, `include_activities: true`, and `include_smart_fields: true`. This returns the most comprehensive single export available. Schedule it via cron or a third-party backup tool.

But a text-only backup is incomplete. Attachments, call recordings (before retention expires), and lead files must be downloaded separately. Treat these as distinct workstreams, not afterthoughts. Close does not provide a single immutable full-org snapshot capability, so a complete backup requires multiple export passes:

1. Export API for leads + activities (JSON)
2. REST API for custom objects, tasks, sequences, users, roles
3. Support tools for email templates, Smart View definitions, custom field definitions
4. File downloads for attachments, lead files, call recordings
5. Event Log mirror (daily cron) for audit trail preservation beyond 30 days

### Compliance (GDPR / CCPA / DSAR)

Close supports GDPR processes and provides Data Processing Agreements with standard contractual clauses. Close processes data in the United States; there is no published option for EU data residency at the time of writing. Organizations subject to EU data residency requirements should evaluate this against their compliance obligations. ([close.com](https://close.com/gdpr))

For a Data Subject Access Request (DSAR), query by contact email or phone via the API, then extract all associated leads, activities, opportunities, and notes. Close's JSON exports meet GDPR Article 20's data portability requirement for machine-readable format.

Close has no native "one-click DSAR export" feature — you'll need to build the query manually or script it via the API. A typical DSAR extraction script queries `GET /api/v1/contact/?email={email}`, retrieves the parent `lead_id`, then fetches all activities filtered by that lead.

**The audit gap:** The Event Log API only covers the last 30 days, with a support-tool cap of 100,000 events. Regulated teams should not treat Close alone as their long-term audit archive. Mirror events to your own warehouse on a daily schedule if you need extended retention for SOX, HIPAA, or GDPR accountability requirements.

For more on compliance-first migration approaches, see our [GDPR-compliant data migration guide](https://clonepartner.com/blog/blog/gdpr-compliant-data-migration-the-enterprise-blueprint/).

## How Portable Is Your Close Data?

[For CTOs] **Portability rating: Mostly Portable.**

Close earns this rating because:
- **~90% of operational data** (leads, contacts, opportunities, activities, custom fields) is fully extractable via the API in JSON format
- The API is well-documented with consistent REST patterns across all endpoints
- There are no contractual or ToS restrictions on data export
- Close publicly states that customers should own their data and not be held captive
- Configuration objects (pipelines, statuses, custom field definitions, sequences) are all API-readable

What prevents a "Fully Portable" rating:
- **Call recordings have plan-dependent retention** — if you don't export before the retention window closes, that data is permanently lost
- **No bulk attachment export** — each file must be downloaded individually via signed S3 URLs
- **Deleted records are unrecoverable** — no trash, archive, or soft-delete API
- **Event log limited to 30 days** — no long-term audit history via the platform itself
- **Custom Objects** (Growth+ only) have forced lead attachment and omitted back references, which may not translate cleanly to other platforms
- **No EU data residency option** — may affect portability for organizations with regional data sovereignty requirements

**The real switching cost** isn't artificial vendor lock-in — it's architectural mismatch. Close's Lead-centric model means every export intended for a Contact-centric or Account-centric CRM requires significant data transformation. You cannot export a CSV from Close and import it into Salesforce or HubSpot without writing mapping scripts to untangle the Lead-Contact-Opportunity hierarchy. The data is accessible, but reshaping it for import into another platform requires non-trivial engineering, especially for activity history.

## Timeline and Resourcing for a Full Data Export

[For PMs] How long does it actually take to get everything out? The following estimates are derived from observed extraction times across multiple Close orgs ranging from 2,000 to 300,000+ leads, accounting for API rate limit pacing, attachment download volume, and post-export data normalization.

| Dataset Size | Scoping | Extraction | Validation & Cleanup | Total | Minimum Team |
|---|---|---|---|---|---|
| **Small** (<10K leads) | 1–2 hours | 1–3 hours (UI export + spot API calls) | 2–4 hours | **1 day** | 1 ops person, developer optional |
| **Medium** (10K–100K leads) | 2–4 hours | 4–8 hours (API extraction) | 4–8 hours | **2–4 days** | 1 developer + 1 PM for validation |
| **Large** (100K+ leads) | 4–8 hours | 8–24 hours (rate limit pacing) | 1–2 days | **5–10 days** | 1–2 developers + 1 PM + 1 data steward |

For small datasets, a RevOps manager can use the UI to export CSVs and manually clean the data. For medium and large datasets, you need a developer writing scripts to handle API pagination, attachment downloads, and JSON normalization.

The bottleneck is rarely the API itself — it's normalizing the nested JSON into your destination data model and ensuring no historical emails or call records get orphaned from their parent contacts.

> Need help exporting or migrating your Close data? Book a free 30-minute call with our migration engineers. We'll scope your extraction, map your data model, and give you a realistic timeline — no obligation.
>
> [Talk to us](https://cal.com/clonepartner/meet?duration=30)

## Frequently asked questions

### Can I export all my data from Close CRM?

You can export the vast majority of your data from Close. Leads, Contacts, Opportunities, and all activity types (emails, calls, SMS, notes, meetings) are exportable via the API in JSON format. The native UI exporter handles leads, contacts, and opportunities in CSV or JSON. The gaps are call recording audio files (subject to plan-based retention that permanently deletes files after 30 or 90 days), deleted records, long-term audit history beyond 30 days, and integration configurations.

### Does Close export include attachments?

No. Close does not include file attachments in any standard export (CSV, JSON, or Export API). Email attachments appear as URL references in the email activity JSON and must be downloaded individually. Note attachments can be exported as a ZIP via support tools. Lead files can be downloaded as a ZIP via the Download Lead Files support tool. Call recordings have their own download path with plan-dependent retention limits.

### What format does Close export data in?

Close supports CSV and JSON. CSV produces flat tabular files suitable for spreadsheets but strips activity content to summaries and loses nested relationships. JSON is the recommended format for backups and migrations because it preserves the Lead-Contact-Opportunity hierarchy and includes complete activity data. Export files are GZIP compressed with UTF-8 encoding and ISO 8601 timestamps in UTC.

### What are Close's API rate limits for bulk export?

Close enforces rate limits per endpoint group at approximately 20 requests per second per API key, with an organization-wide ceiling of about 60 RPS (3x the per-key limit). Exceeding limits returns HTTP 429 with a retry-after header. Pagination is limited to 100 records per page, and deep pagination via _skip has a per-resource maximum offset — use date-range windowing for large extractions.

### How do I export Close data to migrate to another CRM?

Start with a JSON export of all leads using the Export API with include_activities set to true. Then separately extract activity types, attachments, and configuration data via the REST API. Close's Lead-centric model acts as both lead and account in other CRMs, creating structural mismatches that require data transformation before import into platforms like HubSpot, Salesforce, or GoHighLevel. Build the target schema mapping before you start downloading data.
