Cold Email Infrastructure

    The NeverBounce API: What It Automates, and the Decisions It Hands Back

    NeverBounce refuses automated requests on its marketing pages and renders its docs in JavaScript. Here is the v4 API, read from surfaces that answer a fetcher.

    August 13, 202610 min read
    Share:
    The short answer

    The NeverBounce v4 API automates single checks, bulk job creation, progress callbacks and credit introspection against api.neverbounce.com/v4.2, with the key passed as a query parameter. It deliberately stops short in three places: the spend decision after a free sample, the meaning of a catchall result, and how stale a stored verdict may become.

    Key takeaways

    • Both bulk switches default to off. auto_parse and auto_start are 0 unless set, and the vendor states that starting a job deducts the credits and the run cannot then be stopped or restarted.
    • run_sample returns an estimated bounce rate at no credit cost, and the documentation says outright that the decision to run the full validation is yours to make from that estimate.
    • Five result codes exist: valid, invalid, disposable, catchall and unknown. The vendor labels catchall Unverifiable and defines unknown as the server being unreachable, so two of the five are handed back rather than answered.
    • Version 4.2 added job callbacks, which the changelog says remove the need for a long-running process polling for updates, though polling remains supported.

    Reviewed and updated August 13, 2026

    Two things happen when you point an automated fetcher at NeverBounce. The marketing site returns HTTP 403, so www.neverbounce.com and its pricing page will not serve a script at all. The developer documentation at developers.neverbounce.com returns HTTP 200 and renders its content in JavaScript, so the raw bytes carry the navigation and none of the reference material. Both were checked directly in August 2026, and between them they make this a hard API to write about from evidence rather than from recollection.

    There is a better route, and the vendor built it deliberately. The documentation site publishes a machine index at developers.neverbounce.com/llms.txt and serves every reference page a second time as plain Markdown, by appending .md to the path. That mirror is first-party, it is fetchable, and it carries the full OpenAPI definition for each endpoint. Everything below comes from those Markdown pages, from the vendor's own changelog, and from the SDK repositories NeverBounce publishes on GitHub. No price appears anywhere in this article, because the pages that would carry one refuse automated requests, and a third-party pricing tracker is not a source.

    What the API is, in one paragraph of specifics

    The OpenAPI definition embedded in the /check reference gives a server of https://api.neverbounce.com/v4.2 and a security scheme of type apiKey, passed in: query under the parameter name key. Version 4 credentials look like secret_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx, and the Ruby, Python, Node and Go SDK READMEs each carry the identical warning: the eight-character username and twelve to sixteen character secret key from the V3 API will not authenticate a V4 request and will come back as an auth_failure.

    A key in a query string ends up in access logs and error trackers unless something strips it, so mask that parameter in your HTTP client before the first production call. The getting-started page adds the related boundary in blunt terms: the standard API is "not suitable for use in client-side scripts", because using it there means exposing credentials and "giving anyone access to your account". The Node SDK repeats it. Browser-side verification goes through the vendor's JavaScript widget, and the API has a poe_confirm call whose entire job is to verify that a result produced in the browser has not been tampered with.

    Single checks: what the response actually decides

    GET /single/check takes email as the only required parameter, plus three optional ones documented in the OpenAPI block: address_info and credits_info, both defaulting to false, and timeout, described as the maximum time in seconds the API should try to verify the address.

    The result property carries one of five codes, and the reference page defines each of them:

    Result codePublished description
    validVerified as real address
    invalidVerified as not valid
    disposableA temporary, disposable address
    catchallA domain wide-setting, also known as Accept-all (Unverifiable)
    unknownThe server cannot be reached

    Three of those five are answers. Two are the API telling you it has done all it can.

    catchall is labelled Unverifiable by the vendor itself, which is the honest description: the receiving server accepts every recipient offered to it, so no probe can distinguish a real mailbox from a typo. That is a property of the domain rather than a fault in the check, and what a catch-all domain looks like in a live campaign covers what it does to a send.

    unknown means the server could not be reached inside the time allowed. The timeout documentation is worth quoting for how carefully it is worded: the parameter tells the API how long to try "before giving up and returning an unknown result code", and "the total request time can exceed this timeout, as network latency is not taken into consideration". A three-second timeout is not a three-second guarantee on your request path, so size your own client timeout above it.

    Alongside result, the response carries a flags array explaining how the verdict was reached. The reference tabulates twenty-two of them and describes the list as common flags rather than an exhaustive set, so code defensively against unfamiliar values. Several are worth reading rather than discarding. accepts_all restates the catch-all condition at the host level. smtp_connectable says a connection to the remote mail server succeeded. spamtrap_network says the host is affiliated with a known spam trap network. disposable_email identifies the class covered in the disposable email entry. And historical_response indicates the result was generated using the historical-driven algorithm rather than a live probe, which is the flag to watch if you care whether an answer is fresh.

    One encoding detail from the same page saves an afternoon: an address containing a + alias must have that character encoded as %2B for x-www-form-urlencoded content types, because a bare + decodes as a space.

    Bulk jobs: genuinely automatable, with two deliberate stops

    The list side is where the API earns its keep, and it is a state machine rather than a single call. The /create reference states the thing most people get wrong on first read, in bold on the vendor's own page: verification results are not returned in the response. Creating a job gives you a job ID and nothing else.

    Input comes in two shapes. supplied_input takes an array of objects or arrays carrying the email plus any ancillary data you want to keep with it, and the vendor warns that the API enforces a maximum request size of 25 Megabytes, returning 413 Entity Too Large above it. remote_input takes a URL to a hosted file, and the documented examples include HTTP basic auth and FTP with credentials in the URI string, which the Go SDK's godoc confirms as HTTP, HTTPS, FTP and SFTP.

    Then come the two switches that define what is automated and what is not.

    auto_parse and auto_start both default to 0. Parsing indexes the file. Starting runs the verification, and the reference is explicit that "Setting this to 1 or true will start the job and deduct the credits". The Go SDK adds the sharper version of the same warning: once the list has been started the credits are deducted "and the process cannot be stopped or restarted". There is no cancel.

    Between parse and start sits run_sample, which is the most useful parameter in the whole API and the one that exists precisely because a machine should not make this call. It runs a sample of the list and returns an estimated bounce rate "without costing you", and the documentation states the purpose directly: "Based on the estimated bounce rate you can decide whether or not to perform the full validation or not."

    1. Step 1Create

      Supply data inline under 25 Megabytes, or a remote URL. No verification results come back in the response.

    2. Step 2Parse

      Indexing runs the moment auto_parse is on. Once parsed, the vendor states a job cannot be reparsed.

    3. Step 3Sample

      run_sample returns an estimated bounce rate at no credit cost, before you commit to the full list.

    4. Step 4Start

      auto_start defaults to 0. Starting deducts the credits, and the run cannot be stopped or restarted.

    5. Step 5Watch

      Poll /status, or register a callback_url and receive the ten job events as POSTs.

    6. Step 6Collect

      /results returns paginated rows joined to your original data. /download returns the CSV.

    The NeverBounce bulk job state machine. Both defaults are off, so a job sits still until something starts it.

    Watching a job without a polling loop

    Until version 4.2 the only way to know a job had finished was to ask repeatedly. The 4.2 changelog introduces job callbacks and states the benefit plainly: "you no longer need a long running process to periodically poll our API for updates, though this is still an option."

    Supply a callback_url at job creation, optionally with a callback_headers array, and NeverBounce sends a POST carrying a JSON body of event and job_id, for example {"job_id":4920062,"event":"job_deleted"}. Ten events are published, covering parsing started and finished, sample started and finished, run started and finished, review completed, stats updated, failed and deleted. The job_stats_updated event carries its own warning on the reference page: it "will be sent frequently while a job is running", so treat it as a progress ticker rather than something to fan out from.

    If you do poll, the /status reference publishes the full vocabulary you are polling against: uploading, parsing, queued, waiting, waiting_analyzed, running, complete, failed and under_review. Two of those nine are not progress at all.

    queued is documented as meaning "we're either too busy or you have too many active jobs", which makes it a capacity signal about the vendor's load and about your own concurrency rather than a stage in the job's own progress. under_review means "the job has fallen into our Q/A review and requires action on our end", and the 4.2 changelog records that API jobs are no longer eligible for manual review by default, with the feature now requiring an opt-in at job creation. Any timing model you build should still handle the state, because a job that enters it waits on a human at the vendor.

    The status response also carries a total object whose fields are more interesting than they look. billable is defined as the number of rows containing syntactically correct emails and "is number of credits processing this job will consume". duplicates counts rows containing duplicated emails and, in the vendor's words, "is not the number of unique duplicates but the total of every instance". The reference defines billable by syntactic correctness and states no exemption for repeats, so the safe reading is that a duplicated address is a duplicated row. Deduplicate before upload and the question does not arise.

    Fully automatableWire it and walk away
    • Single checks at the point of collection
    • Job creation from inline data or a remote URL
    • Parsing, via auto_parse
    • Progress tracking, via callbacks or /status
    • Paginated result collection and CSV download
    • Credit balance and job counts, via /info
    • Job deletion once a job is queued, waiting, complete or failed
    Needs a decisionA person on the hook
    • Whether to start after the free sample's bounce estimate
    • What a catchall result means for your risk appetite
    • Whether an unknown gets retried, dropped or sourced again
    • How old a stored verdict may be before it is re-checked
    • Whether to opt a job into manual review
    Sorting the NeverBounce API surface into what a job runner can own outright and what still needs a person on the hook.

    Account introspection, and the failures worth naming

    GET /account/info returns a credits_info object with paid_credits_used, free_credits_used, paid_credits_remaining and free_credits_remaining, plus a job_counts object breaking down completed, under_review, queued and processing. The Python SDK's README shows the same call returning a billing_type field. That is enough to build a preflight check that refuses to submit a job the account cannot pay for, which is a better failure than discovering it mid-run.

    On errors, the SDKs are the clearest source. The Go wrapper publishes four typed error constants: general_failure, auth_failure, bad_referrer and throttle_triggered, and the Node SDK exposes the same four as GeneralError, AuthError, BadReferrerError and ThrottleError. The comment attached to the throttle case in both repositories is the useful part: too many requests in a short time, "try again shortly or adjust your rate limit settings for this application in the dashboard". That points at a per-application rate limit living in your own account rather than at a global figure. No numeric ceiling appears on any NeverBounce surface reachable by an automated fetch, so read yours out of the dashboard and treat throttle_triggered as a backoff signal rather than something to size against a published table.

    Job-level failures get their own vocabulary on the status reference: unknown_file_encoding, empty_file, file_too_large, file_corrupt, and a null value meaning an unknown failure. Version 4.2 added the failure_reason property that carries them, so a job in failed status can be diagnosed without opening a ticket. Four of those five are input problems you can validate for locally before spending an upload.

    Before you set auto_start
    • Yes: Deduplicate the file. Billable counts rows, and duplicates counts every instance.
    • Yes: Confirm the payload is under 25 Megabytes, or switch to a remote URL.
    • Yes: Save the file as UTF-8, the encoding the failure reasons single out.
    • Yes: Run the free sample and read the bounce estimate before committing credits.
    • Yes: Check credits_info against the row count so the job cannot stall on balance.
    • Depends: Register a callback_url rather than building a polling loop.
    • No: Set auto_start on the first run of a new pipeline.
    Checks worth running before a NeverBounce bulk job starts, because starting deducts credits and cannot be undone.

    What none of this settles

    The API will tell you an address is catchall and it will not tell you whether to email it. It will tell you a check came back unknown and it will not tell you whether that is worth retrying. It will hand you an estimated bounce rate on a free sample and leave the spend decision with you. Those are the right places to stop. An accept-all server is a wall in front of every SMTP probe, whoever runs it, so the useful comparison between verifiers is about what they charge for an unresolvable result and how cleanly they hand it back. That comparison is in the email verification tools breakdown.

    The re-check question deserves one more line, because it is the one people quietly get wrong. A verdict is true on the day it was produced and decays from there as people change jobs, so a stored valid from last quarter is a claim about last quarter. Data decay is the reason a verification store needs an age policy rather than a permanent cache, and it is also why re-sourcing an address is sometimes cheaper than re-checking one, which is the trade the email finder comparison works through.

    Verification is one layer. It protects your bounce rate and, through that, your sending domain's reputation, and it does nothing about authentication, warmup or copy, which is what the deliverability guide covers. If you are wiring verification into a sending platform rather than a signup form, the webhook and rate-limit patterns in the Smartlead API guide are the neighbouring half of the same job.

    Every address that comes out of our email-finding waterfall is verified through MillionVerifier before upload. That is documented policy rather than a verdict on any vendor here, and the principle behind it travels: an address nobody can evidence does not go into a send.

    If you would rather have the sourcing, verification and sending run for you, get a free campaign plan and we will show you the path for your market.

    Pricing and features verified as of August 2026. Verify current terms with the vendor before relying on them.

    Sources, all first-party and all fetched 13 August 2026: /check reference, /create reference, /status reference, job callbacks, version 4.2 changelog, and the Ruby, Go and Python SDK repositories.

    Questions

    Frequently asked questions.

    Frequently asked questions
    Where is the NeverBounce API documented if the site blocks fetchers?
    The marketing pages return HTTP 403 to automated requests and the developer site renders in JavaScript. The vendor also publishes a machine index at developers.neverbounce.com/llms.txt and serves every reference page as plain Markdown by appending .md to the path, including the full OpenAPI definition. The GitHub SDK repositories are first-party too.
    What does a NeverBounce catchall result mean?
    The reference page defines catchall as a domain wide-setting, also known as Accept-all, and marks it Unverifiable. The receiving server accepts every recipient offered to it, so no probe can prove a mailbox exists. Whether to email that contact is a judgement about the bounce risk you are willing to carry, and no verifier can make it for you.
    Can a NeverBounce bulk job be cancelled once it starts?
    No. The /start reference and the Go SDK both state that once the list has been started the credits are deducted and the process cannot be stopped or restarted. That is why auto_start defaults to 0 and why the free sample exists: the estimated bounce rate is the last checkpoint before the spend becomes irreversible.
    How do you track a NeverBounce job without polling?
    Supply a callback_url at job creation, optionally with callback_headers. NeverBounce sends a POST carrying event and job_id for ten published events covering parsing, sampling, running, review, failure and deletion. Treat job_stats_updated with care, since the reference says it is sent frequently while a job is running.
    Email VerificationAPICold EmailDeliverabilityData Quality
    Byline

    About the author.

    Tim Carden

    Tim Carden is CMO / CTO at RevenueFlow, which builds and operates outbound revenue engines for B2B companies. Studied at McGill University.

    Tim Carden · CMO / CTO

    Connect on LinkedIn →
    Your next move

    Ready to scale your outreach?

    We build GTM engines that book real meetings. See the receipts.

    Further reading

    Related articles.

    Cold Email Infrastructure

    The ZeroBounce API: Auth, Rate Limits, and What to Store Per Address

    ZeroBounce publishes three different answers to its own rate-limit question. Here is which one to build against, plus the statuses no API can decide for you.

    11 min readRead →
    Cold Email Infrastructure

    ZeroBounce Alternatives: Price the Bundle Against What You Actually Use

    ZeroBounce sells eighteen tools with a ten thousand credit floor. Work out your monthly volume and your real bundle use before deciding whether to move, and where.

    8 min readRead →
    Cold Email Infrastructure

    ZeroBounce in Practice: The Bundle, the Accuracy Claim, and Who Should Buy It

    ZeroBounce sells verification credits inside a deliverability bundle. What the pricing page lists, how to read the accuracy claim, and the teams it fits.

    8 min readRead →
    Cold Email Infrastructure

    NeverBounce Under ZoomInfo: What Buying Verification From a Data Platform Changes

    NeverBounce serves no pricing page to automated requests, so here is what its own surfaces do show, and what changes when your verifier belongs to a data platform.

    8 min readRead →
    Cold Email Infrastructure

    ZeroBounce Pricing: What the Page Shows, and the Three Things Buyers Miss

    What the ZeroBounce pricing page actually publishes, which billing state it shows by default, and the credit rules that decide what a buyer really pays.

    7 min readRead →
    Cold Email Infrastructure

    BriteVerify API: Key Types, Rate Limits, and the Browser Key Trap

    The BriteVerify API splits into a client side key on a public path and a server side key on a private one. Endpoints, rate limits, and how to read a risky verdict.

    11 min readRead →