{
  "openapi": "3.1.0",
  "info": {
    "title": "LYMOS CRM API",
    "version": "1.0",
    "description": "API REST do LYMOS CRM. Referência em https://crm.lymos.com.br/docs.",
    "contact": {
      "name": "LYMOS",
      "email": "contato@lymos.com.br",
      "url": "https://lymos.com.br"
    }
  },
  "servers": [
    {
      "url": "https://crm.lymos.com.br/api/v1"
    }
  ],
  "security": [
    {
      "token": []
    }
  ],
  "components": {
    "securitySchemes": {
      "token": {
        "type": "http",
        "scheme": "bearer",
        "description": "Token criado em Ajustes > Integrações > API (começa com crm_)"
      }
    },
    "responses": {
      "Erro": {
        "description": "Erro",
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "properties": {
                "error": {
                  "type": "string"
                }
              }
            }
          }
        }
      }
    }
  },
  "paths": {
    "/contacts": {
      "get": {
        "tags": [
          "Contatos"
        ],
        "summary": "Listar e buscar contatos",
        "description": "Devolve os contatos não arquivados, do mais recente para o mais antigo.",
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "required": false,
            "description": "Busca no nome, nome do WhatsApp, empresa e e-mail",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "phone",
            "in": "query",
            "required": false,
            "description": "Telefone (só os dígitos contam; acha pelo final do número)",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "tag",
            "in": "query",
            "required": false,
            "description": "Nome ou id de uma etiqueta",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Quantos devolver (padrão 50, máximo 500)",
            "schema": {
              "type": "number"
            }
          },
          {
            "name": "offset",
            "in": "query",
            "required": false,
            "description": "Pular os primeiros N (paginação)",
            "schema": {
              "type": "number"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "example": {
                  "items": [
                    {
                      "id": 128,
                      "name": "Ana Souza",
                      "display_name": "Ana Souza",
                      "phone": "5511999990000",
                      "email": "ana@exemplo.com.br",
                      "company": "Loja da Ana",
                      "role": "Sócia",
                      "city": "São Paulo",
                      "birthday": "1990-05-14",
                      "how_met": "Instagram",
                      "stage_id": 3,
                      "deal_value": 49700,
                      "cadence_days": 15,
                      "starred": false,
                      "archived": false,
                      "custom": {
                        "plano_interesse": "Profissional"
                      },
                      "tags": [
                        {
                          "id": 7,
                          "name": "Lead quente",
                          "color": "#e5484d"
                        }
                      ],
                      "last_message_at": 1791846000000,
                      "created_at": 1791800000000,
                      "updated_at": 1791846000000
                    }
                  ]
                }
              }
            }
          },
          "default": {
            "$ref": "#/components/responses/Erro"
          }
        }
      },
      "post": {
        "tags": [
          "Contatos"
        ],
        "summary": "Criar ou atualizar pelo telefone",
        "description": "Se já existe um contato com esse WhatsApp, ele é atualizado (resposta 200); senão, é criado (201) e as automações de \"Contato novo\" rodam. Mande phone com DDI e DDD. Sem phone, name é obrigatório e o contato é criado sem WhatsApp.",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "example": {
                  "id": 128,
                  "name": "Ana Souza",
                  "display_name": "Ana Souza",
                  "phone": "5511999990000",
                  "email": "ana@exemplo.com.br",
                  "company": "Loja da Ana",
                  "role": "Sócia",
                  "city": "São Paulo",
                  "birthday": "1990-05-14",
                  "how_met": "Instagram",
                  "stage_id": 3,
                  "deal_value": 49700,
                  "cadence_days": 15,
                  "starred": false,
                  "archived": false,
                  "custom": {
                    "plano_interesse": "Profissional"
                  },
                  "tags": [
                    {
                      "id": 7,
                      "name": "Lead quente",
                      "color": "#e5484d"
                    }
                  ],
                  "last_message_at": 1791846000000,
                  "created_at": 1791800000000,
                  "updated_at": 1791846000000
                }
              }
            }
          },
          "default": {
            "$ref": "#/components/responses/Erro"
          }
        },
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "phone": {
                    "type": "string",
                    "description": "WhatsApp com DDI, ex.: 5511999990000"
                  },
                  "name": {
                    "type": "string",
                    "description": "Nome"
                  },
                  "email": {
                    "type": "string",
                    "description": "E-mail"
                  },
                  "company": {
                    "type": "string",
                    "description": "Empresa"
                  },
                  "role": {
                    "type": "string",
                    "description": "Cargo"
                  },
                  "city": {
                    "type": "string",
                    "description": "Cidade"
                  },
                  "birthday": {
                    "type": "string",
                    "description": "Aniversário: AAAA-MM-DD ou --MM-DD"
                  },
                  "how_met": {
                    "type": "string",
                    "description": "Como conheceu / origem"
                  },
                  "deal_value": {
                    "type": "number",
                    "description": "Valor do negócio em centavos (49700 = R$ 497,00)"
                  },
                  "cadence_days": {
                    "type": "number",
                    "description": "Falar com ele a cada N dias"
                  },
                  "stage_id": {
                    "type": "number",
                    "description": "Etapa do funil (veja GET /stages)"
                  },
                  "tags": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Etiquetas por nome (cria se não existir) ou id"
                  },
                  "custom": {
                    "type": "object",
                    "description": "Campos personalizados: { \"campo\": \"valor\" }"
                  }
                },
                "required": []
              },
              "example": {
                "phone": "5511999990000",
                "name": "Ana Souza",
                "company": "Loja da Ana",
                "tags": [
                  "Site",
                  "Lead quente"
                ],
                "custom": {
                  "plano_interesse": "Profissional"
                }
              }
            }
          }
        }
      }
    },
    "/contacts/{id}": {
      "get": {
        "tags": [
          "Contatos"
        ],
        "summary": "Ver um contato",
        "description": "Ficha completa do contato, com etiquetas e campos personalizados.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "example": {
                  "id": 128,
                  "name": "Ana Souza",
                  "display_name": "Ana Souza",
                  "phone": "5511999990000",
                  "email": "ana@exemplo.com.br",
                  "company": "Loja da Ana",
                  "role": "Sócia",
                  "city": "São Paulo",
                  "birthday": "1990-05-14",
                  "how_met": "Instagram",
                  "stage_id": 3,
                  "deal_value": 49700,
                  "cadence_days": 15,
                  "starred": false,
                  "archived": false,
                  "custom": {
                    "plano_interesse": "Profissional"
                  },
                  "tags": [
                    {
                      "id": 7,
                      "name": "Lead quente",
                      "color": "#e5484d"
                    }
                  ],
                  "last_message_at": 1791846000000,
                  "created_at": 1791800000000,
                  "updated_at": 1791846000000
                }
              }
            }
          },
          "default": {
            "$ref": "#/components/responses/Erro"
          }
        }
      },
      "patch": {
        "tags": [
          "Contatos"
        ],
        "summary": "Atualizar um contato",
        "description": "Mude só os campos que mandar (os mesmos do POST, menos phone). Mandar \"\" apaga o campo.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "example": {
                  "id": 128,
                  "name": "Ana Souza",
                  "display_name": "Ana Souza",
                  "phone": "5511999990000",
                  "email": "ana@exemplo.com.br",
                  "company": "Loja da Ana",
                  "role": "Sócia",
                  "city": "São Paulo",
                  "birthday": "1990-05-14",
                  "how_met": "Instagram",
                  "stage_id": 3,
                  "deal_value": 49700,
                  "cadence_days": 15,
                  "starred": false,
                  "archived": false,
                  "custom": {
                    "plano_interesse": "Profissional"
                  },
                  "tags": [
                    {
                      "id": 7,
                      "name": "Lead quente",
                      "color": "#e5484d"
                    }
                  ],
                  "last_message_at": 1791846000000,
                  "created_at": 1791800000000,
                  "updated_at": 1791846000000
                }
              }
            }
          },
          "default": {
            "$ref": "#/components/responses/Erro"
          }
        }
      }
    },
    "/contacts/{id}/tags": {
      "post": {
        "tags": [
          "Etiquetas"
        ],
        "summary": "Pôr uma etiqueta",
        "description": "Por nome (cria a etiqueta se não existir) ou por id. Pode disparar automações de \"Tag adicionada\".",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "example": {
                  "id": 128,
                  "name": "Ana Souza",
                  "display_name": "Ana Souza",
                  "phone": "5511999990000",
                  "email": "ana@exemplo.com.br",
                  "company": "Loja da Ana",
                  "role": "Sócia",
                  "city": "São Paulo",
                  "birthday": "1990-05-14",
                  "how_met": "Instagram",
                  "stage_id": 3,
                  "deal_value": 49700,
                  "cadence_days": 15,
                  "starred": false,
                  "archived": false,
                  "custom": {
                    "plano_interesse": "Profissional"
                  },
                  "tags": [
                    {
                      "id": 7,
                      "name": "Lead quente",
                      "color": "#e5484d"
                    }
                  ],
                  "last_message_at": 1791846000000,
                  "created_at": 1791800000000,
                  "updated_at": 1791846000000
                }
              }
            }
          },
          "default": {
            "$ref": "#/components/responses/Erro"
          }
        },
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "description": "Nome da etiqueta"
                  },
                  "tag_id": {
                    "type": "number",
                    "description": "Ou o id de uma etiqueta existente"
                  }
                },
                "required": []
              },
              "example": {
                "name": "Cliente"
              }
            }
          }
        }
      }
    },
    "/contacts/{id}/tags/{tagId}": {
      "delete": {
        "tags": [
          "Etiquetas"
        ],
        "summary": "Tirar uma etiqueta",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "tagId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "example": {
                  "id": 128,
                  "name": "Ana Souza",
                  "display_name": "Ana Souza",
                  "phone": "5511999990000",
                  "email": "ana@exemplo.com.br",
                  "company": "Loja da Ana",
                  "role": "Sócia",
                  "city": "São Paulo",
                  "birthday": "1990-05-14",
                  "how_met": "Instagram",
                  "stage_id": 3,
                  "deal_value": 49700,
                  "cadence_days": 15,
                  "starred": false,
                  "archived": false,
                  "custom": {
                    "plano_interesse": "Profissional"
                  },
                  "tags": [
                    {
                      "id": 7,
                      "name": "Lead quente",
                      "color": "#e5484d"
                    }
                  ],
                  "last_message_at": 1791846000000,
                  "created_at": 1791800000000,
                  "updated_at": 1791846000000
                }
              }
            }
          },
          "default": {
            "$ref": "#/components/responses/Erro"
          }
        }
      }
    },
    "/tags": {
      "get": {
        "tags": [
          "Etiquetas"
        ],
        "summary": "Listar etiquetas",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "example": {
                  "items": [
                    {
                      "id": 7,
                      "name": "Lead quente",
                      "color": "#e5484d"
                    }
                  ]
                }
              }
            }
          },
          "default": {
            "$ref": "#/components/responses/Erro"
          }
        }
      }
    },
    "/stages": {
      "get": {
        "tags": [
          "Funil"
        ],
        "summary": "Listar etapas do funil",
        "description": "kind: open (em andamento), won (ganho) ou lost (perdido).",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "example": {
                  "items": [
                    {
                      "id": 3,
                      "name": "Proposta",
                      "kind": "open"
                    }
                  ]
                }
              }
            }
          },
          "default": {
            "$ref": "#/components/responses/Erro"
          }
        }
      }
    },
    "/contacts/{id}/messages": {
      "post": {
        "tags": [
          "Conversa"
        ],
        "summary": "Enviar mensagem de WhatsApp",
        "description": "Manda um texto pelo WhatsApp conectado, como se fosse você. Respeita os limites de envio da conta. No WhatsApp oficial (API da Meta), fora da janela de 24 horas só modelos aprovados são entregues: use um fluxo ou automação com modelo.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "example": {
                  "id": 5521,
                  "contact_id": 128,
                  "from_me": true,
                  "type": "text",
                  "body": "Oi, Ana! Seu pedido saiu para entrega.",
                  "sent_by": "api",
                  "status": "pending"
                }
              }
            }
          },
          "default": {
            "$ref": "#/components/responses/Erro"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "text": {
                    "type": "string",
                    "description": "Mensagem"
                  }
                },
                "required": [
                  "text"
                ]
              },
              "example": {
                "text": "Oi, Ana! Seu pedido saiu para entrega."
              }
            }
          }
        }
      },
      "get": {
        "tags": [
          "Conversa"
        ],
        "summary": "Ler as últimas mensagens",
        "description": "Da mais nova para a mais antiga. ts em milissegundos.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Quantas (padrão 50, máximo 500)",
            "schema": {
              "type": "number"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "example": {
                  "items": [
                    {
                      "id": 5520,
                      "wa_id": "3EB0…",
                      "from_me": false,
                      "type": "text",
                      "body": "Qual o prazo de entrega?",
                      "status": null,
                      "sent_by": null,
                      "ts": 1791845900000
                    }
                  ]
                }
              }
            }
          },
          "default": {
            "$ref": "#/components/responses/Erro"
          }
        }
      }
    },
    "/contacts/{id}/notes": {
      "post": {
        "tags": [
          "Conversa"
        ],
        "summary": "Anotar na ficha",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "example": {
                  "id": 902,
                  "contact_id": 128,
                  "body": "Pediu orçamento pelo site: 3 usuários.",
                  "pinned": 0
                }
              }
            }
          },
          "default": {
            "$ref": "#/components/responses/Erro"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "body": {
                    "type": "string",
                    "description": "Texto da nota"
                  }
                },
                "required": [
                  "body"
                ]
              },
              "example": {
                "body": "Pediu orçamento pelo site: 3 usuários."
              }
            }
          }
        }
      }
    },
    "/contacts/{id}/reminders": {
      "post": {
        "tags": [
          "Conversa"
        ],
        "summary": "Criar tarefa / lembrete",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "example": {
                  "id": 77,
                  "contact_id": 128,
                  "title": "Ligar para fechar",
                  "due_at": 1792515600000
                }
              }
            }
          },
          "default": {
            "$ref": "#/components/responses/Erro"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "title": {
                    "type": "string",
                    "description": "O que fazer"
                  },
                  "due_at": {
                    "type": "number",
                    "description": "Quando: milissegundos ou data ISO (2026-10-20T14:00:00-03:00)"
                  }
                },
                "required": [
                  "title",
                  "due_at"
                ]
              },
              "example": {
                "title": "Ligar para fechar",
                "due_at": "2026-10-20T14:00:00-03:00"
              }
            }
          }
        }
      }
    },
    "/contacts/{id}/flows/{flowId}": {
      "post": {
        "tags": [
          "Fluxos e automações"
        ],
        "summary": "Iniciar um fluxo de atendimento",
        "description": "O id do fluxo aparece no endereço da tela do fluxo. Responde 409 com o motivo quando o contato não pode entrar (ex.: já está nesse fluxo).",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "flowId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "example": {
                  "ok": true
                }
              }
            }
          },
          "default": {
            "$ref": "#/components/responses/Erro"
          }
        },
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "force": {
                    "type": "boolean",
                    "description": "Iniciar mesmo se ele já passou por esse fluxo"
                  }
                },
                "required": []
              },
              "example": {}
            }
          }
        }
      }
    },
    "/automations/{id}/run": {
      "post": {
        "tags": [
          "Fluxos e automações"
        ],
        "summary": "Rodar uma automação para um contato",
        "description": "Roda as ações da automação agora. O que mandar em data fica disponível nas mensagens como {{dados.campo}}. status volta ok, ou skipped com o motivo em detail (ex.: condições não atendidas).",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "example": {
                  "status": "ok",
                  "detail": "Enviou a mensagem \"Seu pedido 1043 foi confirmado\""
                }
              }
            }
          },
          "default": {
            "$ref": "#/components/responses/Erro"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "contact_id": {
                    "type": "number",
                    "description": "Contato"
                  },
                  "data": {
                    "type": "object",
                    "description": "Dados extras para as mensagens"
                  },
                  "force": {
                    "type": "boolean",
                    "description": "Ignorar condições e limite de repetição"
                  }
                },
                "required": [
                  "contact_id"
                ]
              },
              "example": {
                "contact_id": 128,
                "data": {
                  "pedido": "1043"
                }
              }
            }
          }
        }
      }
    }
  }
}