REST Enrichment Inside a Hiring Product: Auth, Credits, Rate Limits
REST enrichment inside a hiring product: auth, credits, and rate limits for builders – Bearer keys, found-only billing, honest empty paths.

Hiring products that add enrichment should treat REST lookup as a module: auth, credits, rate limits, and honest empty UI – not a CRM bolt-on. Invenitor’s find API: LinkedIn or GitHub profile URL in, email/phone out when found, empty means not found. Connecting people; a lookup API, not a sales cloud.
Architecture sibling: Adding Contact Lookup to an ATS: Architecture Notes for Builders. Category: What a Contact Lookup API Actually Does. Hub: LinkedIn or GitHub Profile URL → Contact Lookup API. Docs: /docs.
Auth
- Use Bearer API keys from a secure secret store – never ship keys in frontend bundles.
- Map keys to a workspace/tenant so recruiters share a credit pool.
- Rotate keys when people leave; do not paste keys into public tickets.
MCP twin uses the same key mindset: /mcp.md, Claude / Cursor Agents.
Credits inside the product
Surface balance and pack expiry (Invenitor: 30 days) in admin UI. 1 credit only when we return an email, a phone, or both. Empty completed finds are free. Timeouts and errors do not spend. Show found vs empty vs error in audit logs without dumping PII into analytics junk drawers.
Billing pillar: Credits, Empty Results, and Timeouts. Pricing tiles: /pricing. PAYG narrative: Pay-As-You-Go Contact APIs. India packs: INR Credit Packs.
Rate limits (guidance, not theater)
Document soft guidance (e.g. about one find per minute language in docs) as client hygiene, not a fake marketing SLA. Rate-limit UI double-clicks. Batch imports should queue with backoff. Do not nightly re-enrich hoping coverage flips on a clock – soft mesh does not work that way; we do not publish hit-rate %.
Empty and error UI contract
| Outcome | UI | Billing |
|---|---|---|
| Found email/phone/both | Show primary fields | 1 credit |
| Empty completed | Not found | Free |
| Timeout / error | Retryable error | No spend |
Primary fields: One Primary Contact, Never Invented. Honesty: Empty Means Not Found. Definition: What Is a LinkedIn Profile URL Lookup?.
Sync patterns that stay sane
On-demand button first; capped batch second; agent-assisted fill via MCP third. Avoid invent-on-merge. Sheets path for customers who are not ready for ATS: Agency Desk Playbook.
What not to ship
- Scraper fallbacks.
- Name+domain email guessing.
- Hit-rate dashboards with invented %.
- Forcing sequencer seats to unlock lookup.
Seat vs credit packaging: Seat Subscriptions vs Pay-Per-Lookup Credits. Free-plan competitor traps: The Hidden Cost of "Free Plan" Enrichment Tools.
What should you do next?
Prototype Bearer auth against /docs, wire empty UI before batch jobs, buy a small pack on /pricing, and only then expose admin batch. Keep the module optional. Keep empty empty.
Observability without vanity metrics
Log outcome class (found | empty | error), latency, and tenant id. Do not publish public hit-rate % from production. Recruiter-facing copy: Contact Enrichment Explained for Recruiters. India customer reality: India Boutique IT Staffing, Screening Calls Faster. Global pricing wedge: US Price Arbitrage.
Launch checklist for the lookup module
Empty UI shipped. Bearer secrets reviewed. Credit balance visible to admins. Double-click idempotent. Audit outcome classes. MCP optional docs linked (/mcp.md). Recruiter help text points to Empty Means Not Found and What Is a LinkedIn Profile URL Lookup?. Desk customers: Agency Desk Playbook, Screening Calls Faster. Commercial: /pricing, Pay-As-You-Go Contact APIs, US Price Arbitrage. Credit B in order notes: 1 credit only when we return an email, a phone, or both. Empty completed finds are free. Timeouts and errors do not spend. Hub: LinkedIn or GitHub Profile URL → Contact Lookup API.
Tenancy, permissions, and who may look up
Only roles that may see candidate contacts should trigger find. Log actor id with outcome class. Do not expose raw API keys to every recruiter browser. Shared workspace credits beat one enrichment seat per head for thin URL→fields needs – Seat Subscriptions vs Pay-Per-Lookup Credits. India customers: India Boutique IT Staffing, Contract Recruiters in India, UPI to API Key. Agents: Claude / Cursor Agents, What Is an MCP Server?. Free-plan competitor traps: The Hidden Cost of "Free Plan" Enrichment Tools. GitHub: GitHub Profile URL Contact Lookup. Freelance SOP link for help centers: Freelance Recruiter Workflow. Billing pillar: Credits, Empty Results, and Timeouts. Keep Connecting people – optional module, honest empty, found-only spend.
Questions
How should a hiring product authenticate to Invenitor?
Bearer API keys stored in secrets, mapped to a workspace credit pool – see /docs.
When does a credit spend inside the product?
1 credit only when we return an email, a phone, or both. Empty completed finds are free. Timeouts and errors do not spend.
How should rate limits be treated?
As client hygiene and UI guards – follow /docs guidance; do not invent SLA theater.
What UI should empty show?
Not found. Do not invent email or phone.
Should keys live in the frontend?
No. Keep keys server-side or in a secure agent config per /mcp.md.
REST or MCP?
REST for product backends; MCP for agents. Same Credit B.
Where do packs and pricing live?
/pricing – INR via Razorpay for India buyers.
More in this cluster

What Is a LinkedIn Profile URL Lookup?
What is a LinkedIn profile URL lookup? A find call with a person profile URL that returns email/phone when available – empty means not found.
Read

GitHub Profile URL Contact Lookup: When Developer Profiles Are the Lead
When developer profiles are the lead: GitHub profile URL contact lookup – same find API as LinkedIn, empty means not found, credits only on found outcomes.
Read

Adding Contact Lookup to an ATS: Architecture Notes for Builders
Architecture notes for builders: add contact lookup to an ATS as an optional module – profile URL in, contacts out when found, empty UI that stays honest.
Read