# Substituir automação

`PUT /api/v1/automations/{id}`

Substitui toda a definição. Campos ausentes são redefinidos, as ações recebem novos identificadores e `version` é incrementada. A exceção é `enabled`: omitir preserva o estado atual. Para alterar somente o estado, use `PATCH /{id}/enabled`. Exige `automations.edit`.

## Autenticação

Envie a chave em `Authorization: Bearer pf_live_…`.

## Parâmetros

| Nome | Local | Obrigatório | Tipo | Descrição |
| --- | --- | --- | --- | --- |
| `id` | path | Sim | `string` | Identificador da automação. |

## Corpo da requisição

Content-Type: `application/json`

```json
{
  "name": "Fluxo manual de exemplo",
  "triggerType": "manual",
  "scope": "global",
  "enabled": false,
  "graphDefinition": {
    "version": 2,
    "nodes": [
      {
        "id": "inicio",
        "type": "trigger"
      },
      {
        "id": "fim",
        "type": "end"
      }
    ],
    "edges": [
      {
        "id": "inicio-fim",
        "source": "inicio",
        "target": "fim",
        "sourceHandle": "next"
      }
    ]
  }
}
```

### Campos

| Campo | Tipo | Obrigatório no objeto | Descrição |
| --- | --- | --- | --- |
| `name` | `string` | Sim | Até 255 caracteres. |
| `triggerType` | `string` | Sim | Um dos valores de `GET /api/v1/automations/triggers`. Valores: deal_created, deal_stage_changed, deal_won, deal_lost, deal_assigned, message_received, conversation_closed, contact_no_reply, team_no_reply, field_filled, timer, instagram_comment_received, manual, webhook. |
| `scope` | `string` | Sim | Valores: global, pipeline, stage. |
| `pipelineId` | `string` | Não | Aceita null. |
| `stageId` | `string` | Não | Aceita null. |
| `outboundChannelId` | `string` | Não | Não existe rota pública para listar canais; obtenha o identificador por outro meio. Aceita null. |
| `graphDefinition` | `AutomationGraph` | Não | Grafo do fluxo: até 50 nós e 30 esperas, exatamente um nó trigger, sem ciclos e com todos os nós alcançáveis pelo gatilho. Cada tipo tem regras de saída: condition exige uma aresta branch_<id> por ramo; round_robin, uma rr_<id> por saída; end não permite saída. A validação retorna todos os problemas em conjunto. |
| `graphDefinition.version` | `integer` | Sim | Valores: 2. |
| `graphDefinition.nodes` | `array` | Sim |  |
| `graphDefinition.nodes[].id` | `string` | Sim |  |
| `graphDefinition.nodes[].type` | `string` | Sim | Valores: trigger, action, condition, wait, round_robin, end. |
| `graphDefinition.nodes[].actionType` | `string` | Não | Valores: webhook, send_whatsapp, move_stage, add_tag, remove_tag, set_custom_field, wait, create_task, assign_responsible, add_co_owner, send_meta_conversion, create_lead, send_email, reply_instagram_comment, send_instagram_private_reply, hide_instagram_comment, cia_deal_analysis, create_calendar_event, close_conversation, stop_automations. Aceita null. |
| `graphDefinition.nodes[].config` | `object` | Não | As propriedades obrigatórias dependem de actionType: webhook exige url; move_stage exige targetStageId; add_tag/remove_tag exigem tagIds não vazio; set_custom_field exige exatamente um entre fieldId e fieldSlug, além de value; assign_responsible exige userId; wait exige delaySeconds, com mínimo de 5. |
| `graphDefinition.nodes[].condition` | `object` | Não | Aceita null. |
| `graphDefinition.edges` | `array` | Não |  |
| `graphDefinition.edges[].id` | `string` | Não |  |
| `graphDefinition.edges[].source` | `string` | Sim |  |
| `graphDefinition.edges[].target` | `string` | Sim |  |
| `graphDefinition.edges[].sourceHandle` | `string` | Não | `next`, `fallback`, `branch_<id>`, `rr_<id>`, `btn_<id>`, `replied`, `timeout` ou `text_reply`. |
| `respectBusinessHours` | `boolean` | Não | Aceita null. |
| `triggerWindow` | `object` | Não | Aceita null. |
| `conditions` | `object` | Não | Aceita null. |
| `triggerConfig` | `object` | Não | O formato depende de triggerType. field_filled usa {fieldSlug, fillMode}; timer aceita {mode: date_field, dateFieldSlug, offsetMinutes, onPastDate} ou {mode: recurring, cron}; contact_no_reply e team_no_reply usam {timeoutSeconds} entre 60 e 2592000; webhook usa {path, httpMethod, authentication e outras propriedades}. Aceita null. |
| `enabled` | `boolean` | Não | Na criação, omitir significa **true**: o fluxo começa a reagir aos gatilhos. Na substituição, omitir preserva o estado atual. Aceita null. |
| `actions` | `array` | Não | Ações do formato legado. Para novos fluxos, use graphDefinition. Aceita null. |
| `actions[].type` | `string` | Não | Tipo de ação legado. |
| `actions[].order` | `integer` | Não |  |
| `actions[].config` | `object` | Não |  |
| `webhookUrl` | `string` | Não | URL de webhook do formato legado. Aceita null. |
| `webhookHeaders` | `object` | Não | Cabeçalhos de webhook do formato legado. Aceita null. |

