SendSure
API Guides
Updated 2026-07-036 min read

Official SDKs (Node.js & Python)

Install the official SendSure SDKs to verify emails from Node.js or Python in a few lines, with built-in rate-limit handling and webhook signature verification.

Official SDKs

SendSure ships official SDKs for Node.js and Python so you can add email verification to your product in a few lines — no HTTP plumbing, retry logic, or signature code to write yourself.

Both SDKs are zero-dependency, cover the same API surface, and handle rate limits for you:

  • verify — single email, returns verdict, score, and reason
  • verifyBatch / verify_batch — up to 100 emails per call
  • verifyMany / verify_many — lists of any size, auto-chunked with progress callbacks
  • jobs — async bulk verification: upload a list, process in the background, download the cleaned CSV
  • credits — current balance for the account that owns the key
  • Webhook signature verification (v2 scheme) helpers

Authentication uses your API key from the dashboard (Settings → API Keys). Keys start with si_live_ and are sent in the X-API-Key header — the SDKs do this automatically.

Node.js

npm install @sendsure/sdk
import { SendSure } from '@sendsure/sdk';

const sendsure = new SendSure({ apiKey: process.env.SENDSURE_API_KEY });

const result = await sendsure.verify('jane@example.com');
// result.result → 'valid' | 'invalid' | 'unknown' | 'risky'
// result.score  → 0–100 confidence
// result.reason → human-readable explanation

const batch = await sendsure.verifyBatch(['a@example.com', 'b@example.com']);
console.log(batch.valid, batch.invalid, batch.creditsRemaining);

Works from TypeScript and plain JavaScript (ESM and CommonJS), Node 18+.

Python

pip install sendsure
from sendsure import SendSure

client = SendSure(api_key="si_live_...")

result = client.verify("jane@example.com")
if result["result"] == "valid":
    ...  # safe to send

batch = client.verify_batch(["a@example.com", "b@example.com"])

Python 3.8+, standard library only.

Bulk jobs (large lists, async)

For big lists, upload a job instead of calling the synchronous endpoints — the platform processes it in the background and you download a cleaned CSV when it finishes:

const { jobId } = await sendsure.jobs.upload(emails); // or { content, filename } for a CSV/XLSX file
await sendsure.jobs.process(jobId);                   // charges 1 credit per email
const job = await sendsure.jobs.waitForCompletion(jobId, {
  onProgress: (j) => console.log(`${j.progress}%`),
});
const csv = await sendsure.jobs.download(jobId, { type: 'safe' });
job = client.jobs.upload(emails=emails)  # or file=("list.csv", csv_content)
client.jobs.process(job["jobId"])
client.jobs.wait_for_completion(job["jobId"])
csv = client.jobs.download(job["jobId"], type="safe")

Uploading is free — credits are only charged when processing starts. cancel refunds unused credits, and results/breakdown give you row-level detail and per-category counts.

Large lists (synchronous)

Both SDKs chunk automatically and respect rate limits (Retry-After on 429 is honored, with a bounded retry budget):

const merged = await sendsure.verifyMany(emails, {
  onProgress: (done, total) => console.log(`${done}/${total}`),
});
merged = client.verify_many(emails, on_progress=lambda done, total: print(done, total))

Billable requests are never auto-retried after a network failure or server error, so a retry can never double-charge you.

Verifying webhooks

If you registered a webhook endpoint, verify each delivery with the v2 signature helper before trusting the payload:

import { webhooks } from '@sendsure/sdk';

const event = webhooks.constructEvent(rawBody, signatureHeader, secret);
from sendsure import construct_event

event = construct_event(raw_body, signature_header, secret)

Both throw when the signature is invalid or the timestamp is outside the 5-minute tolerance. Deduplicate deliveries by the event id — retries reuse the same id. See the webhooks and API quickstart for the full signature scheme.

Error handling

Every non-2xx response raises a typed error with status and code:

import { SendSureError } from '@sendsure/sdk';

try {
  await sendsure.verify(email);
} catch (err) {
  if (err instanceof SendSureError && err.code === 'insufficient_credits') {
    // top up in the dashboard
  }
}
from sendsure import SendSureError

try:
    client.verify(email)
except SendSureError as err:
    if err.code == "insufficient_credits":
        ...

Other platforms

  • Zapier, Make, n8n — use the no-code integrations from the dashboard's Integrations page.
  • Any other language — the REST API is small and documented in the API quickstart: POST /api/verify/single and POST /api/verify/batch with the X-API-Key header.

Keep reading

More docs from the api guides section.