Clarify to UGRU CRM Migration: The CTO's Technical Guide
Technical guide to migrating from Clarify to UGRU CRM. Covers API extraction, schema mapping, CSV import, custom object handling, and validation for financial advisory firms.
Planning a migration?
Get a free 30-min call with our engineers. We'll review your setup and map out a custom migration plan — no obligation.
Schedule a free call- 1,500+ migrations completed
- Zero downtime guaranteed
- Transparent, fixed pricing
- Project success responsibility
- Post-migration support included
Migrating from Clarify to UGRU CRM means moving from an AI-native, schema-flexible CRM built for startup sales teams into a purpose-built financial advisory practice management suite with a fixed data model. The two platforms share almost no architectural DNA. Clarify uses a JSON:API-based data model with custom objects, typed relationships, and per-workspace API keys. UGRU bundles CRM, financial planning, accounting, and compliance into a single pre-integrated interface — with no support for arbitrary custom objects and limited API surface for inbound data. (developer.clarify.ai)
The hard part is not getting data out of Clarify — its API is clean and well-documented. The hard part is deciding what stays live in UGRU, what gets flattened into notes or attachments, and what should live in an archive. If your Clarify workspace only holds companies, people, and open deals, a CSV-led migration can work. If you need people-to-deal relationships, activity timelines, meeting notes, custom objects, or compliance-friendly document history, treat this as an engineered migration with staging, crosswalk tables, and UAT. (developer.clarify.ai)
This guide covers the full migration path: data extraction from Clarify's API, transformation to fit UGRU's rigid schema, and import into UGRU's ingestion layer.
Why Teams Migrate from Clarify to UGRU CRM
The migration usually happens for one specific reason: the team is a financial advisory firm that outgrew Clarify's generalist approach and needs a platform with built-in financial planning, FINRA-compliant email archiving, and practice management workflows.
Common triggers:
- Industry-specific functionality — UGRU includes goal-based planning, needs analysis, estate planning, cash flow modeling, and retirement income planning directly inside the CRM. Clarify has none of this.
- FINRA compliance — UGRU is designed for FINRA-regulated environments, including built-in email archiving with retention controls. Clarify was not designed for regulated financial services and does not provide native email archiving.
- Consolidated tooling — UGRU eliminates the need for separate accounting, financial planning, and marketing automation tools. For small RIA firms (Registered Investment Advisors), this all-in-one approach reduces total subscription cost and vendor management overhead.
- Pre-built advisory workflows — UGRU ships with over 40 pre-designed workflows for client acquisition, annual reviews, RMD (Required Minimum Distribution) reminders, and client termination — configured for financial advisory processes out of the box.
If you are a general B2B sales team rather than an advisory practice, UGRU's specialization may be a reason not to move. The platform's fixed schema and financial-services-specific modules add friction without benefit for non-advisory use cases.
This migration is a downgrade in schema flexibility. Clarify supports custom objects, typed relationships, and a modern API. UGRU's data model is fixed and purpose-built. If you rely on Clarify's custom objects for non-financial data, expect to lose or flatten those structures.
Core Data Model Differences: Clarify vs. UGRU CRM
Before touching any data, understand where the two platforms diverge at the schema level.
| Concept | Clarify | UGRU CRM |
|---|---|---|
| Contacts | person object with collection fields (email_addresses.items []) |
Contacts categorized as Prospects, Clients, Vendors, or Associates |
| Companies | company object with domains as unique field |
Accounts / Organizations |
| Deals/Opportunities | deal object with pipeline stages via Lists |
Opportunities with Sales Forecasting and Pipeline |
| Activities | Activity stream + meeting and task objects |
Notes, Follow-up Calls, Appointments, Calendar Events |
| Custom Objects | Fully supported (c_* prefix), same API endpoints |
Not supported — fixed schema only |
| Relationships | Typed, foreign-key-based with many-to-many support | Implicit hierarchy: Entity → Individual → Household |
| API Format | JSON:API specification, REST | Limited; CSV import is primary ingestion method |
| Authentication | Per-workspace API keys | N/A for import; API credentials where available |
The critical gap: Clarify's custom objects (c_sales_order, c_subscription, etc.) have no equivalent in UGRU. Any data stored in custom objects must be flattened into notes, attached as documents, or abandoned. (docs.clarify.ai)
UGRU's Household Data Model Explained
UGRU organizes contacts using a three-tier hierarchy that is central to how financial advisory firms manage client relationships:
- Entity — A business or organization (e.g., "Smith Family Trust," "ABC Corporation"). This is the top-level container, equivalent to Clarify's
companyobject. - Individual — A person linked to one or more entities (e.g., "John Smith" linked to both his employer and his family trust). Maps to Clarify's
personobject. - Household — A grouping that connects related individuals for financial planning purposes (e.g., John Smith and Jane Smith share a household, which rolls up their combined AUM, policies, and financial plans).
In CSV import terms, this means UGRU expects columns like Household_Name or Household_ID to link individuals. If John and Jane Smith should share a household, both contact rows need a matching household identifier. Without this, UGRU imports them as unrelated individuals — and an advisor loses the ability to see combined household net worth, joint account holdings, or shared financial plans.
Clarify has no household concept. Clarify's many-to-many relationships between people and companies are flexible but untyped for financial advisory use. During migration, you must:
- Identify spouse/partner pairs in Clarify (often stored as custom fields, notes, or implicit in shared company associations)
- Assign a consistent
Household_Nameto each group - Include this field in your contact CSV before UGRU import
This mapping is almost always a manual or semi-automated step and is one of the most time-consuming parts of the migration for advisory firms with 500+ client households.
Migration Approaches
There are five viable methods for moving data between these two platforms. The right choice depends on data volume, relationship complexity, and available engineering bandwidth.
1. Native CSV Export/Import
How it works: Export data from Clarify as CSV files via the UI or API, map columns manually, then use UGRU's built-in CSV import tool to load records. Clarify exports whatever columns are visible in a given view, so add every field you need before downloading. Lead Finder results must be added to a list before they can be exported. (docs.clarify.ai)
When to use it: Fewer than 500 records, simple data (contacts + companies only), no custom objects.
Pros: No code required. UGRU auto-matches CSV column headers to internal fields and checks for duplicates during import.
Cons: Destroys relational links. Clarify's email_addresses.items [] array must be manually split into separate columns. Activity history (meetings, tasks, comments) does not export cleanly to CSV. No way to import financial plan data.
Scalability: Small datasets only. Above 1,000 records, manual field mapping and duplicate resolution becomes a multi-day effort.
Complexity: Low
2. API-Based Migration
How it works: Use Clarify's REST API to programmatically extract all objects with relationships intact, transform into UGRU's expected format, and load via UGRU's import mechanism (CSV or available API endpoints). Clarify uses Authorization: api-key ..., documents offset pagination with page [limit] and page [offset], and publishes a 3,000-requests-per-minute-per-endpoint limit. (developer.clarify.ai)
When to use it: 500–10,000 records, need to preserve activity history, have engineering resources.
Pros: Preserves full relational context during extraction. The include parameter lets you pull related records in the same call. Clarify's rate limit is generous enough for most advisory firms — a 5,000-contact extraction with related companies and deals typically completes in under 10 minutes.
Cons: The bottleneck is UGRU's import side, not Clarify's export. UGRU's inbound API surface is limited compared to platforms like Salesforce or HubSpot. Most data will ultimately flow through CSV import regardless of how it was extracted.
Scalability: Good for extraction; constrained by UGRU's import capabilities on the load side.
Complexity: Medium–High
3. Third-Party Migration Tools
How it works: Use a platform like Trujay or Import2 to connect source and target CRMs and run an automated migration.
When to use it: When both platforms are supported by the tool. Check current connector availability — neither Clarify nor UGRU is a mainstream CRM for most migration platforms, so connector coverage is sparse as of 2024.
Pros: Minimal engineering effort if connectors exist. Built-in field mapping UI.
Cons: Connector coverage for both Clarify and UGRU is sparse. Most tools focus on Salesforce/HubSpot/Pipedrive ecosystems. Custom objects from Clarify are unlikely to be handled. Financial planning data from UGRU's specialized modules won't be mapped.
Scalability: Depends entirely on the tool's connector quality.
Complexity: Low (if a connector exists), otherwise not viable
4. Custom ETL Pipeline
How it works: Build a purpose-built extract-transform-load pipeline using Python, Node.js, or a data integration framework (dlt, Airbyte). Extract from Clarify's API, transform with custom mapping logic, load into UGRU.
When to use it: 5,000+ records, complex custom objects, need for repeatable or auditable migrations, or when you need to merge data from multiple sources (e.g., multiple Clarify workspaces).
Pros: Full control over transformation logic. Can handle edge cases like merging duplicate contacts, splitting multi-value fields, archiving custom objects as documents, and constructing household groupings. Auditable and rerunnable.
Cons: Requires developer time — typically 2–4 weeks for a mid-complexity migration (5,000 contacts, 3 custom objects, 2 years of activity history). You own the maintenance and debugging.
Scalability: Excellent. Built for large datasets with batching and pagination.
Complexity: High
5. Middleware / Integration Platforms (Zapier, Make)
How it works: Use Zapier or Make to create workflows that trigger on Clarify events and push data to UGRU. Clarify publicly documents Zapier, Pipedream, webhook, and API automation paths. UGRU's public integrations page lists a smaller app set. (docs.clarify.ai)
When to use it: Ongoing sync of small data volumes (new contacts, updated deals) after the initial migration — not for bulk historical migration.
Pros: No code. Good for keeping platforms in sync during a phased transition.
Cons: Not designed for bulk historical migration. Zapier's task quotas (e.g., 750 tasks/month on the free tier, 2,000 on Starter) make large-volume moves slow and expensive. Multi-step relationship reconstruction is impractical in a linear workflow automation tool.
Scalability: Poor for migration; acceptable for ongoing lightweight sync.
Complexity: Low–Medium
Migration Approach Comparison
| Method | Complexity | Best For | Relationship Preservation | Custom Object Support | Bulk Capable |
|---|---|---|---|---|---|
| CSV Export/Import | Low | <500 records, contacts only | ❌ Lost | ❌ None | ❌ No |
| API-Based | Medium–High | 500–10K records, full history | ✅ On extract | ⚠️ Archive only | ✅ Yes |
| Third-Party Tools | Low | Supported platform pairs | ⚠️ Partial | ❌ Unlikely | ⚠️ Varies |
| Custom ETL | High | 5K+ records, complex schemas | ✅ Full control | ✅ Transform/archive | ✅ Yes |
| Middleware (Zapier) | Low–Medium | Ongoing sync, small volume | ❌ Limited | ❌ None | ❌ No |
Recommendations by Scenario
- Small advisory firm (<500 clients), no dev team: CSV export/import with manual cleanup. Budget 2–3 days for mapping, household assignment, and validation.
- Mid-sized RIA (500–5,000 clients), some technical staff: API-based extraction from Clarify, custom transformation script, CSV import into UGRU. Budget 40–80 hours of engineering time when you account for schema discovery, household mapping, transformation debugging, import error resolution, and record-by-record validation.
- Enterprise firm or multi-office RIA: Custom ETL pipeline with staging database. The combination of custom objects, activity history, multi-workspace extraction, and household relationship reconstruction justifies a dedicated engineering sprint of 3–4 weeks.
- Phased transition (running both CRMs temporarily): API-based extraction for the initial load, plus Zapier/Make for ongoing delta sync of new contacts during the transition window.
When to Use a Managed Migration Service
Build in-house when you have a dedicated engineer with 2+ weeks of availability, your data is clean, and you have fewer than 2,000 records with no custom objects.
Use a managed migration service when:
- Household relationships matter — Clarify's many-to-many relationships between people, companies, and deals must be manually reconstructed in UGRU's entity/individual/household hierarchy. A CSV import flattens these. Rebuilding across hundreds of client households is a multi-day manual effort that requires domain knowledge of your client base.
- Activity history is business-critical — Meeting notes, call summaries, and deal timeline entries from Clarify's activity stream have no direct bulk import path into UGRU. A managed service can script the extraction, transformation, and attachment of these records to the correct UGRU contacts.
- FINRA compliance is non-negotiable — Email archives and document trails must be migrated intact for regulatory compliance. Dropping records during migration creates audit risk. See the FINRA Email Archive section below for specific guidance.
- The target API is under-documented — UGRU's public materials reference a developer API, but the public resources reviewed do not expose endpoint-level reference docs or published rate limits. Building against an undocumented API adds significant project risk. Contact UGRU support directly to request API documentation, sandbox access, and rate limit details before committing to an API-based load strategy. (ugru.com)
- You can't afford extended downtime — A botched migration that requires rollback and re-import can leave your advisory team without CRM access during client-facing hours.
- You have multiple Clarify workspaces — Firms with separate workspaces for different teams or offices face a more complex extraction with potential ID collisions and duplicate resolution across workspaces.
DIY migrations rarely fail on export. They fail on hidden costs: mapping workshops, reruns after duplicates, manual relationship repair, household construction, and the engineering hours spent writing one-off cleanup scripts.
UGRU's free basic migration: UGRU offers free basic data migration assistance for new customers. Based on public materials, this typically covers contact and account import from CSV files. It is unlikely to cover custom object archival, activity history reconstruction, household relationship mapping, or FINRA email archive migration. Confirm scope and exclusions with UGRU sales before relying on this service for anything beyond simple contact import.
Pre-Migration Planning
Data Audit Checklist
Before extracting anything, inventory what exists in Clarify and what UGRU can actually accept. Use Clarify's schema endpoint (GET /schemas) to discover all objects and fields programmatically. (developer.clarify.ai)
| Clarify Object | Record Count | Has Custom Fields? | UGRU Equivalent | Migration Path |
|---|---|---|---|---|
person |
Count via API | Check schema | Contact (with type + household) | Direct import |
company |
Count via API | Check schema | Account/Organization (Entity) | Direct import |
deal |
Count via API | Check schema | Opportunity | Import + manual pipeline setup |
meeting |
Count via API | N/A | Notes / Calendar Events | Flatten to notes |
task |
Count via API | N/A | Tasks / Follow-ups | Map to UGRU task types |
Custom objects (c_*) |
Count via API | Yes | None | Archive as docs or notes |
| Comments/Activities | Count via API | N/A | Notes | Append to parent records |
Multi-Workspace Inventory
If your firm uses multiple Clarify workspaces (e.g., separate workspaces for different advisor teams or office locations), audit each workspace separately. Key concerns:
- ID collisions: Two workspaces may have contacts with the same email but different activity histories. Decide on a mastering strategy (which workspace's data wins on conflict).
- Cross-workspace relationships: A client in Workspace A may have deals tracked in Workspace B. Map these before extraction.
- API key per workspace: Each workspace requires its own API key for extraction.
Clean Dead Data
- Contacts with no email, no activity in 12+ months, and no associated deals → exclude
- Deals in
lostorclosedstages older than your reporting window → archive, don't migrate - Test records, demo data, duplicate contacts → clean before extraction
- AI-generated contacts from Clarify's email/calendar sync that were never verified → review and prune
Define Migration Scope
Decide explicitly:
- Time window: All historical data, or only records from the last N years?
- Object scope: All objects, or contacts + companies + open deals only?
- Custom objects: Archive as PDFs/CSVs in a document store, or discard?
- Activity history: Full timeline appended as notes, or summary notes only?
- Household construction: Will you map households before import, or reconstruct them in UGRU post-import?
Choose Cutover Strategy
- Big bang: Extract everything, import over a weekend, cut over Monday morning. Works for firms under 2,000 clients with tolerance for a 48-hour CRM blackout.
- Phased: Migrate contacts and companies first, validate, then migrate deals and activities in a second pass. Lower risk, longer timeline (typically 1–2 weeks).
- Incremental: Migrate historical data first, then run delta syncs for new records created during the transition. Best for firms that can't afford any CRM downtime. Requires Zapier/Make or a custom sync script.
For a broader migration planning framework, see The Ultimate CRM Data Migration Checklist.
Data Model and Object Mapping
This is where most migrations fail. The mapping isn't 1:1, and the structural differences create data that doesn't fit cleanly.
Object-Level Mapping
| Clarify Object | UGRU CRM Target | Notes |
|---|---|---|
person |
Contact (Client, Prospect, Vendor, or Associate type) | Map person.type or deal stage to UGRU contact category. Add Household_Name column. |
company |
Account / Organization (Entity) | UGRU links individuals to entities via household structure |
deal |
Opportunity | Pipeline stages must be manually recreated in UGRU's pipeline settings |
meeting |
Calendar Event or Note | Meeting transcripts → notes with date prefix |
task |
Task / Follow-up | Map to UGRU's task system; preserve due dates |
c_* (custom objects) |
No equivalent | Flatten to notes or archive as attached documents |
Clarify's core object model documents person, company, deal, meeting, and task. There is no dedicated lead object — Lead Finder is a prospecting source, not a core CRM entity. Leads from Clarify typically map to a UGRU contact with "Prospect" type. (developer.clarify.ai)
Field-Level Mapping
Clarify uses collection fields and structured data. UGRU expects flat CSV columns.
| Clarify Field | Type | UGRU Field | Transformation |
|---|---|---|---|
person.name.first_name |
String | First Name | Direct |
person.name.last_name |
String | Last Name | Direct |
person.email_addresses.items [0] |
Array [String] | Extract first element | |
person.email_addresses.items [1] |
Array [String] | Email 2 | Extract second element (discard items [2+] or append to notes) |
person.phone_numbers.items [0] |
Array [String] | Phone | Extract first element |
person.phone_numbers.items [1] |
Array [String] | Phone 2 | Extract second element |
person.title |
String | Title | Direct |
company.name |
String | Account Name | Direct |
company.domains.items [0] |
Array [String] | Website | Extract first element |
deal.name |
String | Opportunity Name | Direct |
deal.value |
Number | Opportunity Amount | Direct |
deal.stage |
String (from List) | Pipeline Stage | Map to UGRU pipeline values via lookup table |
deal.close_date |
ISO 8601 | Expected Close Date | Reformat to MM/DD/YYYY |
meeting.summary |
Text | Note Body | Prepend meeting date: [2024-01-15 Meeting] ... |
task.title |
String | Task Subject | Direct |
task.due_date |
ISO 8601 | Due Date | Reformat to MM/DD/YYYY |
| (constructed) | N/A | Household_Name | Derive from spouse pairs, shared addresses, or manual assignment |
| (constructed) | N/A | Contact Type | Map from deal stage: has active deal → "Client"; no deal → "Prospect" |
Collection fields are the #1 source of import errors. Clarify stores emails as {"items": ["a@b.com", "c@d.com"]}. A naive JSON-to-CSV conversion produces a single cell with the JSON string. You must explicitly split these into separate columns before import. If a contact has more than 2 email addresses, take the first two for UGRU's primary and secondary email fields and concatenate the rest into a notes field (e.g., Additional emails: c@d.com, e@f.com).
Clarify enums are case-sensitive. Clarify treats email, domain, and deal name as key match fields for person, company, and deal records. UGRU emphasizes validation, duplicate checking during import, and mandatory lookups. Create an explicit mapping table for every picklist before transformation:
| Clarify Deal Stage | UGRU Pipeline Stage |
|---|---|
qualified |
Qualified Lead |
proposal_sent |
Proposal |
negotiation |
Negotiation |
closed_won |
Won |
closed_lost |
Lost |
Store this mapping table as a versioned artifact (spreadsheet or JSON file), not as hardcoded logic scattered through transformation scripts. (developer.clarify.ai)
Create UGRU custom fields for legacy_clarify_id, legacy_company_id, and legacy_deal_id before the first test load. Those keys make reruns, reconciliation, and rollback much easier. If UGRU does not support custom fields for all object types, store the legacy ID in a dedicated notes prefix: [ClarifyID: abc123].
Handling Relationships and Dependencies
Clarify links records via typed relationships — a person has a company_id, a deal has linked people. UGRU uses its entity → individual → household hierarchy.
Import order matters — this is non-negotiable:
- Companies/Accounts first (these become parent entities in UGRU)
- Contacts second (link to companies via account name or ID match; include household assignments)
- Opportunities third (link to contacts via contact name or imported ID)
- Activities/Notes last (attach to parent records by matching on legacy IDs)
If you import contacts before companies, UGRU cannot link them. You'll need to either re-import or manually associate records — both painful at scale. For 1,000 contacts, manual re-association at 2 minutes per record is 33 hours of labor.
Clarify people ↔ deals are many-to-many. A single deal can be linked to multiple contacts, and a single contact can be linked to multiple deals. If you flatten them too early (e.g., by putting a single Contact Name column on the opportunity CSV), one contact can end up linked to the wrong opportunity set, or multi-party deals lose participants from pipeline reporting entirely. Extract relationship tables separately and rebuild them after accounts and contacts exist in UGRU. (developer.clarify.ai)
Migration Architecture: Extract → Transform → Load
┌─────────────┐ ┌──────────────────┐ ┌─────────────┐
│ Clarify │ │ Transform │ │ UGRU CRM │
│ REST API │────▶│ (Python/Node) │────▶│ CSV Import │
│ │ │ │ │ or API │
└─────────────┘ └──────────────────┘ └─────────────┘
│ │ │
JSON:API Flatten arrays Auto-match
Pagination Map fields Dedup check
include= Date formatting Field mapping
relationships Household construction
Relationship IDs
For Clarify, use two extract paths: CSV exports for fast object dumps (useful for initial record counts and quick validation), and the API for anything relational or timeline-driven. Clarify documents standard REST endpoints, list-to-CSV export, offset pagination, include for related records, and a 3,000-requests-per-minute-per-endpoint limit. (docs.clarify.ai)
Clarify API: Extraction Details
Clarify's API follows JSON:API conventions. Key extraction patterns:
# Authenticate and fetch contacts with related company and deal records
curl --globoff -H 'Authorization: api-key YOUR_API_KEY' \
'https://api.clarify.ai/v1/workspaces/your-slug/objects/person/resources?page[limit]=500&include=company_id,deals'
# Fetch schema to discover all objects and fields
curl -H 'Authorization: api-key YOUR_API_KEY' \
https://api.clarify.ai/v1/workspaces/your-slug/schemas
# Fetch custom objects (discover c_* types from schema first)
curl --globoff -H 'Authorization: api-key YOUR_API_KEY' \
'https://api.clarify.ai/v1/workspaces/your-slug/objects/c_subscription/resources?page[limit]=500'Rate limits: 3,000 requests per minute, per workspace, per endpoint. Each endpoint has its own budget — fetching /person and /company in parallel does not share a quota. For a 5,000-contact firm, full extraction typically completes in under 10 minutes with page [limit]=500 (10 pages × 5 object types ≈ 50 requests). (developer.clarify.ai)
Pagination: List endpoints return paginated results with meta (totals) and links (next/previous). Follow links.next until links.next is null or absent. Each next URL includes the offset parameters — do not re-append them.
UGRU CRM: Import Capabilities and Constraints
UGRU's primary data ingestion path is CSV import. Known constraints based on public materials and typical behavior:
- Auto-field matching: UGRU attempts to match CSV column headers to internal fields automatically. Use UGRU's exact field names as column headers to avoid manual remapping.
- Duplicate detection: Built-in dedup checks during import, matching on email address for contacts and organization name for accounts.
- Supported import entities: Contacts, accounts/organizations, opportunities.
- Unsupported via CSV import: Financial plans, accounting data, workflow configurations, FINRA email archives, Decision Center calculator inputs.
- File format: CSV with UTF-8 encoding. Test with a 10-row file first to confirm delimiter handling (comma vs. semicolon based on locale).
- File size and row limits: Not publicly documented. If importing more than 5,000 rows, split into batches of 1,000–2,000 rows to reduce risk of timeout or partial failure. Validate each batch independently before proceeding.
- Partial failure behavior: Test whether UGRU's import is atomic (all-or-nothing per file) or row-level (imports valid rows, skips invalid ones). A single malformed row in an atomic import rejects the entire file. Confirm this behavior with a test import containing one intentionally invalid row.
- Basic migration assistance: UGRU offers free basic data migration for new customers, typically covering contact and account CSV import. Confirm scope with UGRU sales.
UGRU's public materials reference a developer API, but endpoint-level reference docs and published rate limits were not found in publicly available materials as of this writing. If your migration plan depends on API writes into UGRU (rather than CSV), take these steps before committing to a cutover date:
- Contact UGRU support and request API documentation
- Ask for sandbox/test environment credentials
- Confirm which objects support API create/update operations
- Get rate limit and batch size specifications in writing
- Test authentication and a single record create before designing your pipeline
(ugru.com)
UGRU's publicly documented import/export capabilities are strongest for contacts and organizations. Opportunities, activities, workflows, documents, and advisor-specific modules (Decision Center, financial planning, compliance) are available in the product, but their programmatic import paths are not fully documented publicly. Expect some Clarify data to be remodeled during migration, not migrated verbatim. (ugru.com)
FINRA Email Archive Migration
For advisory firms, FINRA compliance requires retention of client communications. This creates a specific migration challenge because Clarify and UGRU handle email archiving differently.
Clarify's email situation: Clarify syncs emails from connected accounts (Gmail, Outlook) and surfaces them in the activity timeline, but it is not a FINRA-compliant email archiving system. It does not provide retention policies, tamper-evident storage, or supervisory review workflows. If you are currently using Clarify, your FINRA email archive likely lives in a separate system (Smarsh, Global Relay, Proofpoint, or your broker-dealer's archiving solution).
UGRU's email archiving: UGRU includes built-in FINRA-compliant email functionality with archiving. Emails sent through UGRU are automatically archived. However, historical emails from before the migration — whether they lived in Clarify's activity stream or a third-party archive — need to be handled separately.
Migration approach for email archives:
- Identify your current FINRA archive: If you're using a third-party archiving service, that archive typically remains in place regardless of CRM migration. Confirm with your compliance team that the archive is independent of Clarify.
- Email activity in Clarify's timeline: Extract email records from Clarify's activity API. These are activity references, not full archived emails. Export them as notes attached to the relevant UGRU contact record with timestamps and subject lines intact.
- Post-migration: Configure UGRU's email system as your go-forward FINRA-compliant channel. Ensure all advisors switch to sending client communications through UGRU rather than personal email clients.
- Gap analysis: Document any period between Clarify shutdown and UGRU go-live where email archiving may have been interrupted. Your compliance officer needs this for regulatory documentation.
Do not assume that migrating email references from Clarify's activity stream into UGRU constitutes FINRA-compliant email archiving. Clarify's activity records are summaries, not the original archived messages. Your FINRA archive should be maintained independently of either CRM.
Step-by-Step Migration Process
Step 1: Extract Data from Clarify
import requests
import time
import json
import logging
logging.basicConfig(level=logging.INFO, filename="migration_extract.log")
logger = logging.getLogger(__name__)
API_KEY = "your_clarify_api_key"
BASE_URL = "https://api.clarify.ai/v1/workspaces/your-slug"
HEADERS = {"Authorization": f"api-key {API_KEY}"}
def extract_all_records(object_type, include=None, page_limit=500):
"""
Extract all records of a given object type with pagination and retry logic.
Returns a list of JSON:API resource objects.
"""
records = []
included_records = []
url = f"{BASE_URL}/objects/{object_type}/resources"
params = {"page[limit]": page_limit}
if include:
params["include"] = include
page_count = 0
while url:
try:
response = requests.get(url, headers=HEADERS, params=params)
if response.status_code == 429:
retry_after = int(response.headers.get("Retry-After", 2))
logger.warning(f"Rate limited on {object_type}, waiting {retry_after}s")
time.sleep(retry_after)
continue
response.raise_for_status()
data = response.json()
batch = data.get("data", [])
records.extend(batch)
# Collect included (related) records
if "included" in data:
included_records.extend(data["included"])
page_count += 1
total = data.get("meta", {}).get("total", "unknown")
logger.info(
f"{object_type}: page {page_count}, "
f"fetched {len(batch)} records, "
f"total so far: {len(records)}/{total}"
)
# Follow pagination — next URL includes offset params
url = data.get("links", {}).get("next")
params = {} # params are encoded in the next URL
except requests.exceptions.RequestException as e:
logger.error(f"Request failed for {object_type}: {e}")
time.sleep(5)
continue
logger.info(f"Extraction complete: {object_type} = {len(records)} records")
return records, included_records
# Extract all object types with relationships
persons, person_includes = extract_all_records("person", include="company_id,deals")
companies, _ = extract_all_records("company")
deals, deal_includes = extract_all_records("deal", include="company_id")
meetings, _ = extract_all_records("meeting")
tasks, _ = extract_all_records("task")
# Discover and extract custom objects
schema_response = requests.get(f"{BASE_URL}/schemas", headers=HEADERS)
schemas = schema_response.json()
custom_objects = {}
for schema in schemas.get("data", []):
obj_type = schema.get("id", "")
if obj_type.startswith("c_"):
logger.info(f"Found custom object: {obj_type}")
custom_objects[obj_type], _ = extract_all_records(obj_type)
# Save raw extracts for audit trail
for name, data in [("persons", persons), ("companies", companies),
("deals", deals), ("meetings", meetings), ("tasks", tasks)]:
with open(f"raw_{name}.json", "w") as f:
json.dump(data, f, indent=2)
logger.info(f"Saved raw_{name}.json ({len(data)} records)")
for obj_type, data in custom_objects.items():
with open(f"raw_{obj_type}.json", "w") as f:
json.dump(data, f, indent=2)Step 2: Transform Data
import csv
from datetime import datetime
# Build lookup tables from extracted data
company_lookup = {c["id"]: c["attributes"].get("name", "") for c in companies}
# Household mapping — load from a manually prepared CSV or derive programmatically
# Format: {"person_id": "Household Name"}
# This step almost always requires manual review for accuracy
household_map = {} # Populate from your household mapping file
# Stage mapping — versioned artifact
STAGE_MAP = {
"qualified": "Qualified Lead",
"proposal_sent": "Proposal",
"negotiation": "Negotiation",
"closed_won": "Won",
"closed_lost": "Lost",
}
def flatten_collection(field_data, max_values=2):
"""Split items[] array into separate values, handling None and short arrays."""
items = field_data.get("items", []) if field_data else []
result = [items[i] if i < len(items) else "" for i in range(max_values)]
overflow = items[max_values:] if len(items) > max_values else []
return result, overflow
def reformat_date(iso_date):
"""Convert ISO 8601 to MM/DD/YYYY for UGRU import."""
if not iso_date:
return ""
try:
return datetime.fromisoformat(iso_date.replace("Z", "+00:00")).strftime("%m/%d/%Y")
except (ValueError, AttributeError):
return ""
def resolve_company_name(person):
"""Look up company name from relationship data."""
relationships = person.get("relationships", {})
company_rel = relationships.get("company_id", {})
company_data = company_rel.get("data")
if company_data and isinstance(company_data, dict):
return company_lookup.get(company_data.get("id"), "")
return ""
def determine_contact_type(person, person_deal_ids):
"""Map to UGRU contact type based on deal status."""
if person["id"] in person_deal_ids:
return "Client"
return "Prospect"
def flatten_person_for_ugru(person, person_deal_ids):
"""Transform a Clarify person record into UGRU contact format."""
attrs = person.get("attributes", {})
name = attrs.get("name", {})
emails, overflow_emails = flatten_collection(attrs.get("email_addresses"), max_values=2)
phones, overflow_phones = flatten_collection(attrs.get("phone_numbers"), max_values=2)
# Build overflow notes for data that exceeds UGRU's field capacity
notes_parts = []
if overflow_emails:
notes_parts.append(f"Additional emails: {', '.join(overflow_emails)}")
if overflow_phones:
notes_parts.append(f"Additional phones: {', '.join(overflow_phones)}")
return {
"First Name": name.get("first_name", ""),
"Last Name": name.get("last_name", ""),
"Email": emails[0],
"Email 2": emails[1],
"Phone": phones[0],
"Phone 2": phones[1],
"Title": attrs.get("title", ""),
"Company": resolve_company_name(person),
"Contact Type": determine_contact_type(person, person_deal_ids),
"Household_Name": household_map.get(person["id"], ""),
"Notes": "; ".join(notes_parts),
"Source_CRM_ID": person["id"],
}
def flatten_company_for_ugru(company):
"""Transform a Clarify company record into UGRU account format."""
attrs = company.get("attributes", {})
domains, _ = flatten_collection(attrs.get("domains"), max_values=1)
return {
"Account Name": attrs.get("name", ""),
"Website": domains[0],
"Source_CRM_ID": company["id"],
}
def flatten_deal_for_ugru(deal):
"""Transform a Clarify deal record into UGRU opportunity format."""
attrs = deal.get("attributes", {})
clarify_stage = attrs.get("stage", "")
return {
"Opportunity Name": attrs.get("name", ""),
"Amount": attrs.get("value", ""),
"Pipeline Stage": STAGE_MAP.get(clarify_stage, clarify_stage),
"Expected Close Date": reformat_date(attrs.get("close_date")),
"Source_CRM_ID": deal["id"],
}
def write_ugru_csv(records, filename):
"""Write transformed records to UTF-8 CSV for UGRU import."""
if not records:
logger.warning(f"No records to write for {filename}")
return
with open(filename, "w", newline="", encoding="utf-8") as f:
writer = csv.DictWriter(f, fieldnames=records[0].keys())
writer.writeheader()
writer.writerows(records)
logger.info(f"Wrote {len(records)} records to {filename}")
# Build person-to-deal mapping for contact type determination
person_deal_ids = set()
for deal in deals:
rels = deal.get("relationships", {})
people_data = rels.get("people", {}).get("data", [])
if isinstance(people_data, list):
for p in people_data:
person_deal_ids.add(p.get("id"))
# Transform and write
ugru_accounts = [flatten_company_for_ugru(c) for c in companies]
ugru_contacts = [flatten_person_for_ugru(p, person_deal_ids) for p in persons]
ugru_opps = [flatten_deal_for_ugru(d) for d in deals]
write_ugru_csv(ugru_accounts, "ugru_import_accounts.csv")
write_ugru_csv(ugru_contacts, "ugru_import_contacts.csv")
write_ugru_csv(ugru_opps, "ugru_import_opportunities.csv")Step 3: Import into UGRU CRM
- Pre-flight: Validate each CSV — check encoding (UTF-8), confirm no JSON strings in cells, verify row counts match expectations.
- Import accounts first: Log into UGRU CRM → navigate to the import wizard → upload
ugru_import_accounts.csv. Companies/accounts must exist before contacts can be linked. - Validate account import: Confirm record count matches. Spot-check 10 accounts for correct names and websites.
- Import contacts second: Upload
ugru_import_contacts.csv. UGRU will auto-match fields and flag duplicates on email match. Review field mapping and correct any mismatches before confirming. - Validate contact import: Confirm contacts are linked to the correct accounts. Check household assignments.
- Import opportunities third: Upload
ugru_import_opportunities.csv. Link to contacts via name or imported ID. - Import activities: Flatten meetings and tasks to notes and either import via CSV (if UGRU's notes import supports it) or enter via UGRU's interface for smaller volumes. Include the date and activity type in the note body:
[2024-01-15 Meeting] Discussed retirement planning timeline... - Sample validation: Verify 20–50 records across each object type for accuracy.
Step 4: Rebuild Relationships and Household Structure
After import, verify and manually correct:
- Contacts are linked to the correct accounts/organizations
- Household groupings are correct (spouses, trusts, and related entities are properly connected)
- Opportunities are associated with the right contacts (for multi-party deals, UGRU may require manual linking of additional contacts)
- Territory assignments are correct for multi-advisor firms
Step 5: Validate Data
Run the validation checks described in the Validation section below.
Edge Cases and Challenges
Duplicate Records
Clarify may already contain duplicates — especially if AI-generated contacts from email/calendar sync were never merged. UGRU's import dedup will flag some on exact email match, but fuzzy duplicates ("Jon Smith" vs. "Jonathan Smith" at the same company) will slip through. Run a dedup pass before extraction using email + company name as a composite key. Snapshot both sides and decide mastering rules (which record survives, which gets merged) before the first load. (docs.clarify.ai)
Multi-Value Collection Fields
Clarify stores emails, phone numbers, and domains as arrays. If a contact has 4 email addresses, take the first two for UGRU's primary and secondary fields, and concatenate the rest into a notes field with a clear prefix: Additional emails: c@d.com, e@f.com. Do not silently drop data — advisors may need that fourth email for a client's trust administrator.
Meeting Transcripts and AI Summaries
Clarify auto-generates meeting summaries and call transcripts. These live in the activity stream, not as standalone objects. Extract via the activities endpoint and format as structured notes on the corresponding UGRU contact or opportunity:
[2024-03-15 Meeting Transcript]
Participants: John Smith, Jane Smith, Advisor Mike
Summary: Discussed Q1 portfolio performance, agreed to increase
401(k) contributions by 2%. Next review scheduled for Q3.
---
[Full transcript below]
...
Custom Objects with No Target
Any c_* custom object in Clarify (subscriptions, support tickets, custom deal types) has no home in UGRU. Options ranked by data preservation:
- Export to CSV and store in document management — archive in UGRU's document vault or a SharePoint/Google Drive folder, linked from UGRU notes
- Flatten key fields into contact or opportunity notes — with a clear prefix:
[Legacy Subscription Data] Plan: Premium, Start: 2023-01-01, MRR: $500 - Store as PDF attachments on the relevant UGRU record
- Discard — only if the data has no regulatory or business value
Do not compress all custom object data into a single unstructured notes field unless you are certain no one will need to search, filter, or report on that data again.
Workflow and Automation Loss
Clarify AI agents, automated activity tracking, and custom workflows do not transfer. UGRU has its own workflow engine with 40+ pre-built templates for advisory firms. Document every Clarify automation before migration, then map each one to either a UGRU pre-built workflow or a custom workflow you'll build post-migration. Some automations may not have equivalents and will be permanently lost.
Attachment and Document Migration
Documents attached to Clarify records need to be downloaded via API and re-uploaded to UGRU's document management system. Clarify comments live in activity streams; UGRU offers notes, document vaults, and PDF-style email archives, but the models are not one-to-one. For FINRA compliance, maintain a checklist of every client-facing document and verify each one is accounted for in UGRU post-migration.
API Failures and Retries
Clarify returns 429 Too Many Requests when rate limits are exceeded. The response includes a Retry-After header specifying wait time in seconds. Implement retry logic with the header value (as shown in the extraction code above), not fixed delays. (developer.clarify.ai)
For UGRU's import side, test CSV import failure behavior before production migration. Determine whether a single malformed row causes the entire file to be rejected (atomic) or only that row (row-level). Validate CSVs programmatically before upload:
- No null bytes or non-UTF-8 characters
- All required fields populated
- Date fields in MM/DD/YYYY format
- No JSON strings in cells (indicates unflatten collection fields)
- Row count matches expected count
Limitations and Constraints
UGRU's fixed schema is the primary constraint. Capabilities Clarify has that UGRU does not:
- No custom objects — UGRU is a pre-integrated suite. You cannot create arbitrary entity types.
- No JSON:API — UGRU's data model doesn't follow a standard API specification for inbound data.
- Limited public API documentation — UGRU's API is not as mature or publicly documented as platforms like Salesforce, HubSpot, or even Clarify. CSV is the reliable and well-documented import path.
- Household structure is manual — UGRU's entity/individual/household hierarchy must be configured during or after import. There is no automated household detection.
- Financial planning data is one-way — You can import contacts and opportunities, but you cannot programmatically import financial plan data into UGRU's Decision Center calculators. Financial plans must be created manually in UGRU.
Potential data loss scenarios:
- Custom object data with no UGRU equivalent (mitigate: archive externally)
- Multi-value fields beyond primary/secondary (mitigate: overflow to notes)
- Meeting transcript formatting and timestamps (mitigate: structured notes with date prefixes)
- Workflow configurations and automation rules (mitigate: document before migration)
- Rich text formatting in notes (may be stripped to plain text during CSV round-trip)
- Many-to-many deal-to-contact relationships (mitigate: extract as separate relationship table)
UGRU email limit discrepancy: UGRU's features page states up to 5,000 emails per day and 150,000 per month, while the Statement of Services says 25,000 mass emails per group per month are included with overages billed separately. Confirm your specific contract terms before rebuilding nurture campaigns or drip sequences. (ugru.com)
For more on UGRU's data export capabilities, see How to Export Data from UGRU CRM: Methods, Limits & Formats.
Validation and Testing
Record Count Comparison
After import, compare counts at the object level:
| Object | Clarify Count | UGRU Count | Delta | Status |
|---|---|---|---|---|
| Contacts | X | Y | X-Y | ✅ / ❌ |
| Accounts | X | Y | X-Y | ✅ / ❌ |
| Opportunities | X | Y | X-Y | ✅ / ❌ |
| Households | N/A (constructed) | Y | — | Verify against mapping file |
| Notes/Activities | X | Y | X-Y | ✅ / ❌ |
Any delta > 0 requires investigation. Common causes: duplicate merge during import, records filtered by UGRU's import validation rules, encoding errors in CSV, empty required fields causing row rejection.
Field-Level Validation
For a sample of 50 records across each object type:
- Verify first name, last name, email, phone match the Clarify source
- Confirm company/account associations are correct
- Check that opportunity values and stages transferred accurately
- Validate that notes contain the expected activity history with correct dates
- Confirm household assignments link the correct individuals
Sampling Strategy
Don't validate purely at random. Bias your sample toward records most likely to have data integrity issues:
- Records with the most relationships (high-value clients with multiple deals, household members)
- Records with custom fields or custom object associations
- Records with special characters, non-ASCII names, or long text fields
- Records at the boundary of any date filters used during extraction
- Duplicate merges — verify the surviving record has all data from both sources
- Closed-lost deals — confirm they imported with correct stage and weren't filtered
- Multi-contact opportunities — verify all participants are linked
- Any custom-object data that was compressed into notes — verify it's readable and searchable
User Acceptance Testing (UAT)
Before go-live, have 2–3 advisors spend 30 minutes working in UGRU with their migrated data:
- Can they find their top 10 clients by name search?
- Are notes and activity history present and in chronological order?
- Do pipeline reports reflect expected opportunity values and stages?
- Are household groupings correct (can they see combined household AUM)?
- Are workflow triggers firing correctly on migrated records?
- Can they access attached documents?
UAT should be role-based: advisors, operations staff, compliance officers, and admin users each test the workflows they actually touch. Document sign-off from each role before go-live.
Rollback Plan
Before starting the production import:
- Document UGRU's pre-migration state (record counts, existing data snapshot)
- Keep all source CSVs and raw Clarify API JSON extracts archived with timestamps
- Confirm with UGRU support whether a full data rollback (bulk delete of imported records) is available and how long it takes
- If running big-bang, keep Clarify active (read-only) for at least 2 weeks post-migration as a reference system
- Define rollback triggers: what level of data loss or corruption triggers a rollback vs. a manual fix? (e.g., >5% record count delta = rollback; <5% = investigate and fix)
Post-Migration Tasks
Rebuild Pipelines and Automations
Clarify AI agents, activity timelines, campaigns, and meeting intelligence do not map one-to-one to UGRU's workflows, drip campaigns, document handling, and reporting. UGRU ships workflow automation and over 40 pre-defined best-practice workflows for financial advisors — useful as starting points, but you still need to configure your own ownership rules, pipeline stages, task triggers, email templates, and reports after data lands.
After migration:
- Configure sales pipeline stages to match your Clarify deal stages (use the stage mapping table from the transformation step)
- Set up drip campaigns for client communications
- Activate pre-built workflows for client onboarding, RMD reminders, annual reviews, and account opening
- Configure territory assignments if you have multiple advisors
- Set up UGRU's email system for FINRA-compliant client communications
- Recreate any custom reports that existed in Clarify
User Training
UGRU's interface is fundamentally different from Clarify's AI-first approach. Plan for:
- 1–2 hours of guided training per advisor, focusing on daily workflows
- UGRU's embedded training videos are available on most pages — point users to these for self-service learning
- A written "cheat sheet" mapping old Clarify workflows to new UGRU equivalents (e.g., "Where Clarify showed meeting summaries on the contact page, UGRU stores them under Notes")
Structure onboarding around what changed most: where notes live, how opportunities relate to accounts and contacts via the household hierarchy, what history moved into live CRM vs. archive, and which automations were rebuilt, simplified, or dropped.
Monitoring
For the first 30 days after go-live:
- Spot-check 10 records daily for data accuracy (rotate across object types)
- Monitor for orphaned contacts (no account association) — run a weekly report
- Verify email deliverability from UGRU's built-in email system
- Confirm FINRA compliance settings are active on all client communications
- Watch for duplicates created by ongoing data entry (advisors re-entering contacts that already exist)
- Check for missing documents, broken reports, and workflow anomalies
- Track user adoption: are advisors actually using UGRU or reverting to spreadsheets/Clarify?
Best Practices
- Back up everything before extraction. Export your full Clarify workspace via API and store the raw JSON files with timestamps. You can always re-transform from raw data — you cannot re-extract from a deactivated workspace.
- Run a test migration first. Import 50–100 records into a UGRU test environment. Validate field mapping, household linking, and import behavior before touching production.
- Validate incrementally. Don't import 5,000 contacts and then start checking. Import in batches of 500–1,000, validate each batch, then proceed.
- Preserve source IDs. Add a
Source_CRM_IDfield in UGRU (custom field if supported, or as a notes prefix) to maintain a cross-reference back to Clarify records. Invaluable for debugging, reruns, and post-migration support requests. - Document every transformation. Keep a versioned mapping spreadsheet that records every field mapping decision, data type conversion, picklist mapping, and business rule applied during transformation. This is your audit trail.
- Don't migrate what you don't need. This migration is an opportunity to clean house. Stale leads, test records, and duplicate contacts should be filtered before extraction — not imported and cleaned later.
- Automate repeatable transforms. Do not hand-edit the final CSV load files. Make picklist mapping a governed artifact (a JSON or CSV file), not an email thread or a formula buried in a spreadsheet.
- Treat archive design as part of scope. Custom objects, old meeting transcripts, and compliance documents need a designated home — even if it's outside UGRU (e.g., a SharePoint document library linked from UGRU notes).
- Run at least one full test migration and one delta rehearsal before production cutover. The delta rehearsal validates your process for handling records created between the initial extract and the final cutover.
- Get UGRU import constraints in writing. Before production migration, confirm file size limits, row limits per CSV, partial failure behavior, and any field-level validation rules with UGRU support.
Making the Right Call
Migrating from Clarify to UGRU CRM is architecturally a move from flexibility to specialization. You're trading custom objects, AI-driven automation, and a modern API for industry-specific financial planning, built-in FINRA compliance, and pre-configured advisory workflows.
The technical challenge isn't extraction — Clarify's API is clean, well-documented, and rate-limited at a generous 3,000 requests per minute per endpoint. The challenge is fitting flexible, relationship-rich data into UGRU's fixed schema without losing the associations that make your client data useful — particularly household structures, multi-party deal relationships, and activity history.
For firms with under 500 clients and clean data (no custom objects, no complex household structures), a CSV-based migration is feasible in 2–3 days. For anything more complex — custom objects, years of activity history, household structures, multi-workspace consolidation, FINRA compliance requirements — budget 40–80 hours of engineering time or engage a managed migration service.
For more on evaluating your migration options, see Top 5 Best CRM Migration Solutions and The Ultimate CRM Data Migration Checklist.
Frequently Asked Questions
- Can I migrate custom objects from Clarify to UGRU CRM?
- No. UGRU CRM does not support custom objects. Any custom objects in Clarify (c_* prefix) must be flattened into notes, archived as attached documents, or exported to CSV for separate storage. There is no programmatic way to create arbitrary entity types in UGRU.
- What is the best way to import data into UGRU CRM?
- UGRU's primary data ingestion method is CSV import via its built-in migration wizard. The tool auto-matches fields and checks for duplicates. Import in order: accounts/organizations first, contacts second, opportunities third. UGRU also offers free basic data migration assistance for new customers.
- Does Clarify CRM have an API for data export?
- Yes. Clarify provides a REST API following the JSON:API specification. It supports per-workspace API key authentication, paginated queries, relationship includes, and a rate limit of 3,000 requests per minute per endpoint. You can extract persons, companies, deals, meetings, tasks, and custom objects.
- Does UGRU CRM have an API for migration?
- UGRU's Statement of Services says a developer API is available, but public endpoint docs and rate limits were not surfaced in materials reviewed. CSV import is the documented and reliable path. Confirm API details directly with UGRU before building against it.
- Will I lose data migrating from Clarify to UGRU CRM?
- Some data loss is likely unless carefully managed. Custom objects, multi-value fields beyond primary/secondary, meeting transcript formatting, workflow configurations, and rich text formatting in notes may not transfer. Relationship links between contacts, companies, and deals are flattened by CSV export and must be rebuilt.

