Buttondown Events API

The Events API from Buttondown — 2 operation(s) covering the unified event store that also powers webhooks.

OpenAPI Specification

buttondown-events-api-openapi.yml Raw ↑
openapi: 3.1.0
info:
  title: Buttondown Events 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: Events
paths:
  /events:
    get:
      operationId: list_events
      summary: List Events
      parameters:
      - in: query
        name: event_type
        schema:
          description: If provided, only return events of the given type (e.g. `delivered`, `opened`, `clicked`).
          $ref: '#/components/schemas/EmailEventType'
        required: false
        description: If provided, only return events of the given type (e.g. `delivered`, `opened`, `clicked`).
      - in: query
        name: ordering
        schema:
          allOf:
          - enum:
            - creation_date
            - -creation_date
            title: Ordering
            type: string
          default: -creation_date
          description: The ordering to apply to the results.
        required: false
        description: The ordering to apply to the results.
      - in: query
        name: expand
        schema:
          description: 'If provided, expand the given field. (Only supported field: ''subscriber'').'
          items:
            enum:
            - automation
            - subscriber
            - email
            type: string
          title: Expand
          type: array
        required: false
        description: 'If provided, expand the given field. (Only supported field: ''subscriber'').'
      - in: query
        name: email_id
        schema:
          description: If provided, only return events for the given email.
          title: Email Id
          type: string
        required: false
        description: If provided, only return events for the given email.
      - in: query
        name: automation_id
        schema:
          description: If provided, only return events for the given automation.
          title: Automation Id
          type: string
        required: false
        description: If provided, only return events for the given automation.
      - in: query
        name: subscriber_id
        schema:
          description: If provided, only return events for the given subscriber.
          title: Subscriber Id
          type: string
        required: false
        description: If provided, only return events for the given subscriber.
      - 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/EmailEventPage'
        '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 events
      tags:
      - Events
      security:
      - ApiKeyAuth: []
  /events/{id}:
    get:
      operationId: get_event
      summary: Get Event
      parameters:
      - in: path
        name: id
        schema:
          title: Id
          type: string
        required: true
      - in: query
        name: expand
        schema:
          description: 'If provided, expand the given field. (Only supported field: ''subscriber'').'
          items:
            enum:
            - automation
            - subscriber
            - email
            type: string
          title: Expand
          type: array
        required: false
        description: 'If provided, expand the given field. (Only supported field: ''subscriber'').'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/EmailEvent'
          links: {}
        '403':
          description: Forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorMessage'
        '404':
          description: Not Found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorMessage'
        '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 event by its ID
      tags:
      - Events
      security:
      - ApiKeyAuth: []
