How to warm up a Facebook ad account — without getting it banned.
Step-by-step warm-up schedule for new and aged Meta ad accounts, plus how to vet 'verified' and aged accounts before you buy and the 8-point eligibility checklist to run before your first dollar of spend.
The 21-day warm-up schedule
The numbers below assume a personal or aged BM. Agency ad accounts compress this timeline to about a week because the parent BM is already whitelisted.
Six rules that keep warm-up from killing the account
The single fastest way to get a verified account disabled is to push $500+ on day one. Meta's risk model flags accounts whose spend jumps more than ~30% per day in the first two weeks.
Don't swap cards, switch currencies, or move billing country mid-warm-up. Each change triggers a manual review hold.
Mixing pixels or pointing one account at multiple unrelated domains during warm-up is the #2 disable trigger.
Log in from the same residential IP and device you used at verification. Use a dedicated browser profile or an anti-detect browser if managing many accounts.
An ad account tied to a dead Facebook Page warms up slower. Post organic content, reply to comments, and run a small Page Like campaign in parallel.
First 14 days are the wrong time to test before/after photos, weight-loss claims, or crypto angles. Warm with your most compliant creative, then introduce edge offers gradually.
How to choose an aged or “verified” Meta ad account
Most “aged verified accounts” sold online are neither. Six checks separate a real aged account — one that will hold $5k/day caps — from a relabelled new account that will disable inside a week.
An account that's 4 years old but never spent a dollar is a cold account in a costume. Demand a screenshot of the Billing tab showing lifetime spend ≥ $5,000 across at least 90 days of activity — that's the threshold where Meta's trust signals actually compound.
Personal-profile verification (blue check) means nothing for ad limits. What matters is BM domain verification + business verification (legal entity confirmed via D-U-N-S or utility bill). Ask for the green ✓ in Business Settings → Security Center.
Open Account Quality. You want zero active restrictions, zero ad-level rejections in the last 30 days, and an account status of 'Active'. One unresolved appeal = walk away; it will surface again the moment spend ramps.
If the seller can't transfer the root admin email and reset 2FA to your device, you're renting a timebomb. The original owner can reclaim the account at any time, and Meta will side with the verified identity on the profile.
A 5-year-old ad account paired with a 2-week-old Page warms up like a new account. The linked Page should be at least 6 months old, have organic posts, and show 'green' Page Quality status.
If the account was verified in DE, the card, billing address, IP, and timezone after handover should stay DE for the first 30 days. Mismatched geo is the #1 reason aged accounts get re-verified — and fail.
Eligibility checks to run before your first dollar of spend
Whether the account is brand-new, aged, or rented from an agency, run this 8-point pre-flight before funding. Every line maps to a real disable trigger we've seen in the wild.
Business Settings → Ad Accounts → Account Status. Anything other than 'Active' (Disabled, In Review, Restricted) means do not spend.
facebook.com/accountquality should show no active issues across Ads, Page, and Business assets. Resolve or reject the account before funding.
Currency is set once and cannot be changed. Confirm the currency matches your reporting before the first dollar runs, and set a billing threshold you're comfortable with — Meta auto-raises it as trust grows.
Events Manager → Test Events. You should see PageView, ViewContent, and at least one purchase/lead event from real traffic within the last 7 days. A silent pixel forces the algorithm to learn from zero.
Brand Safety → Domains. The domain shows ✓ Verified and Aggregated Event Measurement priorities are configured (top 8 events ranked). Without this, iOS 14+ traffic underperforms by 30–60%.
Add two payment methods, mark one as primary. A single declined charge during warm-up triggers a 24-hour pause that resets trust momentum.
Only you (or your media buyer) should have Admin. Remove the previous owner, any agency, and any 'system user' tokens you didn't issue. Stray tokens are the most common silent-takeover vector.
Set an account-level spending limit at 2× your planned week-one daily budget. This is the safety net if a scaling rule misfires before warm-up is complete.
Aged-account selection & pre-flight checklist (PDF)
Both checklists above in a single printable PDF — 6 selection criteria for buying aged accounts plus the 8-point pre-flight before your first dollar of spend. Use it side-by-side with any account handover.
Pixel and Conversions API warm-up
An aged ad account on a cold pixel still optimizes like a new account. Meta scores event volume and Event Match Quality (EMQ) as a separate trust signal — ramp it in parallel with spend, not after.
Setup verification — six checks before the first event
Place the base pixel snippet directly in the site <head> so it fires before the consent banner blocks it. GTM body-injected pixels lose 15–25% of events to race conditions and ad blockers.
Server-side events post to graph.facebook.com/v19.0/{PIXEL_ID}/events with a valid CAPI access token. Generate the token in Events Manager → Settings → Conversions API and store it server-side only.
Send the same event_id and event_name from both the browser pixel and CAPI. Without dedup, you'll double-count purchases and the algorithm optimizes against inflated data.
Email, phone, fbp, fbc, client_ip_address, and client_user_agent must be sent with CAPI events. Hash PII with SHA-256 before sending. Event Match Quality below 6.0 cripples optimization.
Events Manager → Test Events should display two rows per action: one labelled 'Browser' and one 'Server'. If you only see one, dedup is broken or CAPI isn't firing.
Events Manager → Overview → 'Event Coverage'. Every priority event should show ≥ 90% coverage and an EMQ score of 7+. Anything red blocks iOS attribution.
Event ramping schedule
Mirror this against the ad-account spend ramp above — the two clocks must move together to keep EMQ climbing.
Event naming & deduplication — the rules that prevent double-counting
Browser pixel and CAPI fire the same conversion from two places. Meta only collapses them into one event when every rule below is satisfied. Miss one and the algorithm optimizes against inflated, noisy data.
Standard events get algorithmic optimization, AEM priority slots, and proper attribution windows. Custom events get none of the above and cannot be ranked in Aggregated Event Measurement.
| Use this | Not this | When it fires |
|---|---|---|
| PageView | page_view, Pageview | Every route change |
| ViewContent | ProductView, view_item | Product / detail page |
| AddToCart | add_to_cart, Cart | Cart-add click confirmed |
| InitiateCheckout | begin_checkout | Checkout step 1 loaded |
| AddPaymentInfo | PaymentEntered | Card details submitted |
| Purchase | purchase, Order, Sale | Order confirmed (server-side) |
| Lead | FormSubmit, SignUp | Qualified form completion |
| CompleteRegistration | Signup, register | Verified account creation |
Names are case-sensitive. Purchase dedupes; purchase creates a parallel custom event with zero history.
The event_id is your dedup key. It must be:
- · Generated once per conversion (e.g. order ID, lead UUID) — not regenerated on retries or page refreshes.
- · Identical on browser + server — pass it from the page to your backend, don't let each side generate its own.
- · Stable for ≥ 7 days — Meta's dedup window is 7 days for Purchase, 48h for others. If the same Order ID re-fires inside the window, it's dropped (correctly).
- · Globally unique — prefer order IDs over hashes; if you must hash, salt with the user ID so two users buying the same SKU don't collide.
Meta dedupes per (event_name, event_id, action_source) triple. Sending a browser event as "website" and the server twin as "system_generated" bypasses dedup entirely.
| Channel | action_source | Dedups with |
|---|---|---|
| Website (browser + CAPI) | website | Browser pixel only |
| Native mobile app | app | SDK-emitted events |
| Email / SMS flow | email · chat | Not deduped — server-only |
| Offline / POS | physical_store | Not deduped — server-only |
| CRM / backend job | system_generated | Never deduped — keep separate |
Browser fires immediately; the server twin can lag (webhook delays, batch jobs). Meta only dedupes if both timestamps fall inside the same 7-day window. Set event_time to the moment the conversion actually happened (the order timestamp), not the moment your script ran.
- 1. Events Manager → Test Events → fire a real Purchase. You should see two rows ("Browser" + "Server") collapse into one within ~60 seconds.
- 2. Events Manager → Diagnostics → look for "Server and browser events not deduplicated". If present, your event_id or event_name don't match.
- 3. Overview → Event Coverage. Confirm "Deduplicated" status, not "Browser-only" or "Server-only".
- 4. If a single test purchase shows as 2 conversions in Ads Manager 24h later, dedup is broken — do not scale spend.
- · GTM tag fires twice on SPA route changes — pixel emits the same event with a new auto-generated ID each time. Fix: pass your own eventID.
- · Stripe + Shopify both posting Purchase with different IDs — pick one source of truth (usually Stripe), disable the other.
- · Retry loop without idempotency — your retry queue sends the same event 5 times with 5 different event_ids. Generate once, persist, then retry.
- · Mixing standard + custom for the same action — "Purchase" pixel-side and "purchase_complete" server-side never collapse.
- · Subscription renewals reusing the original order ID — month 2 gets dropped as a duplicate. Use {orderId}_{billingCycle}.
- · Duplicate Purchase events (browser + server with mismatched event_id) — counted as two real conversions, inflating ROAS and poisoning optimization.
- · EMQ < 5 for more than 48 hours — re-check that hashed email, phone, IP, and user-agent are all being sent server-side.
- · Switching pixels mid-warm-up — the new pixel inherits zero history. If you must migrate, run both in parallel for 14 days.
- · Test Events showing only 'Browser' rows — CAPI isn't firing or the access token is wrong. Fix before any spend ramp.
Copy-paste Conversions API setup
Minimal, production-shaped snippets for the Graph API endpoint, browser pixel dedup, server-side event payloads, signature-verified webhook receivers, and retry logic with exponential backoff. Swap {PIXEL_ID} and CAPI_ACCESS_TOKEN for your own values — never ship the access token to the browser.
1. Endpoint URL
The single Graph API endpoint every server-side event POSTs to. Pin the version (v19.0+) so Meta's monthly rollouts don't silently change your schema.
POST https://graph.facebook.com/v19.0/{PIXEL_ID}/events
?access_token=CAPI_ACCESS_TOKEN
Content-Type: application/json2. Browser pixel — emit a dedup event_id
Generate one ID per logical conversion and send it from both browser and server. Same event_name + event_id = Meta dedupes; mismatch = double-counted purchases.
// Generate once per conversion; reuse on the server call.
const eventId = crypto.randomUUID();
fbq('track', 'Purchase', {
value: 49.00,
currency: 'USD',
content_ids: ['SKU-123'],
content_type: 'product',
}, { eventID: eventId });
// Then POST the same eventId to your /capi proxy below.
fetch('/api/capi/purchase', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
event_id: eventId,
value: 49.00,
currency: 'USD',
email: '[email protected]',
}),
});3. Server event payload (Node.js)
Hash all PII with SHA-256 before sending. Include fbp, fbc, client_ip_address and client_user_agent — every missing field drops Event Match Quality.
import { createHash } from 'crypto';
const sha256 = (v: string) =>
createHash('sha256').update(v.trim().toLowerCase()).digest('hex');
export async function sendPurchase({
eventId, value, currency, email, ip, ua, fbp, fbc,
}: {
eventId: string; value: number; currency: string;
email: string; ip: string; ua: string; fbp?: string; fbc?: string;
}) {
const payload = {
data: [{
event_name: 'Purchase',
event_time: Math.floor(Date.now() / 1000),
event_id: eventId, // dedup key
action_source: 'website',
event_source_url: 'https://your-domain.com/checkout/success',
user_data: {
em: [sha256(email)],
client_ip_address: ip,
client_user_agent: ua,
fbp, fbc,
},
custom_data: { value, currency },
}],
};
return postWithRetry(
`https://graph.facebook.com/v19.0/${process.env.PIXEL_ID}/events` +
`?access_token=${process.env.CAPI_ACCESS_TOKEN}`,
payload,
);
}4. Retry with exponential backoff + jitter
Graph API returns transient 5xx and rate-limit responses under load. Retry 5xx and HTTP 429 up to 4 times, never retry 4xx (your payload is the bug).
const sleep = (ms: number) => new Promise(r => setTimeout(r, ms));
export async function postWithRetry(url: string, body: unknown, max = 4) {
let attempt = 0;
while (true) {
const res = await fetch(url, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(body),
});
if (res.ok) return res.json();
// 4xx (except 429) = bad payload, don't retry
if (res.status >= 400 && res.status < 500 && res.status !== 429) {
throw new Error(`CAPI ${res.status}: ${await res.text()}`);
}
if (++attempt > max) {
throw new Error(`CAPI giving up after ${max} retries: ${res.status}`);
}
// Exponential backoff: 500ms, 1s, 2s, 4s + up to 250ms jitter
const delay = 2 ** (attempt - 1) * 500 + Math.random() * 250;
await sleep(delay);
}
}5. Signature-verified webhook receiver
For Stripe/Shopify/Paddle → CAPI bridges, always verify the upstream signature before firing the Meta event. An unsigned webhook is a free conversion-inflation API for attackers.
import { createHmac, timingSafeEqual } from 'crypto';
export async function handleStripeWebhook(req: Request) {
const signature = req.headers.get('stripe-signature') ?? '';
const raw = await req.text();
const expected = createHmac('sha256', process.env.STRIPE_WEBHOOK_SECRET!)
.update(raw)
.digest('hex');
const ok =
signature.length === expected.length &&
timingSafeEqual(Buffer.from(signature), Buffer.from(expected));
if (!ok) return new Response('invalid signature', { status: 401 });
const event = JSON.parse(raw);
if (event.type !== 'checkout.session.completed') {
return new Response('ignored', { status: 200 });
}
await sendPurchase({
eventId: event.data.object.id, // Stripe ID = stable dedup key
value: event.data.object.amount_total / 100,
currency: event.data.object.currency.toUpperCase(),
email: event.data.object.customer_details.email,
ip: event.data.object.metadata.client_ip,
ua: event.data.object.metadata.client_ua,
fbp: event.data.object.metadata.fbp,
fbc: event.data.object.metadata.fbc,
});
return new Response('ok', { status: 200 });
}6. cURL smoke test
Append test_event_code (from Events Manager → Test Events) so the call shows up in the live test stream instead of polluting production data.
curl -X POST \
"https://graph.facebook.com/v19.0/{PIXEL_ID}/events?access_token=$CAPI_ACCESS_TOKEN" \
-H 'Content-Type: application/json' \
-d '{
"data": [{
"event_name": "Purchase",
"event_time": '"$(date +%s)"',
"event_id": "test-'"$(uuidgen)"'",
"action_source": "website",
"event_source_url": "https://your-domain.com/checkout/success",
"user_data": {
"em": ["'"$(printf '%s' '[email protected]' | shasum -a 256 | cut -d" " -f1)"'"]
},
"custom_data": { "value": 49.00, "currency": "USD" }
}],
"test_event_code": "TEST12345"
}'Score your pixel + CAPI before you advance
Run this 10-question check at every stage gate. The scoring is weighted toward the signals Meta actually uses — dedup, EMQ, and red flags carry more weight than coverage percentages. Below 90 means hold; below 50 means restart.
- 01.Base pixel is installed in <head>, not body-injected via GTMBody-injected pixels lose 15–25% of events to ad blockers and race conditions.
- 02.Conversions API is live with a stored, server-side access tokenIf the token is in client code, regenerate it before continuing.
- 03.Browser + server events share the same event_name and event_idMismatched dedup keys double-count purchases and poison optimization.
- 04.All PII (email, phone, fbp, fbc, IP, user-agent) is SHA-256 hashed before sendRaw PII is rejected silently; EMQ never climbs.
- 05.Events Manager → Test Events shows both 'Browser' and 'Server' rowsOnly one row = dedup is broken or CAPI isn't firing.
- 06.Event Match Quality (EMQ) for priority events is ≥ 7.0Below 6.0 cripples iOS attribution; below 7.0 limits scaling.
- 07.Event coverage report shows ≥ 90% for every priority eventRed coverage blocks Aggregated Event Measurement.
- 08.Domain verified and 8 AEM priorities are configuredWithout AEM ranking, iOS 14+ traffic underperforms 30–60%.
- 09.Current ramp window's event volume target has been hit for 3 consecutive daysThree stable days is the minimum signal Meta needs before you advance.
- 10.No Purchase events before Day 10, no pixel swap, no payment failure in last 7 daysAny one of these resets the trust clock — restart the current stage.
Audience seasoning — targeting, creative & budget over 21 days
Spend ramp and pixel ramp keep the account alive. Audience seasoning is what teaches Meta's algorithm who actually converts. Follow this schedule in parallel with the spend and CAPI clocks — every change below is a deliberate trust signal, not an optimization.
Four rules that make or break seasoning
Replacing every ad on the same day resets the learning phase and tanks delivery for 48–72h. Stagger swaps so at least one Day-1 winner is always live.
Editing an active ad set's targeting (geo, age, interests, LAL %) re-enters learning. Duplicate the ad set with new targeting instead, then pause the old once the new one stabilizes.
Meta's risk model flags spend jumps above ~30%/day in the first 14 days. The 'duplicate and 2x' tactic that works on aged accounts will get a warm-up account restricted.
During seasoning, pause ads below 1% CTR after 1k impressions. Scale only ad sets where CPA holds within 20% of target across 3 consecutive days.
Creative rotation rules
Seasoning fails more often from creative fatigue than from spend mistakes. Use these rules as the default policy for every ramp — phase-specific cadence, hard variation limits, and explicit pause triggers.
| Phase | Active creatives per ad set | Refresh cadence | Max variations introduced / week |
|---|---|---|---|
| Days 1–7 (trust) | 2–3 | No refresh — let signal stabilize | 0 new |
| Days 8–14 (signal) | 3–4 | Add 1 new variant every 3 days | 2 new |
| Days 15–21 (scale) | 4–6 | Add 1 new variant every 2 days | 3 new |
| Post-warm-up (BAU) | 5–8 | Refresh winners weekly, test losers out | 4 new |
- One variable at a time. Change either hook, visual, or CTA — never two on the same variant. Otherwise you can't attribute lift.
- Cap concurrent tests at 3. More than 3 simultaneous variants per ad set splits learning and resets the phase.
- Keep the winner anchored. Always leave the current top performer running while new variants ramp — never swap the entire stack at once.
- Use post IDs, not new posts. Reuse the same post ID across ad sets so social proof (likes, comments, shares) compounds.
- No format mixing mid-phase. Don't mix static, video, and carousel inside a single ad set during days 1–14 — the algorithm needs clean placement signal.
- Frequency > 2.5 (7-day): queue a refresh. > 3.5 with falling CTR → ship the refresh today.
- CTR drop > 25% vs the creative's 3-day rolling baseline → introduce a new hook variant.
- CPM rise > 30% on a single creative while account CPM is flat → fatigue, not delivery. Replace the creative, not the ad set.
- Hook rate < 15% on a fresh creative after 2,000 impressions → kill it, don't iterate. The first impression is the strongest signal.
- Refresh order: hook first, then thumbnail, then CTA, then offer. Never touch the offer during days 1–14.
- Frequency ≥ 4.0 on a 7-day window — pause immediately, regardless of ROAS.
- Negative feedback score ≥ 0.10% (Hides + Reports / Impressions) — pause and review creative compliance.
- CTR < 0.6% for 48h with ≥ 5,000 impressions — pause; the creative is dead, not under-delivered.
- 0 purchases at 3× target CPA on a single creative — pause, keep ad set alive on remaining variants.
- EMQ drops below 6.0 while a single creative dominates spend — pause that creative; it's likely sending malformed events.
- Policy warning on the ad — pause sitewide on that creative, don't just edit. Edits inherit the strike.
A pause is not a kill. Wait 24h, then either relaunch the creative in a fresh ad set or archive it. Never edit a paused ad and resume — duplicate it instead so learning starts clean.
Printable 21-day audience seasoning checklist
One card per day. Tick the box when the action is shipped, then verify the gate before moving to the next day. Print the PDF for the wall above the media-buyer's desk, or use the on-page version below.
- Day 1Phase 1 · Cold ignition
Action: 1 broad ad set (25–54, country only). 3 ads: UGC video, static, carousel. Engagement or Traffic objective. $10–$20 lifetime.
Gate before Day +1: Pixel + CAPI dedup verified in Test Events. ≥ 200 PageViews.
- Day 2Phase 1 · Cold ignition
Action: Hold targeting and creative. Do NOT edit the ad set (counts as a reset). Confirm both 'Browser' and 'Server' rows in Events Manager.
Gate before Day +1: EMQ ≥ 5 on PageView. No active restrictions in Account Quality.
- Day 3Phase 2 · First lookalike
Action: Duplicate the broad ad set. Add ONE 1% LAL (PageView seed ≥ 1k). Switch optimization to ViewContent or Lead. Push to $25–$40/day.
Gate before Day +1: ≥ 30 ViewContent / Lead events fired across pixel + CAPI.
- Day 4Phase 2 · First lookalike
Action: Refresh 1 of 3 ads only (new hook). Keep two Day-1 ads alive as trust anchors.
Gate before Day +1: CPA tracking inside Ads Manager, not just GA. No payment declines.
- Day 5Phase 2 · First lookalike
Action: Raise budget +30% max. Add a second creative variant of the winning hook.
Gate before Day +1: EMQ climbing toward 6+. Pixel firing ≥ 50 conversions in last 7 days.
- Day 6Phase 3 · Mid-funnel ramp
Action: Add 1–3% LAL from AddToCart + ONE single-interest ad set (not stacked). 3 ad sets total. Push to $100–$150/day.
Gate before Day +1: AddToCart firing server-side via CAPI. Dedup OK.
- Day 7Phase 3 · Mid-funnel ramp
Action: Rotate in 2 new ads, pause the lowest-CTR ad. Keep at least one Day-1 winner running.
Gate before Day +1: No ad-level rejections in the last 7 days.
- Day 8Phase 3 · Mid-funnel ramp
Action: Move the strongest ad set to AddToCart optimization. Hold others on ViewContent.
Gate before Day +1: InitiateCheckout firing ≥ 10/day across pixel + CAPI.
- Day 9Phase 3 · Mid-funnel ramp
Action: Scale winners +20% (never duplicate-then-2x). Add AddPaymentInfo server-side.
Gate before Day +1: EMQ ≥ 7 on at least one priority event.
- Day 10Phase 3 · Mid-funnel ramp
Action: Maintain Page activity: 1 organic post + reply to comments. Budget $250–$300/day.
Gate before Day +1: Account Quality still green. Spend ramp under +30%/day.
- Day 11Phase 4 · Retargeting + CBO
Action: Launch retargeting: 7-day site visitors + 95% video viewers. Cap at 20% of total spend. Add 1–5% LAL.
Gate before Day +1: Retargeting audience size ≥ 1k. Frequency target ≤ 2.5.
- Day 12Phase 4 · Retargeting + CBO
Action: Open CBO at the campaign level with 3–5 ad sets. Move one ad set to Purchase optimization.
Gate before Day +1: ≥ 25 Purchase or Lead events in last 7 days.
- Day 13Phase 4 · Retargeting + CBO
Action: Launch first creative iteration batch: 3 new ads on the Day-6 winning angle.
Gate before Day +1: Kill any ad below 1% CTR after 1k impressions.
- Day 14Phase 4 · Retargeting + CBO
Action: Scale to $500–$700/day. Audit AEM priorities — top 8 events ranked in Brand Safety → Domains.
Gate before Day +1: CPA within 20% of target across the last 3 days.
- Day 15Phase 4 · Retargeting + CBO
Action: Activate Value optimization on any campaign that has cleared Learning (50 events / 7 days).
Gate before Day +1: Purchase event out of Learning phase on at least one ad set.
- Day 16Phase 5 · Full funnel
Action: Layer full funnel: cold broad + 1/3/5% LALs + 7d/30d retargeting. Exclude purchasers from prospecting.
Gate before Day +1: Frequency on cold ≤ 1.8. No audience overlap above 20%.
- Day 17Phase 5 · Full funnel
Action: Push to $1k/day. Maintain creative refresh cadence at 30–50% per week (never 100%).
Gate before Day +1: EMQ ≥ 7 on every priority event.
- Day 18Phase 5 · Full funnel
Action: Open a parallel Advantage+ Shopping campaign with the existing winning creative.
Gate before Day +1: No 'Limited delivery' warning on any ad set.
- Day 19Phase 5 · Full funnel
Action: Scale CBO winners +30%. Archive (do not delete) losers — preserves account history.
- Day 20Phase 5 · Full funnel
Action: Test 1 policy-edge creative in a sandbox ad set only. Hold compliant creative on main campaigns.
Gate before Day +1: Sandbox ad set passes review without flags.
- Day 21Phase 5 · Graduation
Action: Account is seasoned. Open broad targeting + Advantage+ audience. Retargeting drops to 15–25% of budget. Ready to scale to $2k–$5k+/day.
Gate before Day +1: All Day-21 gates green. Begin the scaling playbook.
The exact KPIs that decide if you advance, hold, or pull back
During seasoning, vanity metrics lie. Watch six signals and compare them against the phase you're in. If two or more KPIs miss the floor for 48 hours, hold spend at the current step instead of scaling.
| KPI | Days 1–7 (trust) | Days 8–14 (signal) | Days 15–21 (scale) | Pull-back trigger |
|---|---|---|---|---|
| CTR (link, all placements) | ≥ 0.8% | ≥ 1.1% | ≥ 1.3% | < 0.6% for 48h |
| CPM (feed, broad) | Baseline ±20% | Baseline ±15% | Stable / falling | +40% spike day-over-day |
| Hook rate (3s/impr.) | ≥ 18% | ≥ 22% | ≥ 25% | < 15% on 3+ creatives |
| Add-to-cart rate (ATC/LPV) | ≥ 4% | ≥ 6% | ≥ 8% | < 3% with healthy CTR |
| Purchase rate (PUR/ATC) | Not required | ≥ 8% | ≥ 12% | 0 purchases at 3× target CPA |
| Event Match Quality (EMQ) | ≥ 6.0 | ≥ 7.0 | ≥ 8.0 | Drops > 1.0 point in 24h |
| Dedup rate (browser + server) | ≥ 70% | ≥ 85% | ≥ 90% | < 60% (double-counting) |
| Frequency (7-day) | ≤ 1.5 | ≤ 2.2 | ≤ 3.0 | > 3.5 with falling CTR |
- CTR (link): measures creative + audience fit. Use link CTR, not all-clicks — all-clicks inflates with thumb-scrolls.
- CPM: tracks how Meta prices the account. A rising CPM with flat CTR is the earliest sign of degraded delivery trust.
- Hook rate: isolates creative from targeting. Below 15% means the thumbnail/first 3s is the bottleneck, not the account.
- ATC rate: the first true intent signal. Healthy ATC with weak purchases = checkout or pricing issue, not warm-up.
- Purchase rate: the only KPI that proves seasoning worked. Don't scale until it clears the phase floor for 3 days running.
- EMQ: Events Manager → Datasets → Event Match Quality. Below 6.0 starves the algorithm regardless of spend.
- Advance only when ≥ 4 of the 6 primary KPIs (CTR, CPM, ATC, Purchase, EMQ, Dedup) meet the next phase's floor for 48 consecutive hours.
- Hold spend flat if 2 KPIs miss. Don't cut — cuts re-trigger the learning phase and waste prior trust.
- Pull back to the previous phase's daily cap if any red trigger fires, then hold 72 hours before retrying.
- Never scale on a single good day. The algorithm needs a stable 3-day trend to lock signal.
- Report window: use 7-day click + 1-day view during seasoning to match the attribution Meta optimizes on.
Pair this with the readiness quiz before each phase change, and the Pixel + CAPI warm-up rules so EMQ stays above the floor.
Skip the warm-up: rent a pre-warmed account
Every account we sell or rent ships pre-warmed with verified spend history, clean payment methods, and a real Page tied to it. If you need to scale this week instead of next month, start with an aged personal account or an agency ad account from our inventory.
Want a human to review your warm-up plan?
Send us your current account status, vertical, target spend, and which stage you're stuck on. We'll reply with a tailored warm-up schedule, flag the policy risks specific to your offer, and quote pre-warmed accounts or BMs if you'd rather skip the 21 days entirely.
- Free account health check — disable risk, spend ceiling, BM trust
- Custom 21-day warm-up calendar for your vertical & geo
- Pixel / CAPI deduplication audit (event match quality)
- Inventory quote: aged, verified, agency BM, or reinstatement
No spam, no calls. Share only what you're comfortable sharing — ad account ID is enough to start a health check.
Frequently asked questions
What does it mean to 'warm up' a Facebook ad account?
Warming up is a gradual spend, event, and audience ramp on a new or freshly assigned ad account so Meta's trust signals build before you push real budget. Done right, daily spend caps rise from a few dollars to several thousand within 2–3 weeks; done wrong, the account is disabled before it ever scales.
Do aged or 'verified' Meta ad accounts still need to be warmed up?
Yes. An aged account inherits trust from its previous owner — but the moment ownership, IP, device fingerprint, payment method, pixel, or creative changes, Meta re-evaluates from a fresh baseline. Plan on 7–10 days of gentle handover spend on an aged account and 14–21 days on a brand-new one. Skipping the handover ramp is the #1 reason 'verified' accounts get disabled in their first week.
What does 'verified' Meta ad account actually mean?
Three different verifications exist and only two matter for ad spend: (1) business verification — Meta confirmed the legal entity behind the Business Manager, (2) domain verification — the BM controls the destination URL with Aggregated Event Measurement priorities set, and (3) personal profile blue check — irrelevant for ads. A genuine 'verified' account being sold should have items 1 and 2 already complete on the seller's BM with a documented transfer path to yours.
How do I prove an aged ad account is actually aged before warm-up?
Ask for four artifacts before you spend a dollar: (1) a screenshot of the Billing tab showing lifetime spend and the first-charge date, (2) a Business Settings → Security Center screenshot showing business verification, (3) a live screen-share of Account Quality (facebook.com/accountquality) showing no active restrictions, and (4) the original Page creation date plus follower count. Account creation date alone proves nothing — consistent monthly spend over 6+ months is what builds the trust signal you're paying for.
What eligibility checks should I run on a 'verified' account before the first ad runs?
Eight checks: Account Status = Active, Account Quality clear, currency set correctly (cannot be changed later), billing threshold and a primary + backup payment method, pixel firing real events in the last 7 days, domain verified with AEM priorities, admin roles scoped to you only (remove previous owners and stray system-user tokens), and an account-level spending limit at 2× planned week-one budget. Any failure here means do not spend — fix the gap first.
Does buying an aged or verified account let me skip warm-up entirely?
No, but it compresses the timeline dramatically. Aged accounts inherit billing-threshold history and a lower 'new account' risk score, so they reach $5k/day caps in 7–10 days instead of 21–30. You still need a gentle handover ramp on the new buyer's IP, device, pixel, and payment method to avoid the 'sudden owner change' anomaly flag that disables 'verified' accounts within their first week.
Do the pixel and Conversions API need their own warm-up alongside the account?
Yes. Meta scores event volume and Event Match Quality (EMQ) as a separate trust signal from account spend, so a fresh pixel on an aged account still optimizes like a new one. Ramp events in parallel with spend: PageView and ViewContent for 48 hours, upper-funnel conversions days 2–4, mid-funnel days 5–9, and Purchase only after EMQ ≥ 7 and 25+ weekly purchase events.
Do I still need the Facebook pixel if I'm running Conversions API?
Yes — run both, deduplicated with the same event_id. The browser pixel captures fbp/fbc cookies that CAPI alone can't generate, and the server feed catches the 20–40% of events ad blockers and iOS 14+ kill. CAPI alone caps EMQ at around 5, which cripples iOS optimization.
What Event Match Quality (EMQ) score should I target during warm-up?
7.0 or higher per priority event. Below 6, Meta's optimizer essentially flies blind on iOS traffic. Fastest wins: send hashed email AND phone (not one or the other), include client_ip_address + client_user_agent on every server event, and forward fbp/fbc from the browser cookie.
How long does warming up a Meta ad account take end to end?
Plan on 14–21 days to reach $1,000+/day caps on a personal BM, 5–7 days on an agency ad account (the agency BM is already whitelisted), and 30+ days on a brand-new un-aged account to safely reach $5k/day. Aged 'verified' accounts on a clean handover land in the 7–10 day window.
How fast can I scale budget during warm-up without triggering a restriction?
Cap daily increases at +30% during days 1–14 and +50% from day 15 once CPA is stable across 3 consecutive days. The 'duplicate the ad set and double the budget' tactic that works on aged, trusted accounts is the single biggest cause of warm-up restrictions — Meta's risk model treats sudden 2x jumps on young accounts as compromised-account behavior.
Should I rotate creative aggressively while seasoning a new or aged account?
No. Replace at most 30–50% of creative per week and never swap 100% of ads in a single day — full refreshes reset the learning phase. Keep at least one Day-1 winner alive as a trust anchor while you layer in new hooks and formats.
When should I introduce Lookalike and retargeting audiences?
Lookalikes from Day 3 (1% from PageView, seed ≥ 1k), broader 1–3% LALs from Day 6 once AddToCart fires consistently, and retargeting from Day 11 — capped at ~20% of total spend until Day 16. Adding retargeting too early starves the algorithm of the cold-traffic signals it needs to build a prospecting audience.
Can I warm up multiple ad accounts at the same time?
Yes, but each account needs its own browser profile, payment method, and consistent residential or business IP. Running 10 accounts from the same fingerprint at the same time triggers Meta's linked-account detection and risks a full BM disable across every connected asset.
What spend should I start with on a brand-new ad account?
$5–$20/day for the first 48 hours on an Engagement or Traffic objective with manual bidding off, then ramp by ~30% per day. Jumping straight to Conversion + Purchase optimization on day one with a $100+ budget is the fastest path to a 'pending review' restriction.