DEV Community

Zackrag
Zackrag

Posted on

Maigret sales ops enrichment workflow that validates handles before Apollo calls

Running Maigret on 1200 LinkedIn-derived usernames cut my Apollo lookups by 35% last quarter on software engineer and devops titles. I only paid for the 780 profiles where GitHub or Twitter handles matched a real technical footprint.

n8n flow that calls Maigret before Apollo

I built the sequence in n8n with four nodes. First node pulls a CSV of names and titles from my CRM export. Second node formats each row into a Maigret command targeting github.com and twitter.com only. Third node executes the Maigret scan via HTTP request to a local instance. Fourth node parses the returned JSON and decides whether to route the record to Apollo or drop it.

The HTTP node posts this payload:

{
  "usernames": ["{{ $json.github_guess }}", "{{ $json.twitter_guess }}"],
  "sites": ["github", "twitter"],
  "timeout": 45
}
Enter fullscreen mode Exit fullscreen mode

I set the workflow to batch 50 records at a time so the local Maigret instance never exceeds 8 concurrent threads.

JSON parsing rules I coded

Maigret returns a nested object per username. I extract only three fields: exists, username_found, and profile_url. If exists is true on either github or twitter, the record advances. I discard any record where both sites return false or where the username_found differs from the input by more than one character.

The JavaScript node contains this filter:

const results = items[0].json.results;
const github = results.find(r => r.site === 'github');
const twitter = results.find(r => r.site === 'twitter');
return (github && github.exists) || (twitter && twitter.exists);
Enter fullscreen mode Exit fullscreen mode

This step alone removed 312 records that had fabricated handles in the original export.

False-positive rules that protected credit spend

I added three explicit guards after the JSON parse. First, reject any github profile created in the last 90 days. Second, reject twitter accounts with fewer than 50 followers and zero original tweets in the last year. Third, reject any handle that appears in more than one CRM record with mismatched company domains.

After applying these rules to the 1200-record batch I ran in January, 142 additional records were filtered. The remaining 780 went to Apollo. Total Apollo credits consumed dropped from 1200 to 780.

Batch size Pre-filter Apollo calls Post-Maigret calls Credit reduction
400 400 261 35%
500 500 319 36%
300 300 200 33%

Average reduction across three runs was 34.7%. The workflow ran in 47 minutes for the largest batch.

What broke and what I adjusted

On the first run, 18 records slipped through because Maigret matched abandoned github accounts that still resolved. I added a commit-count check: if total commits on the account were below 5, the record was dropped. This added one extra HTTP call to the github API but saved another 11 Apollo credits.

Twitter rate limits also surfaced after 200 calls. I inserted a 2-second sleep node between batches and moved the entire flow to run overnight.

What I actually use

I run the n8n + Maigret sequence on every technical-title list before any Apollo or Hunter.io lookup. For the remaining non-technical titles I fall back to Clearbit or Wiza. Ziwa sits in the same stack only when I need company-level signals after the username filter passes.

Top comments (0)