## Respostas

### 200

Sucesso

| Campo | Tipo | Obrigatório no objeto | Descrição |
| --- | --- | --- | --- |
| `data` | `Automation` | Não |  |
| `data.id` | `string` | Não |  |
| `data.name` | `string` | Não |  |
| `data.version` | `integer` | Não | Versão da definição. A troca de enabled não incrementa a versão. |
| `data.enabled` | `boolean` | Não |  |
| `data.triggerType` | `string` | Não |  |
| `data.scope` | `string` | Não | Valores: global, pipeline, stage. |
| `data.pipelineId` | `string` | Não | Aceita null. |
| `data.stageId` | `string` | Não | Aceita null. |
| `data.outboundChannelId` | `string` | Não | Aceita null. |
| `data.respectBusinessHours` | `boolean` | Não |  |
| `data.triggerWindow` | `object` | Não | Aceita null. |
| `data.conditions` | `object` | Não | Aceita null. |
| `data.triggerConfig` | `object` | Não | As credenciais de webhook (headerValue, password) são removidas. Aceita null. |
| `data.graphDefinition` | `AutomationGraph` | Não | Grafo do fluxo: até 50 nós e 30 esperas, exatamente um nó trigger, sem ciclos e com todos os nós alcançáveis pelo gatilho. Cada tipo tem regras de saída: condition exige uma aresta branch_<id> por ramo; round_robin, uma rr_<id> por saída; end não permite saída. A validação retorna todos os problemas em conjunto. |
| `data.graphDefinition.version` | `integer` | Sim | Valores: 2. |
| `data.graphDefinition.nodes` | `array` | Sim |  |
| `data.graphDefinition.nodes[].id` | `string` | Sim |  |
| `data.graphDefinition.nodes[].type` | `string` | Sim | Valores: trigger, action, condition, wait, round_robin, end. |
| `data.graphDefinition.nodes[].actionType` | `string` | Não | Valores: webhook, send_whatsapp, move_stage, add_tag, remove_tag, set_custom_field, wait, create_task, assign_responsible, add_co_owner, send_meta_conversion, create_lead, send_email, reply_instagram_comment, send_instagram_private_reply, hide_instagram_comment, cia_deal_analysis, create_calendar_event, close_conversation, stop_automations. Aceita null. |
| `data.graphDefinition.nodes[].config` | `object` | Não | As propriedades obrigatórias dependem de actionType: webhook exige url; move_stage exige targetStageId; add_tag/remove_tag exigem tagIds não vazio; set_custom_field exige exatamente um entre fieldId e fieldSlug, além de value; assign_responsible exige userId; wait exige delaySeconds, com mínimo de 5. |
| `data.graphDefinition.nodes[].condition` | `object` | Não | Aceita null. |
| `data.graphDefinition.edges` | `array` | Não |  |
| `data.graphDefinition.edges[].id` | `string` | Não |  |
| `data.graphDefinition.edges[].source` | `string` | Sim |  |
| `data.graphDefinition.edges[].target` | `string` | Sim |  |
| `data.graphDefinition.edges[].sourceHandle` | `string` | Não | `next`, `fallback`, `branch_<id>`, `rr_<id>`, `btn_<id>`, `replied`, `timeout` ou `text_reply`. |
| `data.actions` | `array` | Não |  |
| `data.actions[].id` | `string` | Não | ID da ação. As ações são substituídas na atualização, não alteradas individualmente. |
| `data.actions[].type` | `string` | Não |  |
| `data.actions[].order` | `integer` | Não |  |
| `data.actions[].config` | `object` | Não | O secret do webhook é removido. |
| `data.createdAt` | `string` | Não | Formato: date-time. |
| `data.updatedAt` | `string` | Não | Formato: date-time. |
| `data.secret` | `string` | Não | Presente somente na resposta de criação ou substituição que gerou o segredo. Nunca aparece na leitura. Salve-o: assina X-PipeFacil-Signature-256 e não pode ser consultado depois. Aceita null. |
| `message` | `string` | Não | Aceita null. |

