> ## Documentation Index
> Fetch the complete documentation index at: https://docs.dally.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# automation.arm

> Access: public. Send a JSON body; unknown keys are rejected with 400 invalid_request (inputs are strict). Responses may gain fields additively — never remove or repurpose; ignore unknown response fields.



## OpenAPI

````yaml /api-reference/openapi.json post /v1/automation.arm
openapi: 3.1.0
info:
  title: Dally API
  version: v1
  description: >-
    PRIVATE (posture 2026-09-01): the MCP connector is Dally's only supported
    surface; this REST surface serves internal harnesses only, and its keys are
    WorkOS-dashboard-issued, never product-issued (CONTEXT.md § Positions).
    Headless Dally v1 — Slack-shape RPC: every operation is POST
    /v1/<family.verb> with a JSON body. Cursor-only pagination ({items,
    has_more, next_cursor}; next_cursor null is the only end signal).
    Unversioned while private (Jim 2026-09-03): a retired name drops in the
    first migration after the deployed release stops naming it; inputs are
    strict, responses are tolerant.
servers:
  - url: https://dally.ai
    description: The production Headless Dally v1 API.
security: []
paths:
  /v1/automation.arm:
    post:
      tags:
        - automation
      summary: >-
        Propose a reply automation, a creator's DM automation: a keyword in a
        comment, story reply or DM sends one message as the creator with a link,
        tracked unless the creator says otherwise, once per person, off until
        the creator flips its switch. Ask for a missing keyword; every other
        field has a default the board shows.
      description: >-
        Access: public. Send a JSON body; unknown keys are rejected with 400
        invalid_request (inputs are strict). Responses may gain fields
        additively — never remove or repurpose; ignore unknown response fields.
      operationId: automation.arm
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                keywords:
                  minItems: 1
                  maxItems: 10
                  type: array
                  items:
                    type: string
                    minLength: 1
                    maxLength: 64
                    pattern: ^[^\s<>]+$
                  description: >-
                    The words that fire the reply, one to ten, each one word; a
                    trigger carrying any of them as a whole word, in any case,
                    is answered. No word may answer twice on one surface while
                    both rules are on. When the creator names no word, ask which
                    one should fire it before proposing, offering the word the
                    reel's caption calls for when it names one; never invent a
                    word.
                message:
                  type: string
                  minLength: 1
                  maxLength: 800
                  description: >-
                    The one line Dally sends as the creator, at most 800 Unicode
                    code points; the link and the disclosure are added after it.
                    When the creator gives no line, write one short line that
                    offers what the reel promises and say it is yours; the board
                    shows it and automation.edit changes it.
                link_url:
                  description: >-
                    Where the link lands; https only. Default: Dally's home
                    page.
                  type: string
                  format: uri
                content_ids:
                  maxItems: 50
                  type: array
                  items:
                    type: string
                    format: uuid
                    pattern: >-
                      ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$
                  description: >-
                    The posts a comment listens on and the stories a story reply
                    listens on, from content.content_id; empty means any of the
                    creator's. The creator's latest post is their newest content
                    row by published_at. Ignored on the dm surface.
                surfaces:
                  description: >-
                    Which surfaces fire it, one to three: comment, story_reply,
                    dm. Default: all three. A creator's 'DM automation' names
                    where the reply lands, always the DMs, not the surface that
                    fires it.
                  minItems: 1
                  maxItems: 3
                  type: array
                  items:
                    type: string
                    enum:
                      - comment
                      - story_reply
                      - dm
                    description: >-
                      comment: a comment on one of the automation's posts (reel,
                      image or album), or on any of the creator's posts,
                      answered in the commenter's DMs. story_reply: a reply to
                      one of the automation's stories or highlights, or to any
                      of the creator's stories, answered in that thread. dm: a
                      DM carrying a keyword, answered in that thread.
                tracked_link:
                  description: >-
                    true: the link is sent as dally.ai/r/<code>, so taps, visits
                    and sales are counted per person; false: the link is sent as
                    typed and only sends and reads are counted
                  type: boolean
                follow_ups:
                  type: object
                  properties:
                    signed_up:
                      description: Sent the first time the person signs up for the creator.
                      type: string
                      minLength: 1
                      maxLength: 1000
                    connected:
                      description: >-
                        Sent the first time the person connects an account to
                        what they signed up for.
                      type: string
                      minLength: 1
                      maxLength: 1000
                    purchased:
                      description: Sent the first time the person pays.
                      type: string
                      minLength: 1
                      maxLength: 1000
                  additionalProperties: false
                  description: >-
                    One more message per later step the person takes — signed
                    up, connected, purchased — each sent once in the same
                    Instagram thread as the creator, and only while Instagram's
                    reply window is still open; nothing is ever queued for
                    later.
              required:
                - keywords
                - message
              additionalProperties: false
            example:
              keywords:
                - pumpkin
                - recipe
              message: Here is the link you asked for.
      responses:
        '200':
          description: Success. request_id is present on every response.
          content:
            application/json:
              schema:
                type: object
                properties:
                  rule:
                    type: object
                    properties:
                      rule_id:
                        type: string
                        format: uuid
                        pattern: >-
                          ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$
                        description: >-
                          The rule id automation.arm answered with;
                          keyword_rules.rule_id.
                      state:
                        type: string
                        enum:
                          - proposed
                          - armed
                          - disarmed
                        description: >-
                          proposed (rendered in the frame, awaiting the
                          creator's switch), armed (answering triggers),
                          disarmed (turned off; the switch turns it back on).
                      surfaces:
                        minItems: 1
                        type: array
                        items:
                          type: string
                          enum:
                            - comment
                            - story_reply
                            - dm
                          description: >-
                            comment: a comment on one of the automation's posts
                            (reel, image or album), or on any of the creator's
                            posts, answered in the commenter's DMs. story_reply:
                            a reply to one of the automation's stories or
                            highlights, or to any of the creator's stories,
                            answered in that thread. dm: a DM carrying a
                            keyword, answered in that thread.
                        description: >-
                          Which surfaces fire it, one to three: comment,
                          story_reply, dm.
                      platform:
                        type: string
                        description: 'The platform the rule answers on: instagram today.'
                      keywords:
                        minItems: 1
                        type: array
                        items:
                          type: string
                          minLength: 1
                        description: >-
                          The words that fire it, any of them, matched as whole
                          words without regard to case.
                      message:
                        type: string
                        description: The one line Dally sends as the creator.
                      link_url:
                        type: string
                        format: uri
                        description: >-
                          Where the link lands; a tracked link records the
                          click-through first.
                      disclosure:
                        type: string
                        description: The line every automated reply ends with.
                      tracked_link:
                        type: boolean
                        description: >-
                          true: the link is sent as dally.ai/r/<code>, so taps,
                          visits and sales are counted per person; false: the
                          link is sent as typed and only sends and reads are
                          counted.
                      reply_preview:
                        type: string
                        description: >-
                          The whole reply as it will be sent: the message, the
                          link as the person will see it, and the disclosure.
                      reels:
                        type: array
                        items:
                          type: object
                          properties:
                            content_id:
                              type: string
                              format: uuid
                              pattern: >-
                                ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$
                              description: The reel; content.content_id.
                            permalink:
                              anyOf:
                                - type: string
                                - type: 'null'
                              description: >-
                                The reel's Instagram address when Dally holds
                                it.
                          required:
                            - content_id
                            - permalink
                        description: >-
                          The posts it listens on for comments and the stories
                          it listens on for story replies; empty means any of
                          the creator's.
                      environment:
                        type: string
                        enum:
                          - local
                          - staging
                          - production
                        description: >-
                          The one environment whose worker answers this rule;
                          the others only record.
                      armed_at:
                        anyOf:
                          - type: string
                            format: date-time
                            pattern: >-
                              ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$
                            description: >-
                              An ISO-8601 UTC timestamp, e.g.
                              2026-08-12T17:00:00Z.
                          - type: 'null'
                        description: >-
                          When the creator last armed the rule; null while
                          proposed.
                      disarmed_at:
                        anyOf:
                          - type: string
                            format: date-time
                            pattern: >-
                              ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$
                            description: >-
                              An ISO-8601 UTC timestamp, e.g.
                              2026-08-12T17:00:00Z.
                          - type: 'null'
                        description: >-
                          When the creator turned the rule off; null while it
                          answers.
                      counts:
                        type: object
                        properties:
                          sends:
                            type: integer
                            minimum: 0
                            description: >-
                              Sends: how many messages Dally sent as the creator
                              under this rule, one per person.
                          delivered:
                            type: integer
                            minimum: 0
                            description: >-
                              How many of those Sends Instagram reported
                              delivered.
                          reads:
                            type: integer
                            minimum: 0
                            description: >-
                              How many the person opened, from Instagram's read
                              receipt; reads over delivered is the read rate.
                          click_throughs:
                            type: integer
                            minimum: 0
                            description: >-
                              How many tapped the tracked link, invalid traffic
                              excluded; click-throughs over delivered is the
                              click-through rate.
                          claims:
                            type: integer
                            minimum: 0
                            description: >-
                              How many of those people claimed an account that
                              already existed.
                          sign_ups:
                            type: integer
                            minimum: 0
                            description: How many of those people signed up new.
                          invalid_traffic:
                            type: integer
                            minimum: 0
                            description: >-
                              How many arrivals at the tracked link no person
                              made, never counted as a click-through.
                          purchases:
                            type: integer
                            minimum: 0
                            description: >-
                              How many of those people paid, from the checkout
                              webhook; purchases over click-throughs is the
                              conversion rate.
                          revenue_cents:
                            type: integer
                            minimum: 0
                            description: >-
                              What those purchases paid, in cents, summed over
                              the paths that purchased.
                        required:
                          - sends
                          - delivered
                          - reads
                          - click_throughs
                          - claims
                          - sign_ups
                          - invalid_traffic
                          - purchases
                          - revenue_cents
                        description: >-
                          The rule's conversion paths counted, the same numbers
                          keyword_rules carries; conversion_paths has the rows.
                      confirm:
                        anyOf:
                          - type: object
                            properties:
                              operation:
                                type: string
                                const: automation.confirm
                                description: The write operation the frame's switch calls.
                              follow_up:
                                type: string
                                description: >-
                                  The line the switch posts when the host cannot
                                  call the operation itself.
                            required:
                              - operation
                              - follow_up
                          - type: 'null'
                        description: >-
                          How the creator arms it, present while proposed or
                          disarmed; never call it yourself.
                      disarm:
                        anyOf:
                          - type: object
                            properties:
                              operation:
                                type: string
                                const: automation.disarm
                                description: The write operation that turns the rule off.
                              follow_up:
                                type: string
                                description: >-
                                  The line the switch posts when the host cannot
                                  call the operation itself.
                            required:
                              - operation
                              - follow_up
                          - type: 'null'
                        description: >-
                          How the creator turns the rule off, present while
                          armed.
                      follow_ups:
                        type: object
                        properties:
                          signed_up:
                            description: >-
                              Sent the first time the person signs up for the
                              creator.
                            type: string
                            minLength: 1
                            maxLength: 1000
                          connected:
                            description: >-
                              Sent the first time the person connects an account
                              to what they signed up for.
                            type: string
                            minLength: 1
                            maxLength: 1000
                          purchased:
                            description: Sent the first time the person pays.
                            type: string
                            minLength: 1
                            maxLength: 1000
                        description: >-
                          One more message per later step the person takes —
                          signed up, connected, purchased — each sent once in
                          the same Instagram thread as the creator, and only
                          while Instagram's reply window is still open; nothing
                          is ever queued for later.
                    required:
                      - rule_id
                      - state
                      - surfaces
                      - platform
                      - keywords
                      - message
                      - link_url
                      - disclosure
                      - tracked_link
                      - reply_preview
                      - reels
                      - environment
                      - armed_at
                      - disarmed_at
                      - counts
                      - confirm
                      - disarm
                    description: >-
                      One reply automation: its surfaces, its posts and stories
                      or any of them, its keywords, the one line Dally sends as
                      the creator with the link and the disclosure, where it
                      stands, and its counts.
                  show:
                    type: object
                    properties:
                      kind:
                        type: string
                        const: automation_board
                        description: >-
                          The dally_show kind that renders every automation with
                          its switch.
                      data:
                        type: object
                        properties:
                          rule_id:
                            type: string
                            format: uuid
                            pattern: >-
                              ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$
                            description: >-
                              The rule id automation.arm answered with;
                              keyword_rules.rule_id.
                        description: The rule the board opens on; none after a delete.
                    required:
                      - kind
                      - data
                    description: >-
                      How it is shown: dally_write renders this kind on this
                      very answer, so the creator already sees the board; do not
                      render it again. The board reads the creator's automations
                      itself and takes no rows from you.
                  request_id:
                    type: string
                    minLength: 1
                    description: >-
                      Server-minted id for this request. Present on every
                      response, success and error — quote it when reporting a
                      problem.
                required:
                  - rule
                  - show
                  - request_id
              example:
                rule:
                  rule_id: 3c1f0b7d-4a52-4e88-b6c3-1d7e9a204f61
                  state: proposed
                  surfaces:
                    - comment
                    - story_reply
                    - dm
                  platform: instagram
                  keywords:
                    - pumpkin
                    - recipe
                  message: Here is the link you asked for.
                  link_url: https://dally.ai/
                  disclosure: — automated reply
                  tracked_link: true
                  reply_preview: |-
                    Here is the link you asked for.
                    https://dally.ai/r/<click_id>

                    — automated reply
                  reels: []
                  environment: production
                  armed_at: null
                  disarmed_at: null
                  counts:
                    sends: 0
                    delivered: 0
                    reads: 0
                    click_throughs: 0
                    claims: 0
                    sign_ups: 0
                    invalid_traffic: 0
                    purchases: 0
                    revenue_cents: 0
                  confirm:
                    operation: automation.confirm
                    follow_up: Arm the pumpkin rule
                  disarm: null
                show:
                  kind: automation_board
                  data:
                    rule_id: 3c1f0b7d-4a52-4e88-b6c3-1d7e9a204f61
                request_id: req_01j8zkq
        default:
          description: >-
            Error — the real HTTP status carries the class; the body is always
            the one error envelope. Codes: invalid_request, stale_cursor,
            query_too_broad, unauthorized, forbidden, no_connected_accounts,
            stale_authority, not_found, precondition_failed, method_not_allowed,
            stale_snapshot, stale_revision, execution_payload_erased,
            exhaustiveness_unavailable, rate_limited, internal_error,
            unavailable, search_unavailable.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
      security:
        - bearerAuth: []
        - apiKeyAuth: []
components:
  schemas:
    ErrorEnvelope:
      type: object
      properties:
        error:
          type: object
          properties:
            code:
              type: string
              enum:
                - invalid_request
                - stale_cursor
                - query_too_broad
                - unauthorized
                - forbidden
                - no_connected_accounts
                - stale_authority
                - not_found
                - precondition_failed
                - method_not_allowed
                - stale_snapshot
                - stale_revision
                - execution_payload_erased
                - exhaustiveness_unavailable
                - rate_limited
                - internal_error
                - unavailable
                - search_unavailable
              description: >-
                The machine-readable error code. The set only grows — treat
                unknown codes by falling back to the HTTP status class.
            message:
              type: string
              description: >-
                A human-readable teaching message: what failed and the exact
                fix, never just the symptom.
            details:
              description: >-
                Optional structured context for this code — e.g.
                estimated_matches and ceiling on query_too_broad.
              type: object
              propertyNames:
                type: string
              additionalProperties: {}
          required:
            - code
            - message
          description: The error object — the one shape every failure wears.
        request_id:
          type: string
          minLength: 1
          description: >-
            Server-minted id for this request. Present on every response,
            success and error — quote it when reporting a problem.
      required:
        - error
        - request_id
      description: The ONE error envelope (API-ERR-001).
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: 'A WorkOS-dashboard-issued internal API key on Authorization: Bearer.'
    apiKeyAuth:
      type: apiKey
      in: header
      name: x-api-key
      description: The same internal API key, accepted on x-api-key.

````