uCheckeruChecker
Mark AvrilovPublished 8 min read

Email validation webhook: getting verification results without polling the API

A validation webhook is an HTTP request the verification service sends to your server on its own once a job is done. Instead of asking the API “finished yet?” every few seconds, you leave an address and the service tells you.

It is the usual pattern for slow operations. Checking a list takes minutes, longer for a big one, and there is no point holding a connection open the whole time. The service accepts the job, hands back an ID and gets to work; the result comes later as a separate request going the other way.


Webhook or polling

Polling is as simple as it gets. Your code hits a status endpoint every few seconds; the uChecker API docs suggest every 5 to 10 seconds. A job that runs for twenty minutes, polled every ten seconds, means roughly 120 requests, and only the last one tells you anything.

A webhook is one request, and it arrives the moment the job finishes rather than on the next poll. That does not make polling wrong. It is easier to debug, needs no public URL, works from behind NAT or from a laptop, and a script that cleans a list once a month will never need more. Webhooks pay off when you run many jobs or when an automated chain waits on the result.

How it works in uChecker

You pass the address in the validation request itself, in the webhook_url field. Both endpoints accept it: POST /api/v1/validate/bulk for a list and POST /api/v1/validate/single for one address. There is no account-wide setting, so every job can point somewhere different.

Single-address checks are asynchronous too. The response returns a task_id straight away, and the check itself takes anywhere from a few seconds to two minutes depending on the domain. So a webhook is useful for a signup form as well, not just for big lists.

When the job completes, uChecker sends a POST with Content-Type: application/json and five fields in the body.

The addresses themselves are not in the body, even for a one-address job. The webhook only says the results are ready; you fetch them with GET /api/v1/tasks/{task_id}/results and your API key. One quirk worth knowing: per the docs, the webhook summary counts addresses flagged as risky under bad, unlike the task analytics. If you want those under unknown, read GET /api/v1/tasks/{task_id}/analytics.

Retries and what your endpoint should return

A delivery counts when your server answers with a 2xx code within 30 seconds; the docs ask for a 200. Any other code, a dropped connection or a timeout triggers a retry after 30 seconds, then after one, five and fifteen minutes. That is five attempts in total. If your server stays down for more than twenty-odd minutes, the notification is lost, but the job and its results are still there to fetch by polling.

Two rules follow for the handler. Return 200 only after the data is stored. If the database write fails, a 500 and a retry beat acknowledging the request and losing the result.

And the handler has to cope with the same request twice. Sometimes you process everything and the response never makes it back (say, processing took longer than 30 seconds), so the service treats the attempt as failed and sends it again. The job ID is in the body and in the X-Webhook-Task-Id header; check it before doing anything. The attempt number is in X-Webhook-Attempt.

Heavy lifting such as downloading results or updating the CRM is better done after you respond: accept the request, push the job ID onto your own queue, return 200.

Securing the endpoint

A webhook URL is reachable from the internet, so anyone can POST to it. How much that matters depends on how far your handler trusts the request body. The usual defences:

uChecker does not sign the body. The setup that works is a secret token in webhook_url, HTTPS, and a handler that does not trust the numbers in the body. On each notification it calls the API with its own key and reads the status and results from there. A forged request can at worst make you fetch data one extra time; it cannot change that data.

uChecker will not call private or internal addresses (localhost, 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16 and the like), so a test handler has to be reachable from outside, through a tunnel if nothing else.

Where it fits

ESP webhooks for deliveries, bounces and opens work in a similar way but are a separate topic, covered in the email event webhook guide.

Sources

Your API key is in the dashboard. Connect uChecker. The first 100 checks are free.

webhookcallback URLvalidation APIpollingintegration

Mark Avrilov · Author

Published