Buttondown Newsletters API

The Newsletters API from Buttondown — 7 operation(s) covering newsletter settings, branding, locale, and custom sending/hosting domain verification.

OpenAPI Specification

buttondown-newsletters-api-openapi.yml Raw ↑
openapi: 3.1.0
info:
  title: Buttondown Newsletters 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: Newsletters
paths:
  /newsletters:
    get:
      operationId: list_newsletters
      summary: List Newsletters
      parameters:
      - 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/NewsletterPage'
        '400':
          description: Bad Request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorMessage'
        '403':
          description: Forbidden
          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: List all newsletters
      tags:
      - Newsletters
      security:
      - ApiKeyAuth: []
    post:
      operationId: create_newsletter
      summary: Create Newsletter
      parameters: []
      responses:
        '201':
          description: Created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Newsletter'
          links:
            retrieve_newsletter:
              operationId: retrieve_newsletter
              parameters:
                path.id: $response.body#/id
            update_newsletter:
              operationId: update_newsletter
              parameters:
                path.id: $response.body#/id
            delete_newsletter:
              operationId: delete_newsletter
              parameters:
                path.id: $response.body#/id
        '400':
          description: Bad Request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorMessage_CreateNewsletterErrorCode_'
        '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'
        '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: Create a new newsletter
      tags:
      - Newsletters
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/NewsletterInput'
        required: true
      security:
      - ApiKeyAuth: []
  /newsletters/{id}:
    get:
      operationId: retrieve_newsletter
      summary: Retrieve Newsletter
      parameters:
      - in: path
        name: id
        schema:
          title: Id
          type: string
        required: true
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Newsletter'
          links:
            update_newsletter:
              operationId: update_newsletter
              parameters:
                path.id: $response.body#/id
            delete_newsletter:
              operationId: delete_newsletter
              parameters:
                path.id: $response.body#/id
        '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 newsletter by its ID
      tags:
      - Newsletters
      security:
      - ApiKeyAuth: []
    patch:
      operationId: update_newsletter
      summary: Update Newsletter
      parameters:
      - in: path
        name: id
        schema:
          title: Id
          type: string
        required: true
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Newsletter'
          links:
            retrieve_newsletter:
              operationId: retrieve_newsletter
              parameters:
                path.id: $response.body#/id
            delete_newsletter:
              operationId: delete_newsletter
              parameters:
                path.id: $response.body#/id
        '400':
          description: Bad Request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorMessage'
        '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 newsletter's settings
      tags:
      - Newsletters
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/NewsletterUpdateInput'
        required: true
      security:
      - ApiKeyAuth: []
    delete:
      operationId: delete_newsletter
      summary: Delete Newsletter
      parameters:
      - in: path
        name: id
        schema:
          title: Id
          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 newsletter
      tags:
      - Newsletters
      security:
      - ApiKeyAuth: []
  /newsletters/{id}/sending-domain:
    get:
      operationId: retrieve_sending_domain
      summary: Retrieve Sending Domain
      parameters:
      - in: path
        name: id
        schema:
          title: Id
          type: string
        required: true
      - in: query
        name: force
        schema:
          default: false
          description: When true, trigger a fresh DNS re-verification instead of serving the last-known record.
          title: Force
          type: boolean
        required: false
        description: When true, trigger a fresh DNS re-verification instead of serving the last-known record.
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SendingDomainRecord'
        '400':
          description: Bad Request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorMessage'
        '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 the DNS verification status and required records for a newsletter's custom sending domain. While
        `is_checking` is true, a background re-verification is in flight; poll until it flips to false. Pass `force=true`
        to trigger a re-check.
      tags:
      - Newsletters
      security:
      - ApiKeyAuth: []
  /newsletters/{id}/hosting-domain:
    get:
      operationId: retrieve_hosting_domain
      summary: Retrieve Hosting Domain
      parameters:
      - in: path
        name: id
        schema:
          title: Id
          type: string
        required: true
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HostingDomainRecord'
        '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 the DNS verification status for a newsletter's custom hosting domain. This synchronously re-verifies
        the domain's DNS records.
      tags:
      - Newsletters
      security:
      - ApiKeyAuth: []
