Menu · Leads
Leads

Email status

Ruuster's verdict on each lead's email address (valid, invalid, blocked, soft bounce, complaint, unsubscribed, unknown), how to read it, how to get it by lookup or webhook, and how to keep it in Follow Up Boss, Sure Send or Sierra Interactive through their APIs.

View as Markdown

Ruuster checks a lead's address before the first email it sends them, and records what happens on every send after that: bounces, blocks and drops from the mail provider, unsubscribes and spam reports. This guide explains the one verdict Ruuster makes from that history and the two ways to get it: a lookup, and a webhook event when it changes.

  • Look it up: Get a lead's email status, by email, CRM id or lead id.
  • Be told when it changes: the lead.email_status_changed webhook event.
  • Keep it in your CRM: write it to custom fields (or tags) through your CRM's API on each event, so smart lists and action plans can use it. See Keep it in your CRM.

The statuses

status Means What to do
valid Ruuster is delivering to this address Nothing
invalid The mailbox does not exist, is closed or disabled, is a throwaway address or a spam trap, or the address is on the bounce list Call or text instead, or get a new address
blocked The recipient's mail provider refused the message for policy, reputation or content reasons. The mailbox itself may be fine Use another channel for now
soft_bounce A temporary problem: the mailbox is full, or their server did not answer The address may still be good. Keep it
complaint The lead reported a Ruuster email as spam, so sends to them are dropped Do not email them from Ruuster again
unsubscribed The lead unsubscribed from Ruuster emails, or the CRM record carries an opt-out tag Respect it. If they ask to receive emails again, email helpme@ruuster.com
unknown Not verified yet, or the check could not decide Normal for new leads; see below

Precedence when more than one thing is true: delivery on is always valid; the lead's own unsubscribe outranks a later bounce; a recorded failure outranks a CRM opt-out tag.

Why new leads are unknown. Ruuster verifies an address right before the first email it sends, not when the lead arrives. A lead who has not been emailed yet has not been checked yet. About six in ten of a brokerage's newest contacts are in this state; it resolves on the first send.

What comes with the status

Field Description
code What is behind the verdict: the SMTP code and whether it was a bounce or a block (5.1.1 bounce, 4.2.2 block), the verification status (inbox_full, disposable), or the suppression reason (unsubscribed address, spam reporting address). null when valid
reason One sentence, in plain words
source platform (the delivery flags), verification (the pre-send check), delivery (a send), lead (they unsubscribed), crm (an opt-out tag)
checkedEmail The address the verdict is about, when lead contact details are on. Compare it with the lead's current email to tell whether a changed address has been checked yet
failedAt When the failure behind the verdict was recorded, if there is one
since When the verdict last changed
previousStatus The verdict before this one, when known

Look up one lead

curl -s "https://api.ruuster.com/v1/leads/email-status?email=sam.lee%40example.com" \
  -H "x-api-key: $RUUSTER_API_KEY" -H "x-email: $RUUSTER_EMAIL"

The answer lists every lead with that address (a person can be a registered user and a CRM contact), each with emailStatus. The verdict is refreshed every 15 minutes; a lead the refresh has not reached yet, or whose address changed since, is classified on the call and comes back with since and previousStatus null. It is a lookup call: 20 per minute per key.

In an AI assistant the tool is leads_email_status: "what's the email status for sam.lee@example.com".

Be told when it changes

Subscribe to lead.email_status_changed, or to lead.*, which includes it. It fires when the verdict moves: a check or a send fails, the lead unsubscribes, delivery is turned back on, or a new lead's address gets its first verdict. data.emailStatus carries the fields above plus previousStatus; data.lead names the lead and its crmExternalId. A brokerage's first fill publishes no events; only changes after that do.

{ "kind": "lead.email_status_changed", "occurredAt": "2026-10-29T14:10:00Z",
  "data": { "lead": { "leadId": "user:c0ff3e21-8a4b-4c7d-9e15-2b6f8d3a1c04", "firstName": "Sam", "lastName": "Lee", "crmExternalId": "48213", "agentId": "7c1e9b42-3d85-4a6f-9e07-1b2c8d4f5a69" },
            "emailStatus": { "status": "invalid", "code": "5.1.1 bounce",
                             "reason": "The mailbox does not exist or no longer accepts mail.",
                             "source": "delivery", "failedAt": "2026-10-29T14:02:11Z",
                             "since": "2026-10-29T14:10:00Z", "previousStatus": "valid" } } }

See Webhooks for subscribing and Verifying deliveries for signatures.

Keep it in your CRM

