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

# Criar automação

> A automação nasce sempre desligada (`active: false`). Criar não conta no
teto de automações ativas do plano; ligar conta. Ligue com
`PUT /v1/automations/{id}/active`.

Com `Idempotency-Key`, repetir a chamada devolve a automação já criada.

Permissão: `AUTOMATIONS_MANAGE`. Essa permissão é opcional na chave:
chaves antigas não têm.




## OpenAPI

````yaml /openapi.yaml post /v1/automations
openapi: 3.0.3
info:
  title: API da Arara
  description: >
    API REST da Arara para WhatsApp Business: mensagens, templates, campanhas,

    contatos, conversas, formulários, automações, smart links e carteira.


    Esta especificação cobre só os endpoints que aceitam **chave de API**

    (`Authorization: Bearer ara_live_...`). Rotas usadas apenas pelo painel

    (gestão de chaves, configuração do webhook, pagamentos e perfil pessoal)

    ficam de fora.


    ## Autenticação


    Header `Authorization: Bearer ara_live_...`. Crie a chave em

    https://app.ararahq.com/dashboard/apikeys. As chaves são sempre LIVE:

    mensagens são entregues de verdade e o custo sai da carteira.


    ## Permissões da chave


    Chave criada sem permissões explícitas tem acesso total (`ADMIN`). Chave

    com permissões restritas só alcança:


    - `READ`: `GET` em `/v1/messages`, `/v1/campaigns`, `/v1/templates`,
      `/v1/flows`, `/v1/automations` e `/v1/organizations/me/numbers`.
    - `MESSAGES_SEND`: escrita em `/v1/messages/**`, `POST /v1/media/upload` e
      `POST /v1/flows/{id}/test`.
    - `TEMPLATES_WRITE`: escrita em `/v1/templates/**` e `/v1/flows/**`.

    - `CAMPAIGNS_SEND`: escrita em `/v1/campaigns/**`.

    - `CONTACTS_WRITE`: escrita em `/v1/contacts/**`.

    - `AUTOMATIONS_MANAGE`: escrita em `/v1/automations/**`.

    - `WEBHOOKS_MANAGE`: escrita em `/webhook/**`.


    Qualquer outra rota exige `ADMIN`. Fora do escopo, a resposta é `403`.


    ## Rate limit


    Por usuário da chave: 1.200 leituras (`GET`) por minuto e 3.000 escritas por

    minuto. Toda resposta traz `X-RateLimit-Remaining`. Acima do limite: `429`

    com `Retry-After` e `error.code = RATE_LIMIT_EXCEEDED`. O envio tem limites

    próprios (`SEND_RATE_LIMITED`, `BATCH_BUSY`,
    `MARKETING_FREQUENCY_EXCEEDED`).


    ## Formato de erro


    ```json

    { "error": { "code": "ERROR_CODE", "message": "Descrição", "details": {} } }

    ```


    Exceções: falha de autenticação (`401`, `403` e `503` do filtro de chave)

    volta no formato padrão do Spring (`timestamp`, `status`, `error`, `path`,

    sem `code`), e alguns `404` e `403` voltam sem corpo.
  version: 2.1.0
  contact:
    name: AraraHQ
    url: https://ararahq.com
    email: oi@ararahq.com
servers:
  - url: https://api.ararahq.com
    description: Produção
security:
  - bearerAuth: []