components:
  schemas:
    ApexAliasProvider:
      properties:
        id:
          description: Stable identifier for the DNS provider (e.g. `cloudflare`).
          title: Id
          type: string
        name:
          description: Human-readable name of the DNS provider.
          title: Name
          type: string
        apex_alias_support:
          description: How the provider supports pointing an apex/root domain at a CNAME target (e.g. CNAME flattening or
            ALIAS records).
          title: Apex Alias Support
          type: string
        wording_kind:
          description: Which copy variant to show for this provider's setup instructions.
          title: Wording Kind
          type: string
        nameserver_regexes:
          description: Patterns matched against a domain's nameservers to detect this provider.
          items:
            type: string
          title: Nameserver Regexes
          type: array
        support_doc_url:
          anyOf:
          - type: string
          - type: 'null'
          description: Link to the provider's own DNS documentation, when available.
          title: Support Doc Url
        side_notes:
          description: Provider-specific caveats to surface alongside the setup guidance.
          title: Side Notes
          type: string
        buttondown_guide_url:
          anyOf:
          - type: string
          - type: 'null'
          description: A first-party Buttondown setup guide for this provider, when one exists.
          title: Buttondown Guide Url
        supports_nameserver_delegation:
          default: true
          description: Whether the provider lets customers delegate a child zone with NS records.
          title: Supports Nameserver Delegation
          type: boolean
      required:
      - id
      - name
      - apex_alias_support
      - wording_kind
      - nameserver_regexes
      - support_doc_url
      - side_notes
      title: ApexAliasProvider
      type: object
    CreateNewsletterErrorCode:
      description: 'Represents the type of error that occurred when creating a newsletter.


        Human-readable error messages are provided in the `detail` field of the response;

        these values are meant to be parseable by code or client logic.'
      enum:
      - domain_incorrect
      - domain_path
      - domain_protocol
      - email_domain_conflicts_with_hosting_domain
      - email_domain_contains_at
      - email_domain_incorrect
      - email_domain_path
      - email_domain_protocol
      - email_domain_used_by_other_account
      - invalid_metadata
      - username_already_exists
      - username_malformed
      - username_reserved
      - username_too_short
      title: CreateNewsletterErrorCode
      type: string
    ErrorMessage:
      properties:
        code:
          description: The error code.
          title: Code
          type: string
        detail:
          description: A human-readable description of the error.
          title: Detail
          type: string
        metadata:
          additionalProperties:
            type: string
          default: {}
          description: Additional context about the error. When present, a `documentation_url` key links to docs explaining
            how to resolve it.
          title: Metadata
          type: object
      required:
      - detail
      title: ErrorMessage
      type: object
    ErrorMessage_CreateNewsletterErrorCode_:
      properties:
        code:
          allOf:
          - $ref: '#/components/schemas/CreateNewsletterErrorCode'
          description: The error code.
        detail:
          description: A human-readable description of the error.
          title: Detail
          type: string
        metadata:
          additionalProperties:
            type: string
          default: {}
          description: Additional context about the error. When present, a `documentation_url` key links to docs explaining
            how to resolve it.
          title: Metadata
          type: object
      required:
      - detail
      title: ErrorMessage[CreateNewsletterErrorCode]
      type: object
    HostingDomainRecord:
      properties:
        domain:
          description: The custom hosting domain being verified.
          title: Domain
          type: string
        record_type:
          description: The DNS record type the domain should use (typically `CNAME`).
          title: Record Type
          type: string
        data:
          description: The record values currently observed at the domain, if any.
          items:
            type: string
          title: Data
          type: array
        nameservers:
          description: The domain's nameservers, used to detect its DNS provider.
          items:
            type: string
          title: Nameservers
          type: array
        apex_alias_provider:
          anyOf:
          - $ref: '#/components/schemas/ApexAliasProvider'
          - type: 'null'
        status:
          $ref: '#/components/schemas/HostingDomainStatus'
      required:
      - domain
      - record_type
      - data
      - status
      title: HostingDomainRecord
      type: object
    HostingDomainStatus:
      description: The DNS verification status of a newsletter's custom hosting domain.
      enum:
      - none
      - invalid
      - valid
      title: HostingDomainStatus
      type: string
    Newsletter:
      description: 'You will likely not need to interact with your newsletter settings

        programmatically, but if you do, this is the endpoint for you. You can

        create, update, and list newsletters via the API; this is ideal for

        integrating with Buttondown as a headless email or newsletter provider

        (e.g. for a SaaS product.)'
      properties:
        id:
          description: A unique TypeID associated with the object.
          title: Id
          type: string
        creation_date:
          description: The date and time at which the object was first created.
          format: date-time
          title: Creation Date
          type: string
        announcement_bar_background_color:
          default: ''
          description: The background color for the announcement bar on your archive page. Must be a valid hex color code.
          title: Announcement Bar Background Color
          type: string
        announcement_bar_text:
          default: ''
          description: Text displayed in the announcement bar on your archive page. Useful for promotions, updates, or calls
            to action.
          title: Announcement Bar Text
          type: string
        announcement_bar_visibility:
          allOf:
          - $ref: '#/components/schemas/NewsletterAnnouncementBarVisibility'
          default: disabled
          description: Controls who sees the announcement bar on your archive page.
          enum:
          - disabled
          - everyone
          - free_only
          - logged_out_only
          - paid_only
        api_key:
          description: The API key for this newsletter, used for authenticating API requests.
          format: uuid
          title: Api Key
          type: string
        archive_theme:
          allOf:
          - $ref: '#/components/schemas/NewsletterArchiveTheme'
          default: modern
          description: The visual theme for your newsletter's archive page. See [archive themes](https://docs.buttondown.com/customizing-web-design)
            for previews.
          enum:
          - classic
          - modern
          - arbus
          - lovelace
          - myrna
        auditing_mode:
          anyOf:
          - $ref: '#/components/schemas/NewsletterAuditingMode'
          - type: 'null'
          description: The auditing mode for your newsletter, which controls spam and abuse protection. See [the Firewall](https://docs.buttondown.com/firewall)
            for more information.
          enum:
          - disabled
          - enabled
          - aggressive
        css:
          default: ''
          description: Custom CSS styling applied to your newsletter emails. See [CSS customization](https://docs.buttondown.com/customizing-email-design#adding-custom-css)
            for more information.
          title: Css
          type: string
        custom_churn_email_body:
          default: ''
          description: Custom body content for the email sent when a paid subscriber cancels. Supports template tags like
            `{{ subscriber.email }}` and `{{ newsletter.name }}`.
          title: Custom Churn Email Body
          type: string
        custom_churn_email_subject:
          default: ''
          description: Custom subject line for the email sent when a paid subscriber cancels. Supports template tags like
            `{{ newsletter.name }}`.
          title: Custom Churn Email Subject
          type: string
        custom_churn_email_template:
          anyOf:
          - $ref: '#/components/schemas/NewsletterEmailTemplate'
          - type: 'null'
          description: The email template to use for churn emails. If not set, uses the newsletter's default template.
        custom_email_template:
          anyOf:
          - type: string
          - type: 'null'
          description: The identifier for a custom email template. See [email templates](https://docs.buttondown.com/customizing-email-design#buttondowns-default-templates)
            for available options.
          title: Custom Email Template
        custom_expired_trial_notification_body:
          default: ''
          description: Custom body content for the email sent when a subscriber's free trial expires. Supports template tags.
          title: Custom Expired Trial Notification Body
          type: string
        custom_expired_trial_notification_subject:
          default: ''
          description: Custom subject line for the email sent when a subscriber's free trial expires. Supports template tags.
          title: Custom Expired Trial Notification Subject
          type: string
        custom_expired_trial_notification_template:
          anyOf:
          - $ref: '#/components/schemas/NewsletterEmailTemplate'
          - type: 'null'
          description: The email template to use for expired trial notification emails. If not set, uses the newsletter's
            default template.
        custom_gift_subscription_email_body:
          default: ''
          description: Custom body content for the email sent when someone receives a gift subscription. Supports template
            tags.
          title: Custom Gift Subscription Email Body
          type: string
        custom_gift_subscription_email_subject:
          default: ''
          description: Custom subject line for the email sent when someone receives a gift subscription. Supports template
            tags.
          title: Custom Gift Subscription Email Subject
          type: string
        custom_gift_subscription_email_template:
          anyOf:
          - $ref: '#/components/schemas/NewsletterEmailTemplate'
          - type: 'null'
          description: The email template to use for gift subscription emails. If not set, uses the newsletter's default template.
        custom_gift_unsubscription_email_body:
          default: ''
          description: Custom body content for the email sent when a gift subscription ends. Supports template tags.
          title: Custom Gift Unsubscription Email Body
          type: string
        custom_gift_unsubscription_email_subject:
          default: ''
          description: Custom subject line for the email sent when a gift subscription ends. Supports template tags.
          title: Custom Gift Unsubscription Email Subject
          type: string
        custom_gift_unsubscription_email_template:
          anyOf:
          - $ref: '#/components/schemas/NewsletterEmailTemplate'
          - type: 'null'
          description: The email template to use for gift unsubscription emails. If not set, uses the newsletter's default
            template.
        custom_premium_confirmation_email_body:
          default: ''
          description: Custom body content for the email sent when a subscriber upgrades to a paid plan. Supports template
            tags.
          title: Custom Premium Confirmation Email Body
          type: string
        custom_premium_confirmation_email_subject:
          default: ''
          description: Custom subject line for the email sent when a subscriber upgrades to a paid plan. Supports template
            tags.
          title: Custom Premium Confirmation Email Subject
          type: string
        custom_premium_confirmation_email_template:
          anyOf:
          - $ref: '#/components/schemas/NewsletterEmailTemplate'
          - type: 'null'
          description: The email template to use for premium confirmation emails. If not set, uses the newsletter's default
            template.
        custom_subscription_confirmation_email_subject:
          default: ''
          description: Custom subject line for the double opt-in confirmation email sent to new subscribers. Supports template
            tags.
          title: Custom Subscription Confirmation Email Subject
          type: string
        custom_subscription_confirmation_email_template:
          anyOf:
          - $ref: '#/components/schemas/NewsletterEmailTemplate'
          - type: 'null'
          description: The email template to use for subscription confirmation emails. If not set, uses the newsletter's default
            template.
        custom_subscription_confirmation_email_text:
          default: ''
          description: Custom body content for the double opt-in confirmation email. Must contain `{{ confirmation_url }}`
            as an HTML or Markdown link.
          title: Custom Subscription Confirmation Email Text
          type: string
        custom_subscription_confirmation_reminder_email_subject:
          default: ''
          description: Custom subject line for the reminder email sent to subscribers who haven't confirmed. Supports template
            tags.
          title: Custom Subscription Confirmation Reminder Email Subject
          type: string
        custom_subscription_confirmation_reminder_email_text:
          default: ''
          description: Custom body content for the reminder email sent to subscribers who haven't confirmed. Supports template
            tags.
          title: Custom Subscription Confirmation Reminder Email Text
          type: string
        custom_subscription_confirmed_email_subject:
          default: ''
          description: Custom subject line for the email sent after a subscriber confirms their subscription. Supports template
            tags.
          title: Custom Subscription Confirmed Email Subject
          type: string
        custom_subscription_confirmed_email_text:
          default: ''
          description: Custom body content for the email sent after a subscriber confirms their subscription. Supports template
            tags.
          title: Custom Subscription Confirmed Email Text
          type: string
        description:
          description: A brief description of your newsletter, displayed on your public archive page and used for SEO.
          title: Description
          type: string
        domain:
          default: ''
          description: The custom domain where your newsletter archives are hosted (e.g., 'newsletter.example.com'). See [custom
            domains](https://docs.buttondown.com/hosting-on-a-custom-domain) for setup instructions.
          title: Domain
          type: string
        email_address:
          default: ''
          description: The 'From' email address used when sending your newsletter. Must be verified before use.
          title: Email Address
          type: string
        email_domain:
          default: ''
          description: The custom domain from which your newsletter emails are sent (e.g., 'mail.example.com'). See [sending
            domains](https://d

# --- truncated at 32 KB (76 KB total) ---
# Full source: https://raw.githubusercontent.com/api-evangelist/buttondown/refs/heads/main/openapi/buttondown-newsletters-api-openapi.yml