{
  "openapi": "3.0.3",
  "info": {
    "title": "API do Pingo",
    "version": "1.0.0",
    "description": "API pública do Pingo (v1): crie e consulte leads, mova de etapa no funil e puxe métricas. Disponível a partir do plano Corrente. A chave é criada em Configurações > API e vai no cabeçalho `Authorization: Bearer pgo_live_...`. Use SEMPRE a partir do seu servidor, nunca do navegador. Documentação completa: https://www.pingotracker.com.br/docs/api"
  },
  "servers": [
    {
      "url": "https://www.pingotracker.com.br/api/v1"
    }
  ],
  "security": [
    {
      "bearerAuth": []
    }
  ],
  "tags": [
    {
      "name": "Leads"
    },
    {
      "name": "Funil"
    },
    {
      "name": "Métricas"
    }
  ],
  "paths": {
    "/leads": {
      "post": {
        "operationId": "criarLead",
        "tags": [
          "Leads"
        ],
        "summary": "Criar ou atualizar um lead",
        "description": "Cria o lead e o coloca no funil. Se já existe cadastro com o mesmo telefone, atualiza em vez de duplicar.\n\nO telefone é o que identifica o lead. O Pingo reconhece o mesmo número com ou sem o 9º dígito e com ou sem o 55, então reenviar \"41 99999-0000\" e \"+55 41 9196-8668\" não cria dois cadastros.\n\nVocê NÃO envia a origem. Ela é calculada pelo Pingo a partir dos sinais de `attribution` (utm_source, utm_medium, fbclid, gclid...), com a mesma regra do resto do aplicativo. Sem nenhum sinal, o lead fica como `untracked` (Não rastreado). Sinal com formato inválido é ignorado e voltado num aviso (`warnings`), sem derrubar o lead.\n\nVale o primeiro contato: se o lead já tem uma origem registrada (qualquer uma diferente de `untracked` e `direct`, inclusive `social`, `organic` e `referral`), a chamada não muda nenhum dado de origem dele (utm, fbc, gclid...). Se a origem é `untracked` ou `direct`, o Pingo preenche a origem e só os campos de origem que ainda estão vazios, então a origem de um lead antigo pode mudar uma única vez.\n\nPara repetir o envio com segurança (formulário reenviado, webhook que chega duas vezes), mande um `external_id` único por envio. Com o mesmo `external_id`, o Pingo devolve `duplicate: true` e não grava nada de novo.\n\nO lead entra na etapa de entrada do funil padrão. Para outro funil ou etapa, informe `deal.pipeline_id` e `deal.stage_id` (veja GET /pipelines). Se o lead já tem negócio aberto nesse funil, ele NÃO é movido: para mover, use POST /leads/{id}/stage.\n\nEsta chamada só grava. Não envia mensagem ao lead e não dispara NA HORA nenhuma automação do funil. Atenção: se a etapa tem uma automação por tempo (por exemplo, follow-up para quem fica parado há alguns dias), ela passa a valer para o lead da API como vale para qualquer outro lead.\n\nA nota (`notes`) é acrescentada à ficha do lead, marcada com [API · nome da chave · data], sem apagar o que a equipe já escreveu. Tags novas são criadas na conta (até 5 por chamada).\n\nUma chave SEM `leads:read` (a de um formulário, por exemplo) recebe sempre a mesma resposta curta, `{ \"received\": true }` com status 202, seja o lead novo ou já existente: assim a chave de escrita não serve para descobrir quem já é cliente. Com `leads:read`, a resposta traz `id`, `created`, `duplicate`, `deal` e o cadastro (`lead`); `created: false` (status 200) quer dizer que o telefone já era conhecido no Pingo (cadastro ou conversa).\n\nPermissão necessária: `leads:write`.",
        "x-required-scope": "leads:write",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": false,
                "properties": {
                  "phone": {
                    "type": "string",
                    "description": "Telefone com DDD (ex.: 41999990000) ou com + e código do país (ex.: +14155550123). Pode vir com espaço, parênteses e traço; letras e ramal são recusados. Número com 10 ou 11 dígitos sem + só é aceito se for brasileiro de verdade (DDD que existe); um zero antes do DDD (041...) é tirado.",
                    "example": "41999990000"
                  },
                  "name": {
                    "type": "string",
                    "description": "Nome do lead. Em um cadastro que já existe, o nome não é sobrescrito.",
                    "example": "Maria Silva"
                  },
                  "email": {
                    "type": "string",
                    "description": "E-mail. Só preenche se o cadastro ainda não tem e-mail.",
                    "example": "maria@exemplo.com.br"
                  },
                  "notes": {
                    "type": "string",
                    "description": "Observação acrescentada à ficha do lead.",
                    "example": "Quer horário à tarde"
                  },
                  "tags": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Tags aplicadas ao lead. As que não existem são criadas.",
                    "example": "site"
                  },
                  "external_id": {
                    "type": "string",
                    "description": "Identificador DO ENVIO na sua origem (um por envio, não um valor fixo). Repetir o mesmo valor com o mesmo telefone não duplica nada; o mesmo valor com OUTRO telefone dá 409 external_id_conflict.",
                    "example": "form-2026-0001"
                  },
                  "consent": {
                    "type": "boolean",
                    "description": "Se `true`, registra o consentimento LGPD do lead. Nunca remove um consentimento já dado.",
                    "example": true
                  },
                  "attribution": {
                    "type": "object",
                    "additionalProperties": false,
                    "properties": {
                      "utm_source": {
                        "type": "string"
                      },
                      "utm_medium": {
                        "type": "string"
                      },
                      "utm_campaign": {
                        "type": "string"
                      },
                      "utm_content": {
                        "type": "string"
                      },
                      "utm_term": {
                        "type": "string"
                      },
                      "fbclid": {
                        "type": "string"
                      },
                      "fbc": {
                        "type": "string"
                      },
                      "gclid": {
                        "type": "string"
                      },
                      "gbraid": {
                        "type": "string"
                      },
                      "wbraid": {
                        "type": "string"
                      },
                      "gad_source": {
                        "type": "string"
                      },
                      "referrer": {
                        "type": "string"
                      }
                    },
                    "description": "Sinais de origem, todos texto e opcionais: utm_source, utm_medium, utm_campaign, utm_content, utm_term, fbclid, fbc (o valor do cookie _fbc do Meta, se você o tiver), gclid, gbraid, wbraid, gad_source e referrer (URL completa, com https://; só o endereço e o caminho são guardados). Os identificadores de clique (fbclid, gclid, gbraid, wbraid) têm letras, números, _ e - (8 a 500 caracteres); fora disso são ignorados com aviso."
                  },
                  "deal": {
                    "type": "object",
                    "additionalProperties": false,
                    "properties": {
                      "pipeline_id": {
                        "type": "string",
                        "description": "Funil de destino. Sem isto, vale o funil padrão."
                      },
                      "stage_id": {
                        "type": "string",
                        "description": "Etapa de destino (do mesmo funil). Não pode ser etapa de ganho."
                      },
                      "value": {
                        "type": "number",
                        "description": "Valor PREVISTO do negócio em reais, quando o negócio é criado agora (não é venda fechada). Se o funil da conta tem uma automação que envia conversão ao Meta, ela pode usar esse valor quando o negócio for movido no Pingo.",
                        "example": 1500.5
                      }
                    }
                  }
                },
                "required": [
                  "phone"
                ]
              },
              "example": {
                "name": "Maria Silva",
                "phone": "41999990000",
                "email": "maria@exemplo.com.br",
                "notes": "Quer horário à tarde",
                "tags": [
                  "site"
                ],
                "external_id": "form-2026-0001",
                "consent": true,
                "attribution": {
                  "utm_source": "google",
                  "utm_medium": "cpc",
                  "utm_campaign": "implante-curitiba",
                  "gclid": "Cj0KCQjwExemploGclid123",
                  "referrer": "https://www.google.com/"
                },
                "deal": {
                  "value": 1500.5
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "created": {
                          "type": "boolean"
                        },
                        "duplicate": {
                          "type": "boolean"
                        },
                        "deal": {
                          "type": "object",
                          "properties": {
                            "id": {
                              "type": "string"
                            },
                            "pipeline_id": {
                              "type": "string"
                            },
                            "stage_id": {
                              "type": "string"
                            },
                            "status": {
                              "type": "string"
                            },
                            "value": {
                              "type": "number"
                            },
                            "entered_stage_at": {
                              "type": "string"
                            },
                            "created_at": {
                              "type": "string"
                            }
                          }
                        },
                        "lead": {
                          "type": "object",
                          "properties": {
                            "id": {
                              "type": "string"
                            },
                            "name": {
                              "type": "string"
                            },
                            "phone": {
                              "type": "string"
                            },
                            "email": {
                              "type": "string"
                            },
                            "tags": {
                              "type": "array",
                              "items": {
                                "type": "string"
                              }
                            },
                            "origin": {
                              "type": "string"
                            },
                            "utm": {
                              "type": "object",
                              "properties": {
                                "source": {
                                  "type": "string"
                                },
                                "medium": {
                                  "type": "string"
                                },
                                "campaign": {
                                  "type": "string"
                                }
                              }
                            },
                            "deals": {
                              "type": "array",
                              "items": {
                                "type": "object",
                                "properties": {
                                  "id": {
                                    "type": "string"
                                  },
                                  "pipeline_id": {
                                    "type": "string"
                                  },
                                  "stage_id": {
                                    "type": "string"
                                  },
                                  "status": {
                                    "type": "string"
                                  },
                                  "value": {
                                    "type": "number"
                                  },
                                  "entered_stage_at": {
                                    "type": "string"
                                  },
                                  "created_at": {
                                    "type": "string"
                                  }
                                }
                              }
                            },
                            "created_at": {
                              "type": "string"
                            },
                            "updated_at": {
                              "type": "string"
                            }
                          }
                        }
                      }
                    }
                  }
                },
                "example": {
                  "data": {
                    "id": "cm1lead0000000000000000a1",
                    "created": true,
                    "duplicate": false,
                    "deal": {
                      "id": "cm1negoc0000000000000000a1",
                      "pipeline_id": "cm1funil000000000000000a1",
                      "stage_id": "cm1etapa000000000000entr1",
                      "status": "open",
                      "value": 1500.5,
                      "entered_stage_at": "2026-10-15T13:20:11.000Z",
                      "created_at": "2026-10-15T13:20:11.000Z"
                    },
                    "lead": {
                      "id": "cm1lead0000000000000000a1",
                      "name": "Maria Silva",
                      "phone": "5541999990000",
                      "email": "maria@exemplo.com.br",
                      "tags": [
                        "site",
                        "vip"
                      ],
                      "origin": "google_ads",
                      "utm": {
                        "source": "google",
                        "medium": "cpc",
                        "campaign": "implante-curitiba"
                      },
                      "deals": [
                        {
                          "id": "cm1negoc0000000000000000a1",
                          "pipeline_id": "cm1funil000000000000000a1",
                          "stage_id": "cm1etapa000000000000entr1",
                          "status": "open",
                          "value": 1500.5,
                          "entered_stage_at": "2026-10-15T13:20:11.000Z",
                          "created_at": "2026-10-15T13:20:11.000Z"
                        }
                      ],
                      "created_at": "2026-10-15T13:20:11.000Z",
                      "updated_at": "2026-10-15T13:20:11.000Z"
                    }
                  }
                }
              }
            }
          },
          "202": {
            "description": "Chave sem leads:read (só escrita): resposta uniforme",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "received": {
                          "type": "boolean"
                        }
                      }
                    }
                  }
                },
                "example": {
                  "data": {
                    "received": true
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Erro401"
          },
          "403": {
            "$ref": "#/components/responses/Erro403"
          },
          "409": {
            "description": "`ambiguous_lead`: Há mais de um cadastro com este telefone no Pingo. Resolva a duplicidade no Pingo. (Chave sem leads:read recebe a resposta curta 202 e o envio não é aplicado.)\n\n`external_id_conflict`: O external_id já foi usado em um envio de outro telefone.\n\n`pipeline_not_configured`: O funil informado não tem etapa de entrada.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "422": {
            "description": "`validation_error`: Campo inválido, campo desconhecido, telefone inválido ou funil/etapa que não existe na conta.\n\n`stage_in_other_pipeline`: A etapa informada não é do funil informado.\n\n`won_requires_closing`: A etapa é de ganho: o fechamento (valor) é registrado no Pingo, não pela API.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/Erro429"
          },
          "500": {
            "$ref": "#/components/responses/Erro500"
          }
        }
      },
      "get": {
        "operationId": "listarLeads",
        "tags": [
          "Leads"
        ],
        "summary": "Listar leads",
        "description": "Lista os leads da conta, de 100 em 100 no máximo, com filtros que não são dado pessoal.\n\nAs páginas são por `cursor`: devolva em `cursor` o `next_cursor` da resposta anterior até ele vir `null`.\n\nPara sincronizar de tempos em tempos, use `updated_since` com a hora da última sincronização menos 5 minutos de folga. A data de atualização do lead considera também a mudança de etapa dos negócios. Um lead pode aparecer mais de uma vez em sincronizações seguidas; trate pelo `id`.\n\nPara achar UM lead por telefone ou e-mail, use POST /leads/lookup (telefone e e-mail não devem ir na URL).\n\n`origin` e `utm` só aparecem se o plano da conta inclui a Origem automática.\n\nPermissão necessária: `leads:read`.",
        "x-required-scope": "leads:read",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Quantos leads por página. Padrão 50.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 50,
              "description": "Quantos leads por página. Padrão 50.",
              "example": 50
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "description": "O `next_cursor` da página anterior.",
            "schema": {
              "type": "string",
              "description": "O `next_cursor` da página anterior."
            }
          },
          {
            "name": "pipeline_id",
            "in": "query",
            "required": false,
            "description": "Só leads com negócio neste funil.",
            "schema": {
              "type": "string",
              "description": "Só leads com negócio neste funil."
            }
          },
          {
            "name": "stage_id",
            "in": "query",
            "required": false,
            "description": "Só leads com negócio nesta etapa.",
            "schema": {
              "type": "string",
              "description": "Só leads com negócio nesta etapa."
            }
          },
          {
            "name": "tag",
            "in": "query",
            "required": false,
            "description": "Só leads com esta tag (sem diferenciar maiúscula).",
            "schema": {
              "type": "string",
              "description": "Só leads com esta tag (sem diferenciar maiúscula)."
            }
          },
          {
            "name": "updated_since",
            "in": "query",
            "required": false,
            "description": "Só leads atualizados a partir deste momento.",
            "schema": {
              "type": "string",
              "format": "date-time",
              "description": "Só leads atualizados a partir deste momento.",
              "example": "2026-10-15T00:00:00Z"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string"
                          },
                          "name": {
                            "type": "string"
                          },
                          "phone": {
                            "type": "string"
                          },
                          "email": {
                            "type": "string"
                          },
                          "tags": {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          },
                          "origin": {
                            "type": "string"
                          },
                          "utm": {
                            "type": "object",
                            "properties": {
                              "source": {
                                "type": "string"
                              },
                              "medium": {
                                "type": "string"
                              },
                              "campaign": {
                                "type": "string"
                              }
                            }
                          },
                          "deals": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "properties": {
                                "id": {
                                  "type": "string"
                                },
                                "pipeline_id": {
                                  "type": "string"
                                },
                                "stage_id": {
                                  "type": "string"
                                },
                                "status": {
                                  "type": "string"
                                },
                                "value": {
                                  "type": "number"
                                },
                                "entered_stage_at": {
                                  "type": "string"
                                },
                                "created_at": {
                                  "type": "string"
                                }
                              }
                            }
                          },
                          "created_at": {
                            "type": "string"
                          },
                          "updated_at": {
                            "type": "string"
                          }
                        }
                      }
                    },
                    "next_cursor": {
                      "nullable": true
                    }
                  }
                },
                "example": {
                  "data": [
                    {
                      "id": "cm1lead0000000000000000a1",
                      "name": "Maria Silva",
                      "phone": "5541999990000",
                      "email": "maria@exemplo.com.br",
                      "tags": [
                        "site",
                        "vip"
                      ],
                      "origin": "google_ads",
                      "utm": {
                        "source": "google",
                        "medium": "cpc",
                        "campaign": "implante-curitiba"
                      },
                      "deals": [
                        {
                          "id": "cm1negoc0000000000000000a1",
                          "pipeline_id": "cm1funil000000000000000a1",
                          "stage_id": "cm1etapa000000000000entr1",
                          "status": "open",
                          "value": 1500.5,
                          "entered_stage_at": "2026-10-15T13:20:11.000Z",
                          "created_at": "2026-10-15T13:20:11.000Z"
                        }
                      ],
                      "created_at": "2026-10-15T13:20:11.000Z",
                      "updated_at": "2026-10-15T13:20:11.000Z"
                    }
                  ],
                  "next_cursor": null
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Erro401"
          },
          "403": {
            "$ref": "#/components/responses/Erro403"
          },
          "422": {
            "description": "`validation_error`: Parâmetro inválido ou desconhecido (ex.: limit acima de 100).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/Erro429"
          },
          "500": {
            "$ref": "#/components/responses/Erro500"
          }
        }
      }
    },
    "/leads/lookup": {
      "post": {
        "operationId": "buscarLead",
        "tags": [
          "Leads"
        ],
        "summary": "Achar um lead por telefone ou e-mail",
        "description": "Devolve o lead que tem aquele telefone (ou e-mail). É POST de propósito: dado pessoal não deve ir na URL.\n\nInforme exatamente um entre `phone` e `email`.\n\nO telefone é comparado com e sem o 9º dígito e com e sem o 55. O e-mail não diferencia maiúscula. Número de outro país vai com o + na frente (ex.: +14155550123), mesmo que a resposta o traga só com dígitos: sem o +, 10 ou 11 dígitos só valem se forem brasileiros.\n\nSe houver mais de um cadastro com o mesmo contato, a resposta é 409 (`ambiguous_lead`): a API não adivinha qual é o certo.\n\nPermissão necessária: `leads:read`.",
        "x-required-scope": "leads:read",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": false,
                "properties": {
                  "phone": {
                    "type": "string",
                    "description": "Telefone a procurar.",
                    "example": "41999990000"
                  },
                  "email": {
                    "type": "string",
                    "description": "E-mail a procurar (use este OU o telefone)."
                  }
                }
              },
              "example": {
                "phone": "41999990000"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "name": {
                          "type": "string"
                        },
                        "phone": {
                          "type": "string"
                        },
                        "email": {
                          "type": "string"
                        },
                        "tags": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        },
                        "origin": {
                          "type": "string"
                        },
                        "utm": {
                          "type": "object",
                          "properties": {
                            "source": {
                              "type": "string"
                            },
                            "medium": {
                              "type": "string"
                            },
                            "campaign": {
                              "type": "string"
                            }
                          }
                        },
                        "deals": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string"
                              },
                              "pipeline_id": {
                                "type": "string"
                              },
                              "stage_id": {
                                "type": "string"
                              },
                              "status": {
                                "type": "string"
                              },
                              "value": {
                                "type": "number"
                              },
                              "entered_stage_at": {
                                "type": "string"
                              },
                              "created_at": {
                                "type": "string"
                              }
                            }
                          }
                        },
                        "created_at": {
                          "type": "string"
                        },
                        "updated_at": {
                          "type": "string"
                        }
                      }
                    }
                  }
                },
                "example": {
                  "data": {
                    "id": "cm1lead0000000000000000a1",
                    "name": "Maria Silva",
                    "phone": "5541999990000",
                    "email": "maria@exemplo.com.br",
                    "tags": [
                      "site",
                      "vip"
                    ],
                    "origin": "google_ads",
                    "utm": {
                      "source": "google",
                      "medium": "cpc",
                      "campaign": "implante-curitiba"
                    },
                    "deals": [
                      {
                        "id": "cm1negoc0000000000000000a1",
                        "pipeline_id": "cm1funil000000000000000a1",
                        "stage_id": "cm1etapa000000000000entr1",
                        "status": "open",
                        "value": 1500.5,
                        "entered_stage_at": "2026-10-15T13:20:11.000Z",
                        "created_at": "2026-10-15T13:20:11.000Z"
                      }
                    ],
                    "created_at": "2026-10-15T13:20:11.000Z",
                    "updated_at": "2026-10-15T13:20:11.000Z"
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Erro401"
          },
          "403": {
            "$ref": "#/components/responses/Erro403"
          },
          "404": {
            "description": "`not_found`: Nenhum lead com esse contato.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "409": {
            "description": "`ambiguous_lead`: Mais de um cadastro com esse contato.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "422": {
            "description": "`validation_error`: Telefone inválido, ou os dois (ou nenhum) informados.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/Erro429"
          },
          "500": {
            "$ref": "#/components/responses/Erro500"
          }
        }
      }
    },
    "/leads/{id}": {
      "get": {
        "operationId": "obterLead",
        "tags": [
          "Leads"
        ],
        "summary": "Consultar um lead",
        "description": "Devolve o lead pelo id, com tags, origem e negócios.\n\nUm id que não existe na sua conta e um id de outra conta dão exatamente a mesma resposta: 404.\n\nPermissão necessária: `leads:read`.",
        "x-required-scope": "leads:read",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "O `id` do lead.",
            "schema": {
              "type": "string",
              "description": "O `id` do lead.",
              "example": "cm1lead0000000000000000a1"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "name": {
                          "type": "string"
                        },
                        "phone": {
                          "type": "string"
                        },
                        "email": {
                          "type": "string"
                        },
                        "tags": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        },
                        "origin": {
                          "type": "string"
                        },
                        "utm": {
                          "type": "object",
                          "properties": {
                            "source": {
                              "type": "string"
                            },
                            "medium": {
                              "type": "string"
                            },
                            "campaign": {
                              "type": "string"
                            }
                          }
                        },
                        "deals": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string"
                              },
                              "pipeline_id": {
                                "type": "string"
                              },
                              "stage_id": {
                                "type": "string"
                              },
                              "status": {
                                "type": "string"
                              },
                              "value": {
                                "type": "number"
                              },
                              "entered_stage_at": {
                                "type": "string"
                              },
                              "created_at": {
                                "type": "string"
                              }
                            }
                          }
                        },
                        "created_at": {
                          "type": "string"
                        },
                        "updated_at": {
                          "type": "string"
                        }
                      }
                    }
                  }
                },
                "example": {
                  "data": {
                    "id": "cm1lead0000000000000000a1",
                    "name": "Maria Silva",
                    "phone": "5541999990000",
                    "email": "maria@exemplo.com.br",
                    "tags": [
                      "site",
                      "vip"
                    ],
                    "origin": "google_ads",
                    "utm": {
                      "source": "google",
                      "medium": "cpc",
                      "campaign": "implante-curitiba"
                    },
                    "deals": [
                      {
                        "id": "cm1negoc0000000000000000a1",
                        "pipeline_id": "cm1funil000000000000000a1",
                        "stage_id": "cm1etapa000000000000entr1",
                        "status": "open",
                        "value": 1500.5,
                        "entered_stage_at": "2026-10-15T13:20:11.000Z",
                        "created_at": "2026-10-15T13:20:11.000Z"
                      }
                    ],
                    "created_at": "2026-10-15T13:20:11.000Z",
                    "updated_at": "2026-10-15T13:20:11.000Z"
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Erro401"
          },
          "403": {
            "$ref": "#/components/responses/Erro403"
          },
          "404": {
            "description": "`not_found`: Lead não encontrado na conta.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/Erro429"
          },
          "500": {
            "$ref": "#/components/responses/Erro500"
          }
        }
      },
      "patch": {
        "operationId": "atualizarLead",
        "tags": [
          "Leads"
        ],
        "summary": "Atualizar um lead",
        "description": "Muda nome, e-mail, tags e acrescenta uma nota. O telefone não muda por aqui.\n\nEnvie só o que quer mudar, ao menos um campo.\n\n`email: null` apaga o e-mail. `add_tags` cria as tags que não existem; `remove_tags` ignora as que não existem. O telefone não pode ser alterado (ele liga o cadastro à conversa do WhatsApp).\n\nA mudança vale só no Pingo: o cadastro do seu sistema de gestão (Feegow, Clinicorp, Conta Azul...) não é alterado, então os dois podem ficar diferentes.\n\nA nota é acrescentada à ficha, nunca substitui. Se a ficha não comporta mais texto (limite de 2.000 caracteres), a resposta é 409 `notes_full` e NADA é alterado.\n\nPermissão necessária: `leads:write`.",
        "x-required-scope": "leads:write",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "O `id` do lead.",
            "schema": {
              "type": "string",
              "description": "O `id` do lead.",
              "example": "cm1lead0000000000000000a1"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": false,
                "properties": {
                  "name": {
                    "type": "string",
                    "description": "Novo nome.",
                    "example": "Maria Silva"
                  },
                  "email": {
                    "type": "string",
                    "nullable": true,
                    "description": "Novo e-mail, ou `null` para apagar."
                  },
                  "add_tags": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Tags a acrescentar."
                  },
                  "remove_tags": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "Tags a retirar."
                  },
                  "notes": {
                    "type": "string",
                    "description": "Nota acrescentada à ficha."
                  }
                }
              },
              "example": {
                "name": "Maria Silva",
                "add_tags": [
                  "retorno"
                ],
                "remove_tags": [
                  "site"
                ],
                "notes": "Ligar na quinta"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "updated": {
                          "type": "boolean"
                        },
                        "lead": {
                          "type": "object",
                          "properties": {
                            "id": {
                              "type": "string"
                            },
                            "name": {
                              "type": "string"
                            },
                            "phone": {
                              "type": "string"
                            },
                            "email": {
                              "type": "string"
                            },
                            "tags": {
                              "type": "array",
                              "items": {
                                "type": "string"
                              }
                            },
                            "origin": {
                              "type": "string"
                            },
                            "utm": {
                              "type": "object",
                              "properties": {
                                "source": {
                                  "type": "string"
                                },
                                "medium": {
                                  "type": "string"
                                },
                                "campaign": {
                                  "type": "string"
                                }
                              }
                            },
                            "deals": {
                              "type": "array",
                              "items": {
                                "type": "object",
                                "properties": {
                                  "id": {
                                    "type": "string"
                                  },
                                  "pipeline_id": {
                                    "type": "string"
                                  },
                                  "stage_id": {
                                    "type": "string"
                                  },
                                  "status": {
                                    "type": "string"
                                  },
                                  "value": {
                                    "type": "number"
                                  },
                                  "entered_stage_at": {
                                    "type": "string"
                                  },
                                  "created_at": {
                                    "type": "string"
                                  }
                                }
                              }
                            },
                            "created_at": {
                              "type": "string"
                            },
                            "updated_at": {
                              "type": "string"
                            }
                          }
                        }
                      }
                    }
                  }
                },
                "example": {
                  "data": {
                    "id": "cm1lead0000000000000000a1",
                    "updated": true,
                    "lead": {
                      "id": "cm1lead0000000000000000a1",
                      "name": "Maria Silva",
                      "phone": "5541999990000",
                      "email": "maria@exemplo.com.br",
                      "tags": [
                        "site",
                        "vip"
                      ],
                      "origin": "google_ads",
                      "utm": {
                        "source": "google",
                        "medium": "cpc",
                        "campaign": "implante-curitiba"
                      },
                      "deals": [
                        {
                          "id": "cm1negoc0000000000000000a1",
                          "pipeline_id": "cm1funil000000000000000a1",
                          "stage_id": "cm1etapa000000000000entr1",
                          "status": "open",
                          "value": 1500.5,
                          "entered_stage_at": "2026-10-15T13:20:11.000Z",
                          "created_at": "2026-10-15T13:20:11.000Z"
                        }
                      ],
                      "created_at": "2026-10-15T13:20:11.000Z",
                      "updated_at": "2026-10-15T13:20:11.000Z"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Erro401"
          },
          "403": {
            "$ref": "#/components/responses/Erro403"
          },
          "404": {
            "description": "`not_found`: Lead não encontrado na conta.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "409": {
            "description": "`notes_full`: A ficha do lead está cheia. Nada foi alterado.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "422": {
            "description": "`validation_error`: Campo inválido ou desconhecido (inclusive `phone`), ou corpo vazio.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/Erro429"
          },
          "500": {
            "$ref": "#/components/responses/Erro500"
          }
        }
      }
    },
    "/leads/{id}/stage": {
      "post": {
        "operationId": "moverEtapa",
        "tags": [
          "Funil"
        ],
        "summary": "Mover o lead de etapa",
        "description": "Move o negócio aberto do lead para outra etapa do mesmo funil.\n\nMover pela API NÃO dispara a automação da etapa: não manda mensagem ao lead e não envia conversão ao Meta. É o mesmo que mover em massa no Pingo sem marcar \"disparar a automação\". Automações por tempo da etapa nova (\"parado há N dias\") continuam valendo.\n\nA API não entra em etapa de ganho (fechar exige registrar o valor no Pingo) e não tira o negócio de uma etapa de ganho (não desfaz venda). Mover para uma etapa de perda e reabrir (sair da perda) funcionam.\n\nSe o lead tem mais de um negócio aberto no funil da etapa, informe `deal_id`. Mover para a etapa em que o negócio já está devolve `changed: false`.\n\nPermissão necessária: `pipeline:write`.",
        "x-required-scope": "pipeline:write",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "O `id` do lead.",
            "schema": {
              "type": "string",
              "description": "O `id` do lead.",
              "example": "cm1lead0000000000000000a1"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": false,
                "properties": {
                  "stage_id": {
                    "type": "string",
                    "description": "Etapa de destino (veja GET /pipelines).",
                    "example": "cm1etapa00000000000000pre1"
                  },
                  "deal_id": {
                    "type": "string",
                    "description": "Negócio a mover, quando o lead tem mais de um aberto no funil."
                  }
                },
                "required": [
                  "stage_id"
                ]
              },
              "example": {
                "stage_id": "cm1etapa00000000000000pre1"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "changed": {
                          "type": "boolean"
                        },
                        "deal": {
                          "type": "object",
                          "properties": {
                            "id": {
                              "type": "string"
                            },
                            "pipeline_id": {
                              "type": "string"
                            },
                            "stage_id": {
                              "type": "string"
                            },
                            "status": {
                              "type": "string"
                            },
                            "value": {
                              "type": "number"
                            },
                            "entered_stage_at": {
                              "type": "string"
                            },
                            "created_at": {
                              "type": "string"
                            }
                          }
                        }
                      }
                    }
                  }
                },
                "example": {
                  "data": {
                    "changed": true,
                    "deal": {
                      "id": "cm1negoc0000000000000000a1",
                      "pipeline_id": "cm1funil000000000000000a1",
                      "stage_id": "cm1etapa00000000000000pre1",
                      "status": "open",
                      "value": 1500.5,
                      "entered_stage_at": "2026-10-15T14:02:40.000Z",
                      "created_at": "2026-10-15T13:20:11.000Z"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Erro401"
          },
          "403": {
            "$ref": "#/components/responses/Erro403"
          },
          "404": {
            "description": "`not_found`: Lead, etapa ou negócio não encontrado na conta, ou o lead não tem negócio aberto nesse funil.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "409": {
            "description": "`ambiguous_deal`: Mais de um negócio aberto no funil da etapa. Informe `deal_id`.\n\n`stage_in_other_pipeline`: A etapa é de outro funil que o do negócio.\n\n`won_requires_closing`: A etapa é de ganho.\n\n`deal_already_won`: O negócio já está numa etapa de ganho.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/Erro429"
          },
          "500": {
            "$ref": "#/components/responses/Erro500"
          }
        }
      }
    },
    "/pipelines": {
      "get": {
        "operationId": "listarFunis",
        "tags": [
          "Funil"
        ],
        "summary": "Listar funis e etapas",
        "description": "Os funis da conta com suas etapas: são os ids que POST /leads e POST /leads/{id}/stage pedem.\n\nO funil padrão vem primeiro. `is_entry` marca a etapa onde o lead novo nasce; `is_won` e `is_lost` marcam as etapas de ganho e de perda.\n\nPermissão necessária: `pipeline:read`.",
        "x-required-scope": "pipeline:read",
        "responses": {
          "200": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string"
                          },
                          "name": {
                            "type": "string"
                          },
                          "is_default": {
                            "type": "boolean"
                          },
                          "stages": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "properties": {
                                "id": {
                                  "type": "string"
                                },
                                "name": {
                                  "type": "string"
                                },
                                "order": {
                                  "type": "integer"
                                },
                                "is_entry": {
                                  "type": "boolean"
                                },
                                "is_won": {
                                  "type": "boolean"
                                },
                                "is_lost": {
                                  "type": "boolean"
                                }
                              }
                            }
                          }
                        }
                      }
                    }
                  }
                },
                "example": {
                  "data": [
                    {
                      "id": "cm1funil000000000000000a1",
                      "name": "Comercial",
                      "is_default": true,
                      "stages": [
                        {
                          "id": "cm1etapa000000000000entr1",
                          "name": "Leads de Entrada",
                          "order": 0,
                          "is_entry": true,
                          "is_won": false,
                          "is_lost": false
                        },
                        {
                          "id": "cm1etapa00000000000000pre1",
                          "name": "Pré Vendas",
                          "order": 1,
                          "is_entry": false,
                          "is_won": false,
                          "is_lost": false
                        },
                        {
                          "id": "cm1etapa000000000000fech1",
                          "name": "Fechado",
                          "order": 5,
                          "is_entry": false,
                          "is_won": true,
                          "is_lost": false
                        },
                        {
                          "id": "cm1etapa000000000000perd1",
                          "name": "Perdido (sem contato)",
                          "order": 6,
                          "is_entry": false,
                          "is_won": false,
                          "is_lost": true
                        }
                      ]
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Erro401"
          },
          "403": {
            "$ref": "#/components/responses/Erro403"
          },
          "429": {
            "$ref": "#/components/responses/Erro429"
          },
          "500": {
            "$ref": "#/components/responses/Erro500"
          }
        }
      }
    },
    "/metrics": {
      "get": {
        "operationId": "metricas",
        "tags": [
          "Métricas"
        ],
        "summary": "Métricas do período",
        "description": "Números agregados da conta (leads por dia e por origem, negócios por etapa). Nenhum dado de pessoa.\n\nO período vai de `from` a `to`, os dois inclusive, em dias de Brasília (padrão: os últimos 30 dias; no máximo 366 dias).\n\n`leads` conta as conversas criadas no período, de qualquer canal (WhatsApp, formulários, API). Dias sem lead não aparecem em `daily`. `scheduled` conta os leads do período que estão AGORA numa etapa de agendamento: quem já avançou para outra etapa deixa de contar. `closed` conta os que estão numa etapa de venda ou numa etapa com valor configurado (uma etapa \"Agendou R$ 450\" conta). Os dois são `null` se a conta não configurou a etapa. `attended` são as consultas com comparecimento na agenda do período.\n\n`pipeline.stages[].open_deals` é o retrato de HOJE (negócios abertos por etapa), não depende do período.\n\n`by_origin` só aparece se o plano da conta inclui a Origem automática. Receita não faz parte desta versão.\n\nEsta rota é mais pesada: limite de 20 chamadas por minuto por chave.\n\nPermissão necessária: `metrics:read`.",
        "x-required-scope": "metrics:read",
        "parameters": [
          {
            "name": "from",
            "in": "query",
            "required": false,
            "description": "Primeiro dia do período.",
            "schema": {
              "type": "string",
              "format": "date",
              "description": "Primeiro dia do período.",
              "example": "2026-10-01"
            }
          },
          {
            "name": "to",
            "in": "query",
            "required": false,
            "description": "Último dia do período (inclusive).",
            "schema": {
              "type": "string",
              "format": "date",
              "description": "Último dia do período (inclusive).",
              "example": "2026-10-15"
            }
          },
          {
            "name": "pipeline_id",
            "in": "query",
            "required": false,
            "description": "Funil para o retrato de negócios por etapa. Padrão: o funil padrão.",
            "schema": {
              "type": "string",
              "description": "Funil para o retrato de negócios por etapa. Padrão: o funil padrão."
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Sucesso",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "object",
                      "properties": {
                        "period": {
                          "type": "object",
                          "properties": {
                            "from": {
                              "type": "string"
                            },
                            "to": {
                              "type": "string"
                            }
                          }
                        },
                        "leads": {
                          "type": "integer"
                        },
                        "scheduled": {
                          "type": "integer"
                        },
                        "closed": {
                          "type": "integer"
                        },
                        "attended": {
                          "type": "integer"
                        },
                        "daily": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "date": {
                                "type": "string"
                              },
                              "leads": {
                                "type": "integer"
                              }
                            }
                          }
                        },
                        "by_origin": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "origin": {
                                "type": "string"
                              },
                              "leads": {
                                "type": "integer"
                              }
                            }
                          }
                        },
                        "pipeline": {
                          "type": "object",
                          "properties": {
                            "id": {
                              "type": "string"
                            },
                            "name": {
                              "type": "string"
                            },
                            "stages": {
                              "type": "array",
                              "items": {
                                "type": "object",
                                "properties": {
                                  "id": {
                                    "type": "string"
                                  },
                                  "name": {
                                    "type": "string"
                                  },
                                  "open_deals": {
                                    "type": "integer"
                                  }
                                }
                              }
                            }
                          }
                        }
                      }
                    }
                  }
                },
                "example": {
                  "data": {
                    "period": {
                      "from": "2026-10-01",
                      "to": "2026-10-15"
                    },
                    "leads": 128,
                    "scheduled": 31,
                    "closed": 9,
                    "attended": 24,
                    "daily": [
                      {
                        "date": "2026-10-14",
                        "leads": 9
                      },
                      {
                        "date": "2026-10-15",
                        "leads": 12
                      }
                    ],
                    "by_origin": [
                      {
                        "origin": "google_ads",
                        "leads": 60
                      },
                      {
                        "origin": "meta_ads",
                        "leads": 48
                      },
                      {
                        "origin": "direct",
                        "leads": 20
                      }
                    ],
                    "pipeline": {
                      "id": "cm1funil000000000000000a1",
                      "name": "Comercial",
                      "stages": [
                        {
                          "id": "cm1etapa000000000000entr1",
                          "name": "Leads de Entrada",
                          "open_deals": 14
                        },
                        {
                          "id": "cm1etapa00000000000000pre1",
                          "name": "Pré Vendas",
                          "open_deals": 22
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Erro401"
          },
          "403": {
            "$ref": "#/components/responses/Erro403"
          },
          "404": {
            "description": "`not_found`: pipeline_id não existe na conta.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "422": {
            "description": "`validation_error`: Data inválida, período invertido ou maior que 366 dias.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Erro"
                }
              }
            }
          },
          "429": {
            "$ref": "#/components/responses/Erro429"
          },
          "500": {
            "$ref": "#/components/responses/Erro500"
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "description": "Chave da API (pgo_live_...), criada em Configurações > API."
      }
    },
    "schemas": {
      "Erro": {
        "type": "object",
        "properties": {
          "error": {
            "type": "object",
            "properties": {
              "code": {
                "type": "string",
                "enum": [
                  "invalid_api_key",
                  "api_not_enabled",
                  "plan_inactive",
                  "comercial_not_enabled",
                  "insufficient_scope",
                  "invalid_json",
                  "payload_too_large",
                  "validation_error",
                  "not_found",
                  "ambiguous_lead",
                  "external_id_conflict",
                  "ambiguous_deal",
                  "pipeline_not_configured",
                  "stage_in_other_pipeline",
                  "won_requires_closing",
                  "deal_already_won",
                  "notes_full",
                  "rate_limited",
                  "internal_error"
                ],
                "description": "Código estável para o seu sistema tratar."
              },
              "message": {
                "type": "string",
                "description": "Explicação em português."
              },
              "request_id": {
                "type": "string",
                "description": "Identificador da chamada (também no cabeçalho X-Request-Id). Informe ao suporte."
              },
              "details": {
                "type": "object",
                "description": "Em validation_error, `fields` lista campo e motivo."
              }
            },
            "required": [
              "code",
              "message",
              "request_id"
            ]
          }
        }
      }
    },
    "responses": {
      "Erro401": {
        "description": "`invalid_api_key`: chave ausente, mal formada, desconhecida ou revogada.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Erro"
            }
          }
        }
      },
      "Erro403": {
        "description": "`api_not_enabled`, `plan_inactive`, `comercial_not_enabled` ou `insufficient_scope`.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Erro"
            }
          }
        }
      },
      "Erro429": {
        "description": "`rate_limited`: muitas requisições. Espere o tempo do cabeçalho Retry-After.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Erro"
            }
          }
        },
        "headers": {
          "Retry-After": {
            "schema": {
              "type": "integer"
            },
            "description": "Segundos até poder tentar de novo."
          }
        }
      },
      "Erro500": {
        "description": "`internal_error`: erro do nosso lado. Informe o request_id ao suporte.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Erro"
            }
          }
        }
      }
    }
  }
}