components:
  schemas:
    Action:
      description: An action to perform when the automation's trigger fires.
      properties:
        type:
          $ref: '#/components/schemas/AutomationActionType'
          description: The type of action to perform.
        metadata:
          additionalProperties: true
          description: Configuration specific to the action type.
          title: Metadata
          type: object
        timing:
          anyOf:
          - $ref: '#/components/schemas/Timing'
          - type: 'null'
          description: When to execute this action. Defaults to immediate if not specified.
      required:
      - type
      - metadata
      title: Action
      type: object
    Analytics:
      properties:
        recipients:
          default: 0
          description: The number of subscribers the email was dispatched to.
          title: Recipients
          type: integer
        deliveries:
          default: 0
          description: The number of successful deliveries (recipients minus failures).
          title: Deliveries
          type: integer
        opens:
          default: 0
          description: The number of unique opens recorded.
          title: Opens
          type: integer
        clicks:
          default: 0
          description: The number of unique link clicks recorded.
          title: Clicks
          type: integer
        temporary_failures:
          default: 0
          description: The number of temporary delivery failures (e.g. soft bounces).
          title: Temporary Failures
          type: integer
        permanent_failures:
          default: 0
          description: The number of permanent delivery failures (e.g. hard bounces).
          title: Permanent Failures
          type: integer
        unsubscriptions:
          default: 0
          description: The number of subscribers who unsubscribed after receiving this email.
          title: Unsubscriptions
          type: integer
        complaints:
          default: 0
          description: The number of spam complaints recorded against this email.
          title: Complaints
          type: integer
        survey_responses:
          default: 0
          description: The number of survey responses submitted from this email.
          title: Survey Responses
          type: integer
        webmentions:
          default: 0
          description: The number of inbound webmentions received for this email.
          title: Webmentions
          type: integer
        page_views_lifetime:
          default: 0
          description: The total number of archive page views for this email since publication.
          title: Page Views Lifetime
          type: integer
        page_views_30:
          default: 0
          description: The number of archive page views in the last 30 days.
          title: Page Views 30
          type: integer
        page_views_7:
          default: 0
          description: The number of archive page views in the last 7 days.
          title: Page Views 7
          type: integer
        subscriptions:
          default: 0
          description: The number of new subscribers attributed to this email.
          title: Subscriptions
          type: integer
        paid_subscriptions:
          default: 0
          description: The number of new paid subscribers attributed to this email.
          title: Paid Subscriptions
          type: integer
        replies:
          default: 0
          description: The number of reply emails received from subscribers.
          title: Replies
          type: integer
        comments:
          default: 0
          description: The number of comments posted on this email.
          title: Comments
          type: integer
        social_mentions:
          default: 0
          description: The number of social media mentions of this email.
          title: Social Mentions
          type: integer
        temporary_failure_breakdown:
          description: Breakdown of temporary failures by reason code, sorted by count descending.
          items:
            $ref: '#/components/schemas/FailureBreakdownItem'
          title: Temporary Failure Breakdown
          type: array
        permanent_failure_breakdown:
          description: Breakdown of permanent failures by reason code, sorted by count descending.
          items:
            $ref: '#/components/schemas/FailureBreakdownItem'
          title: Permanent Failure Breakdown
          type: array
      title: Analytics
      type: object
    ArchivalMode:
      description: 'Governs who can view this email in the archive.


        `ARCHIVE_ONLY` is the odd one out: the email is publicly archived but

        is not email content at all (e.g. an imported blog post), so it is

        excluded from email-rendering contexts like "recent issues" widgets.'
      enum:
      - archive_only
      - disabled
      - enabled
      - enabled_for_paid_subscribers
      - enabled_for_subscribers
      title: ArchivalMode
      type: string
    Automation:
      description: A rule that automatically performs actions in response to events.
      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
        name:
          description: The name of the automation.
          title: Name
          type: string
        status:
          $ref: '#/components/schemas/AutomationStatus'
          description: Whether the automation is enabled or disabled.
        trigger:
          $ref: '#/components/schemas/ExternalEventType'
          description: The event that causes this automation to run.
        actions:
          description: The actions to perform when the trigger fires.
          items:
            $ref: '#/components/schemas/Action'
          title: Actions
          type: array
        filters:
          $ref: '#/components/schemas/FilterGroup'
          description: Conditions that must be met for the automation to run.
        metadata:
          additionalProperties: true
          description: Additional metadata for the automation.
          title: Metadata
          type: object
        should_evaluate_filter_after_delay:
          description: If true, filters are re-evaluated after the delay has passed.
          title: Should Evaluate Filter After Delay
          type: boolean
      required:
      - id
      - creation_date
      - name
      - status
      - trigger
      - actions
      - filters
      - metadata
      - should_evaluate_filter_after_delay
      title: Automation
      type: object
    AutomationActionType:
      description: The action that is triggered when the automation is successfully run.
      enum:
      - add_tags
      - remove_tags
      - send_email
      - add_metadata
      - remove_metadata
      - change_email_address
      - gift_premium_subscription
      - ungift_premium_subscription
      - send_discord_invitation
      - send_github_invitation
      - create_subscriber
      - unsubscribe_subscriber
      - shopify_unsubscribe
      - shopify_resubscribe
      - shopify_set_tags
      - shopify_create_customer
      - send_notification
      - forward_reply
      - create_arena_post
      - create_bluesky_post
      - create_linkedin_post
      - create_mastodon_post
      - create_tumblr_post
      - create_twitter_post
      - create_export
      - create_gift_subscriber
      - send_post_request
      - send_confirmation_reminder
      - update_email_type
      title: ActionType
      type: string
    AutomationStatus:
      enum:
      - active
      - inactive
      title: Status
      type: string
      description: An enumeration.
    Callout:
      description: 'Surfacing-time flags about an email that the UI uses to render contextual

        callouts (e.g. in the analytics panel). Computed on read; not persisted.'
      enum:
      - first_send_on_sending_domain
      title: Callout
      type: string
    Delay:
      description: Configuration for how long to wait before executing the automation's action.
      properties:
        value:
          description: The number of time units to delay.
          title: Value
          type: string
        unit:
          description: The unit of time for the delay.
          enum:
          - minutes
          - hours
          - days
          - weeks
          title: Unit
          type: string
        time_of_day:
          anyOf:
          - enum:
            - morning
            - evening
            - ''
            type: string
          - type: 'null'
          description: If set, the action will be executed at this time of day after the delay has passed.
          title: Time Of Day
      required:
      - value
      - unit
      title: Delay
      type: object
    Email:
      description: 'Emails are why you''re here on Buttondown, right?

        Creating an email via the API is just like creating one in the interface;

        it will instantly trigger sending actual emails,

        based on the tags and email type you provide.


        Relevant changes to the schema:


        - [2024-08-15](https://docs.buttondown.com/api-changelog-2024-08-15): unshipped the `included_tags` and `excluded_tags`
        fields.

        - [2024-12-30](https://docs.buttondown.com/api-changelog-2024-12-30): unshipped the `is_comments_disabled` field,
        and replaced it with a more flexible `commenting_mode` field.

        - [2025-09-23](https://docs.buttondown.com/api-changelog-2025-09-23): increased the maximum length of the `subject`
        field from 1000 to 2000 characters.'
      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
        absolute_url:
          description: The canonical web URL of the email on the newsletter's archive.
          title: Absolute Url
          type: string
        analytics:
          anyOf:
          - $ref: '#/components/schemas/Analytics'
          - type: 'null'
          description: Aggregate analytics for the email. Null until the email has been sent.
        callouts:
          description: A list of callouts that apply to this email — surfaced in the UI alongside analytics to flag context
            the reader should know about (e.g., first send on a custom sending domain).
          items:
            $ref: '#/components/schemas/Callout'
          title: Callouts
          type: array
        attachments:
          anyOf:
          - items:
              type: string
            type: array
          - type: 'null'
          description: A list of attachment IDs present on the email. (See [Attachments](https://docs.buttondown.com/api-attachments-introduction)
            for more information.)
          title: Attachments
        body:
          description: 'The body of the email, in either HTML or markdown format. Buttondown attempts to intelligently detect
            the format of the body automatically, but you can also specify the format explicitly by prepending the text with
            the `buttondown-editor-mode` comment: `<!-- buttondown-editor-mode: fancy -->` or `<!-- buttondown-editor-mode:
            plaintext -->`.'
          title: Body
          type: string
        canonical_url:
          description: The URL of the original source of the content.
          title: Canonical Url
          type: string
        commenting_mode:
          $ref: '#/components/schemas/EmailCommentingMode'
          description: Controls whether subscribers can comment on this email.
        description:
          description: A human-readable description of the email, used for archives and SEO.
          title: Description
          type: string
        archival_mode:
          $ref: '#/components/schemas/ArchivalMode'
          description: Controls who can view this email in the archive.
        email_type:
          allOf:
          - $ref: '#/components/schemas/EmailType'
          default: public
          deprecated: true
          description: 'The type of email. Defaults to `PUBLIC`. Deprecated: this is a legacy single-axis view derived from
            `archival_mode` (archive visibility) and `filters` (audience); prefer setting those directly. Because it is derived,
            it does not always round-trip: writing it alongside an explicit `archival_mode` that disagrees will report the
            value implied by the two underlying fields, and writing a value that already matches the derived one is a no-op.'
        featured:
          description: Designated whether or not this email should be highlighted within the archives.
          title: Featured
          type: boolean
        filters:
          $ref: '#/components/schemas/FilterGroup'
          description: Tag-based filter rules determining which subscribers receive this email.
        image:
          description: A primary image URL used when previewing the email on the web or in other contexts.
          title: Image
          type: string
        metadata:
          additionalProperties: true
          default: {}
          description: A structured key-value blob that you can use to store arbitrary data on the object. Metadata can be
            nested — you can store objects and arrays within your metadata. (You can [read more about metadata.](https://docs.buttondown.com/metadata))
          title: Metadata
          type: object
        modification_date:
          description: The date and time at which the object was last modified.
          format: date-time
          title: Modification Date
          type: string
        publish_date:
          anyOf:
          - format: date-time
            type: string
          - type: 'null'
          description: The date and time at which the email should be published in the future (for scheduled emails), or the
            date and time at which the email was published (for sent emails).
          title: Publish Date
        related_email_ids:
          description: A list of email IDs that are related to this email. Related emails are shown at the bottom of the email
            and archive pages.
          items:
            type: string
          title: Related Email Ids
          type: array
        secondary_id:
          anyOf:
          - type: integer
          - type: 'null'
          description: 'An informal ''number'' for the email, used in some templates (''This was issue #123'').'
          title: Secondary Id
        should_trigger_pay_per_email_billing:
          description: Whether this email should trigger pay-per-email billing for paid subscribers. Use this to differentiate
            between free updates and premium newsletters.
          title: Should Trigger Pay Per Email Billing
          type: boolean
        slug:
          anyOf:
          - type: string
          - type: 'null'
          description: A short, human-readable identifier for the email, used in the archive URL.
          example: welcome-to-the-newsletter
          title: Slug
        source:
          $ref: '#/components/schemas/EmailSource'
          description: The source of the email.
          example: app
        status:
          $ref: '#/components/schemas/EmailStatus'
          description: The current status of the email.
          example: draft
        subject:
          description: The subject line for the email.
          maxLength: 2000
          title: Subject
          type: string
        suppression_reason:
          anyOf:
          - $ref: '#/components/schemas/EmailSuppressionReason'
          - type: 'null'
          description: If the email has been suppressed from sending, the reason why.
        template:
          anyOf:
          - $ref: '#/components/schemas/NewsletterEmailTemplate'
          - type: 'null'
          description: If present, this template overrides your newsletter's default email template.
      required:
      - id
      - creation_date
      - absolute_url
      - body
      - canonical_url
      - commenting_mode
      - description
      - archival_mode
      - featured
      - filters
      - image
      - modification_date
      - related_email_ids
      - should_trigger_pay_per_email_billing
      - source
      - status
      - subject
      title: Email
      type: object
    EmailCommentingMode:
      description: 'Governs who can comment on this email.


        This enum replaces the `is_comments_disabled` field, which has been deprecated. (Also note that this field may be
        superseded by newsletter-level settings; for instance, "enabled" is an invalid and inert value if the newsletter itself
        has comments disabled.)'
      enum:
      - disabled
      - enabled
      - enabled_for_paid_subscribers
      title: CommentingMode
      type: string
    EmailEvent:
      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
        subscriber_id:
          anyOf:
          - type: string
          - type: 'null'
          description: The ID of the subscriber the event is attributed to, if any.
          title: Subscriber Id
        email_id:
          anyOf:
          - type: string
          - type: 'null'
          description: The ID of the email the event is attributed to, if any.
          title: Email Id
        automation_id:
          anyOf:
          - type: string
          - type: 'null'
          description: The ID of the automation that sent the email, if any.
          title: Automation Id
        metadata:
          additionalProperties:
            type: string
          description: Event-type-specific metadata (e.g. clicked URL, bounce reason).
          title: Metadata
          type: object
        event_type:
          $ref: '#/components/schemas/EmailEventType'
          description: The type of event (e.g. `delivered`, `opened`, `clicked`, `unsubscribed`).
        subscriber:
          anyOf:
          - $ref: '#/components/schemas/Subscriber'
          - type: 'null'
        email:
          anyOf:
          - $ref: '#/components/schemas/Email'
          - type: 'null'
        automation:
          anyOf:
          - $ref: '#/components/schemas/Automation'
          - type: 'null'
      required:
      - id
      - creation_date
      - metadata
      - event_type
      title: EmailEvent
      type: object
    EmailEventPage:
      properties:
        results:
          description: The list of results for this page.
          items:
            $ref: '#/components/schemas/EmailEvent'
          title: Results
          type: array
        next:
          anyOf:
          - type: string
          - type: 'null'
          description: The URL to the next page of results, if any.
          title: Next
        previous:
          anyOf:
          - type: string
          - type: 'null'
          description: The URL to the previous page of results, if any.
          title: Previous
        count:
          description: The total number of results across all pages.
          title: Count
          type: integer
      required:
      - results
      - count
      title: Page[EmailEvent]
      type: object
    EmailEventType:
      description: The type of a subscriber event, such as a delivery, open, click, or reply.
      enum:
      - bounced
      - clicked
      - complained
      - delivered
      - opened
      - rejected
      - replied
      - unsubscribed
      title: EmailEventType
      type: string
    EmailSource:
      description: 'Represents the original provenance of an email. This value is not exposed

        to subscribers, but does determine some behavior of the email (e.g. whether

        or not analytics can be calculated.)'
      enum:
      - api
      - import
      - app
      - external_feed
      - smtp
      title: Source
      type: string
    EmailStatus:
      description: 'Represents the state of an email.


        No action is required to move from one state or another; Buttondown

        internally handles the transitions, and exposing the status is for

        observability purposes only.'
      enum:
      - draft
      - managed_by_rss
      - about_to_send
      - scheduled
      - in_flight
      - paused
      - deleted
      - errored
      - sent
      - imported
      - throttled
      - resending
      - transactional
      - suppressed
      title: Status
      type: string
    EmailSuppressionReason:
      description: Represents the reason an email was suppressed.
      enum:
      - law_enforcement
      - internal_auditing
      title: SuppressionReason
      type: string
    EmailTransition:
      properties:
        date:
          description: When the email address change took effect.
          format: date-time
          title: Date
          type: string
        old_email_address:
          anyOf:
          - type: string
          - type: 'null'
          description: The subscriber's previous email address, or null for the initial address.
          title: Old Email Address
        new_email_address:
          description: The subscriber's email address after the transition.
          title: New Email Address
          type: string
      required:
      - date
      - new_email_address
      title: EmailTransition
      type: object
    EmailType:
      description: 'The legacy single-axis representation of an email''s audience and

        archive visibility. No longer stored: `filters` owns the audience

        axis and `archival_mode` owns the archive axis, and the deprecated

        API field is derived from those (see `email_type` below).'
      enum:
      - public
      - private
      - premium
      - free
      - churned
      - archival
      title: Type
      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
    ExternalEventType:
      description: 'Various types of events that are recorded by Buttondown, both in terms of exogenous systems

        like Stripe and Memberful, and endogenous ones like email opens and clicks. (In general, if anything

        important ever happens that could be relevant to your newsletter, we have an event type for it!)


        These event types power lots of things within Buttondown. They''re used to trigger automations, webhooks,

        and analytics.


        (Note that the `/v1/events` API speaks an older, shorter vocabulary for subscriber engagement —

        `clicked` rather than `subscriber.clicked` — a relic of a previous events system. Each of those

        names maps onto one of the `subscriber.*` types below.)


        In general, our event namespacing tries to hew to the following pattern:


        `<source>.<object>.<action>`


        When wondering which object we are referring to, default to the _more granular_ object.


        For instance, an email being sent to a subscriber is `subscriber.delivered`, not `email.sent`.'
      enum:
      - advertising_slot.inquiry
      - advertising_slot.purchased
      - automation.invoked
      - date.day.started
      - date.month.started
      - date.week.started
      - date.year.started
      - bigcommerce.customer.created
      - bigcommerce.customer.updated
      - bigcommerce.order.created
      - bigcommerce.order.updated
      - email.created
      - email.deleted
      - email.send.started
      - email.sent
      - email.status.changed
      - email.updated
      - external_feed_item.created
      - export.completed
      - export.created
      - export.failed
      - firewall.blocked
      - mention.created
      - memberful.member.updated
      - memberful.subscription.created
      - memberful.subscription.deleted
      - note.created
      - note.deleted
      - patreon.member.updated
      - patreon.membership.created
      - patreon.membership.deleted
      - shopify.customer.created
      - shopify.customer.updated
      - social_mention.created
      - stripe.checkout.session.completed
      - stripe.customer.updated
      - stripe.invoice.upcoming
      - stripe.subscription.activated
      - stripe.subscription.churning
      - stripe.subscription.deactivated
      - subscriber.activation_bounced
      - subscriber.activation_clicked
      - subscriber.activation_complained
      - subscriber.activation_deferred
      - subscriber.activation_delivered
      - subscriber.activation_opened
      - subscriber.activation_rejected
      - subscriber.bounced
      - subscriber.changed_email
      - subscriber.churned
      - subscriber.clicked
      - subscriber.commented
      - subscriber.complained
      - subscriber.confirmed
      - subscriber.created
      - subscriber.deferred
      - subscriber.deleted
      - subscriber.delivered
      - subscriber.opened
      - subscriber.paid
      - subscriber.paused
  

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