tags:
  - name: Mensagens
    description: Envio, consulta e histórico de mensagens de WhatsApp, e upload de mídia.
  - name: Conversas
    description: >-
      Conversas com cada telefone, resposta dentro da janela de 24h e situação
      da janela.
  - name: Templates
    description: Criação, listagem, status de aprovação e métricas de templates.
  - name: Campanhas
    description: >-
      Envio do mesmo template para muitos contatos, com estimativa, agendamento,
      cancelamento e teste A/B.
  - name: Contatos
    description: Base de contatos da organização e direitos do titular (LGPD).
  - name: Opt-out
    description: Registro e consulta de quem pediu para não receber mensagens.
  - name: Formulários
    description: >-
      Formulários nativos do WhatsApp (Flows) e as respostas recebidas.
      Disponíveis do plano Voo para cima.
  - name: Automações
    description: >-
      Sequências de passos que rodam sozinhas para cada contato que entra por um
      gatilho. Exigem plano com recuperação de receita.
  - name: Smart Links
    description: Links wa.me rastreáveis, com QR code.
  - name: Números
    description: >-
      Números de WhatsApp da organização e o perfil comercial exibido no
      WhatsApp.
  - name: Carteira
    description: Saldo, extrato, recarga automática e preços.
  - name: Consulta de telefone
    description: Consulta de tipo de linha e de WhatsApp de um número (cobrada).
  - name: Recuperação
    description: Endpoint de recuperação de receita (carrinho abandonado, Pix, boleto).
  - name: Conta
    description: Identidade da chave, plano da organização e status da API.
paths:
  /v1/automations:
    post:
      tags:
        - Automações
      summary: Criar automação
      description: |
        A automação nasce sempre desligada (`active: false`). Criar não conta no
        teto de automações ativas do plano; ligar conta. Ligue com
        `PUT /v1/automations/{id}/active`.

        Com `Idempotency-Key`, repetir a chamada devolve a automação já criada.

        Permissão: `AUTOMATIONS_MANAGE`. Essa permissão é opcional na chave:
        chaves antigas não têm.
      operationId: createAutomation
      parameters:
        - $ref: '#/components/parameters/IdempotencyKeyOptional'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AutomationUpsertRequest'
            examples:
              carrinho:
                summary: Lembrete de carrinho abandonado
                value:
                  name: Lembrete de carrinho
                  trigger: cart.abandoned
                  steps:
                    - type: wait
                      config:
                        minutes: 60
                    - type: message
                      config:
                        templateId: 0b8f6c1e-7a52-4a1b-9a0e-3f2d6c9e1a44
                        variables:
                          - nome
              cobranca:
                summary: Cobrança com espera de pagamento
                value:
                  name: Cobrança do plano mensal
                  trigger: webhook
                  steps:
                    - type: message
                      config:
                        templateId: 0b8f6c1e-7a52-4a1b-9a0e-3f2d6c9e1a44
                        variables:
                          - nome
                    - type: wait_payment
                      config:
                        timeoutMinutes: 60
                      branches:
                        paid:
                          - type: tag
                            config:
                              tag: pagou
                        unpaid:
                          - type: message
                            config:
                              templateId: 5d2a9b7c-1e44-4f0a-8c3b-6a7e2d1f9b10
                              variables:
                                - nome
      responses:
        '201':
          description: Automação criada
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Automation'
        '400':
          $ref: '#/components/responses/AutomationInvalid'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/RateLimited'
