Subscriber

Subscribers are the main way you collect email addresses and recipients on Buttondown. They're what you see on your subscribers page.

Basic subscriber

{
"creation_date": "2019-08-24T14:15:22Z",
"email": "user@example.com",
"id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
"metadata": {
"foo": "bar"
},
"notes": "",
"referrer_url": "http://jmduke.com",
"secondary_id": 3,
"source": "api",
"subscriber_type": "regular",
"tags": [],
"utm_campaign": "",
"utm_medium": "",
"utm_source": ""
}
fieldtypedescription
idstring
emailstring
notesstring
metadataobject
tagsarray
referrer_urlstring
creation_datestring
secondary_idinteger
subscriber_typeSubscriberType
sourceSubscriberSource
utm_campaignstring
utm_mediumstring
utm_sourcestring
referral_codestring
avatar_urlstring
stripe_customer_idstring
stripe_couponStripeCoupon
unsubscription_datestring
churn_datestring
unsubscription_reasonstring
transitionsarray
ip_addressstring
last_open_datestring
last_click_datestring

Type (SubscriberType)

Represents the state of a subscriber and what emails they should or should not be receiving. This type is meant to be fully expressive so as to consolidate the logic of determining what emails a subscriber should receive into a single place.


typeidentifierdescription
regular
regularnormal subscribers who have not unsubscribed or deactivated in any way
premium
premiumsubscribers with active premium subscriptions
trialed
trialedsubscribers that are temporarily receiving a premium subscription to your newsletter
unpaid
unpaidsubscribers who have not yet purchased a subscription to your newsletter
gifted
giftedsubscribers that have been gifted free premium subscriptions
churning
churningsubscribers who have elected to not renew their subscription to your newsletter and will become unpaid subscribers at the end of their current billing period
unactivated
unactivatedsubscribers who have not yet confirmed their email or opted in
paused
pausedsubscribers that are on a temporary hold from their premium subscription, but are still subscribed to your newsletter
unsubscribed
unsubscribedsubscribers that have voluntarily unsubscribed from your newsletter
spammy
spammysubscribers that have been deemed spammy by Buttondown's automated systems
complained
complainedsubscribers that have registered a complaint with their email provider
malformed
malformedsubscribers whose email appears to be invalid
removed
removedsubscribers who have been explicitly removed by the newsletter (notably, this does not mean unsubscribers: use /v1/unsubscribers for that!)
disabled
disabledsubscribers who have been disabled by the newsletter
disposable
disposablesubscribers who have been deemed disposable by Buttondown's automated systems
Past due
past_duesubscribers who technically have active paid subscriptions, but have not paid their invoices in time
churned
churnedsubscribers which were previously premium subscribers, but have since churned but are not unsubscribed

Source (SubscriberSource)

Represents the original provenance of a subscriber. This value is not exposed to subscribers; it's only used for internal tracking purposes and governs some of the behavior of the subscriber (i.e. whether or not to require double opt-in.)


typeidentifierdescription
API
api
import
import
organic
organic
admin
admin
user
user

Create Subscriber

curl
python
ruby
typescript
Copy to clipboard
import requests
headers = {
"Authorization": f"Token {BUTTONDOWN_API_KEY}",
}
BASE_URL = "https://api.buttondown.email"
ENDPOINT = "/v1/subscribers"
response = requests.post(f"{BASE_URL}{ENDPOINT}", headers=headers)

Parameters

parametertypedescriptionoptional
emailstring
notesstring
metadataobject
tagsarray
referrer_urlstring
utm_campaignstring
utm_mediumstring
utm_sourcestring
referring_subscriber_idstring
subscriber_type

Responses

StatusDescriptionSample Response
201Created
{
"creation_date": "2019-08-24T14:15:22Z",
"email": "user@example.com",
"id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
"metadata": {
"foo": "bar"
},
"notes": "",
"referrer_url": "http://jmduke.com",
"secondary_id": 3,
"source": "api",
"subscriber_type": "regular",
"tags": [],
"utm_campaign": "",
"utm_medium": "",
"utm_source": ""
}
400Bad Request
{
"code": "something_went_wrong",
"detail": "Your call is very important to us."
}
403Forbidden
{
"code": "something_went_wrong",
"detail": "Your call is very important to us."
}
409Conflict
{}

Error codes

typeidentifierdescription
Email already exists
email_already_existsA subscriber already exists with that email
Email invalid
email_invalidThe email is invalid
Tag invalid
tag_invalidThe tag is invalid

List Subscribers

curl
python
ruby
typescript
Copy to clipboard
import requests
headers = {
"Authorization": f"Token {BUTTONDOWN_API_KEY}",
}
BASE_URL = "https://api.buttondown.email"
ENDPOINT = "/v1/subscribers"
response = requests.get(f"{BASE_URL}{ENDPOINT}", headers=headers)

Parameters

parametertypedescriptionoptional
typearray
idsarray
emailstring
tagstring
-tagstring
orderingstring
utm_sourcearray
pricearray
couponarray
datearray
last_open_datearray
last_click_datearray

Responses

