@bye_bouncer/sdk
v0.2.0
Published
Official Node.js SDK for the ByeBouncer email verification API.
Maintainers
Readme
@bye_bouncer/sdk
Official Node.js/TypeScript SDK for the ByeBouncer email verification API.
Real-time single-email verification, bulk CSV verification (up to 50k emails per job), credits management, HMAC-signed webhooks.
Install
npm install @bye_bouncer/sdk
# or
pnpm add @bye_bouncer/sdk
# or
yarn add @bye_bouncer/sdkRequires Node.js 18+.
Quickstart
import { ByeBouncer } from "@bye_bouncer/sdk";
const client = new ByeBouncer({ apiKey: process.env.BB_API_KEY! });
const result = await client.verify("[email protected]");
console.log(result.status); // "deliverable" | "undeliverable" | "risky" | "unknown"
console.log(result.action); // "allow" | "review" | "block"
console.log(result.signals); // ["valid_syntax", "mx_found", ...]
console.log(result.credits_remaining);Get your BB_API_KEY from https://byebouncer.com/dashboard (format bb_live_...).
Bulk verification
const { job, estimated_seconds } = await client.bulk({
emails: ["[email protected]", "[email protected]", /* ...up to 5.000 */],
filename: "my_list.csv",
webhook_url: "https://api.myapp.com/hooks/byebouncer", // optional
});
console.log(`Job ${job.id}, ~${estimated_seconds}s`);If you pass webhook_url, the creation response includes the effective
webhook_secret (generated or supplied). Store it immediately; later job reads
never return it.
Polling for completion
For small jobs (<5k emails), poll and download the CSV directly:
const { job: final, csv } = await client.bulkAndWait(
{ emails: [...] },
{
intervalMs: 3000,
onProgress: (j) => console.log(`${j.processed}/${j.total_emails}`),
}
);
require("fs").writeFileSync("results.csv", csv);Webhooks (recommended for large jobs)
Prefer webhooks over polling. On completion ByeBouncer POSTs to your URL with:
X-ByeBouncer-Event: bulk.completed
X-ByeBouncer-Signature: <hex HMAC-SHA256(body, webhook_secret)>
Content-Type: application/json
{
"event": "bulk.completed",
"job_id": "...",
"processed": 1234,
"valid": 800, "invalid": 300, "unknown": 134,
"credits_refunded": 0,
"timestamp": "2026-09-05T14:30:00Z"
}Attach or rotate the webhook after creating the job:
const { webhook_secret } = await client.bulkSetWebhook(job.id, {
webhook_url: "https://api.myapp.com/hooks/byebouncer",
});
// Store webhook_secret NOW — it is returned only once.Manual polling + download
const status = await client.bulkStatus(jobId);
if (status.status === "completed") {
const { url } = await client.bulkDownloadUrl(jobId);
const res = await fetch(url);
const csv = await res.text();
}Cancel
const cancelled = await client.bulkCancel(jobId);
console.log(`Refunded ${cancelled.credits_refunded} credits`);Error handling
All non-2xx responses throw a ByeBouncerError (or subclass) with code, status, and detail.
import { ByeBouncer, InsufficientCreditsError, RateLimitError } from "@bye_bouncer/sdk";
try {
await client.verify("[email protected]");
} catch (err) {
if (err instanceof InsufficientCreditsError) {
console.error(`Out of credits (${err.creditsRemaining ?? "?"} left)`);
} else if (err instanceof RateLimitError) {
console.error(`Rate limited, retry after ${err.retryAfterSeconds}s`);
} else {
throw err;
}
}API reference
Every method mirrors the OpenAPI spec.
| Method | Endpoint | Description |
|--------|----------|-------------|
| verify(email) | POST /verify | Verify a single email |
| credits() | GET /credits | Get balance |
| bulk(options) | POST /bulk | Enqueue a bulk job |
| bulkStatus(id) | GET /bulk/{id} | Fetch job |
| bulkCancel(id) | DELETE /bulk/{id} | Cancel |
| bulkDownloadUrl(id) | GET /bulk/{id}/download | Signed CSV URL |
| bulkSetWebhook(id, opts) | POST /bulk/{id}/webhook | Attach/rotate webhook |
| bulkWaitForCompletion(id, opts) | polls bulkStatus | Convenience helper |
| bulkAndWait(input, opts) | create+poll+download | Convenience helper |
Options
new ByeBouncer({
apiKey: "bb_live_...", // required
baseUrl: "https://api.byebouncer.com", // default
timeoutMs: 30_000, // per-request timeout
fetch: customFetch, // custom fetch (Node < 18)
});Support
- Docs: https://byebouncer.com/docs
- Email: [email protected]
- Issues: https://github.com/fidelp27/byebouncer/issues
License
MIT © ByeBouncer
