Tag gating, and domain verification on the API

Implicit tag creation now needs the tags feature, and custom domains are readable over the API

July 24, 2026
Breaking API change

This is a backwards-incompatible change to Buttondown's API. Pinning your newsletter or request to an older API version keeps the previous behavior where a version was cut for it.

Tag creation now requires the tags feature

Creating tags implicitly through the subscriber endpoints — supplying a not-yet-existing tag in the tags field of POST /v1/subscribers or PATCH /v1/subscribers/{id} — now requires a plan that includes tags (Basic or higher). On plans without tags, these requests return 403 with the error code feature_disabled; previously, the tag was silently created. Referencing tags that already exist is unaffected. This matches the behavior of the dedicated POST /v1/tags endpoint, which was already gated the same way.

Custom domain verification on the API

We've exposed a newsletter's custom domain verification on the public API, so you can check DNS setup programmatically instead of only in the web app.

Two new read-only endpoints return the underlying DNS records and their current verification state:

The newsletter object also now includes two read-only summary fields:

Each is an at-a-glance verification status (for example none, invalid, or valid) so you can tell whether a newsletter's domains are configured correctly without fetching the full record set.

These additions are read-only and don't change the behavior of any existing endpoints.

Example

Retrieve a newsletter's sending domain records and verification state:

import requests

url = "https://api.buttondown.com/v1/newsletters/{id}/sending-domain"
headers = {
  "Authorization": "Token $BUTTONDOWN_API_KEY"
}

response = requests.request("GET", url, headers=headers)
print(response.text)

The summary status is also available inline on the newsletter object:

import requests

url = "https://api.buttondown.com/v1/newsletters/{id}"
headers = {
  "Authorization": "Token $BUTTONDOWN_API_KEY"
}

response = requests.request("GET", url, headers=headers)
print(response.text)
Buttondown is the last email platform you’ll switch to.