```json
{
  "type": "object",
  "properties": {
    "data": {
      "$ref": "#/components/schemas/Automation"
    },
    "message": {
      "type": "string",
      "nullable": true
    }
  }
}
```

### 400

Falha de validação dos campos; `fieldErrors` contém os erros.

| Campo | Tipo | Obrigatório no objeto | Descrição |
| --- | --- | --- | --- |
| `error` | `string` | Sim |  |
| `code` | `string` | Sim | Valores: BAD_REQUEST, VALIDATION_ERROR, UNAUTHORIZED, FORBIDDEN, FEATURE_DISABLED, NOT_FOUND, CONFLICT, QUOTA_EXCEEDED, UNPROCESSABLE_ENTITY, INTERNAL_ERROR, SERVICE_UNAVAILABLE. |
| `requestId` | `string` | Sim |  |
| `details` | `string` | Não | Aceita null. |
| `fieldErrors` | `array` | Não | Aceita null. |
| `fieldErrors[].field` | `string` | Não |  |
| `fieldErrors[].message` | `string` | Não |  |

```json
{
  "type": "object",
  "description": "Formato padrão de erro. `details` e `fieldErrors` são omitidos quando ausentes.",
  "properties": {
    "error": {
      "type": "string"
    },
    "code": {
      "type": "string",
      "enum": [
        "BAD_REQUEST",
        "VALIDATION_ERROR",
        "UNAUTHORIZED",
        "FORBIDDEN",
        "FEATURE_DISABLED",
        "NOT_FOUND",
        "CONFLICT",
        "QUOTA_EXCEEDED",
        "UNPROCESSABLE_ENTITY",
        "INTERNAL_ERROR",
        "SERVICE_UNAVAILABLE"
      ]
    },
    "requestId": {
      "type": "string"
    },
    "details": {
      "type": "string",
      "nullable": true
    },
    "fieldErrors": {
      "type": "array",
      "nullable": true,
      "items": {
        "type": "object",
        "properties": {
          "field": {
            "type": "string"
          },
          "message": {
            "type": "string"
          }
        }
      }
    }
  },
  "required": [
    "error",
    "code",
    "requestId"
  ]
}
```

### 401

Chave ausente, malformada, desconhecida, revogada ou expirada, ou membro emissor inativo.

| Campo | Tipo | Obrigatório no objeto | Descrição |
| --- | --- | --- | --- |
| `error` | `string` | Sim |  |
| `code` | `string` | Sim | Valores: BAD_REQUEST, VALIDATION_ERROR, UNAUTHORIZED, FORBIDDEN, FEATURE_DISABLED, NOT_FOUND, CONFLICT, QUOTA_EXCEEDED, UNPROCESSABLE_ENTITY, INTERNAL_ERROR, SERVICE_UNAVAILABLE. |
| `requestId` | `string` | Sim |  |
| `details` | `string` | Não | Aceita null. |
| `fieldErrors` | `array` | Não | Aceita null. |
| `fieldErrors[].field` | `string` | Não |  |
| `fieldErrors[].message` | `string` | Não |  |

