Skip to content

Add CSuiteFinder to the catalog (work-email resolution + enrichment) - #402

Open
lbesecker195 wants to merge 2 commits into
superdesigndev:mainfrom
lbesecker195:vendor/csuitefinder
Open

lbesecker195 wants to merge 2 commits into
superdesigndev:mainfrom
lbesecker195:vendor/csuitefinder

Conversation

@lbesecker195

Copy link
Copy Markdown

Adds CSuiteFinder — work-email resolution, verification, person and company enrichment.

Contact: lbesecker195@gmail.com (for arranging a test credential; happy to send a credits grant too)

Eligibility

Requirement Status
Self-serve keys POST /csuitefinder/register with an email returns a key immediately — no dashboard, no sales call
Key in header, not path Authorization: Bearer <key> (also accepts X-API-Key)
Free probe that rejects a bad key GET /billing/balance — 200 valid / 401 invalid, spends nothing
Published pricing, stable URL https://csuitefinder.com/csuitefinder/pricing — live JSON rate card, no credential required
Docs with example values https://csuitefinder.com/ documents every route with worked examples

Probe bad-key behavior, observed on the wire 2026-09-09

$ curl -i -H "Authorization: Bearer garbage_not_a_real_key" \
    https://csuitefinder.com/csuitefinder/billing/balance
HTTP/1.1 401 Unauthorized
{"error":"unauthorized","message":"Invalid API key."}

A valid key on the same route returns 200.

Billing model

Tokens at a flat, published $0.0025 each; bundles from $1,000 (400,000 tokens). New accounts self-register and get 400 trial tokens ($1).

Exactly one route spends tokens/email/find, 1 token per address resolved, nothing when it resolves nothing. Every other data route is included: 0 tokens, but still requires a positive balance, so an exhausted key gets 402 rather than unlimited free enrichment. That distinction is in each cost note.

  • Rate card (machine-readable, unauthenticated): https://csuitefinder.com/csuitefinder/pricing
  • Human pricing: https://csuitefinder.com/
  • OpenAPI: not published yet. Happy to add one if that unlocks the extended tier — say the word.

Self-verification ledger

Every test_request below was live-called on 2026-09-09 against a fresh trial key. The meter is the token_balance field on GET /billing/balance, read immediately before and after each call.

endpoint http test target tokens observed catalog price matches? evidence
csuitefinder.people.email.find 200 Patrick Collison @ stripe.com 1 per_success 1 tok ($0.0025) balance 400 → 399
csuitefinder.people.email.find (repeat) 200 same target again 1 per_success 1 tok balance 399 → 398 — repeats are not free
csuitefinder.people.email.find (miss) 200 name that does not resolve 0 per_success (miss free) balance 398 → 398 — confirms per_success
csuitefinder.people.email.verify 200 patrick@stripe.com 0 free (included) balance 398 → 398
csuitefinder.people.enrich 200 patrick@stripe.com 0 free (included) balance 398 → 398
csuitefinder.people.name.lookup 200 patrick@stripe.com 0 free (included) balance 398 → 398
csuitefinder.companies.email_pattern 200 someone@stripe.com 0 free (included) balance 398 → 398
csuitefinder.companies.enrich 200 someone@stripe.com 0 free (included) balance 398 → 398
csuitefinder.companies.identify 200 someone@stripe.com 0 free (included) balance 398 → 398
csuitefinder.account.usage 200 0 free balance 398 → 398
csuitefinder.account.usage.history 200 days=7 0 free balance 398 → 398
csuitefinder.account.pricing 200 — (no key needed) 0 free unauthenticated

Reconciliation: 400 granted − 2 finds billed = 398 remaining, which is the balance the account ended on. No deliberate-miss test targets are used as test_requests — every catalogued test_request is a real, resolving call. The miss row above was an extra probe run specifically to prove miss-is-free, and is not in the YAML.

Two things worth flagging to whoever verifies:

  1. Repeats are not free here. Unlike some providers in this catalog, a second identical /email/find charges again. So an observed delta of 0 on this API always means "no result", never "cache hit" — the meter is unambiguous, and re-running verification on the same targets will cost the same as the first run.
  2. confidence: verified on the cost blocks reflects that live balance-delta measurement, not a docs transcription. I have deliberately not added verified: stamps or example responses — those are yours.

Full-surface map

Every documented operation. There are 15 in total; 10 catalogued.

