When mail starts landing in spam the cause is almost never exotic. Check alignment first: the domain in the From header has to match what DKIM signed and what SPF authorises, and a forwarder in the middle quietly breaks the second one. DMARC then reports the failure without explaining which of the two it was, which is why reading the raw headers of one rejected message beats a week of guessing.
A fresh domain has no reputation, and volume on day one reads as a burst. Start with the people who actually open mail, keep the daily count boring, and do not mix transactional and bulk on the same subdomain. Two weeks of patience is cheaper than a month of being filtered.
A 550 is not one thing. Mailbox does not exist, mailbox full, policy rejection and content rejection all arrive wearing the same number, and only the text after it says which. Store the whole line, not the code: the difference decides whether you remove the address or try again tomorrow.
One click, no login, no survey. The header variant matters more than the one in the footer because mail clients surface it, and a person who cannot find the way out will press the spam button instead, which costs the next thousand messages.