Skip to main content

Twenty Record Cleanup Plan

Date: 2026-05-12 Purpose: Safely clear existing demo/test records from Twenty CRM while preserving schema Status: Ready for dry-run


Scope

Delete records from:

  • People (standard object)
  • Companies (standard object)
  • Opportunities (standard object, if test records exist)
  • Tasks (standard object, if test records exist)
  • Notes (standard object, if test records exist)
  • Locations (custom object)
  • Households (custom object)
  • Engagements (custom object)
  • Needs (custom object)
  • Offers (custom object)
  • Skills (custom object)
  • ConsentRecords (custom object)
  • StakeholderRelationships (custom object)
  • Demographics (custom object)

Do NOT delete:

  • Objects/schema definitions
  • Fields/field definitions
  • Users/accounts
  • Workspace settings
  • API keys
  • Permissions/roles

Safety Rules

  1. Dry-run first — Always run with --dry-run before --apply
  2. Count before deletion — Report record counts for each object
  3. Export/log records — Save current records to JSON before deletion
  4. No schema changes — Only delete records, never schema
  5. Preserve workspace — Do not delete users, settings, or configuration

Cleanup Order

Delete in reverse dependency order to avoid relation errors:

1. Notes (may link to any object)
2. Tasks (may link to any object)
3. Demographics (links to Person)
4. StakeholderRelationships (links to Person, Company)
5. ConsentRecords (links to Person)
6. Skills (links to Person)
7. Offers (links to Person)
8. Needs (links to Person)
9. Engagements (links to Household, Person)
10. Opportunities (standard, may link to Person, Company)
11. People (links to Household)
12. Companies (links to Location, Person)
13. Households (links to Location)
14. Locations (no dependencies)

REST Endpoint Names

ObjectREST Endpoint
People/rest/people
Companies/rest/companies
Opportunities/rest/opportunities
Tasks/rest/tasks
Notes/rest/notes
Locations/rest/locationss
Households/rest/householdss
Engagements/rest/engagementss
Needs/rest/needss
Offers/rest/offerss
Skills/rest/skillss
ConsentRecords/rest/consentrecordss
StakeholderRelationships/rest/stakeholderrelationshipss
Demographics/rest/demographicss

Pre-Cleanup Report

Before deletion, the script will:

  1. Count records in each object
  2. Fetch all records (paginated if necessary)
  3. Save to twenty_records_backup_YYYYMMDD_HHMMSS.json
  4. Display summary:
    Object | Count
    --------------------|------
    People | 5
    Companies | 0
    Locations | 1
    Households | 0
    ...

Dry-Run Output

The dry-run will:

  • Report what would be deleted
  • Show record counts
  • Identify any errors (e.g., missing endpoints)
  • Save report to twenty_cleanup_report.json

Example:

[DRY-RUN] Would delete 5 records from People
[DRY-RUN] Would delete 0 records from Companies
[DRY-RUN] Would delete 1 record from Locations
...
Total records to delete: 6

Apply Mode

When run with --apply:

  • Deletes records in the order specified
  • Reports progress for each object
  • Saves final report to twenty_cleanup_report.json
  • Logs any errors

Example:

Deleting 5 records from People... Done
Deleting 0 records from Companies... Skipped (empty)
Deleting 1 record from Locations... Done
...
Total records deleted: 6

Error Handling

If deletion fails:

  • Log the error
  • Continue with next object (do not abort entire cleanup)
  • Report failed deletions in final summary
  • Save error details to twenty_cleanup_errors.json

Verification After Cleanup

After cleanup, verify:

# Check all objects are empty
curl -H "Authorization: Bearer $TWENTY_API_KEY" \
http://192.168.100.220:3000/rest/people

# Should return: {"data":{"people":[]},"totalCount":0,...}

Usage

# Dry-run (safe, no changes)
python3 cleanup_twenty_records.py --dry-run

# Apply (deletes records)
python3 cleanup_twenty_records.py --apply

Output Files

  • twenty_records_backup_YYYYMMDD_HHMMSS.json — Backup of all records before deletion
  • twenty_cleanup_report.json — Summary of cleanup operation
  • twenty_cleanup_errors.json — Error log (if any failures)

Always run dry-run first. Never run --apply without reviewing dry-run output.