operation catalogued?
GET/POST /email/find
GET/POST /email/deliverable
GET/POST /email/enrich
GET/POST /email/pattern
GET/POST /name/who
GET/POST /company/find
GET/POST /company/info
GET /billing/balance ✅ — free, and the registry probe
GET /billing/usage ✅ — the pre-flight budgeting route
GET /pricing ✅ — free, unauthenticated rate card
POST /register ❌ creates an account; treg injects an existing credential, so it is not an agent operation
POST /billing/topup ❌ starts a PayPal checkout — a payment flow, not data
POST /billing/capture ❌ completes that payment
POST /billing/webhook ❌ PayPal's callback; signature-verified, not caller-facing
GET /health ❌ liveness only, returns no data an agent could use
GET /admin, /admin/metrics.json, /ops/* ❌ operator-only, behind a separate admin token

Both rules of thumb from the vendor doc are covered: the free pre-flight routes (/pricing, /billing/usage, /billing/balance) are in, and there is no cheaper tier of any operation to omit — the cheap tier is the default, since only one route bills at all.

Capability mapping

All five capabilities already exist; nothing new is proposed. Every endpoint lands next to existing providers:

  • people.email.find — alongside hunter, tomba, trykitt, findymail, leadmagic
  • people.email.verify — alongside hunter, tomba, trykitt, millionverifier, icypeas
  • people.enrich — alongside hunter, tomba, apollo, pdl
  • companies.email_pattern — alongside thecompaniesapi, tomba
  • companies.enrich — alongside thecompaniesapi, hunter, tomba, companyenrich

Two capabilities carry two endpoints each (/email/enrich + /name/who; /company/info + /company/find). They are genuinely distinct routes sharing a price: the second of each pair returns only the identity fields, for callers who want a name rather than a full record.

Data provenance — disclosure

CSuiteFinder sources some of its underlying data through treg itself, which your vendor docs explicitly permit and encourage ("Reselling treg inside your own product … allowed and encouraged with no special agreement"). Flagging it up front so it is not a surprise mid-review.

What CSuiteFinder adds on top, and why it is not a pass-through: it resolves a company's address pattern once and then applies it to every subsequent employee, so most lookups are answered without any upstream call. That is what makes a flat 1-token price possible where per-person lookups cost more, and it is why six of the seven data routes are included rather than metered.

Checks

scripts/catalog_validate.py   OK — 93 provider file(s), 3217 endpoint(s), 0 error(s), 0 warning(s)
scripts/catalog_verify.py csuitefinder   10/10 PASS (all http 200), live, 2026-09-09
pytest -n auto -q             3039 passed, 5 skipped, 4 failed

The 4 failures are pre-existing on untouched main and unrelated to this PR — I confirmed by stashing this branch and re-running. They are all in tests/test_usage_caps.py, and they are a timezone artifact rather than a real defect: the code dates usage in UTC while the tests assert against local date.today(), so they fail on any machine whose local date differs from UTC at the time of the run.

$ TZ=UTC uv run pytest tests/test_usage_caps.py -q
13 passed

(Local clock was 2026-09-08 23:21 PDT = 2026-09-09 06:21 UTC.) Worth a freeze_time or a UTC-normalised assertion at some point; out of scope here.

Rebased on 6e6ba3f immediately before opening. Diff is the five expected files only — registry entry, catalog YAML, logo, two test lists. No credential value anywhere in the diff, no verified: stamps, no committed examples.

CSuiteFinder resolves a name and a company domain to a work email, then
verifies, enriches and identifies it. Ten endpoints across five capabilities
that already exist in the taxonomy, so every one lands on a comparison shelf
next to Hunter, Tomba and Findymail rather than starting a shelf of one.

  people.email.find        /email/find        1 token ($0.0025), per success
  people.email.verify      /email/deliverable included
  people.enrich            /email/enrich      included
  people.enrich            /name/who          included (narrow form)
  companies.email_pattern  /email/pattern     included
  companies.enrich         /company/info      included
  companies.enrich         /company/find      included (narrow form)
  account.usage            /billing/balance   free (registry probe)
  account.usage            /billing/usage     free
  account.usage            /pricing           free, unauthenticated rate card

Billing is unusual enough to state plainly: tokens cost a flat, published
$0.0025, and exactly one route spends them. The rest are included but still
require a positive balance, so an exhausted key gets 402 rather than unlimited
free enrichment.

Every cost block cites the live rate card at /csuitefinder/pricing, which is
public and needs no credential — a reviewer can machine-check every price
before calling anything.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@github-actions github-actions Bot added the area:dashboard The web dashboard / landing / tutorials label Sep 9, 2026
…ng people.email.find

Four endpoints, all mapped to existing capabilities so this routes the day it
merges:

  people.email.find     /email/linkedin       $0.015 per success
  people.search         /people/search        $0.0025 per row
  companies.search      /company/search       $0.0025 per row
  companies.emails.list /email/company/people $0.0025 per row

The billing preamble was also wrong and is rewritten. The listing described a
token system that no longer exists — prices are in dollars per answer now, the
trial is $1 for a month rather than 400 tokens, and there are four per-row
routes where before there was one billable route. A review run against the live
API would have caught it; better it reads true first.

It also now says why the email price sits under this capability's floor, since
that is the obvious reviewer question: the company's address FORMAT is bought
once and every colleague is resolved from the stored pattern without another
lookup. The per-address price is amortised across a company rather than the
cost of one purchased find. Different unit economics, not a loss-leader.

PROPOSAL, take it or leave it: `people.email.find` covers two jobs with
different inputs, different prices and different buyers, and the router already
distinguishes them (`domain+full_name` vs `linkedin_url`). Naming the split
would give each its own comparison page and stop an agent holding a name and a
domain being quoted a LinkedIn-only provider. It is not a shelf of one — both
sides already have several providers, listed in the file. Every endpoint here is
mapped to the existing capability regardless, so the PR stands either way.

🤖 Generated with [Claude Code](https://claude.com/claude-code)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:dashboard The web dashboard / landing / tutorials

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant