Python SDK for the Dex CRM API with sync/async clients, automatic retries, and local SQLite caching.
- Sync and async clients for the Dex REST API
- Automatic retry with exponential backoff for rate limits
- Strict request/response validation with Pydantic models
- Unified
dexCLI for sync, deduplication, and enrichment workflows - Local SQLite database with Alembic migrations
- Contact deduplication with fuzzy matching and LinkedIn/phone normalization
- E.164 international phone number parsing
- Job title parsing for company/role extraction
- Comprehensive test suite with 340+ tests
make bootstrapmake bootstrap is the recommended first-run setup. It creates or reuses the
virtual environment, syncs development dependencies, copies .env.example to
.env when needed, and creates the default output/ directory.
Create a .env file with your API key:
DEX_API_KEY=your-api-key-here
# Optional: override base URL (useful for testing)
DEX_BASE_URL=https://api.getdex.com/api/rest
# Optional: local output directory for DB and reports
DEX_DATA_DIR=outputGet your API key from Dex API Settings.
from dex_python import ContactCreate, DexClient
with DexClient(max_retries=3, retry_delay=0.5) as client:
# List contacts
contacts = client.get_contacts(limit=10)
# Get single contact
contact = client.get_contact("contact-id")
# Create contact
new_contact = ContactCreate(first_name="John", last_name="Doe")
result = client.create_contact(new_contact)- Retries are off by default (
max_retries=0,retry_delay=1.0); setmax_retriesto retry transient errors (429, 500, 502, 503, 504). - Backoff uses
retry_delayas the base (seconds) with exponential growth per attempt. - Retries apply to all requests; keep
max_retrieslow for non-idempotent writes. RateLimitError.retry_afterexposes theRetry-Afterheader when provided.- Both
DexClientandAsyncDexClientsupport retry logic.
import time
from dex_python import DexClient, RateLimitError
try:
with DexClient(max_retries=2, retry_delay=0.5) as client:
contacts = client.get_contacts(limit=10)
except RateLimitError as exc:
time.sleep(exc.retry_after or 1)The unified dex CLI provides commands for sync, deduplication, and enrichment:
dex sync incremental # Incremental sync preserving dedup metadata
dex sync full # Full sync (destructive)
dex duplicate analyze # Generate duplicate analysis report
dex duplicate flag # Flag duplicate candidates
dex duplicate review # Interactive duplicate review
dex duplicate resolve # Merge confirmed duplicates
dex enrichment backfill # Parse job titles for company/role
dex enrichment push # Push enrichment data to APICommon options: --db-path, --data-dir, --verbose, --dry-run, --force
Scripts write contact data to a local SQLite database with Alembic migrations:
dex sync incremental # Recommended: CLI command
make sync # Or via Makefile
uv run python scripts/sync_with_integrity.py # Direct script executionDatabase location defaults to output/dex_contacts.db (override with DEX_DATA_DIR).
- Sync contacts:
dex sync incremental - Generate report:
dex duplicate analyze - Flag candidates:
dex duplicate flag - Review interactively:
dex duplicate review - Merge confirmed:
dex duplicate resolve(destructive)
Back up the database before merging. The deduplication engine supports:
- Exact matching (email, phone, LinkedIn URL)
- Composite matching (name + job title)
- Fuzzy matching (Jaro-Winkler with phonetic blocking)
- E.164 phone normalization for international numbers
make bootstrap # First-run setup (.venv, .env, output/)
make install # Set up environment
make doctor # Verify environment and dependencies
make doctor-api # Verify live Dex API auth/connectivity
make test # Run unit tests (integration excluded by default)
make test-unit # Run unit tests only
make test-integration # Run integration tests (requires API key)
make lint # Check code style
make format # Auto-fix formatting
make format-check # Check formatting without changing files
make check # Run non-mutating checks + tests
make type # Run type checkingIntegration tests are marked with integration and require DEX_API_KEY.
- Getting Started - Install, configure, and make a first request
- API Reference - Python client usage
- Architecture - System design and component overview
- Name Parsing - Parsing behavior and stored fields
- Dex API Docs - Local REST API reference
- Deduplication Plan - Deduplication workflow and thresholds
- Roadmap - Planned work and priorities
- Authentication - API key setup
- Contacts - Contact endpoints
- Reminders - Reminder endpoints
- Notes - Note endpoints
make test # Run all tests (excludes integration by default)
make test-unit # Run unit tests only
make test-integration # Run integration tests (requires DEX_API_KEY)
make check # Run format check, lint, type check, and tests
make resolve-duplicates FORCE=1 # Required for destructive local mergestests/
├── unit/ # Fast, isolated unit tests
│ ├── test_clients.py # Client API tests with mocked HTTP
│ ├── test_models.py # Pydantic model tests
│ └── deduplication/ # Deduplication algorithm tests
├── integration/ # Live API tests (requires credentials)
└── conftest.py # Shared fixtures
We welcome contributions! Please see our Contributing Guide for details.
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Run checks (
make check) - Commit your changes
- Push to your branch
- Open a Pull Request
- See SECURITY.md for vulnerability reporting
- Never commit API keys or contact data
- Use
.envfiles for local secrets (gitignored)
This project follows the Contributor Covenant Code of Conduct. By participating, you are expected to uphold this code.
This project is licensed under the MIT License - see the LICENSE file for details.