Every API here is available over the APIs.io API and to AI agents over MCP.
MCP server
One button, every client — Claude, Cursor, VS Code and the rest.
https://apis.io/mcp
Tools for apis
7 MCP tools reach this
find_apisBrowse and filter every API in the catalog.
get_api_artifactsOne API's artifacts, grouped by type.
get_openapiThe primary OpenAPI for this API.
find_similar_apisAPIs that look like this one.
apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.
resolveTurn a domain, URL or GitHub org into the provider it belongs to.
find_cohortsEvery scored population of providers in the catalog.
All 92 tools →
Call it yourself
curl for this page
This API
curl "https://apis.io/api/v1/apis/buttondown-automations-api"
All apis
curl "https://apis.io/api/v1/apis?limit=25"
Discovery needs no key. Ratings and market analysis are Pro.
Get an API key
Free tier, no form to fill in. Signing in shares your email address with us — we
store it to create your key and to recognise you if you sign in with another
provider. See our Privacy Policy and
Terms.
A second provider on the same verified email joins the account you already have.
openapi: 3.2.0
info:
title: Buttondown Automations 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: Automations
paths:
/automations:
get:
operationId: list_automations
summary: List Automations
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/AutomationPage'
examples:
list_automations:
summary: List automations
value:
results:
- id: '{{ id }}'
creation_date: '2020-01-01T00:00:00Z'
name: Forward replies to support
status: inactive
trigger: subscriber.replied
actions:
- type: forward_reply
metadata:
recipient: support@example.com
timing: null
filters:
filters: []
groups: []
predicate: and
metadata: {}
should_evaluate_filter_after_delay: false
next: null
previous: null
count: 1
'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 automations
tags:
- Automations
security:
- ApiKeyAuth: []
post:
operationId: create_automation
summary: Create Automation
parameters: []
responses:
'201':
description: Created
content:
application/json:
schema:
$ref: '#/components/schemas/Automation'
examples:
create_automation:
summary: Create an automation
value:
id: '{{ id }}'
creation_date: '2020-01-01T00:00:00Z'
name: Forward replies to support
status: inactive
trigger: subscriber.replied
actions:
- type: forward_reply
metadata:
recipient: support@example.com
timing: null
filters:
filters: []
groups: []
predicate: and
metadata: {}
should_evaluate_filter_after_delay: false
create_send_email_automation:
summary: Create an automation that sends an existing draft
value:
id: '{{ id }}'
creation_date: '2020-01-01T00:00:00Z'
name: Send welcome email on confirmation
status: inactive
trigger: subscriber.confirmed
actions:
- type: send_email
metadata:
email_id: '{{ email.id }}'
timing: null
filters:
filters: []
groups: []
predicate: and
metadata: {}
should_evaluate_filter_after_delay: false
links:
retrieve_automation:
operationId: retrieve_automation
parameters:
path.id: $response.body#/id
update_automation:
operationId: update_automation
parameters:
path.id: $response.body#/id
delete_automation:
operationId: delete_automation
parameters:
path.id: $response.body#/id
'400':
description: Bad Request
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorMessage_AutomationCreationErrorCode_'
'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 automation
tags:
- Automations
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/AutomationInput'
examples:
create_automation:
summary: Create an automation
value:
name: Forward replies to support
trigger: subscriber.replied
filters:
filters: []
groups: []
predicate: and
actions:
- type: forward_reply
metadata:
recipient: support@example.com
create_send_email_automation:
summary: Create an automation that sends an existing draft
value:
name: Send welcome email on confirmation
trigger: subscriber.confirmed
filters:
filters: []
groups: []
predicate: and
actions:
- type: send_email
metadata:
email_id: '{{ email.id }}'
required: true
security:
- ApiKeyAuth: []
/automations/{id}:
get:
operationId: retrieve_automation
summary: Retrieve Automation
parameters:
- in: path
name: id
schema:
title: Id
type: string
required: true
responses:
'200':
description: OK
content:
application/json:
schema:
$ref: '#/components/schemas/Automation'
examples:
retrieve_automation:
summary: Retrieve an automation
value:
id: '{{ id }}'
creation_date: '2020-01-01T00:00:00Z'
name: Forward replies to support
status: inactive
trigger: subscriber.replied
actions:
- type: forward_reply
metadata:
recipient: support@example.com
timing: null
filters:
filters: []
groups: []
predicate: and
metadata: {}
should_evaluate_filter_after_delay: false
links:
update_automation:
operationId: update_automation
parameters:
path.id: $response.body#/id
delete_automation:
operationId: delete_automation
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 automation by its ID
tags:
- Automations
security:
- ApiKeyAuth: []
patch:
operationId: update_automation
summary: Update Automation
parameters:
- in: path
name: id
schema:
title: Id
type: string
required: true
responses:
'200':
description: OK
content:
application/json:
schema:
$ref: '#/components/schemas/Automation'
links:
retrieve_automation:
operationId: retrieve_automation
parameters:
path.id: $response.body#/id
delete_automation:
operationId: delete_automation
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 an automation's properties
tags:
- Automations
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/AutomationUpdateInput'
required: true
security:
- ApiKeyAuth: []
delete:
operationId: delete_automation
summary: Delete Automation
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 an automation
tags:
- Automations
security:
- ApiKeyAuth: []
/automations/{id}/invoke:
post:
operationId: invoke_automation
summary: Invoke Automation
parameters:
- in: path
name: id
schema:
title: Id
type: string
required: true
responses:
'200':
description: OK
'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: Manually trigger an automation
tags:
- Automations
security:
- ApiKeyAuth: []
/automations/{id}/analytics:
get:
operationId: retrieve_automation_analytics
summary: Retrieve Automation Analytics
parameters:
- in: path
name: id
schema:
title: Id
type: string
required: true
responses:
'200':
description: OK
content:
application/json:
schema:
$ref: '#/components/schemas/Analytics'
'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 analytics data for an automation
tags:
- Automations
security:
- ApiKeyAuth: []
components:
schemas:
FilterGroup:
description: "Buttondown's filtering schema can be used for multiple things:\n\n- Filtering [the audience of an email](/api-emails-create) to a specific subset\n- Creating [finely-tuned automations](/api-automation-introduction)\n\nFilters are fractal; they can be nested in groups, and groups can be nested in other groups. This is accomplished through a tree-like structure. Every \"FilterGroup\" has a \"predicate\" field, which is either \"and\" or \"or\", which determines how the filters and groups within the group are combined, a \"groups\" field, which is a list of \"FilterGroup\" objects (that's that recursive bit!), and a \"filters\" field, which are the leaf-level filters themselves.\n\nLet's say you want a simple filter: all subscribers who have a tag whose ID is `sub_tag_0j6hb7h40j6hb7h40j6hb7h40j`. You can do that like this:\n\n```json\n{\n \"filters\": [{\"field\": \"subscriber.tags\", \"operator\": \"contains\", \"value\": \"sub_tag_0j6hb7h40j6hb7h40j6hb7h40j\"}],\n \"groups\": [],\n \"predicate\": \"and\"\n}\n```\n\nNow, let's say you want to filter for subscribers who have that tag and a tag whose ID is `sub_tag_0j6hb7h40j6hb7h40j6hb7h40k`. You can do that like this:\n\n```json\n{\n \"filters\": [{\"field\": \"subscriber.tags\", \"operator\": \"contains\", \"value\": \"sub_tag_0j6hb7h40j6hb7h40j6hb7h40j\"}, {\"field\": \"subscriber.tags\", \"operator\": \"contains\", \"value\": \"sub_tag_0j6hb7h40j6hb7h40j6hb7h40k\"}],\n \"groups\": [],\n \"predicate\": \"and\"\n}\n```\n\nIf you wanted to change that `and` to an `or`, you can do that like this:\n\n```json\n{\n \"filters\": [{\"field\": \"subscriber.tags\", \"operator\": \"contains\", \"value\": \"sub_tag_0j6hb7h40j6hb7h40j6hb7h40j\"}, {\"field\": \"subscriber.tags\", \"operator\": \"contains\", \"value\": \"sub_tag_0j6hb7h40j6hb7h40j6hb7h40k\"}],\n \"groups\": [],\n \"predicate\": \"or\"\n}\n```\n\nNow, let's say you want to filter for subscribers who have the first tag _or_ both the second tag and a third tag whose ID is `sub_tag_0j6hb7h40j6hb7h40j6hb7h40m`. This is where the whole nested thing comes in handy. You can do that like this:\n\n```json\n{\n \"filters\": [{\"field\": \"subscriber.tags\", \"operator\": \"contains\", \"value\": \"sub_tag_0j6hb7h40j6hb7h40j6hb7h40j\"}],\n \"groups\": [\n {\n \"filters\": [{\"field\": \"subscriber.tags\", \"operator\": \"contains\", \"value\": \"sub_tag_0j6hb7h40j6hb7h40j6hb7h40k\"}, {\"field\": \"subscriber.tags\", \"operator\": \"contains\", \"value\": \"sub_tag_0j6hb7h40j6hb7h40j6hb7h40m\"}],\n \"groups\": [],\n \"predicate\": \"and\"\n }\n ],\n \"predicate\": \"or\"\n}\n```\n\nYou can read more about the specific filter construction in the [Filter documentation](/api-emails-filter)."
properties:
filters:
description: The leaf-level filters to apply to the audience.
items:
$ref: '#/components/schemas/Filter'
title: Filters
type: array
groups:
description: The nested groups to apply to the audience.
items:
$ref: '#/components/schemas/FilterGroup'
title: Groups
type: array
predicate:
description: The logical operator to use when combining filters (either 'and' or 'or').
enum:
- and
- or
title: Predicate
type: string
required:
- filters
- groups
- predicate
title: FilterGroup
type: object
ErrorMessage_AutomationCreationErrorCode_:
properties:
code:
allOf:
- $ref: '#/components/schemas/AutomationCreationErrorCode'
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[AutomationCreationErrorCode]
type: object
AutomationStatus:
enum:
- active
- inactive
title: Status
type: string
description: An enumeration.
Filter:
description: "A filter is a single condition that can be evaluated against a [Subscriber](/api-subscribers-retrieve). It has a field, an operator, and a value:\n\n```json\n{\n \"field\": \"subscriber.tags\",\n \"operator\": \"contains\",\n \"value\": \"sub_tag_0j6hb7h40j6hb7h40j6hb7h40j\"\n}\n```\n\nThe field is the path to the field on the subscriber to evaluate. The operator is the operator to use when evaluating the filter. The value is the value to compare the field to. Tag filters require the tag's ID (either a UUID or TypeID), not its name."
properties:
field:
title: Field
type: string
operator:
$ref: '#/components/schemas/Operator'
value:
title: Value
type: string
required:
- field
- operator
- value
title: Filter
type: object
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
ValidationErrorMessage:
properties:
detail:
description: A list of validation errors.
items:
$ref: '#/components/schemas/ValidationErrorDetail'
title: Detail
type: array
required:
- detail
title: ValidationErrorMessage
type: object
Operator:
enum:
- equals
- not_equals
- contains
- not_contains
- is_empty
- is_not_empty
- greater_than
- less_than
title: Operator
type: string
description: An enumeration.
ActionInput:
additionalProperties: false
description: Request payload for 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.
maxProperties: 100
title: Metadata
type: object
timing:
anyOf:
- $ref: '#/components/schemas/TimingInput'
- type: 'null'
description: When to execute this action. Defaults to immediate if not specified.
required:
- type
title: ActionInput
type: object
DelayInput:
additionalProperties: false
description: Request payload configuration for delaying an automation action.
properties:
value:
description: The number of time units to delay.
maxLength: 16
minLength: 1
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: DelayInput
type: object
FailureBreakdownItem:
description: A single failure reason with its count.
properties:
code:
description: The failure reason code (e.g. 'hard_bounce', 'spam')
title: Code
type: string
count:
description: Number of failures with this reason
title: Count
type: integer
required:
- code
- count
title: FailureBreakdownItem
type: object
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
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.
# --- truncated at 32 KB (46 KB total) ---
# Full source: https://raw.githubusercontent.com/api-evangelist/buttondown/refs/heads/main/openapi/buttondown-automations-api-openapi.yml