Every API here is available over the APIs.io API and to AI agents over MCP.
openapi: 3.1.0
info:
title: Buttondown Subscribers API
version: 1.0.0
description: The Buttondown API lets you manage newsletters, subscribers, emails, and more. See [the documentation](https://docs.buttondown.com/api-introduction)
for guides and examples.
license:
name: MIT
url: https://opensource.org/licenses/MIT
servers:
- url: https://api.buttondown.com/v1
security:
- ApiKeyAuth: []
tags:
- name: Subscribers
paths:
/subscribers:
post:
operationId: create_subscriber
summary: Create Subscriber
parameters:
- in: header
name: X-Buttondown-Collision-Behavior
schema:
default: no_op
description: "The behavior to apply when a subscriber with the same email address already exists.\nDefaults to \"\
no_op\", which will return a 400 error if a subscriber with the same email address already exists. Other values\
\ include:\n\n- \"overwrite\", which will overwrite the existing subscriber's data with the new one. This cannot\
\ change terminal subscriber types (unsubscribed, blocked, complained, undeliverable); those requests return a\
\ 400.\n- \"add\", which will merge the new subscriber data into the existing one. For unsubscribed subscribers,\
\ this also resubscribes them as regular.\n "
$ref: '#/components/schemas/CollisionBehavior'
required: false
description: "The behavior to apply when a subscriber with the same email address already exists.\nDefaults to \"\
no_op\", which will return a 400 error if a subscriber with the same email address already exists. Other values\
\ include:\n\n- \"overwrite\", which will overwrite the existing subscriber's data with the new one. This cannot\
\ change terminal subscriber types (unsubscribed, blocked, complained, undeliverable); those requests return a 400.\n\
- \"add\", which will merge the new subscriber data into the existing one. For unsubscribed subscribers, this also\
\ resubscribes them as regular.\n "
- in: header
name: X-Buttondown-Bypass-Firewall
schema:
default: false
description: Bypass the firewall for this subscriber creation. Subject to aggressive rate limiting (5 per hour per
newsletter).
title: X-Buttondown-Bypass-Firewall
type: boolean
required: false
description: Bypass the firewall for this subscriber creation. Subject to aggressive rate limiting (5 per hour per
newsletter).
responses:
'201':
description: Created
content:
application/json:
schema:
$ref: '#/components/schemas/Subscriber'
'400':
description: Bad Request
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorMessage_ValidationErrorCode_'
'403':
description: Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorMessage'
'409':
description: Conflict
'422':
description: Unprocessable Entity
content:
application/json:
schema:
$ref: '#/components/schemas/ValidationErrorMessage'
'429':
description: Too Many Requests
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorMessage'
'401':
description: Unauthorized
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorMessage'
description: Create a new subscriber
tags:
- Subscribers
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/SubscriberInput'
required: true
security:
- ApiKeyAuth: []
get:
operationId: list_subscribers
summary: List Subscribers
parameters:
- in: query
name: bounce_date__end
schema:
description: If provided, only return subscribers who last bounced on or before the given date.
title: Bounce Date End
format: date
type: string
required: false
description: If provided, only return subscribers who last bounced on or before the given date.
- in: query
name: bounce_date__start
schema:
description: If provided, only return subscribers who last bounced on or after the given date.
title: Bounce Date Start
format: date
type: string
required: false
description: If provided, only return subscribers who last bounced on or after the given date.
- in: query
name: bounce_reason
schema:
description: If provided, only return subscribers with the given bounce reason(s).
title: Bounce Reason
items:
$ref: '#/components/schemas/SubscriberUndeliverabilityReason'
type: array
required: false
description: If provided, only return subscribers with the given bounce reason(s).
- in: query
name: churn_date__end
schema:
description: If provided, only return subscribers who churned on or before the given date.
title: Churn Date End
format: date
type: string
required: false
description: If provided, only return subscribers who churned on or before the given date.
- in: query
name: churn_date__start
schema:
description: If provided, only return subscribers who churned on or after the given date.
title: Churn Date Start
format: date
type: string
required: false
description: If provided, only return subscribers who churned on or after the given date.
- in: query
name: coupon
schema:
description: If provided, only return subscribers with the given coupon ID(s).
title: Coupon
items:
type: string
type: array
required: false
description: If provided, only return subscribers with the given coupon ID(s).
- in: query
name: current_price
schema:
description: If provided, only return subscribers who are currently subscribed to the given price ID(s).
title: Current Price
items:
type: string
type: array
required: false
description: If provided, only return subscribers who are currently subscribed to the given price ID(s).
- in: query
name: date__end
schema:
description: If provided, only return subscribers created before the given date.
title: Date End
format: date
type: string
required: false
description: If provided, only return subscribers created before the given date.
- in: query
name: date__start
schema:
description: If provided, only return subscribers created on or after the given date.
title: Date Start
format: date
type: string
required: false
description: If provided, only return subscribers created on or after the given date.
- in: query
name: domain
schema:
description: If provided, only return subscribers whose email domain matches the given domain(s).
example:
- gmail.com
title: Domain
items:
type: string
type: array
required: false
description: If provided, only return subscribers whose email domain matches the given domain(s).
example:
- gmail.com
- in: query
name: email_address
schema:
anyOf:
- type: string
- items:
type: string
type: array
description: If provided, only return subscribers whose email address contains the given string.
title: Email Address
required: false
description: If provided, only return subscribers whose email address contains the given string.
- in: query
name: expand
schema:
description: 'If provided, expand the given field. (Supported: ''stripe_customer'', ''stripe_subscription''.)'
items:
enum:
- stripe_customer
- stripe_subscription
type: string
title: Expand
type: array
required: false
description: 'If provided, expand the given field. (Supported: ''stripe_customer'', ''stripe_subscription''.)'
- in: query
name: form
schema:
description: If provided, only return subscribers that came through the given [form(s)](https://docs.buttondown.com/registration-forms).
example:
- form_abc123
title: Form
items:
type: string
type: array
required: false
description: If provided, only return subscribers that came through the given [form(s)](https://docs.buttondown.com/registration-forms).
example:
- form_abc123
- in: query
name: ids
schema:
description: If provided, only return subscribers with the given IDs.
title: Ids
items:
type: string
type: array
required: false
description: If provided, only return subscribers with the given IDs.
- in: query
name: ip_address
schema:
description: If provided, only return subscribers with the given IP address(es).
title: Ip Address
items:
format: ipvanyaddress
type: string
type: array
required: false
description: If provided, only return subscribers with the given IP address(es).
- in: query
name: last_click_date__end
schema:
description: If provided, only return subscribers whose last click was on or before the given date.
title: Last Click Date End
format: date
type: string
required: false
description: If provided, only return subscribers whose last click was on or before the given date.
- in: query
name: last_click_date__start
schema:
description: If provided, only return subscribers whose last click was on or after the given date.
title: Last Click Date Start
format: date
type: string
required: false
description: If provided, only return subscribers whose last click was on or after the given date.
- in: query
name: last_open_date__end
schema:
description: If provided, only return subscribers whose last open was on or before the given date.
title: Last Open Date End
format: date
type: string
required: false
description: If provided, only return subscribers whose last open was on or before the given date.
- in: query
name: last_open_date__start
schema:
description: If provided, only return subscribers whose last open was on or after the given date.
title: Last Open Date Start
format: date
type: string
required: false
description: If provided, only return subscribers whose last open was on or after the given date.
- in: query
name: -domain
schema:
description: If provided, only return subscribers whose email domain does not match the given domain(s).
example:
- gmail.com
title: -Domain
items:
type: string
type: array
required: false
description: If provided, only return subscribers whose email domain does not match the given domain(s).
example:
- gmail.com
- in: query
name: -tag
schema:
description: If provided, only return subscribers without the given [tag](https://docs.buttondown.com/api-tags-introduction).
example: vip
title: -Tag
type: string
required: false
description: If provided, only return subscribers without the given [tag](https://docs.buttondown.com/api-tags-introduction).
example: vip
- in: query
name: -type
schema:
description: If provided, only return subscribers without the given type.
title: -Type
items:
$ref: '#/components/schemas/SubscriberType'
type: array
required: false
description: If provided, only return subscribers without the given type.
- in: query
name: ordering
schema:
default: -creation_date
description: The ordering to apply to the results.
example: -creation_date
title: Ordering
type: string
required: false
description: The ordering to apply to the results.
example: -creation_date
- in: query
name: price
schema:
description: If provided, only return subscribers who have at one point subscribed to the given price ID(s).
title: Price
items:
type: string
type: array
required: false
description: If provided, only return subscribers who have at one point subscribed to the given price ID(s).
- in: query
name: referral_code
schema:
description: If provided, only return subscribers with the given referral code(s).
title: Referral Code
items:
type: string
type: array
required: false
description: If provided, only return subscribers with the given referral code(s).
- in: query
name: referrer_url
schema:
description: If provided, only return subscribers whose referrer URL(s) contain the given string.
title: Referrer Url
items:
type: string
type: array
required: false
description: If provided, only return subscribers whose referrer URL(s) contain the given string.
- in: query
name: open_rate__end
schema:
description: If provided, only return subscribers with an open rate less than or equal to the given value.
title: Open Rate End
type: number
required: false
description: If provided, only return subscribers with an open rate less than or equal to the given value.
- in: query
name: open_rate__start
schema:
description: If provided, only return subscribers with an open rate greater than or equal to the given value.
title: Open Rate Start
type: number
required: false
description: If provided, only return subscribers with an open rate greater than or equal to the given value.
- in: query
name: click_rate__end
schema:
description: If provided, only return subscribers with a click rate less than or equal to the given value.
title: Click Rate End
type: number
required: false
description: If provided, only return subscribers with a click rate less than or equal to the given value.
- in: query
name: click_rate__start
schema:
description: If provided, only return subscribers with a click rate greater than or equal to the given value.
title: Click Rate Start
type: number
required: false
description: If provided, only return subscribers with a click rate greater than or equal to the given value.
- in: query
name: risk_score__end
schema:
description: If provided, only return subscribers with a [risk score](https://docs.buttondown.com/firewall) less
than or equal to the given value.
title: Risk Score End
type: number
required: false
description: If provided, only return subscribers with a [risk score](https://docs.buttondown.com/firewall) less than
or equal to the given value.
- in: query
name: risk_score__start
schema:
description: If provided, only return subscribers with a [risk score](https://docs.buttondown.com/firewall) greater
than or equal to the given value.
title: Risk Score Start
type: number
required: false
description: If provided, only return subscribers with a [risk score](https://docs.buttondown.com/firewall) greater
than or equal to the given value.
- in: query
name: source
schema:
description: If provided, only return subscribers with the given source(s).
example:
- api
title: Source
items:
$ref: '#/components/schemas/SubscriberSource'
type: array
required: false
description: If provided, only return subscribers with the given source(s).
example:
- api
- in: query
name: subscriber_import
schema:
description: If provided, only return subscribers that were imported by the given subscriber import.
example:
- import_abc123
title: Subscriber Import
items:
type: string
type: array
required: false
description: If provided, only return subscribers that were imported by the given subscriber import.
example:
- import_abc123
- in: query
name: tag
schema:
description: If provided, only return subscribers with the given [tag(s)](https://docs.buttondown.com/api-tags-introduction).
title: Tag
items:
type: string
type: array
required: false
description: If provided, only return subscribers with the given [tag(s)](https://docs.buttondown.com/api-tags-introduction).
- in: query
name: type
schema:
description: If provided, only return subscribers with the given type.
title: Type
example:
- regular
items:
$ref: '#/components/schemas/SubscriberType'
type: array
required: false
description: If provided, only return subscribers with the given type.
example:
- regular
- in: query
name: undeliverability_date__end
schema:
description: If provided, only return subscribers who became undeliverable on or before the given date.
title: Undeliverability Date End
format: date
type: string
required: false
description: If provided, only return subscribers who became undeliverable on or before the given date.
- in: query
name: undeliverability_date__start
schema:
description: If provided, only return subscribers who became undeliverable on or after the given date.
title: Undeliverability Date Start
format: date
type: string
required: false
description: If provided, only return subscribers who became undeliverable on or after the given date.
- in: query
name: undeliverability_reason
schema:
description: If provided, only return subscribers with the given undeliverability reason(s).
title: Undeliverability Reason
items:
$ref: '#/components/schemas/SubscriberUndeliverabilityReason'
type: array
required: false
description: If provided, only return subscribers with the given undeliverability reason(s).
- in: query
name: unsubscription_date__end
schema:
description: If provided, only return subscribers who unsubscribed on or before the given date.
title: Unsubscription Date End
format: date
type: string
required: false
description: If provided, only return subscribers who unsubscribed on or before the given date.
- in: query
name: unsubscription_date__start
schema:
description: If provided, only return subscribers who unsubscribed on or after the given date.
title: Unsubscription Date Start
format: date
type: string
required: false
description: If provided, only return subscribers who unsubscribed on or after the given date.
- in: query
name: unsubscription_reason
schema:
description: If provided, only return subscribers with the given unsubscription reason(s).
example:
- no longer interested
title: Unsubscription Reason
items:
type: string
type: array
required: false
description: If provided, only return subscribers with the given unsubscription reason(s).
example:
- no longer interested
- in: query
name: upgrade_date__end
schema:
description: If provided, only return subscribers who upgraded on or before the given date.
title: Upgrade Date End
format: date
type: string
required: false
description: If provided, only return subscribers who upgraded on or before the given date.
- in: query
name: upgrade_date__start
schema:
description: If provided, only return subscribers who upgraded on or after the given date.
title: Upgrade Date Start
format: date
type: string
required: false
description: If provided, only return subscribers who upgraded on or after the given date.
- in: query
name: utm_campaign
schema:
description: If provided, only return subscribers with the given UTM campaign(s).
example:
- paid_campaign_2024
title: Utm Campaign
items:
type: string
type: array
required: false
description: If provided, only return subscribers with the given UTM campaign(s).
example:
- paid_campaign_2024
- in: query
name: utm_medium
schema:
description: If provided, only return subscribers with the given UTM medium(s).
example:
- paid_campaign_2024
title: Utm Medium
items:
type: string
type: array
required: false
description: If provided, only return subscribers with the given UTM medium(s).
example:
- paid_campaign_2024
- in: query
name: utm_source
schema:
description: If provided, only return subscribers with the given UTM source(s).
example:
- paid_campaign_2024
title: Utm Source
items:
type: string
type: array
required: false
description: If provided, only return subscribers with the given UTM source(s).
example:
- paid_campaign_2024
- in: query
name: page
required: false
description: The page number of the paginated response.
schema:
type: integer
title: Page
description: The page number of the paginated response.
default: 1
example: 1
responses:
'200':
description: OK
content:
application/json:
schema:
$ref: '#/components/schemas/SubscriberPage'
'400':
description: Bad Request
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorMessage_ListSubscribersErrorCode_'
'403':
description: Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorMessage'
'404':
description: Not Found
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorMessage'
'422':
description: Unprocessable Entity
content:
application/json:
schema:
$ref: '#/components/schemas/ValidationErrorMessage'
'409':
description: Conflict
'401':
description: Unauthorized
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorMessage'
'429':
description: Too Many Requests
headers:
Retry-After:
description: Seconds to wait before retrying.
schema:
type: integer
X-RateLimit-Limit:
description: Requests permitted per minute.
schema:
type: integer
X-RateLimit-Remaining:
description: Requests remaining in the current window.
schema:
type: integer
X-RateLimit-Reset:
description: Unix timestamp at which the window resets.
schema:
type: integer
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorMessage'
description: List all subscribers
tags:
- Subscribers
security:
- ApiKeyAuth: []
/subscribers/{id_or_email}:
get:
operationId: retrieve_subscriber
summary: Retrieve Subscriber
parameters:
- in: path
name: id_or_email
schema:
title: Id Or Email
type: string
required: true
- in: query
name: expand
schema:
default: []
description: If provided, expand the given field.
items:
enum:
- stripe_customer
- stripe_subscription
type: string
title: Expand
type: array
required: false
description: If provided, expand the given field.
responses:
'200':
description: OK
content:
application/json:
schema:
$ref: '#/components/schemas/Subscriber'
'403':
description: Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorMessage'
'404':
description: Not Found
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorMessage'
'409':
description: Conflict
'401':
description: Unauthorized
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorMessage'
'429':
description: Too Many Requests
headers:
Retry-After:
description: Seconds to wait before retrying.
schema:
type: integer
X-RateLimit-Limit:
description: Requests permitted per minute.
schema:
type: integer
X-RateLimit-Remaining:
description: Requests remaining in the current window.
schema:
type: integer
X-RateLimit-Reset:
description: Unix timestamp at which the window resets.
schema:
type: integer
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorMessage'
description: Retrieve a specific subscriber by their ID or email address
tags:
- Subscribers
security:
- ApiKeyAuth: []
delete:
operationId: delete_subscriber
summary: Delete Subscriber
parameters:
- in: path
name: id_or_email
schema:
title: Id Or Email
type: string
required: true
responses:
'204':
description: No Content
'403':
description: Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorMessage'
'404':
description: Not Found
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorMessage'
'409':
description: Conflict
'401':
description: Unauthorized
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorMessage'
'429':
description: Too Many Requests
headers:
Retry-After:
description: Seconds to wait before retrying.
schema:
type: integer
X-RateLimit-Limit:
description: Requests permitted per minute.
schema:
type: integer
X-RateLimit-Remaining:
description: Requests remaining in the current window.
schema:
type: integer
X-RateLimit-Reset:
description: Unix timestamp at which the window resets.
schema:
type: integer
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorMessage'
description: Delete a subscriber
tags:
- Subscribers
security:
- ApiKeyAuth: []
patch:
operationId: update_subscriber
summary: Update Subscriber
parameters:
- in: path
name: id_or_email
schema:
title: Id Or Email
type: string
required: true
responses:
'200':
description: OK
content:
application/json:
schema:
$ref: '#/components/schemas/Subscriber'
'400':
description: Bad Request
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorMessage_UpdateSubscriberErrorCode_'
'403':
description: Forbidden
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorMessage'
'404':
description: Not Found
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorMessage'
'409':
description: Conflict
'422':
description: Unprocessable Entity
content:
application/json:
schema:
$ref: '#/components/schemas/ValidationErrorMessage'
'401':
description: Unauthorized
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorMessage'
'429':
description: Too Many Requests
headers:
Retry-After:
description: Seconds to wait before retrying.
schema:
type: integer
X-RateLimit-Limit:
description: Requests permitted per minute.
schema:
type: integer
X-RateLimit-Remaining:
description: Requests remaining in the current window.
schema:
type: integer
X-RateLimit-Reset:
description: Unix timestamp at which the window resets.
schema:
type: integer
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorMessage'
description: Update a subscriber's properties
tags:
- Subscribers
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/SubscriberUpdateInput'
required: true
security:
- ApiKeyAuth: []
/subscribers/{id_or_email}/send-reminder:
post:
operationId: send_reminder
summary: Send Reminder
parameters:
- in: path
name: id_or_email
schema:
title: Id Or Email
type: string
required: true
responses:
'200':
descri
# --- truncated at 32 KB (88 KB total) ---
# Full source: https://raw.githubusercontent.com/api-evangelist/buttondown/refs/heads/main/openapi/buttondown-subscribers-api-openapi.yml