Skip to main content

RB2B → TwentyCRM Import Pipeline

Download

Download RB2B → TwentyCRM Import Pipeline — zip containing the script and README.

Scripts for importing an RB2B visitor-identification CSV export into a TwentyCRM workspace. Creates companies, people, scored opportunities, and "Next Steps" checklist notes.

See tools/rb2b.md for full context on RB2B, the data model, and automation opportunities.


Prerequisites

Python 3.11+ — no third-party packages required (stdlib only).

Add to the root .env file:

RB2B_TWENTYCRM_API_KEY=your-client-workspace-token
RB2B_TWENTYCRM_API_BASE=https://your-twenty-instance.com/rest

Get the API key from Settings → Playground in the target TwentyCRM workspace.

Important: Use the client workspace token — not the Pacing agency workspace token. Each TwentyCRM workspace has its own isolated API keys.


Scripts

1. rb2b-import.py — Import companies and people

Reads the RB2B CSV and creates all companies and people in TwentyCRM. Custom fields are created automatically on the first run.

python3 scripts/resources/rb2b/rb2b-import.py \
--csv ~/Downloads/filtered_custom_report_XXXXXXXXX.csv

What it does:

  1. Reads ProfileType to split rows into Company and Person groups
  2. Creates 9 custom fields on both company and person objects (idempotent — skips fields that already exist):
    • industry, estimatedRevenue (Text)
    • allTimeViews, recentPageViews (Number)
    • lastSeenAt, firstSeenAt (DateTime)
    • leadTags, leadReferrer, visitedPages (Text)
  3. Creates all Company rows first — maps standard fields (name, domainName, linkedinLink, employees, address) plus custom fields
  4. Creates stub companies for any company referenced by a Person row but not present as a Company row
  5. Creates all Person rows — maps name, emails, jobTitle, linkedinLink, city, links to company

Field mapping:

CSVTwentyCRM fieldNotes
CompanyNamenameCompany and person
WebsitedomainName.primaryLinkUrlCompany
LinkedInUrllinkedinLink.primaryLinkUrlBoth
EstimatedEmployeeCountemployeesConverted from range to midpoint integer
City + State + ZipcodeaddressCompany
WorkEmailemails.primaryEmailPerson
FirstName + LastNamename.firstName / name.lastNamePerson
TitlejobTitlePerson
Industryindustry (custom)Both
EstimateRevenueestimatedRevenue (custom)Both
AllTimePageViewsallTimeViews (custom)Both
RecentPageCountrecentPageViews (custom)Both
LastSeenAtlastSeenAt (custom)Both
FirstSeenAtfirstSeenAt (custom)Both
TagsleadTags (custom)Both
MostRecentReferrerleadReferrer (custom)Both
RecentPageUrlsvisitedPages (custom)Deduplicated, newline-separated

Output: Writes rb2b-import-log.json alongside the script with every created record's CRM UUID.


2. rb2b-opportunities.py — Create scored opportunities

Reads the import log and CSV, scores every lead, then creates the top N opportunities with stage, score, and a "Next Steps" checklist note.

python3 scripts/resources/rb2b/rb2b-opportunities.py \
--csv ~/Downloads/filtered_custom_report_XXXXXXXXX.csv \
--top 10

Scoring (1-10):

SignalPoints
Base2
All-time views ≥ 5 / ≥ 15 / ≥ 30 / ≥ 50+1 / +2 / +3 / +4
Recent views ≥ 3 / ≥ 10+1 / +2
"Hot page" tag+2
Has work email+1

Stages assigned:

StageCondition
MEETING"Hot page" AND (has email OR views ≥ 20)
SCREENINGHas email OR views ≥ 10
NEWEverything else

What it creates per opportunity:

  • Opportunity record linked to company, with score and stage set
  • pointOfContact set to linked person (if one exists)
  • One "Next Steps" note with a BlockNote checklist attached via noteTargets

Checklist items generated per lead:

  • Research [name]: industry, size, product & background
  • Find key decision makers (CMO / VP Marketing / Head of Growth)
  • Send personalised cold outreach email (if has email)
  • Follow up after 3 business days (if has email)
  • Review visited pages for intent signals (if has page data)
  • HIGH PRIORITY fast-track note (if score ≥ 7)

Output: Writes rb2b-opportunities-log.json with each created opportunity's ID, stage, score, and tasks.


3. rb2b-notes.py — Add notes to existing opportunities

Idempotent script that adds a "Next Steps" checklist note to any opportunity that doesn't already have one. Useful after manually creating opportunities in the UI.

python3 scripts/resources/rb2b/rb2b-notes.py \
--csv ~/Downloads/filtered_custom_report_XXXXXXXXX.csv

Skips opportunities that already have a note linked via noteTargets.


Typical Run Order

# 1. Import all companies and people
python3 scripts/resources/rb2b/rb2b-import.py \
--csv ~/Downloads/your-export.csv

# 2. Review the score ranking (printed to console) and pick top N
# 3. Create top 10 opportunities with notes
python3 scripts/resources/rb2b/rb2b-opportunities.py \
--csv ~/Downloads/your-export.csv \
--top 10

# 4. If you created additional opportunities manually in the UI, add notes to them
python3 scripts/resources/rb2b/rb2b-notes.py \
--csv ~/Downloads/your-export.csv

Re-running / Idempotency

ScriptSafe to re-run?Notes
rb2b-import.py⚠ PartialCustom field creation is idempotent; company/person creation will create duplicates if run twice. Check CRM before re-running.
rb2b-opportunities.py⚠ PartialWill create duplicate opportunities if run twice on the same leads. Delete existing opps first if re-running.
rb2b-notes.py✅ YesChecks for existing noteTargets before creating.

Logs

All scripts write JSON logs to their working directory:

  • rb2b-import-log.json — company and person CRM IDs
  • rb2b-opportunities-log.json — opportunity CRM IDs, stages, scores

Keep these logs alongside the source CSV — you'll need the IDs if you want to update or delete records later.


Automation (Future)

The current pipeline is manual. See tools/rb2b.md for a full breakdown of automation options, including:

  • RB2B webhook → n8n → TwentyCRM (no CSV step)
  • Automated email sequences via Resend for high-scoring leads
  • LinkedIn Matched Audiences export for retargeting
  • Slack alerts for score-10 leads