components:
  parameters:
    IdempotencyKeyOptional:
      in: header
      name: Idempotency-Key
      required: false
      schema:
        type: string
        maxLength: 255
      description: >-
        Chave de idempotência, de 1 a 255 caracteres, sem caracteres de controle
        (fora disso: `400 INVALID_IDEMPOTENCY_KEY`). Derive de um evento do seu
        sistema (id do pedido, id da tentativa) e reuse a mesma chave nas
        retentativas.
      example: pedido-12345-confirmacao
  schemas:
    AutomationUpsertRequest:
      type: object
      required:
        - name
        - trigger
      properties:
        name:
          type: string
          description: Nome interno da automação.
        trigger:
          type: string
          enum:
            - webhook
            - cart.abandoned
            - payment.failed
            - tag.applied
            - conversation.started
            - button.replied
            - charge.paid
            - charge.expired
          description: |
            Gatilho que coloca um contato na automação. `webhook` é o link
            próprio da automação; `cart.abandoned` e `payment.failed` vêm da
            recuperação de receita; os demais são eventos internos da Arara.
        triggerConfig:
          type: object
          nullable: true
          additionalProperties: true
          description: >-
            Só `button.replied` exige: `{ "replyId": "...", "templateName"?:
            "..." }`. Os demais gatilhos ignoram o campo.
        steps:
          type: array
          default: []
          description: >-
            Passos, na ordem de execução. A lista inteira é reescrita a cada
            `POST` ou `PUT`.
          items:
            $ref: '#/components/schemas/AutomationStep'
    Automation:
      type: object
      required:
        - id
        - name
        - trigger
        - active
        - steps
        - costPerRunBrl
      properties:
        id:
          type: string
          format: uuid
        name:
          type: string
        trigger:
          type: string
        triggerConfig:
          type: object
          nullable: true
          additionalProperties: true
        active:
          type: boolean
          description: '`false` na criação. Mude em `PUT /v1/automations/{id}/active`.'
        steps:
          type: array
          items:
            $ref: '#/components/schemas/AutomationStep'
        costPerRunBrl:
          type: number
          description: Custo estimado, em reais, de cada pessoa que entrar na automação.
        stats:
          type: object
          nullable: true
          properties:
            runsLast30Days:
              type: integer
              format: int64
            inFlight:
              type: integer
              format: int64
            completed:
              type: integer
              format: int64
            stopped:
              type: integer
              format: int64
        webhookUrl:
          type: string
          nullable: true
          description: >-
            URL que o seu sistema precisa chamar, quando o gatilho depende
            disso.
        hook:
          allOf:
            - $ref: '#/components/schemas/AutomationHook'
          nullable: true
          description: Só no gatilho `webhook`.
      example:
        id: 3d5a1f0c-6b2e-4c8d-9a41-0e1f2a3b4c5d
        name: Lembrete de carrinho
        trigger: cart.abandoned
        triggerConfig: null
        active: false
        steps:
          - id: b2f0c1de-1a2b-4c3d-8e4f-5a6b7c8d9e0f
            type: wait
            config:
              minutes: 60
          - id: c7a1e2d3-4b5c-4d6e-9f70-8a9b0c1d2e3f
            type: message
            config:
              templateId: 0b8f6c1e-7a52-4a1b-9a0e-3f2d6c9e1a44
              variables:
                - nome
        costPerRunBrl: 0.38
        stats:
          runsLast30Days: 0
          inFlight: 0
          completed: 0
          stopped: 0
        webhookUrl: null
        hook: null
    AutomationStep:
      type: object
      required:
        - type
      properties:
        type:
          type: string
          enum:
            - message
            - wait
            - condition
            - tag
            - question
            - wait_payment
          description: |
            - `message`: envia um template (`templateId`, `variables` e,
              opcionalmente, `charge`) ou um texto na janela de 24h
              (`sessionText`, até 1.024 caracteres). Nunca os dois.
            - `wait`: `{ "minutes": N }`, de 1 a 43.200 (30 dias).
            - `condition`: `{ "tag": "..." }`. Segue só se o contato ainda não
              tem a etiqueta.
            - `tag`: `{ "tag": "..." }`. Aplica a etiqueta no contato.
            - `question`: pergunta com opções; ramifica em `branches`.
            - `wait_payment`: `{ "timeoutMinutes": N, "referenceId"?: "..." }`;
              ramifica em `paid` e `unpaid`.
        config:
          type: object
          nullable: true
          additionalProperties: true
          description: Configuração do passo. O formato depende de `type`.
        branches:
          type: object
          nullable: true
          description: |
            Só em `question` e `wait_payment`. Chave do ramo para a lista de
            passos daquele ramo. Em `question`: o `id` de cada opção, mais
            `__timeout` e `__other`. Em `wait_payment`: `paid` e `unpaid`.
          additionalProperties:
            type: array
            items:
              $ref: '#/components/schemas/AutomationStep'
        id:
          type: string
          format: uuid
          nullable: true
          readOnly: true
          description: ID do passo na resposta. Muda a cada `PUT`.
    AutomationHook:
      type: object
      required:
        - url
        - signatureEnabled
        - hasSecret
      properties:
        url:
          type: string
          description: >-
            Link próprio da automação
            (`https://api.ararahq.com/hooks/a/ara_hook_...`).
        signatureEnabled:
          type: boolean
        hasSecret:
          type: boolean
          description: Diz só se o segredo existe. O valor nunca volta em leitura.
    Error:
      type: object
      required:
        - error
      properties:
        error:
          type: object
          required:
            - code
            - message
          properties:
            code:
              type: string
              example: INSUFFICIENT_FUNDS
              description: >-
                Código estável do erro. Use este campo no seu tratamento, não a
                mensagem.
            message:
              type: string
              nullable: true
              description: Descrição legível, em português. Pode mudar.
            details:
              type: object
              additionalProperties: true
              description: Dados extras do erro. Vazio na maioria dos casos.
      example:
        error:
          code: INSUFFICIENT_FUNDS
          message: Saldo insuficiente.
          details: {}
    SpringError:
      type: object
      description: >-
        Corpo padrão do Spring nas falhas de autenticação (`401`, `403` e `503`
        do filtro de chave). Não tem `error.code`.
      properties:
        timestamp:
          type: string
          format: date-time
        status:
          type: integer
          example: 401
        error:
          type: string
          example: Unauthorized
        path:
          type: string
          example: /v1/messages
  responses:
    AutomationInvalid:
      description: |
        `AUTOMATION_TRIGGER_INVALID` (gatilho inexistente),
        `AUTOMATION_TRIGGER_CONFIG_INVALID` (`button.replied` sem `replyId`),
        `AUTOMATION_STEP_INVALID` (passo com `type` ou `config` inválido) ou
        `INVALID_JSON`.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error:
              code: AUTOMATION_TRIGGER_INVALID
              message: Gatilho inválido.
              details: {}
    Unauthorized:
      description: >
        Chave inexistente, revogada, expirada, com prefixo errado (`ara_` sem

        `ara_live_`) ou vinda de IP fora da allowlist. O corpo é o JSON padrão
        do

        Spring, sem `error.code`.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/SpringError'
          example:
            timestamp: '2026-09-15T14:30:00.000+00:00'
            status: 401
            error: Unauthorized
            path: /v1/messages
    Forbidden:
      description: >
        Dois casos, com corpos diferentes:


        - Autenticação: header `Authorization` ausente, Bearer que não começa
        com
          `ara_`, chave sem a permissão da rota ou rota que não aceita chave de
          API. Corpo no formato padrão do Spring, sem `error.code`.
        - Regra de negócio, no formato `{ "error": { ... } }`:
          `PLAN_FEATURE_LOCKED`, `PLAN_LIMIT_REACHED`, `ACCOUNT_NOT_ACTIVATED`,
          `NO_DEDICATED_NUMBER`, `ORGANIZATION_SUSPENDED`, `NUMBER_BLOCKED`,
          `FRAUD_SUSPECTED`, `RESOURCE_FORBIDDEN`, `VIEWER_READ_ONLY`.
      content:
        application/json:
          schema:
            anyOf:
              - $ref: '#/components/schemas/Error'
              - $ref: '#/components/schemas/SpringError'
          examples:
            regraDeNegocio:
              summary: Regra de negócio
              value:
                error:
                  code: PLAN_FEATURE_LOCKED
                  message: Seu plano não inclui este recurso.
                  details: {}
            autenticacao:
              summary: Sem header ou sem permissão
              value:
                timestamp: '2026-09-15T14:30:00.000+00:00'
                status: 403
                error: Forbidden
                path: /v1/messages
    RateLimited:
      description: >-
        `RATE_LIMIT_EXCEEDED`: limite geral da API (1.200 leituras ou 3.000
        escritas por minuto, por usuário da chave).
      headers:
        Retry-After:
          schema:
            type: integer
          description: Segundos a aguardar antes de repetir a chamada.
        X-RateLimit-Remaining:
          schema:
            type: integer
          description: Requisições restantes na janela atual.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error:
              code: RATE_LIMIT_EXCEEDED
              message: Muitas requisições. Tente de novo em instantes.
              details: {}
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: ara_live_...
      description: >-
        Chave de API da Arara (`ara_live_...`), enviada no header
        `Authorization: Bearer ara_live_...`. Crie e gerencie as chaves no
        painel: https://app.ararahq.com/dashboard/apikeys. O valor completo
        aparece uma única vez, na criação.

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.