Playbook
EnformionGO Integration Guide
Consumer skip-trace API (Galaxy) for finding an individual’s personal contact info — personal emails and mobile phones — from name + city/state. Tool quick-pick:- Personal email →
enformion_person_search(Person database; returnsemailAddresses[]flaggednonBusiness:1). Do NOT useenformion_workplace_searchfor personal email — it returns other-employer work emails. - Personal mobile (phone-first) →
enformion_contact_enrich(skip-trace, ~53% mobile hit rate). - Officers of a business →
enformion_business_search→ officertahoeId→enformion_person_searchby tahoeId.
When to use
Useenformion_contact_enrich when you need to find the personal mobile of a small business owner (restaurant, retail, local services) who has:
- No LinkedIn profile
- No company domain email
- No B2B database presence
Critical gotchas — read before calling
1. Strip middle initials from last_name (automatic)
The integration automatically strips middle initials. You do NOT need to pre-process — just pass the raw last name. But be aware:"K Tarzai"→ bare last ="Tarzai"✓"De La Cruz Castillo"→ bare last ="Castillo"✓"Smith Jr."→ bare last ="Smith"✓
2. FL SOS officer names (use reverseFlOfficerName helper)
Florida SOS returns officer names as"LASTNAME, FIRSTNAME MIDDLE". You must reverse these before calling:
"SMITH, JOHN EDWARD"→"John Smith"✓"DE LA CRUZ, MARIA"→"Maria De La Cruz"✓
reverseFlOfficerName() is exported from actions/enformion-shared.ts.
3. Rate limits
No documented rate limit, but runs degrade with >200 concurrent requests. The Deepline rate limiter caps at 10 req/s which is safe for all batch sizes.4. No-result interpretation
identityScore: 0= no match found (not billed)identityScore: 75–100= high confidence matchperson.phones[]empty = found the person but no phone on record
Response structure
person.phones.find(p => p.type === "mobile" && p.isConnected === true)?.number
Validation
After finding a phone via EnformionGO, validate it withtrestle_phone_validation:
line_type: "Mobile"+activity_score >= 60= confirmed owner mobileline_type: "Landline"orline_type: "FixedVOIP"= store/office phone — discard
Credentials
Requires two custom headers set from stored credentials:galaxy-ap-name: your API key namegalaxy-ap-password: your API key password
ENFORMION_KEY_NAME + ENFORMION_KEY_PASSWORD environment variables.
API endpoint: https://devapi.enformion.com/Contact/Enrich
enformion_person_search — PERSONAL emails (use this, not workplace_search)
When to use
Useenformion_person_search whenever you need a person’s personal email (and/or phone). This is the Galaxy “Person Search” database (galaxy-search-type: Person). Unlike Workplace Search — which returns the owner’s other-employer work emails 97% of the time — Person Search returns the individual’s personal addresses (gmail/yahoo/comcast), each flagged nonBusiness: 1.
Two lookup modes:
- By name + city/state — the common path.
enformion_person_search({ first_name, last_name, city_state }). - By tahoe_id — exact-person lookup. Pass
{ tahoe_id }to pin one identity (e.g. an officer tahoeId returned byenformion_business_search). Whentahoe_idis set, the name/location fields are ignored.
Recommended flow for business officers (vendor-recommended)
To get the personal contact info of a business’s officers/agents:enformion_business_search({ name, city_state })→ business record withofficers[]/ agents, each carrying atahoeId.- For each officer,
enformion_person_search({ tahoe_id })→ that person’semailAddresses[]+phoneNumbers[].
isError: true (“Access Profile does not permit client to call Business Search.”). When that happens, fall back to person-search-by-name using the officer name you already resolved (from Google/Yelp/SOS) — Person Search is entitled and returns the same personal contact data. (As of 2026-06-09 the aeroailabs profile has Person Search but not Business Search.)
Response structure (Person Search)
persons[0].emailAddresses[0].emailAddress (prefer entries with isPremium: true). No result: persons is an empty array.
Billing
Billed per match (post_deduct, $0.35) only when the top match has a personal email or a connected phone. No charge on empty / no-match.
API endpoint: https://devapi.enformion.com/PersonSearch (galaxy-search-type: Person).
Business Search endpoint: https://devapi.enformion.com/BusinessSearch (galaxy-search-type: Business).
enformion_workplace_search
When to use
Useenformion_workplace_search as a fallback when enformion_contact_enrich returns identityScore: 0 or an empty phones array. It queries a separate B2B employment profile database and has a different rate-limit bucket, so it does not compete with Contact/Enrich capacity.
city_state is optional here (unlike Contact/Enrich where it is required). Omitting it broadens the match at the cost of potentially more ambiguous results.
Critical warning: emailAddresses[]
emailAddresses[] in Workplace Search results are almost always the owner’s OTHER employer (a corporate day job, a franchise group, etc.) and NOT the restaurant’s email. In practice:
- 97% of returned email addresses belong to a different employer.
- Only use an email address if the domain matches the target restaurant’s domain (e.g.,
gary@lincolnautogroup.comis useless if you wantgary@lincolndiner.com).
Rate-limit bucket
Workplace Search uses a separate rate-limit bucket from Contact/Enrich. Both can run concurrently without reducing each other’s throughput. The Deepline rate limiter treats them as independent pools.Response structure
workplaceRecords[0]?.phoneNumbers?.[0]
No result: workplaceRecords will be an empty array [].
Billing
Billed per match (post_deduct, $0.50) only when a workplace record with a phone or email is returned. No charge on empty / no-match.