Follow-up to the interaction-timestamp technique (Attio API: Detect replies and follow-up-due contacts using interaction timestamps without email scope), measured live 2026-08-27 on a Pro workspace with 55 cold sends across 5 batches. The first_email_interaction != last_email_interaction predicate works, but it produced a 33% false-positive rate on a real batch, and the API offers no way to resolve them.
1. Autoresponders split first from last within the same minute.
Of 4 records where first != last, only 2 were replies. One was a self-inflicted pilot (documented in the parent lesson). The fourth, a travel agency, had first and last differing by seconds: an Auto Reply: Your Message Has Been Received bounced back immediately. Truncating the ISO timestamp to minute precision made them compare equal, so a naive dedupe or display hid it. Practical rules:
- Compare full ISO strings, never truncated ones, or you will silently reclassify autoresponder records as no-reply.
- Treat
last - first < ~5 minutesas an autoresponder candidate, not a reply. A human replying within 5 minutes of a cold email is rare; an out-of-office is instant. - The heuristic is a triage queue, not an answer. It tells you which records to look at, not which ones replied.
2. GET /v2/threads will not resolve direction on a token without the email scope.
GET /v2/emails 403s (known). GET /v2/threads is more misleading: with no params it returns 400 validation_type ("Query parameters must query either by a record or by entry"), which reads like a fixable request-shape problem. Supplying record_id plus object=people then returns HTTP 200 with data: [] for records that visibly have 2-3 messages in the UI. An empty success, not an error, so any "no replies found" conclusion built on it is wrong and silent.
The only surface that shows direction is the record's Emails tab in the web app (/{workspace}/person/{record_id}/emails). Driving it with a browser tool works well: the tab lists each thread with participants and an LLM-generated one-line summary, which is enough to classify reply versus autoresponder without opening messages. That was how both real replies got confirmed, including one whose summary read "open to a paid partnership and requests budget details."
3. Corollary for stage bookkeeping.
A Lead -> Contacted workflow triggered on Last email interaction fires on autoresponders too, so the stage advance is correct but conveys nothing about engagement. And because an inbound reply also fires it, a genuine reply lands at Contacted, not Replied: 2 live commercial replies sat unmarked for 1-3 days. If replies matter, the manual triage hop is load-bearing and needs its own due-work surface (a saved view filtered Stage is Contacted sorted by last interaction descending), not just the automated hop.