```json
{
  "type": "object",
  "description": "Formato padrão de erro. `details` e `fieldErrors` são omitidos quando ausentes.",
  "properties": {
    "error": {
      "type": "string"
    },
    "code": {
      "type": "string",
      "enum": [
        "BAD_REQUEST",
        "VALIDATION_ERROR",
        "UNAUTHORIZED",
        "FORBIDDEN",
        "FEATURE_DISABLED",
        "NOT_FOUND",
        "CONFLICT",
        "QUOTA_EXCEEDED",
        "UNPROCESSABLE_ENTITY",
        "INTERNAL_ERROR",
        "SERVICE_UNAVAILABLE"
      ]
    },
    "requestId": {
      "type": "string"
    },
    "details": {
      "type": "string",
      "nullable": true
    },
    "fieldErrors": {
      "type": "array",
      "nullable": true,
      "items": {
        "type": "object",
        "properties": {
          "field": {
            "type": "string"
          },
          "message": {
            "type": "string"
          }
        }
      }
    }
  },
  "required": [
    "error",
    "code",
    "requestId"
  ]
}
```

### 403

Autenticado, mas sem acesso: falta de permissão (`FORBIDDEN`), recurso desligado no workspace (`FEATURE_DISABLED`) ou tentativa de acessar uma agenda não permitida.

| Campo | Tipo | Obrigatório no objeto | Descrição |
| --- | --- | --- | --- |
| `error` | `string` | Sim |  |
| `code` | `string` | Sim | Valores: BAD_REQUEST, VALIDATION_ERROR, UNAUTHORIZED, FORBIDDEN, FEATURE_DISABLED, NOT_FOUND, CONFLICT, QUOTA_EXCEEDED, UNPROCESSABLE_ENTITY, INTERNAL_ERROR, SERVICE_UNAVAILABLE. |
| `requestId` | `string` | Sim |  |
| `details` | `string` | Não | Aceita null. |
| `fieldErrors` | `array` | Não | Aceita null. |
| `fieldErrors[].field` | `string` | Não |  |
| `fieldErrors[].message` | `string` | Não |  |

```json
{
  "type": "object",
  "description": "Formato padrão de erro. `details` e `fieldErrors` são omitidos quando ausentes.",
  "properties": {
    "error": {
      "type": "string"
    },
    "code": {
      "type": "string",
      "enum": [
        "BAD_REQUEST",
        "VALIDATION_ERROR",
        "UNAUTHORIZED",
        "FORBIDDEN",
        "FEATURE_DISABLED",
        "NOT_FOUND",
        "CONFLICT",
        "QUOTA_EXCEEDED",
        "UNPROCESSABLE_ENTITY",
        "INTERNAL_ERROR",
        "SERVICE_UNAVAILABLE"
      ]
    },
    "requestId": {
      "type": "string"
    },
    "details": {
      "type": "string",
      "nullable": true
    },
    "fieldErrors": {
      "type": "array",
      "nullable": true,
      "items": {
        "type": "object",
        "properties": {
          "field": {
            "type": "string"
          },
          "message": {
            "type": "string"
          }
        }
      }
    }
  },
  "required": [
    "error",
    "code",
    "requestId"
  ]
}
```

### 404

Recurso não encontrado ou fora da visibilidade do membro.

| Campo | Tipo | Obrigatório no objeto | Descrição |
| --- | --- | --- | --- |
| `error` | `string` | Sim |  |
| `code` | `string` | Sim | Valores: BAD_REQUEST, VALIDATION_ERROR, UNAUTHORIZED, FORBIDDEN, FEATURE_DISABLED, NOT_FOUND, CONFLICT, QUOTA_EXCEEDED, UNPROCESSABLE_ENTITY, INTERNAL_ERROR, SERVICE_UNAVAILABLE. |
| `requestId` | `string` | Sim |  |
| `details` | `string` | Não | Aceita null. |
| `fieldErrors` | `array` | Não | Aceita null. |
| `fieldErrors[].field` | `string` | Não |  |
| `fieldErrors[].message` | `string` | Não |  |

```json
{
  "type": "object",
  "description": "Formato padrão de erro. `details` e `fieldErrors` são omitidos quando ausentes.",
  "properties": {
    "error": {
      "type": "string"
    },
    "code": {
      "type": "string",
      "enum": [
        "BAD_REQUEST",
        "VALIDATION_ERROR",
        "UNAUTHORIZED",
        "FORBIDDEN",
        "FEATURE_DISABLED",
        "NOT_FOUND",
        "CONFLICT",
        "QUOTA_EXCEEDED",
        "UNPROCESSABLE_ENTITY",
        "INTERNAL_ERROR",
        "SERVICE_UNAVAILABLE"
      ]
    },
    "requestId": {
      "type": "string"
    },
    "details": {
      "type": "string",
      "nullable": true
    },
    "fieldErrors": {
      "type": "array",
      "nullable": true,
      "items": {
        "type": "object",
        "properties": {
          "field": {
            "type": "string"
          },
          "message": {
            "type": "string"
          }
        }
      }
    }
  },
  "required": [
    "error",
    "code",
    "requestId"
  ]
}
```

