From a753539cbf2bf8bc48d4b3a205a44ca9e1715327 Mon Sep 17 00:00:00 2001 From: rehanvandermerwe Date: Wed, 15 Apr 2026 13:26:41 +0200 Subject: [PATCH 1/2] feat(domains): add TrackingCAA record support The Domains API now returns an extra DNS record `TrackingCAA` (type `CAA`, value `0 issue "amazon.com"`) when a `tracking_subdomain` is configured AND the customer's root domain has CAA records that would prevent AWS from issuing the tracking-domain certificate. Updates the Record docstring to list `TrackingCAA` as an example value and extends the create/get domain test fixtures (sync + async) to include the new record. Co-Authored-By: Claude Opus 4.6 --- resend/domains/_record.py | 2 +- tests/domains_async_test.py | 31 ++++++++++++++++++++++++++++++- tests/domains_test.py | 31 ++++++++++++++++++++++++++++++- 3 files changed, 61 insertions(+), 3 deletions(-) diff --git a/resend/domains/_record.py b/resend/domains/_record.py index 0654004..653b628 100644 --- a/resend/domains/_record.py +++ b/resend/domains/_record.py @@ -4,7 +4,7 @@ class Record(TypedDict): record: str """ - The domain record type, ie: SPF, DKIM, Inbound, Tracking. + The domain record type, ie: SPF, DKIM, Inbound, Tracking, TrackingCAA. """ name: str """ diff --git a/tests/domains_async_test.py b/tests/domains_async_test.py index 52ee2f4..627b3d6 100644 --- a/tests/domains_async_test.py +++ b/tests/domains_async_test.py @@ -173,6 +173,14 @@ async def test_domains_create_async_with_tracking_subdomain(self) -> None: "ttl": "Auto", "status": "not_started", }, + { + "record": "TrackingCAA", + "name": "", + "value": '0 issue "amazon.com"', + "type": "CAA", + "ttl": "Auto", + "status": "not_started", + }, ], "region": "us-east-1", } @@ -195,6 +203,13 @@ async def test_domains_create_async_with_tracking_subdomain(self) -> None: assert tracking_record["name"] == "links.example.com" assert tracking_record["value"] == "links1.resend-dns.com" assert tracking_record["type"] == "CNAME" + tracking_caa_record = next( + (r for r in (domain["records"] or []) if r["record"] == "TrackingCAA"), + None, + ) + assert tracking_caa_record is not None + assert tracking_caa_record["type"] == "CAA" + assert tracking_caa_record["value"] == '0 issue "amazon.com"' async def test_domains_get_async_with_tracking_fields(self) -> None: self.set_mock_json( @@ -216,7 +231,15 @@ async def test_domains_get_async_with_tracking_fields(self) -> None: "type": "CNAME", "ttl": "Auto", "status": "verified", - } + }, + { + "record": "TrackingCAA", + "name": "", + "value": '0 issue "amazon.com"', + "type": "CAA", + "ttl": "Auto", + "status": "verified", + }, ], } ) @@ -228,6 +251,12 @@ async def test_domains_get_async_with_tracking_fields(self) -> None: assert domain["open_tracking"] is True assert domain["click_tracking"] is True assert domain["tracking_subdomain"] == "links" + tracking_caa_record = next( + (r for r in (domain["records"] or []) if r["record"] == "TrackingCAA"), + None, + ) + assert tracking_caa_record is not None + assert tracking_caa_record["type"] == "CAA" async def test_domains_update_async(self) -> None: self.set_mock_json( diff --git a/tests/domains_test.py b/tests/domains_test.py index 22df57c..41bc03b 100644 --- a/tests/domains_test.py +++ b/tests/domains_test.py @@ -207,6 +207,14 @@ def test_domains_create_with_tracking_subdomain(self) -> None: "ttl": "Auto", "status": "not_started", }, + { + "record": "TrackingCAA", + "name": "", + "value": '0 issue "amazon.com"', + "type": "CAA", + "ttl": "Auto", + "status": "not_started", + }, ], "region": "us-east-1", } @@ -231,6 +239,13 @@ def test_domains_create_with_tracking_subdomain(self) -> None: assert tracking_record["name"] == "links.example.com" assert tracking_record["value"] == "links1.resend-dns.com" assert tracking_record["type"] == "CNAME" + tracking_caa_record = next( + (r for r in (domain["records"] or []) if r["record"] == "TrackingCAA"), + None, + ) + assert tracking_caa_record is not None + assert tracking_caa_record["type"] == "CAA" + assert tracking_caa_record["value"] == '0 issue "amazon.com"' def test_domains_get_with_tracking_fields(self) -> None: self.set_mock_json( @@ -252,7 +267,15 @@ def test_domains_get_with_tracking_fields(self) -> None: "type": "CNAME", "ttl": "Auto", "status": "verified", - } + }, + { + "record": "TrackingCAA", + "name": "", + "value": '0 issue "amazon.com"', + "type": "CAA", + "ttl": "Auto", + "status": "verified", + }, ], } ) @@ -264,6 +287,12 @@ def test_domains_get_with_tracking_fields(self) -> None: assert domain["open_tracking"] is True assert domain["click_tracking"] is True assert domain["tracking_subdomain"] == "links" + tracking_caa_record = next( + (r for r in (domain["records"] or []) if r["record"] == "TrackingCAA"), + None, + ) + assert tracking_caa_record is not None + assert tracking_caa_record["type"] == "CAA" def test_domains_update(self) -> None: self.set_mock_json( From 86d23b380be3353df4fd876fc43828aeb29518a9 Mon Sep 17 00:00:00 2001 From: drish Date: Wed, 15 Apr 2026 11:41:43 -0300 Subject: [PATCH 2/2] chore: bump version to 2.28.1 --- resend/version.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resend/version.py b/resend/version.py index 52d609a..70bd731 100644 --- a/resend/version.py +++ b/resend/version.py @@ -1,4 +1,4 @@ -__version__ = "2.28.0" +__version__ = "2.28.1" def get_version() -> str: