Pre-Black Friday: 20% off, for as long as you stayEARLYBFon Solo and AgencyEnds Nov 28Start free

How-to guide

How to Run Inbox Warming (With Stop Gates and a Verified List)

DNS checks, a ramp in config, stop rules, and a list you can size for free before you send anything.

Get your free API key →Free to start. No credit card. 1,000 records to spend whenever you like.

Inbox warming means raising a new mailbox's sending volume slowly, on wanted mail to real addresses, until receivers trust it. The two things that wreck it are failed authentication and a bad list. This guide covers both with commands you can run.

LeadOcean does not send or warm mailboxes. It does the list part: a verified-only list sized for free, then pulled in the exact amount the ramp uses. Your sending tool or mail client does the sending.

TL;DR

  • Takes about 40 minutes to set up and three to four weeks to ramp, with a 10-minute daily check.
  • Costs 0 records to size the list and about 350 to pull it on the example ramp (175 search rows, 175 enrichments). Free has 1,000 records for life.
  • Receivers publish rules, not schedules. Google says to start low, avoid sudden spikes and keep spam rate below 0.10% (Google, October 2026). The day-by-day numbers here are our plan.

Prerequisites

  • A mailbox on a domain you control, with DNS access.
  • dig on your machine.
  • A LeadOcean API key exported as $LEADOCEAN_API_KEY. Get one free at app.leadocean.io.
  • Python 3 for the ramp script in Step 4.
  • A way to see bounces: your sender's report, or the mailbox's bounce messages.

Step 1: Authenticate the domain first

Warming an unauthenticated domain only builds a bad reputation faster. Google requires SPF or DKIM for all senders. At 5,000+ messages a day it requires SPF, DKIM and DMARC. Unauthenticated mail can be rejected with a 5.7.26 error (Google, October 2026).

Check what is published:

bash
dig +short TXT acme.com | grep spf
dig +short TXT selector1._domainkey.acme.com
dig +short TXT _dmarc.acme.com

The DKIM selector name depends on your provider, so swap selector1 for yours. Start DMARC in monitor mode:

text
v=DMARC1; p=none; rua=mailto:dmarc@acme.com

Tighten the policy later, once the reports show only your own senders.

Step 2: Size a verified-only list for free

A new mailbox has no history, so early bounces hurt most. Warm on verified addresses only. A count spends nothing.

In an MCP client, call the free tool:

text
leadocean_count_leads
  jobLevel: ["Director"]
  jobFunction: ["Sales & Business Development"]
  country: ["US"]
  emailStatus: ["verified"]

Over REST, add count=true to the query with limit 1:

bash
curl -s -X POST "https://api.leadocean.io/v1/people/search?count=true&limit=1" \
  -H "x-api-key: $LEADOCEAN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "jobLevel": ["Director"],
    "jobFunction": ["Sales & Business Development"],
    "country": ["US"],
    "emailStatus": ["verified"]
  }'

meta.total caps at 100,000. Filter values are exact strings, so check them with leadocean_list_enum_values.

Step 3: Pull only what the ramp needs

Do not buy a 10,000-row list for a 175-email ramp. Ask for the rows you will send, plus a small reserve.

Search returns people, up to 100 a page, one record per person returned:

bash
curl -s -X POST https://api.leadocean.io/v1/people/search \
  -H "x-api-key: $LEADOCEAN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "jobLevel": ["Director"],
    "jobFunction": ["Sales & Business Development"],
    "country": ["US"],
    "emailStatus": ["verified"],
    "limit": 100
  }'

Take the ID from meta.source_ids.person_id on each row, then enrich to get the address. Enrich takes exactly one of linkedin_url, email, phone or person_id:

bash
curl -s -X POST https://api.leadocean.io/v1/people/enrich \
  -H "x-api-key: $LEADOCEAN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"person_id": "PERSON_ID_FROM_SEARCH", "reveal_email": true}'

Read email_status on the enriched record. A search count of verified is an upper bound, and the enriched answer is the one to trust. On Solo ($97 a month) and above you can export a file instead with POST /v1/exports. Bulk CSV export is not on Free.

Step 4: Put the ramp in config

Write the ramp down so a daily batch is never a judgement call. One mailbox, weekdays only. These numbers are illustrative.