Ruuster posts a "Ruuster Email Validation" note on the CRM contact when it validates an address, but notes cannot be filtered. With the webhook and your CRM's own API you can keep the verdict where lists and action plans can use it: custom fields in Follow Up Boss and Sure Send, tags in Sierra Interactive (its API has no custom fields). data.lead.crmExternalId is the person's id in your CRM.

What to store, from each event:

Store From Follow Up Boss Sure Send Sierra Interactive
Status data.emailStatus.status customRuusterEmailStatus (dropdown) custom field, dropdown tag Ruuster Email: invalid (one of seven)
Status code data.emailStatus.code customRuusterEmailStatusCode (text) custom field, text a note, if wanted
Validated email data.lead.email (lead contact details on) customRuusterValidatedEmail (text) custom field, text a note, if wanted
Validation date data.emailStatus.failedAt, else since, as YYYY-MM-DD customRuusterValidationDate (date) custom field, date a note, if wanted

Answer each delivery with a 2xx within 10 seconds, then make the CRM call. Deliveries are at least once, so de-duplicate on the event id if a repeat would matter. A PUT on a person in all three CRMs leaves every field you don't send untouched.

Follow Up Boss. Create the four fields once: through POST /v1/customFields with an owner key (label, type of dropdown, text or date, and choices for the dropdown), or under Admin, then Custom Fields. The name in each field (customRuusterEmailStatus and so on) is the key you write. Then on each event:

curl -s -X PUT -u "$FUB_API_KEY:" -H "Content-Type: application/json" \
  "https://api.followupboss.com/v1/people/$CRM_EXTERNAL_ID" \
  -d '{"customRuusterEmailStatus":"invalid","customRuusterEmailStatusCode":"5.1.1 bounce",
       "customRuusterValidatedEmail":"sam.lee@example.com","customRuusterValidationDate":"2026-10-29"}'

Sure Send. Create the four fields once through POST /customFields (or in Settings) and note the keys it gives them; a custom-field key that doesn't exist is dropped silently, so create them first. Then on each event, with the keys from your account:

curl -s -X PUT -H "Authorization: Bearer $SURESEND_API_KEY" -H "Content-Type: application/json" \
  "https://api.suresend.ai/api/partner/people/$CRM_EXTERNAL_ID" \
  -d '{"customFields":{"ruusterEmailStatus":"invalid","ruusterEmailStatusCode":"5.1.1 bounce",
       "ruusterValidatedEmail":"sam.lee@example.com","ruusterValidationDate":"2026-10-29"}}'

Sierra Interactive. The API has no custom fields, so use one tag per status. tags adds and removeTags removes, so send the new tag and remove the other six in the same call; the code and date can go in a note (POST /leads/{id}/note) if you want them on the record:

curl -s -X PUT -H "Sierra-ApiKey: $SIERRA_API_KEY" -H "Content-Type: application/json" \
  "https://api.sierrainteractivedev.com/leads/$CRM_EXTERNAL_ID" \
  -d '{"tags":["Ruuster Email: invalid"],
       "removeTags":["Ruuster Email: valid","Ruuster Email: blocked","Ruuster Email: soft_bounce",
                     "Ruuster Email: complaint","Ruuster Email: unsubscribed","Ruuster Email: unknown"]}'

Fill in existing contacts. The event covers changes from now on. For contacts you want filled today, call Get a lead's email status with each one's crmExternalId and make the same write. It is a lookup call, 20 per minute per key, so start with the contacts you email.

Then, for example: a smart list where the status is invalid or complaint and a phone is set is your "call instead" list; soft_bounce stays in email plans; unsubscribed stays out of them; and a contact whose email no longer equals the validated email has a new address Ruuster has not checked yet. Ruuster re-validates it on its own once it syncs, and the next event updates the fields.

Good to know

  • Ruuster never emails an invalid, complaint or unsubscribed address. The status tells you what Ruuster already stopped doing.
  • Resubscribing a lead. When a lead who unsubscribed asks to receive emails again, email support at helpme@ruuster.com with the lead's name and address and we turn delivery back on; the status returns to valid and the change fires an event.
  • A repeat of the same failure is not a change. A second full-mailbox bounce leaves since alone and sends no event. A different code, a different status or a changed address does.
  • One verdict per address. Two CRM contacts with the same email get the same status.
  • A fixed address. When the email is corrected in your CRM, the new address syncs to Ruuster within minutes and is checked before the next send. Until then checkedEmail still shows the old one.
  • Contact details off. The lookup and the event still work; checkedEmail, email and phone are left out.