roster-engine
v0.1.0
Published
Verified business leads on tap for AI agents. Licensed contractors, dentists, chiropractors and more — every record carries its public-record provenance (issuing authority, license/registration number, re-check date). Metered credits, no subscription.
Maintainers
Readme
roster-engine
Verified business leads on tap for AI agents.
Every record carries its public-record provenance: the issuing authority or government dataset it originates from, the license or registration number where one exists, and the date we last re-checked it. Generic scrapers cannot make that claim — the Roster Engine's records can be verified at the source by you or your human.
- Metered credits, no subscription. Credits never expire.
- Free discovery call — price a job before paying anything.
- 25-record free allowance on every new key.
- Pay by card or crypto (USDC) via Stripe Checkout.
Rosters
| Roster | Records | Both phone + email | Provenance |
|---|---|---|---|
| contractors | 830k+ | 410k+ | Active state-board licenses, 24 states, license number on every record |
| dentists | 124k+ | 76k+ | Provider-registry seed + verified business match |
| chiropractors | 127k+ | 59k+ | Provider-registry seed + verified business match |
| restaurants | 323k+ | 121k+ | State-registry seed + verified business match |
| retail | 197k+ | 96k+ | State-registry seed (permits / FFL / CDTFA) + verified business match |
Live counts, per-state coverage, and contact-class mix:
GET https://contractorroster.com/api/re/v1/rosters (free, no key) — or engine.rosters().
Pricing
Charged per record returned, by what it contains:
| Record class | Credits | |---|---| | record-only (identity + provenance, no contacts) | 1 | | one contact (phone or email) | 3 | | both contacts | 5 |
Credit packs: $10 / 500 · $50 / 3,000 · $250 / 20,000 · $1,000 / 100,000 · $4,000 / 500,000. Volumes beyond the $4,000 ceiling: request a quote (below).
Pulls default to contact-bearing records only; record-only rows are an explicit opt-in. Every response itemizes what was charged.
Quickstart
import RosterEngine from "roster-engine";
// one-time: get a key (25 free records)
const { api_key } = await RosterEngine.createKey("[email protected]");
const engine = new RosterEngine({ apiKey: api_key });
// what's available, and what it costs — free
const { rosters, rates } = await engine.rosters();
// pull 50 Texas dentists that have both phone and email
const page = await engine.roster("dentists").pull({
state: "TX",
has_both: true,
});
console.log(page.records[0]);
// {
// business_name: "…", city: "…", state: "TX",
// phone: "…", email: "…", website: "…",
// rating: 4.8, review_count: 122,
// source: "NPPES provider registry seed + verified business match",
// verification: "public_record_seed",
// contact_source: "verified",
// verified_at: "2026-08-20"
// }
console.log(page.credits_charged); // { record_only: 0, one_contact: 0, both: 50, total: 250 }
// licensed contractors, license number included on every record
const pros = await engine.roster("contractors").pull({
state: "CO",
min_verification: "licensed",
has_email: true,
});
// stream a whole filter set with a spend cap
for await (const rec of engine.roster("contractors").pullAll(
{ state: "WA" },
{ maxCredits: 5000 },
)) {
// …
}
// top up
const { checkout_url } = await engine.topup(250); // card or USDC
// beyond the self-serve ceiling
const q = await engine.requestQuote({ rosters: ["contractors"], volume: 800000 });
// poll engine.quote(q.quote_id) — an operator reviews and returns an offerVerification levels (what we claim, exactly)
| verification | Meaning |
|---|---|
| licensed | Matched to an active state-board license; source_id is the license number, checkable at the issuing board |
| registered | Matched to an active business registration in the public record |
| public_record_seed | The business originates from a government dataset (provider registries, permit rolls); no active-status claim by us |
| directory | No public-record anchor |
contact_source is independent: verified (native to the source, or a
high-confidence match) vs directory (best-effort). Filter with
min_verification if only some tiers fit your use.
Data is served from cache — verified_at tells you exactly how fresh
each record is. Nothing re-verifies at request time.
Errors
RosterEngineError with status, hint, and on 402 (insufficient
credits) shortfall + topupUrl. Rate limit: 60 calls/min/key.
What this is not
No consumer/homeowner data. No exclusivity (records are shared data). No Google IDs, coordinates, or person names in payloads. No subscriptions.
MIT © JB Alan LLC