python
RAMP = {1: 5, 2: 10, 3: 20, 4: 30}   # sends per day for one mailbox, by week

def batch_for(day, rows):
    week = (day - 1) // 5 + 1
    per_day = RAMP[min(week, 4)]
    start = sum(RAMP[min((d - 1) // 5 + 1, 4)] for d in range(1, day))
    return rows[start : start + per_day]

Weeks 1 to 3 add up to 5*(5+10+20) = 175 sends, so a pull of 175 verified rows covers the first three weeks. Pull the next slice before week 4, and re-run the Step 2 count for it.

Send at the same hour, in plain text, one question per message. Replies and real conversation are the signal. Google asks you to avoid sudden volume spikes, such as doubling at once (Google, October 2026).

Step 5: Stop the ramp on a gate, not a feeling

Move up a week only when the last one was clean. Google's spam rate lines come from its guidelines. The bounce line is our rule of thumb.

yaml
advance_when:
  spam_rate: "< 0.10% in Postmaster Tools"   # Google's line
  hard_bounce_rate: "< 2% of the week's sends"   # our rule
  auth_failures: 0                              # DMARC reports
if_any_fail:
  action: "repeat the week at the same volume, or cut it, then climb again"
never:
  spam_rate: ">= 0.30%"                         # Google: avoid ever reaching this

Postmaster Tools shows little at 5 sends a day. Use bounce counts and replies first, and do not read an empty dashboard as a clean one.

Widen the list in order: another country or function with verified, then catch_all, in its own batch so you can see its bounce rate alone. Never send to invalid, spam_trap, abuse or disposable.

What you get

The Step 2 count, run on 2026-10-21 with the free leadocean_count_leads tool:

json
{
  "total": 75872,
  "totalIsExact": true,
  "distinctCompanies": 33152,
  "credits": 0,
  "unsupportedFilters": []
}

That is 75,872 US directors in sales and business development with a verified address, across 33,152 companies. A 175-row pull is a rounding error against that, and the count cost nothing. Because search counts are an upper bound, confirm each address on enrich.

The same slice with catch_all_valid returned 0 on the same date, so do not plan a batch around it without counting first.

A record from the enrich call has this shape (response shape from the API reference, placeholder values):

json
{
  "success": true,
  "data": {
    "profile_data": { "profile_full_name": "Jane Doe" },
    "contact_data": {
      "has_email": true,
      "email_status": "verified",
      "contact_emails": [
        { "email": "jane.doe@acme.com", "type": "work", "status": "verified", "verified_batch_date": "2026-09-20" }
      ]
    }
  },
  "meta": { "credits": 1 }
}

Troubleshooting

ErrorCauseFix
401Missing or wrong x-api-key header.Re-export $LEADOCEAN_API_KEY from app.leadocean.io and resend.
429Requests above the plan's rate limit (5 a second on Free, 200 on Agency).Honour Retry-After and slow the loop.
402Out of records. Free has 1,000 for life.Add a plan, or lower the pull.
Zero resultsA filter value is not an exact enum string, such as C-Team written as c_suite.List valid values with leadocean_list_enum_values or GET /v1/enums.
Count looks too highA search count of verified is an upper bound.Confirm email_status on the enriched record before sending.
Export refusedThe export is above 50,000 rows a request or 500,000 a day.Lower limit or split the pull.

FAQ

How long does inbox warming take?

Plan on three to four weeks for one mailbox at a few dozen sends a day. No receiver publishes a fixed number. Google says to start low and increase volume gradually (Google, October 2026).

Do I need a warming tool?

No. A tool swaps traffic between mailboxes. You can warm with real one-to-one email to verified contacts. A tool does not fix a bad list or missing authentication.

Does LeadOcean warm my inbox?

No. LeadOcean has no sending, sequencer or warming. It builds the list and shows each address's email_status. See also inbox warm up, Gmail warmup and domain warm up.

Why verified addresses only?

A new sender has no reputation to absorb bounces. On a work address, verified means our own verifier sent to it and it accepted. Add catch_all later, in its own batch.

What does this cost?

Sizing is free. The example pull is about 350 records (175 search rows plus 175 enrichments), inside the 1,000 on Free. See pricing.

Build your inbox warming list from verified addresses only

Free to start. No credit card. 1,000 records to spend whenever you like.

Get your free API key →