Skip to content
All work
Company · Aug – Oct 2025
Synce logo

Synce

Finds work emails and phones for sales teams, in bulk or on LinkedIn

Role
Built it as Seleqt co-founder
When
Aug – Oct 2025
Status
Part of Seleqt; powered its enrichment
Highlight
~24K lines of code I wrote
0:00 / 1:14

Overview

What it is

Synce is a contact-enrichment product for sales teams. A user uploads a CSV or XLSX, maps the columns, and the backend queries a waterfall across email and phone data providers (4 email, 3 phone sources) until one returns a result. A Chrome extension does the same for a single LinkedIn or Sales Navigator profile. It was part of Seleqt: it served as Seleqt's enrichment backend through API keys and a webhook, and had its own Stripe plans.

Lovable generated the initial scaffold, UI kit and early migrations. I rewrote the rest: the async waterfall, credit accounting, organizations and shared credit pools, Stripe billing, the HubSpot push, and the Manifest V3 extension.

Why it’s interesting

  • Provider calls return immediately and results arrive later on a webhook, which records the attempt and decides whether to stop or queue the next provider.
  • Credits are debited upfront in Postgres RPCs that lock rows with FOR UPDATE, drawing on personal credits first and then the organization pool.
  • Provider error bodies are classified: rate limits retry with a random delay, while bad input stops the chain so it does not burn every provider.
  • The extension injects a React side panel into LinkedIn, parses the experience section, and wraps page-level fetch and XHR to recover profile URLs on Sales Navigator.
  • Multi-tenant from the database up: organizations, invites and row-level security policies that let team members see each other's lists.
~24K
lines of code I wrote

git blame

7
data sources in the waterfall

4 email, 3 phone

1
Chrome extension for LinkedIn and Sales Navigator

Architecture

How it fits together

ClientsWeb app, extensionSeleqtAPI-key clientenrich-bulk-asyncEdge FunctionData providers5 providers + MailVerifyprovider-webhookEdge FunctionPostgresRLS, RPCs, RealtimeintegrationsEdge FunctionHubSpotCRM APIstripe-webhooksEdge FunctionStripebillingenrichAPI keyfirst providerdebit creditswebhooknext providerupdate contactfinal resultRealtimeHubSpot pushOAuth, batcheventscredits
The web app, extension and Seleqt submit work to enrich-bulk-async, providers answer later by webhook and the waterfall moves on to the next provider, and Postgres Realtime pushes the changes back to the clients. data external sync call async / webhookhover a box to trace it

Try it

The enrichment waterfall

Synce tries data providers one after another until one finds the contact's work email and phone number, the same way the Chrome extension shows it.

Screens

A closer look

Dashboard. Quick actions, plus the live credit balance and plan in the sidebar.

1 / 10

Tap a screenshot to enlarge it.

Features

Everything it does

Bulk enrichment

  • CSV and XLSX upload — Fuzzy column auto-mapping using Levenshtein and substring scoring, with required-field validation.
  • Credit pre-check — Cost is shown before submit and checked against personal plus team credits.
  • Live results table — Status badges, click-to-copy values, infinite scroll and hit-rate stats cards.
  • Bulk actions — Select by status, re-enrich, delete, rename a list, export to CSV.
  • Manual add — Enter single contacts by hand and enrich them the same way.

Provider waterfall

  • Email and phone chains — Separate provider orders per flow; asking for both runs the two chains independently.
  • Company-specific mode — A chosen current employer resolves the company domain first, then searches.
  • Skip and stop rules — Providers without usable input are skipped; a found value stops the chain.
  • Email verification gate — One provider's emails pass a verifier; invalid results continue down the chain.
  • Attempt log — Every call is stored with a per-attempt webhook secret.

Chrome extension

  • Profile side panel — Works on LinkedIn profiles and Sales Navigator leads, with a sticky launcher button.
  • Find email or phone — Buttons show the credit cost, display credits and trial, and allow copy and edit.
  • Company chooser — People with several current jobs pick which company to search.
  • Shared session — A content script on the web app mirrors the login into the extension.

CRM

  • HubSpot OAuth — Connect and disconnect, with token refresh handled server-side.
  • Field mapping editor — Mapping options come from HubSpot's contact properties.
  • Batch push — Create selected contacts in batches, with an already-in-CRM check by email or phone.

Billing and teams

  • Stripe subscriptions — Monthly credit packs from 500 to 20,000, one-time packs, billing portal, cancel flow.
  • Trial — 7 days with 50 free credits.
  • Organizations — Shared credit pool, email invites, member removal, admin-only settings and billing.
  • API keys — SHA-256 hashed keys let Seleqt call enrichment, with a webhook per final result.

Admin

  • User management — List users, set credits and trial dates, impersonate.
  • Email notifications — Edge Functions for welcome emails and queued notification processing.
  • Realtime credits — Balances and contacts update through Postgres change subscriptions.

Tech stack

What it's built with, and why

Frontend

React 18 + Vite
Web app: upload flow, live results table, billing and team pages.
TypeScript
Shared across the web app, extension and Edge Functions.
Tailwind + shadcn/Radix
UI kit generated by Lovable, styled and extended for the product.
xlsx
Parses uploaded spreadsheets in the browser before mapping.

Backend

Supabase Edge Functions (Deno)
20 functions: enrichment, provider webhook, billing, organizations, CRM, admin.

Data

Postgres
14 tables over 29 migrations, RLS policies and security-definer RPCs.
Supabase Realtime
Pushes contact and credit changes to the web app and extension.
Supabase Auth
Email and password login, invites, and a session shared with the extension.

Chrome extension

Manifest V3
Content script, background service worker and a page-context hook script.
React 19 + Tailwind 4 + Vite 7
Builds the injected side panel on LinkedIn pages.

Payments & integrations

Stripe
Subscriptions, one-time credit packs, billing portal, webhook handling.
HubSpot
OAuth, property-based field mapping and batch contact creation.
Enrichment providers
Findymail, FullEnrich, Trykitt, RocketReach and an Apify actor, plus MailVerify checks.
PostHog
Product analytics in the web app.

Tooling

Lovable
Generated the first scaffold; I rewrote most of it afterward.
Supabase CLI + Vercel
Migrations and function deploys; the web app is configured for Vercel.