StatusDescriptionSample Response
200OK
{
"results": [
{
"creation_date": "2019-08-24T14:15:22Z",
"email": "user@example.com",
"id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
"metadata": {
"foo": "bar"
},
"notes": "",
"referrer_url": "http://jmduke.com",
"secondary_id": 3,
"source": "api",
"subscriber_type": "regular",
"tags": [],
"utm_campaign": "",
"utm_medium": "",
"utm_source": ""
}
],
"count": 1
}
400Bad Request
{
"code": "something_went_wrong",
"detail": "Your call is very important to us."
}
403Forbidden
{
"code": "something_went_wrong",
"detail": "Your call is very important to us."
}
404Not Found
{
"code": "something_went_wrong",
"detail": "Your call is very important to us."
}
409Conflict
{}

Error codes

typeidentifierdescription
Invalid tag
invalid_tag

Retrieve Subscriber

curl
python
ruby
typescript
Copy to clipboard
import requests
headers = {
"Authorization": f"Token {BUTTONDOWN_API_KEY}",
}
BASE_URL = "https://api.buttondown.email"
ENDPOINT = "/v1/subscribers/{id_or_email}"
response = requests.get(f"{BASE_URL}{ENDPOINT}", headers=headers)

Responses

StatusDescriptionSample Response
200OK
{
"creation_date": "2019-08-24T14:15:22Z",
"email": "user@example.com",
"id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
"metadata": {
"foo": "bar"
},
"notes": "",
"referrer_url": "http://jmduke.com",
"secondary_id": 3,
"source": "api",
"subscriber_type": "regular",
"tags": [],
"utm_campaign": "",
"utm_medium": "",
"utm_source": ""
}
403Forbidden
{
"code": "something_went_wrong",
"detail": "Your call is very important to us."
}
404Not Found
{
"code": "something_went_wrong",
"detail": "Your call is very important to us."
}
409Conflict
{}

Delete Subscriber

curl
python
ruby
typescript
Copy to clipboard
import requests
headers = {
"Authorization": f"Token {BUTTONDOWN_API_KEY}",
}
BASE_URL = "https://api.buttondown.email"
ENDPOINT = "/v1/subscribers/{id_or_email}"
response = requests.delete(f"{BASE_URL}{ENDPOINT}", headers=headers)

Responses

StatusDescriptionSample Response
204No Content
{}
403Forbidden
{
"code": "something_went_wrong",
"detail": "Your call is very important to us."
}
404Not Found
{
"code": "something_went_wrong",
"detail": "Your call is very important to us."
}
409Conflict
{}

Update Subscriber

curl
python
ruby
typescript
Copy to clipboard
import requests
headers = {
"Authorization": f"Token {BUTTONDOWN_API_KEY}",
}
BASE_URL = "https://api.buttondown.email"
ENDPOINT = "/v1/subscribers/{id_or_email}"
response = requests.patch(f"{BASE_URL}{ENDPOINT}", headers=headers)

Parameters

parametertypedescriptionoptional
emailstring
notesstring
metadataobject
tagsarray
referrer_urlstring
subscriber_type
unsubscription_reasonstring

Responses

StatusDescriptionSample Response
200OK
{
"creation_date": "2019-08-24T14:15:22Z",
"email": "user@example.com",
"id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
"metadata": {
"foo": "bar"
},
"notes": "",
"referrer_url": "http://jmduke.com",
"secondary_id": 3,
"source": "api",
"subscriber_type": "regular",
"tags": [],
"utm_campaign": "",
"utm_medium": "",
"utm_source": ""
}
400Bad Request
{
"code": "something_went_wrong",
"detail": "Your call is very important to us."
}
403Forbidden
{
"code": "something_went_wrong",
"detail": "Your call is very important to us."
}
404Not Found
{
"code": "something_went_wrong",
"detail": "Your call is very important to us."
}
409Conflict
{}

Error codes

typeidentifierdescription
Invalid tag
invalid_tag

Send Reminder

curl
python
ruby
typescript
Copy to clipboard
import requests
headers = {
"Authorization": f"Token {BUTTONDOWN_API_KEY}",
}
BASE_URL = "https://api.buttondown.email"
ENDPOINT = "/v1/subscribers/{id_or_email}/send-reminder"
response = requests.post(f"{BASE_URL}{ENDPOINT}", headers=headers)

Responses

StatusDescriptionSample Response
200OK
{}
403Forbidden
{
"code": "something_went_wrong",
"detail": "Your call is very important to us."
}
409Conflict
{}

Send Email To

curl
python
ruby
typescript
Copy to clipboard
import requests
headers = {
"Authorization": f"Token {BUTTONDOWN_API_KEY}",
}
BASE_URL = "https://api.buttondown.email"
ENDPOINT = "/v1/subscribers/{id_or_email}/emails/{email_id}"
response = requests.post(f"{BASE_URL}{ENDPOINT}", headers=headers)

Responses

StatusDescriptionSample Response
200OK
{}
400Bad Request
{
"code": "something_went_wrong",
"detail": "Your call is very important to us."
}
403Forbidden
{
"code": "something_went_wrong",
"detail": "Your call is very important to us."
}
404Not Found
{
"code": "something_went_wrong",
"detail": "Your call is very important to us."
}
409Conflict
{}