
ATS fields for outreach metrics
Ben Argeband, Founder & CEO of Heartbeat.ai — Keep it plug-and-play; avoid vendor specifics.
What’s on this page:
Who this is for
This is for recruiting ops leaders who need consistent outreach reporting across an ATS, CRM, dialer, and email tool—without turning recruiters into data-entry clerks.
- Recruiting ops building consistent reporting and definitions
- TA leaders who need channel outcomes that tie back to pipeline stages
- Teams cleaning up suppression, opt-outs, and deliverability before it becomes a brand issue
Quick Answer
- Core Answer
- Implement a minimum viable ATS field schema that separates contact truth from touch outcomes, so outreach metrics reconcile across email and calling tools.
- Key Insight
- Reporting breaks when “sent” is treated as “delivered” and opt-outs live in notes instead of contact-level suppression fields.
- Best For
- Recruiting ops building consistent reporting
Compliance & Safety
This method is for legitimate recruiting outreach only. Always respect candidate privacy, opt-out requests, and local data laws. Heartbeat does not provide medical advice or legal counsel.
Framework: “Clean data, calm recruiting” ops reality
TL;DR lookup: Store delivery/bounce/reply events in the email tool, call events in the dialer, and store suppression/consent/verification as contact truth in the ATS/CRM. Then roll up rates using consistent denominators.
Outreach reporting fails in predictable ways: different tools disagree, recruiters log outcomes differently, and leaders lose confidence in the funnel. “Clean data, calm recruiting” means you standardize a small set of fields that (1) protect deliverability and compliance, (2) make outcomes comparable across channels, and (3) are easy enough that reps will actually use them.
The trade-off is… you’ll capture less nuance in free-text notes, but you’ll gain metrics you can act on and defend across systems.
Step-by-step method
Step 1: Lock metric definitions (with denominators)
Before you build fields, lock definitions so your reports don’t drift by team or tool. Use these canonical definitions and always show the denominator:
- Connect Rate = connected calls / total dials (e.g., per 100 dials).
- Answer Rate = human answers / connected calls (e.g., per 100 connected calls).
- Deliverability Rate = delivered emails / sent emails (e.g., per 100 sent emails).
- Bounce Rate = bounced emails / sent emails (e.g., per 100 sent emails).
- Reply Rate = replies / delivered emails (e.g., per 100 delivered emails).
Operational rule: delivery and bounce events come from the email tool. The ATS stores the resulting contact truth (suppression, opt-out, verification dates) so recruiters can’t accidentally re-contact suppressed records.
Step 2: Implement the minimum viable fields (MVF) first
These minimum viable fields are the smallest set that makes outreach metrics trustworthy and keeps you out of deliverability trouble:
- Consent: status + source + timestamp
- Opt-out / suppression: status + source + date + scope
- Last verified date: email (and phone if you can)
- Last touched date: by channel
- Outcomes by channel: standardized picklists
- Bounce type + bounce reason: hard/soft plus reason taxonomy
- Wrong-person flag: plus corrected-contact workflow
- Suppression source/date: always auditable
For the operational side of suppression, see suppression lists and opt-out management workflows.
Step 3: Separate contact truth from touch truth
Most teams mix “what’s true about the contact” with “what happened on one touch.” That creates overwrites and bad suppression decisions. Keep it clean:
- Contact truth (persists): consent, opt-out/suppression, verification dates, wrong-person flag, preferred channel.
- Touch truth (per activity): channel, timestamp, sender identity, template/sequence ID, outcome, bounce taxonomy (email), call disposition (dialer).
Step 4: Create a channel-agnostic Outreach Touch record
If your ATS supports custom objects, create an “Outreach Touch” object. If it doesn’t, simulate it with a structured activity record using required picklists. Either way, you need consistent fields across the CRM, dialer, and email tool so you can roll up metrics.
Minimum fields for each touch:
- outreach_touch_id (unique)
- contact_id (ATS contact/candidate ID)
- job_id (if applicable)
- channel (call/email/SMS/other)
- touch_at (timestamp)
- sender_user_id (recruiter)
- sender_mailbox_id or sending_domain (for email)
- outcome (standardized picklist)
- outcome_at (timestamp)
- template_id / sequence_id (if used)
Step 5: Add deliverability protection fields (bounce triage ladder worksheet)
When bounces spike, you need to act fast without guessing. Implement a bounce taxonomy and a logged action so ops can suppress, verify, refresh, or run authentication checks.
Uniqueness hook (worksheet): Triage ladder that prevents domain damage: bounce type → suppress/verify/refresh/auth check, plus copy/paste logging fields.
- Classify: bounce_category (hard/soft) + bounce_reason (invalid mailbox, domain not found, blocked/policy, mailbox full, rate limited, other).
- Decide action (log it): suppression_action_taken = suppress / verify / refresh / auth_check / none.
- Apply suppression (contact truth): opt_out_status + suppression_source + suppression_date + suppression_scope.
Visual note for your internal SOP: create a one-page “Bounce triage decision tree” that starts with bounce_reason and ends with the exact field updates to make in the ATS.
Step 6: Standardize outcomes so “no answer” means the same thing everywhere
Picklists beat free text. Keep the list short enough that recruiters don’t guess.
| Channel | Outcome picklist (copy/paste) | Notes |
|---|---|---|
| Call | no answer; left voicemail; gatekeeper; wrong number; connected (voicemail/IVR); human answered; scheduled follow-up; do-not-call request | When “do-not-call request” occurs, set suppression_scope=phone_only and suppression_source=candidate_request. |
| sent; delivered; bounced-soft; bounced-hard; replied-positive; replied-neutral; replied-negative; auto-reply; unsubscribed/opt-out | Delivery/bounce should be sourced from the email tool event stream. | |
| SMS (if used) | sent; delivered; failed; replied; opt-out | Keep opt-out as contact truth in the ATS. |
Step 7: Assign field ownership (auto vs manual) so logging actually happens
Recruiters will not maintain a complex schema manually. Decide what is auto-captured vs manually set, and who owns each field.
| Field group | Where it should be captured | Capture mode | Owner |
|---|---|---|---|
| Delivery events (delivered/bounced + reason) | Email tool | Auto | Ops / systems |
| Suppression status + source/date/scope | ATS contact record | Auto when possible; manual allowed | Ops policy; recruiters execute |
| Call dispositions | Dialer + ATS touch record | Auto from dialer; manual fallback | Recruiters |
| Consent status/source | ATS/CRM contact record | Manual (structured picklist) | Recruiters; audited by ops |
| Verification dates | ATS contact record | Auto from verification workflow | Ops / systems |
Step 8: Joining data for reporting (so your dashboard reconciles)
To make metrics reconcile, decide your join keys up front:
- Primary join: contact_id + outreach_touch_id (best case).
- If you don’t have a stable outreach_touch_id: join on contact_id + channel + touch_at (timestamp) within a tight time window, and treat it as a temporary bridge until you add a touch ID.
- System-of-record rule: use the email tool for delivered/bounced/replied events; use the dialer for dials/connects/answers; use the ATS for suppression/consent/verification and for tying touches to pipeline stages.
This is how you avoid the classic argument where the ATS says “sent 500” and the email tool says “delivered 430” and nobody trusts either number.
Step 9: Build your copy/paste schema (field map + CSV-ready)
Below is a copy/paste schema you can hand to ops or your ATS admin. It’s vendor-agnostic and designed to map cleanly across an ATS, CRM, dialer, and email tool.
Diagnostic Table:
Use this to diagnose why outreach metrics don’t reconcile across systems.
| Symptom | Likely root cause | Field(s) missing or inconsistent | Fix (ops action) |
|---|---|---|---|
| Reply Rate looks “too low” in ATS vs email tool | Replies counted against sent instead of delivered | delivered outcome + delivered timestamp; reply outcome + reply timestamp | Store delivered/replied as touch outcomes; report Reply Rate = replies / delivered emails |
| Recruiters keep emailing people who opted out | Opt-out stored in one tool only; no contact-level suppression truth | opt_out_status; suppression_source/date; suppression_scope | Make suppression a required contact field in ATS; block sequences when suppressed |
| Bounce Rate spikes and nobody knows what to do | No bounce taxonomy; no logged action; no owner | bounce_category; bounce_reason; suppression_action_taken | Use the bounce triage ladder; route auth_check to whoever owns sending domains |
| Call metrics don’t predict pipeline movement | Dialer dispositions don’t map to human answers | total_dials; connected_calls; human_answers; call_outcome | Enforce definitions: Connect Rate = connected calls / total dials; Answer Rate = human answers / connected calls |
| Wrong-person contacts keep recycling into campaigns | No wrong-person flag; no corrected-contact workflow | wrong_person_flag; suppression_scope; refresh_task | Set wrong_person_flag=true; suppress that email/phone; create a refresh task |
Visual note for your internal SOP: keep a short “Postmaster checks” checklist for the person who owns sending domains (authentication alignment, reputation signals, and sudden list-quality changes).
Weighted Checklist:
Score your current schema before you rebuild it. Total 100 points. If you’re under 70, your metrics will be noisy and your deliverability risk is higher than you think.
- (20) Contact-level suppression is explicit (status + source + date + scope)
- (15) Consent/permission is captured (status + source + timestamp)
- (15) Verification is captured (last verified date for email; last verified date for phone if available)
- (10) Wrong-person handling exists (flag + suppression + refresh task)
- (10) Touch outcomes are standardized across channels (picklists, not free text)
- (10) Bounce taxonomy exists (hard/soft + reason)
- (10) “Last touched date” is tracked by channel (prevents over-contacting)
- (10) Reporting uses correct denominators (sent vs delivered; dials vs connected)
Nice-to-have: template_id/sequence_id on touches so you can isolate which messaging correlates with bounces, opt-outs, or replies without reading notes.
Outreach Templates:
These are internal ops templates (not candidate messaging). They reduce back-and-forth and make logging consistent across the ATS/CRM/dialer/email tool stack.
Template 1: Ops ticket to implement the field map
Subject: Implement ATS outreach metrics field schema (contact + touch)
Body: Please add the fields in the attached schema to our ATS and make them available for reporting exports. We need contact-level truth fields (consent, suppression/opt-out, verification dates, wrong-person flag) and touch-level outcome fields (channel outcomes + bounce taxonomy + template/sequence IDs). Deliverables: (1) fields created, (2) picklists configured, (3) required fields enforced on Outreach Touch records, (4) export/report view created, (5) documentation for auto-captured vs manual fields.
Template 2: Recruiter SOP snippet (what to log, when)
When you email: ensure the touch has channel=email and an outcome. Delivery/bounce should be auto-captured from the email tool. If you receive a reply, set outcome=replied-[positive/neutral/negative]. If the candidate opts out, set opt_out_status=true immediately.
When you call: log the call outcome. If a human answers, mark outcome=human answered (this drives Answer Rate). If it’s the wrong person, set wrong_person_flag=true and suppress that phone/email.
Template 3: Deliverability incident note (bounce spike)
Subject: Bounce spike triage (time window + sending domain/mailbox)
Body: We observed increased bounces. Please review bounce_reason distribution (hard vs soft; invalid mailbox vs blocked/policy). Actions: suppress hard bounces; verify/refresh questionable contacts; run authentication checks and review Postmaster signals. Log suppression_action_taken on the touch and suppression_source/date/scope on the contact.
Common pitfalls
1) Counting “sent” as “delivered”
This inflates denominators and makes Reply Rate look worse than it is. Store “sent” and “delivered” separately, and report Reply Rate as replies / delivered emails.
2) Opt-outs stored as notes instead of suppression fields
If opt-outs live in notes, they won’t block future outreach. Make suppression a contact-level truth field with source/date/scope so it’s auditable and enforceable.
3) Bounce type without bounce reason
Hard vs soft is not enough to act. You need a reason taxonomy to decide whether to suppress, verify, refresh, or run authentication checks.
4) Wrong-person isn’t treated as a data quality event
Wrong-person should trigger suppression of that specific email/phone and a refresh task. Otherwise it keeps recycling into sequences.
5) Overbuilding fields nobody uses
Start with the minimum viable fields. Add nice-to-have fields only after you see consistent logging behavior.
How to improve results
1) Build a weekly outreach health report (examples)
Don’t just show counts. Show rates with denominators, by recruiter and by sending domain/mailbox.
Example report columns (email):
- sent_emails
- delivered_emails
- bounced_emails
- replies
- Deliverability Rate = delivered_emails / sent_emails
- Bounce Rate = bounced_emails / sent_emails
- Reply Rate = replies / delivered_emails
Example report columns (calls):
- total_dials
- connected_calls
- human_answers
- Connect Rate = connected_calls / total_dials
- Answer Rate = human_answers / connected_calls
Measure this by… pulling delivery/bounce/reply events from the email tool, pulling dials/connects/answers from the dialer, and pulling suppression/consent/verification from the ATS contact record, then joining on contact_id and outreach_touch_id.
2) Use the bounce triage ladder to protect domains
When bounces rise, don’t guess. Classify by bounce_reason, take the logged action, and update contact-level suppression truth so the same bad address doesn’t get hit again.
3) Tighten verification and refresh cadence (without overpromising)
Verification fields let you stop arguing about “is this email good?” and start operating: if last_verified_email_at is stale, verify or refresh before you send. If you can’t verify, reduce risk by prioritizing contacts with recent verification and by suppressing repeated bounces.
Implementation Notes
Keep a one-page field map with: field name, object (contact/touch), type, allowed values, required?, source system (ATS/CRM/dialer/email tool), and reporting use.
For deliverability monitoring during incidents, review reputation and error signals in Google Postmaster Tools and align authentication settings as needed.
Legal and ethical use
Outreach data includes personal contact information and preferences. Treat suppression and opt-outs as first-class fields, not optional notes. Honor opt-out requests quickly, avoid contacting suppressed records, and document consent/permission where applicable. If you operate across regions, align your process with local data laws and your organization’s policies.
Evidence and trust notes
We publish how we define and audit outreach metrics so ops teams can compare apples-to-apples across tools. Start here: Heartbeat trust methodology and the deeper definitions page accuracy and metrics definitions.
Official deliverability references used in this playbook:
Related internal playbooks:
- Reply rate tracking for physician outreach
- Suppression lists and opt-out management
- How to build a physician call list
FAQs
What are the minimum viable fields I need to report outreach metrics in an ATS?
At minimum: consent status/source/timestamp, opt-out/suppression (status + source + date + scope), last verified date, last touched date by channel, standardized channel outcomes, bounce category + reason, wrong-person flag, and suppression source/date.
Where should bounce data live: ATS or email tool?
The email tool should be the system of record for delivery events (delivered/bounced and bounce reason). The ATS should store the resulting contact truth: suppression status, suppression source/date, suppression scope, and last verified date.
How do I keep call metrics consistent between a dialer and the ATS?
Standardize dispositions and report using fixed definitions: Connect Rate = connected calls / total dials; Answer Rate = human answers / connected calls. Store the call outcome on the touch record and roll up weekly.
What fields prevent repeated outreach to the wrong person?
Add a wrong-person flag at the contact level, suppress the specific email/phone that was wrong, and create a refresh task to find the correct contact. Don’t leave it as a note.
How do I protect deliverability when bounces spike?
Use a bounce taxonomy (hard/soft + reason) and a logged action field (suppress/verify/refresh/auth_check). Review authentication and reputation signals using Postmaster, and stop sending to known-bad addresses.
Next steps
- Implement the minimum viable fields first, then enforce required picklists on Outreach Touch records.
- Standardize reporting using the definitions in accuracy and metrics definitions.
- If you want a workflow that includes ranked mobile numbers by answer probability, start here: create a Heartbeat account.
Appendix: CSV-ready field map (copy/paste)
| Field Name | Object | Type | Allowed Values / Notes | Required? | Primary Source |
|---|---|---|---|---|---|
| consent_status | Contact | Picklist | unknown, implied, explicit, do_not_contact | Yes | ATS/CRM |
| consent_source | Contact | Picklist | candidate_provided, referral, public_profile, prior_relationship, other | Yes | ATS/CRM |
| consent_at | Contact | DateTime | ISO timestamp | No | ATS/CRM |
| opt_out_status | Contact | Boolean | true/false | Yes | ATS (system of record) |
| suppression_source | Contact | Picklist | candidate_request, bounce, internal_compliance, other | Yes | ATS |
| suppression_date | Contact | DateTime | ISO timestamp | Yes | ATS |
| suppression_scope | Contact | Picklist | email_only, phone_only, all_channels, domain_level | Yes | ATS |
| last_verified_email_at | Contact | DateTime | Last time email was verified | Yes | Verification workflow |
| last_verified_phone_at | Contact | DateTime | Last time phone was verified | No | Verification workflow |
| last_touched_email_at | Contact | DateTime | Last email touch timestamp | Yes | Email tool |
| last_touched_call_at | Contact | DateTime | Last call touch timestamp | Yes | Dialer |
| wrong_person_flag | Contact | Boolean | true/false | Yes | ATS/CRM |
| outreach_touch_id | Touch | Text | Unique ID | Yes | ATS/CRM |
| contact_id | Touch | Text | ATS contact/candidate ID | Yes | ATS |
| job_id | Touch | Text | Requisition/job ID (if applicable) | No | ATS |
| channel | Touch | Picklist | call, email, sms, other | Yes | ATS/CRM |
| touch_at | Touch | DateTime | ISO timestamp | Yes | ATS/CRM |
| sender_user_id | Touch | Text | Recruiter user ID | Yes | ATS/CRM |
| sending_domain | Touch | Text | Domain used to send the email (if applicable) | No | Email tool |
| outcome | Touch | Picklist | Use the standardized outcomes table in Step 6 | Yes | ATS/CRM |
| outcome_at | Touch | DateTime | ISO timestamp | No | ATS/CRM |
| bounce_category | Touch | Picklist | hard, soft, none | No | Email tool |
| bounce_reason | Touch | Picklist | invalid_mailbox, domain_not_found, blocked_policy, mailbox_full, rate_limited, other | No | Email tool |
| suppression_action_taken | Touch | Picklist | suppress, verify, refresh, auth_check, none | No | ATS/CRM |
| template_id | Touch | Text | Email template identifier | No | Email tool |
| sequence_id | Touch | Text | Sequence/cadence identifier | No | Email tool |
Note: This page is vendor-agnostic by design and does not assume or claim any native integration between systems.
About the Author
Ben Argeband is the Founder and CEO of Swordfish.ai and Heartbeat.ai. With deep expertise in data and SaaS, he has built two successful platforms trusted by over 50,000 sales and recruitment professionals. Ben’s mission is to help teams find direct contact information for hard-to-reach professionals and decision-makers, providing the shortest route to their next win. Connect with Ben on LinkedIn.