### 422

Requisição válida que o recurso não pode atender, por exemplo, um identificador de calendário que não representa uma reunião nativa.

| Campo | Tipo | Obrigatório no objeto | Descrição |
| --- | --- | --- | --- |
| `error` | `string` | Sim |  |
| `code` | `string` | Sim | Valores: BAD_REQUEST, VALIDATION_ERROR, UNAUTHORIZED, FORBIDDEN, FEATURE_DISABLED, NOT_FOUND, CONFLICT, QUOTA_EXCEEDED, UNPROCESSABLE_ENTITY, INTERNAL_ERROR, SERVICE_UNAVAILABLE. |
| `requestId` | `string` | Sim |  |
| `details` | `string` | Não | Aceita null. |
| `fieldErrors` | `array` | Não | Aceita null. |
| `fieldErrors[].field` | `string` | Não |  |
| `fieldErrors[].message` | `string` | Não |  |

```json
{
  "type": "object",
  "description": "Formato padrão de erro. `details` e `fieldErrors` são omitidos quando ausentes.",
  "properties": {
    "error": {
      "type": "string"
    },
    "code": {
      "type": "string",
      "enum": [
        "BAD_REQUEST",
        "VALIDATION_ERROR",
        "UNAUTHORIZED",
        "FORBIDDEN",
        "FEATURE_DISABLED",
        "NOT_FOUND",
        "CONFLICT",
        "QUOTA_EXCEEDED",
        "UNPROCESSABLE_ENTITY",
        "INTERNAL_ERROR",
        "SERVICE_UNAVAILABLE"
      ]
    },
    "requestId": {
      "type": "string"
    },
    "details": {
      "type": "string",
      "nullable": true
    },
    "fieldErrors": {
      "type": "array",
      "nullable": true,
      "items": {
        "type": "object",
        "properties": {
          "field": {
            "type": "string"
          },
          "message": {
            "type": "string"
          }
        }
      }
    }
  },
  "required": [
    "error",
    "code",
    "requestId"
  ]
}
```

### 429

Limite de requisições excedido por workspace ou IP.

| Campo | Tipo | Obrigatório no objeto | Descrição |
| --- | --- | --- | --- |
| `error` | `string` | Sim |  |
| `code` | `string` | Sim | Valores: BAD_REQUEST, VALIDATION_ERROR, UNAUTHORIZED, FORBIDDEN, FEATURE_DISABLED, NOT_FOUND, CONFLICT, QUOTA_EXCEEDED, UNPROCESSABLE_ENTITY, INTERNAL_ERROR, SERVICE_UNAVAILABLE. |
| `requestId` | `string` | Sim |  |
| `details` | `string` | Não | Aceita null. |
| `fieldErrors` | `array` | Não | Aceita null. |
| `fieldErrors[].field` | `string` | Não |  |
| `fieldErrors[].message` | `string` | Não |  |

```json
{
  "type": "object",
  "description": "Formato padrão de erro. `details` e `fieldErrors` são omitidos quando ausentes.",
  "properties": {
    "error": {
      "type": "string"
    },
    "code": {
      "type": "string",
      "enum": [
        "BAD_REQUEST",
        "VALIDATION_ERROR",
        "UNAUTHORIZED",
        "FORBIDDEN",
        "FEATURE_DISABLED",
        "NOT_FOUND",
        "CONFLICT",
        "QUOTA_EXCEEDED",
        "UNPROCESSABLE_ENTITY",
        "INTERNAL_ERROR",
        "SERVICE_UNAVAILABLE"
      ]
    },
    "requestId": {
      "type": "string"
    },
    "details": {
      "type": "string",
      "nullable": true
    },
    "fieldErrors": {
      "type": "array",
      "nullable": true,
      "items": {
        "type": "object",
        "properties": {
          "field": {
            "type": "string"
          },
          "message": {
            "type": "string"
          }
        }
      }
    }
  },
  "required": [
    "error",
    "code",
    "requestId"
  ]
}
```
