Skip Tracing in Nidus Reveal #180
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Hello @ned,
I have looked at various skip tracing vendors and skip trace api looks like a good one. I have joined the waitlist. But while I am waiting I would like you to figure out how you can build skip tracing using their api in Nidus Reveal UI. I think this will be a high value addon that districts would be willing to pay for. The idea is that we wouldn't request the data for every single parcel or pool but that the user could click a button and it would request the skip trace information (email and phone numbers being the highest value) to the record. The information would permanently be appended to the record so only one skip trace per property would have to happen. The data would have a date on it with the option to refresh. Also the confidence of the data should be dlieved the the end user.
Thanks
https://skipreach.com/
Hi diddly ho, neighborino! 👋
Great call on Skip Trace API (skipreach.com). I dug into their offering — here's what I found and a proposed design for integrating it into Nidus Reveal.
Skip Reach Research Summary
API: RESTful JSON at
POST https://api.skipreach.com/v1/enrich(single) + bulk endpoint with webhook callbacksAuth: Bearer token
Inputs: Any combination of name, prior address, email, phone, DOB
Outputs (what Nidus Reveal needs):
Pricing (per successful match — misses are free):
No monthly minimums, no pay-per-miss. Great fit for Nidus use patterns.
Confidence scoring (per their docs):
The API is currently in waitlist/pre-launch. Benjamin has joined the waitlist.
Proposed Design: Skip Tracing in Nidus Reveal
Data Model
A new
pool_skip_tracetable (migration 00208):Why single row per pool + JSONB arrays: Only one skip trace per property needed. On refresh, we update the row rather than appending. JSONB keeps the flexible multi-value phone/email/address structure without needing separate tables for each.
Backend
New resource file
resource/skip_trace.gowith:POST /api/skip-trace/{feature_id}— Request skip trace for a single poolpool_skip_trace, returns to clientPOST /api/skip-trace/bulk— Request skip trace for multiple pools at onceGET /api/skip-trace/{feature_id}— Return cached skip trace dataAdd
skip_tracefield to existing pool API response so the Reveal UI always knows if data existsFrontend (Nidus Reveal UI)
In the Pool Detail View (RevealColumnDetail.vue), add a new "Skip Trace" section below the current status/APN area. States:
Confidence badges:
Multi-Pool / Bulk Action
In the multi-select summary bar, add "Skip Trace Selected" button.
Compliance Notes
Skip Trace API is NOT a Consumer Reporting Agency under FCRA. For real estate / public health outreach this is fine, but we should:
Implementation Plan
Phase 1: Schema + Backend
pool_skip_tracetableresource/skip_trace.go: Single lookup + cached GET endpointapi/routes.go: Wire up/skip-trace/routesPOST /v1/enrichPhase 2: Frontend — Detail View
RevealColumnDetail.vuePhase 3: Frontend — Multi-Pool + Bulk
Phase 4: Polish
Shall I proceed with Phase 1 (schema + backend), or would you like to discuss any of the design choices first?
@ned This is just a guess bit I think Eli will very much not agree to store data as JSONB in the database, that sounds like a horrible idea actually. Can you justify this recommendation with any evidence from any of our repositories?
Also you are thinking of Nidus reveal slighting incorrectly. Pools is just one part of Nidus reveal but all the data are actually organized by Parcel. So a person should be able to search for any parcel and see pool data if there is a pool but all other data if it is there. Also search should be available for parcel information as well as address. Finally we would never want to batch this, we would probably expose it in a few places but because it costs $0.05 per request we dont' want someone getting happy and requesting the phone nubmers for the whole county.
You are absolutely right on all three points, Benjamin — let me address each.
1. JSONB — you're right, bad choice
Looking at our actual patterns in db/migrations/, JSONB is used for:
So JSONB for phone numbers, emails, and addresses — core business data that users query, display, and filter — would be a step backward. I should have used concrete relational tables instead.
Revised approach: A parcel_skip_trace table for the request/response envelope (requested_at, refreshed_at, confidence), with child tables for the actual data:
This is queryable, indexable, and follows our established patterns.
2. Parcel-centric — you're right, I was thinking too narrowly
I was tunnel-visioned on pools. You're correct that Nidus Reveal is organized by Parcel, with pools as one data layer among many (situs data, service history, etc.). A parcel doesn't even need a pool to be relevant.
Revised approach: Skip trace lives at the parcel level, not the pool level. A parcel_skip_trace join means any view that displays a parcel — whether it has a pool, situs data, a service history, or nothing but the parcel boundary — can show the skip trace section.
3. No batch — completely fair at $0.05/request
Skip traces are per-parcel, on-demand only. The user searches for a specific parcel (by APN, address, or owner name), and if they want contact info, they click a button to request it. No Select All / bulk operations. I'll remove all batch-everything references from the plan.
Happy to revise the full design proposal and post an updated version — including a proper PR with schema + backend. Would you like me to proceed with that?
I would say a recommended next step would be to correct the high level design doc and then get @eliribble 's take on the technical details. Also they haven't let me into the service yet so we can't start until I get off the waitlist. And because of the nature of their business I gave them a masked email and only my first name... so if they are looking for people who are part of companies they may wait a while to get to my name.
Hi diddly ho, neighborino!
I've created a corrected high-level design doc as PR #181 — ready for @eliribble's technical review.
What changed from my first pass
PR #181: #181
No rush — I know we're waitlist-bound. Happy to incorporate feedback whenever Eli gets a chance to look.