token query parameter, because that is the only transport these services support: the plugin cannot keep it out of the URL, so keep request logs off the proxy.
All twelve services take a US number as ten digits only. No +1, no punctuation, no extensions. The plugin rejects anything else rather than reformatting it, because silently repairing a number would hide a bad one you should see rejected.
Things to know before you rely on an answer:
- A refusal can arrive inside a
200. These services predate HTTP error conventions: an unrecognised token answers{"status":"unauthorized"}, a missing one{"status":"ERROR","error_text":"missing token"}, and a bad number{"status":"invalid phone"}, all with a200. The plugin checks the body and throws, so a caller never mistakes a refusal for a disposition. In front of the scripts, the load balancer answers a token it does not recognise with an empty401and a malformed one with an empty403, the same status as the documented throttle for more than 10 calls a second; a5xxmeans the service is down. ?is not “no”. OndncLookupanddncPlus,national_dnc,state_dnc,dmaandlitigatoranswerY,Nor?, where?means the list timed out or could not be checked. Treat?as unknown; reading it as cleared is exactly the mistake that creates a TCPA problem.reassigned: "no_data"is not"no".no_datameans the carriers recorded no change since 27 January 2021, which is not evidence about a particular number. Onlyyesandnoanswer the question you asked.activeandconnectedare different questions.activesays the number sits on a provider still in business; it deliberately does not say anyone answers. UseturboV3,turboStandard,turboorscrubfor connectivity andactiveonly for existence.- Five services overlap.
turboV3gives the most (connection, phone type, caller name, carrier, caller type);turboStandardgives connection and phone type; the legacyturbogives connection,iscelland carrier;scrubandscrubPlusare the cheap list-processing options and may answerunknownfor up to 5% of US numbers. Pick one per workflow rather than chaining them. error_textis{}when there is nothing to report. It is an empty object rather than an empty string or absent, and the same holds forRESPONSEMSGon theRESPONSECODEroutes. The response models accept either shape. Other text fields come from the same XML conversion, so an empty one (acaller_namethe carrier does not expose, say) is returned asnull.fraudCheckreturns numeric strings.scoreis a string from 0 to 1000 andphn_typeis a code explained byphn_desc. They are not parsed here, so a caller comparing them should convert them and see a non-numeric value rather than have it silently coerced.reassignedneeds your consent date.contact_dateis the date you received permission to contact, inYYYY-MM-DD; a reassignment only means anything relative to that date.dncLookupneeds a SAN number from the national registry before the service will answer.- Rate limit. The docs recommend 10 calls a second and refuse a burst with a
403and an empty body. The plugin retries that three times with exponential backoff, waiting for aRetry-Afterheader if one arrives. A malformed token gets the same403, so a typo in the token shows up as a throttle after those retries.
- 12 typed API operations
Setup
1
Install
2
Add the plugin
corsair.ts
multiTenancy: true, scope calls with corsair.withTenant(id). See Quick start for KEK + Hub keys, and Multi-tenancy for account isolation.3
Choose authentication
- API Key (Recommended)
No setup required yet. When you make your first request as a tenant, Corsair prompts for the API key.More: API Key
4
Connect a tenant
Mint a connect link and send the tenant to it. Hub hosts the page and delivers the result to your app — see Connect / OAuth.
Example API calls
Validate a US phone numberWhat’s next
API reference
Every
realphonevalidation.api.* operation with input and output types.Connect / OAuth
createLink, Hub delivery, and tenant connect flows.
Use with agents
Expose this plugin’s operations as MCP tools.