# Customers People: guia de implementação (LLM-Ready) > O People é o produto da linha Customers (https://mycustomers.click) aberto ao público: a ficha de > cada pessoa, do primeiro toque ao pagamento. Eventos de qualquer sistema chegam por webhook > assinado (Standard Webhooks com o prefixo `x-ccm`) ou por importação CSV; o estágio (lead, > prospect, customer) é derivado desses eventos; agentes propõem o próximo passo, que só sai > depois de uma checagem sem IA e, quando é falar com a pessoa, da aprovação de quem assina. > **Modelo mental em uma frase:** uma *fonte* entrega *eventos* assinados; cada evento cai na > *ficha* da *pessoa* cuja *identidade* é igual; o *estágio* é recalculado a partir dos eventos; > tudo o que alguém quer fazer com a pessoa vira uma *ação* numa fila única, conferida por regras > puras antes de existir. > **Atenção: leia a seção 13 antes de prometer qualquer coisa ao usuário.** O People NÃO envia > mensagem por conta própria a quem nunca escreveu, NÃO faz oferta de preço por agente, NÃO tem > conector pronto para ferramenta nenhuma, NÃO tem chave de API e NÃO funde fichas sozinho. **Base da API:** `https://people.worker.mycustomers.click` **Painel:** `https://people.dashboard.mycustomers.click` (login por código enviado ao e-mail) **Servidor MCP:** `POST https://people.worker.mycustomers.click/mcp` (Streamable HTTP, OAuth 2.1) **Runtime:** Cloudflare Workers + D1. Roda sobre o Infrastructure (https://myinfrastructure.click), como qualquer aplicação de cliente. **Última atualização:** 2026-10-07 --- ## 0. O que só uma pessoa faz (diga ao usuário antes de começar) Você, agente, não consegue fazer estes passos. Peça-os ao usuário na hora certa e espere: 1. **Entrar no painel** com o código que chega no e-mail dele. Não há cadastro separado: a conta nasce no primeiro código verificado. 2. **Criar uma fonte** em Dados › Fontes (nome e base legal). O endereço `POST /events/:id` e o segredo `whsec_…` aparecem nessa hora; **o segredo aparece uma única vez**. Peça que ele guarde e te passe os dois como variáveis de ambiente. 3. **Importar um CSV**, numa fonte do tipo importação, pelo painel. 4. **Salvar o Manual e as estratégias**, e escolher o que conta como ativação. 5. **Aprovar as ações** que falam com uma pessoa (Centro de Comando e topo da ficha). 6. **Autorizar o MCP**: na primeira chamada o navegador abre e ele entra com o código do e-mail. O que você faz: escrever o código que assina e envia os eventos, preparar o CSV, ler a base pelo MCP, propor ações e notas, e redigir o Manual e as estratégias para o usuário colar. ## 1. Estrutura (os objetos) - **Conta** — uma base por conta, sem workspace e sem seletor de contexto. A conta é o `sub` do token do Auth. "Não existe" responde igual a "não é seu". - **Pessoa** — a ficha. Tem estágio (`lead`, `prospect`, `customer`), empresa, identidades, a linha do tempo (eventos e ações) com notas, o perfil completo e o próximo passo (com "Feito" e "Trocar"). - **Identidade** — e-mail, telefone, `authId` (o id da pessoa no seu sistema) e outros ids de plataforma, cada um com uma força: forte (e-mail ou telefone marcados como verificados pela fonte, `authId`), média (o resto). - **Empresa** — derivada do `company.domain` informado pela fonte ou do domínio do e-mail corporativo. E-mail de provedor gratuito nunca vira empresa. - **Fonte** — `webhook` ou `import`. Tem nome, base legal (`contract`, `legitimate_interest`, `consent`), segredo e traduções. - **Evento** — `{ id, type, channel, at, person, company, properties }`, imutável. - **Ação** — o que um agente, uma estratégia, um agente pelo MCP ou a pessoa que assina quer fazer com uma pessoa: `note`, `tag`, `stage`, `merge` (internas) e `reply`, `email`, `offer` (mensagens). Tem o evento esperado (`expects`) e o prazo. Aprovação, saída e resultado são estados dela. - **Agentes** — três, um por estágio: Recepção (dona de lead), Acompanhamento (prospect) e Ativação (customer). Rodam com o modelo da plataforma (a conta não cadastra chave) e só propõem. - **Manual** — sete seções versionadas que os agentes leem antes de propor: quem é o cliente, estágios, próximo passo, tom, o que o produto faz, o que nunca prometer, quando passar para mim. - **Respostas salvas** — reconferidas pela checagem a cada versão nova do Manual. - **Estratégia** — passos com espera, evento esperado e parada, para um público filtrado. - **Funil** — Ativação, Expansão e Retenção como modelos, mais os da conta, calculados dos eventos. - **Destino** — um endereço da conta que recebe mensagens aprovadas por webhook assinado. ## 2. Autenticação | Quem chama | Com o quê | Onde | | --- | --- | --- | | Uma pessoa, pelo painel ou por uma chamada sua em nome dela | JWT do Auth (`Authorization: Bearer`) | toda a API, exceto `/events/:id` | | Um agente pelo MCP | token OAuth 2.1 emitido pelo Auth com audiência `https://people.worker.mycustomers.click/mcp` | `POST /mcp` | | Uma fonte | nenhum login: a prova é a assinatura `x-ccm-signature` | `POST /events/:id` | - **Não existe chave de API**, nem de leitura. A leitura é pelo painel e pelo MCP. - Servidor de autorização: `https://auth.worker.myinfrastructure.click` (`/.well-known/oauth-authorization-server`). Metadados do recurso (RFC 9728): `https://people.worker.mycustomers.click/.well-known/oauth-protected-resource`. - Escopos: `auth:read` (leitura) e `auth:write` (propor). O token é validado por audiência (RFC 8707): um token emitido para outro servidor MCP é recusado aqui. ## 3. Entrada de eventos (o protocolo) Toda fonte fala um protocolo só: **Standard Webhooks com o prefixo `x-ccm`**. ``` POST https://people.worker.mycustomers.click/events/ x-ccm-id: x-ccm-timestamp: x-ccm-signature: v1, { "type": "aula.concluida", "timestamp": "2026-10-07T12:00:00Z", "data": { "person": { "email": "ana@escola.exemplo", "name": "Ana Souza" }, "company": { "domain": "escola.exemplo" }, "channel": "web", "properties": { "aula": "Primeira aula" } } } ``` - A chave do HMAC é o segredo **depois** de `whsec_`, decodificado de base64 (o mesmo das bibliotecas de Standard Webhooks). Durante uma troca de segredo, várias assinaturas podem vir separadas por espaço. - `data.person` aceita `email`, `emailVerified`, `name`, `phone`, `phoneVerified`, `authId` e outros ids de plataforma. Sem `data.person`, esses campos são lidos do topo de `data` (`userId` vale como `authId`). `data.properties` é o resto; sem ele, o que sobrar de `data`. - `type` em minúsculas, separado por ponto (`account.created`). O tipo é o vocabulário de quem envia; ver seção 6. - Limite de **256 KB** por entrega. `at`/`timestamp` no futuro além de 5 minutos é recusado. - Trocar o segredo (`POST /sources/:id/rotate`) mantém o anterior válido por **24 horas**. - Resposta: `200 { "accepted": 1, "duplicates": 0, "events": [{ "eventId", "personId", "stage", "duplicate", "type", "translated" }] }`. Reenvio responde 200 igual, com `duplicates: 1`. - Erros de assinatura respondem `401` com a mensagem do que corrigir (cabeçalho faltando, timestamp fora da janela, formato `v1,`, assinatura que não confere). Exemplo em Node: ```js import { createHmac, randomUUID } from 'node:crypto' const id = randomUUID() const timestamp = Math.floor(Date.now() / 1000) const body = JSON.stringify({ type: 'account.created', timestamp: new Date().toISOString(), data: { person: { email } } }) const key = Buffer.from(process.env.PEOPLE_SECRET.replace(/^whsec_/, ''), 'base64') const signature = createHmac('sha256', key).update(`${id}.${timestamp}.${body}`).digest('base64') await fetch(process.env.PEOPLE_SOURCE_URL, { method: 'POST', headers: { 'content-type': 'application/json', 'x-ccm-id': id, 'x-ccm-timestamp': String(timestamp), 'x-ccm-signature': `v1,${signature}` }, body, }) ``` ## 4. Os tipos de evento **Os que movem o estágio** (e nunca mudam): | Evento | Efeito | | --- | --- | | qualquer primeiro evento (`person.touched` na importação) | a pessoa é `lead` | | `account.created` | `prospect` | | `account.activated` | continua `prospect`; marca a ativação | | `subscription.paid` | `customer` (a única forma) | | `subscription.canceled` depois de customer | volta a `prospect` | **Outros que o People já conhece** (não precisam de tradução): `usage.limit_reached`, `subscription.upgraded`, `purchase.completed`, `refund.issued`, `conversation.opened`, `conversation.resolved`, `community.joined`, `message.opened`. **Reservados ao People**, recusados de uma fonte: `note.added`, `stage.changed`, `stage.corrected`, `merge.suggested`, `question.asked`, `next_step.set`, `next_step.done`. `conversation.opened` sem `conversation.resolved` depois, há mais de 48 horas, entra no número "Sem resposta há mais de 48h" do Centro de Comando. ## 5. Importação CSV - Fonte do tipo `import`, pelo painel (`POST /sources/:id/import`, com o JWT da pessoa; até 500 linhas por chamada, o painel divide arquivos maiores). Uma fonte de importação não recebe webhook. - Cabeçalhos em português ou em inglês: `email`/`e-mail`, `nome`/`name`, `telefone`/`phone`/`celular`, `empresa`/`company`, `dominio`/`company_domain`/`site`, `utm_source`/`origem`, `utm_medium`, `utm_campaign`/`campanha`, `created_at`/`data`. Vírgula ou ponto e vírgula. - Cada linha vira um `person.touched` com `channel: import`. O id da linha é o e-mail ou o telefone: **importar o mesmo arquivo de novo não muda nada**. - Linha sem e-mail nem telefone é pulada, com o número da linha no relatório. ## 6. Traduções na fonte - O vocabulário é de quem manda. A fonte guarda um mapa `{ "tipo que chega": "tipo do People" }`, editável (`PATCH /sources/:id { translations }`, até 100 por fonte). - Tipo sem tradução é guardado como chegou e listado na fonte como "a traduzir". **Nada é descartado.** Traduzir relê o que já tinha chegado. - Se o sistema não tem nomes próprios, envie direto os tipos da seção 4. ## 7. Estágio, identidade e ativação - O estágio sai do funil Ativação. Mover à mão vale **só entre lead e prospect**, com motivo (`POST /people/:id/stage`), e dura até um evento discordar. **Customer nunca é manual.** - Um evento só se junta a uma ficha por **identidade igual em tipo e valor**. Quando aponta para duas fichas, vai para a mais forte e a outra é citada num `merge.suggested`. **Duas fichas nunca se fundem sozinhas**; juntar é uma ação `merge`, que começa pedindo confirmação. - O que conta como ativar é da conta (`GET/PUT /activation { event }`): a primeira vez que a pessoa faz o evento escolhido, o People registra `account.activated` naquele momento; as ativações passadas acompanham a escolha. Uma fonte também pode mandar `account.activated` direto. ## 8. Ações, checagem e escada de confiança - Toda ação passa por `checkAction()`, sem IA, antes de existir: espera obrigatória, o que a seção "O que nunca prometer" do Manual barra (negar não é prometer), **datas e "em breve" sempre barrados**, dono da pessoa, opt-out, "assumir eu", política por tipo, **oferta de preço e primeira mensagem para quem nunca escreveu sempre com uma pessoa**, limite de contato por semana (padrão 2, só o que a conta inicia; responder a quem escreveu não conta) e horário de silêncio. - Política por tipo: `free`, `confirm` ou `blocked`. Padrão: `note` livre; `tag`, `stage`, `merge`, `reply`, `email`, `offer` em `confirm`. A escada sugere promover um tipo depois de 50 pedidos com 95% de aprovação em 30 dias, e **nunca** promove `reply`, `email` ou `offer`. - Apagar não é tipo de ação: excluir uma pessoa é humano, digitando o nome dela. - O que não pode sair espera, com o motivo na tela. Nada some. ## 9. Saída - Mensagem aprovada sai por e-mail pelo Messages, **com a chave e o domínio verificado da própria conta** (`PUT /settings/messages { key, from }`), usando o id da ação como chave de idempotência; ou para um destino da conta (`POST /destinations { name, url, reaches }`), assinado no mesmo protocolo `x-ccm`. Um `message.test` assinado confere o endereço ao cadastrar; três falhas seguidas pausam o destino. - Sem canal configurado, a mensagem fica aprovada esperando, e o painel diz por quê. ## 10. Servidor MCP `POST https://people.worker.mycustomers.click/mcp`, Streamable HTTP, revisão 2026-07-28. Um GET responde 405. Sem token, responde 401 com `WWW-Authenticate` apontando para os metadados do recurso. Limite de chamadas por conta (em excesso, 429 com `retry-after`). ```bash claude mcp add --transport http customers-people https://people.worker.mycustomers.click/mcp ``` | Ferramenta | Escopo | O que faz | | --- | --- | --- | | `people_list_people` | leitura | Lista as pessoas (mais recentes primeiro) com estágio, e-mail, empresa, próximo passo. Filtros: `stage`, `q`, `company`, `product`, `origin`, `hasCompany`, `group`, `limit` (até 200), `offset` | | `people_get_person` | leitura | A ficha: identidades com a força de cada uma, empresa, estágio e os passos da Ativação cumpridos | | `people_get_timeline` | leitura | Os eventos da pessoa, do mais recente: `filter` (`notes`, `sources`), `limit`, `offset` | | `people_add_note` | escrita | Propõe uma nota; com a nota em "livre" entra na hora, em "confirma" espera aprovação | | `people_propose_action` | escrita | Propõe `reply`, `email`, `offer`, `stage`, `tag` ou `merge`, com `title`, `reason`, `text`, `subject`, `expects` (obrigatório em mensagens) e `withinHours`. Devolve a ação e a conferência regra a regra | - **Nenhuma ferramenta envia nada a uma pessoa.** Uma proposta entra na mesma fila e passa pela mesma checagem. - A conta nunca é argumento: vem do token. - Toda leitura pelo MCP fica registrada, e em Equipe o painel lista cada cliente MCP que a conta já viu, com revogar e restaurar. Revogado, cada chamada responde 401. ## 11. Privacidade Retenção de 12, 24 ou 36 meses (`PATCH /privacy`); pedidos de titular de exportar e excluir com prazo de 15 dias (`/privacy/requests`); a trilha da conta em CSV (`GET /privacy/trail`); exportar uma pessoa em JSON (`POST /people/:id/export`); excluir digitando o nome (`DELETE /people/:id`). Base legal declarada em cada fonte. **São ferramentas, não uma certificação.** ## 12. Referência da API (HTTP, com o JWT de uma pessoa) - Fontes: `GET/POST /sources`, `GET/PATCH/DELETE /sources/:id`, `POST /sources/:id/rotate`, `POST /sources/:id/import`; ativação: `GET/PUT /activation`. - Pessoas: `GET /people` (os filtros da tela), `GET /people/facets`, `POST /people` (à mão), `GET /people/:id`, `GET /people/:id/timeline`, `POST /people/:id/notes`, `POST /people/:id/stage`, `POST /people/:id/next-step`, `POST /people/:id/export`, `DELETE /people/:id`. - Centro de Comando: `GET /overview` (os três números, quem está por trás, o agente trabalhando e a fila de aprovação, numa chamada só). - Ações: `GET/POST /actions`, `POST /actions/:id/approve`, `POST /actions/:id/reject`. - Motor: `/agents`, `/manual`, `/manual/versions`, `/manual/reads`, `/answers`, `/answers/check`, `/strategies`, `/strategies/:id/reach`, `/strategies/results`, `GET /limits`, `PATCH /settings`. - Funis: `/funnels`, `/funnels/preview`, `/funnels/:id/report`, `/funnels/:id/handoff`. - Destinos: `/destinations`, `/destinations/:id/test`, `/destinations/:id/resume`. - Equipe: `GET /connected`, `POST /connected/:id/revoke`, `POST /connected/:id/restore`, `GET /routines`. - Público: `GET /status` (saúde) e `GET /` (`{"service":"customers-people"}`). Erro é sempre `{ "error": { "code", "message" } }` com o status HTTP certo, nunca 200. Códigos estáveis: `UNAUTHORIZED`, `FORBIDDEN`, `NOT_FOUND`, `VALIDATION_ERROR`, `PAYLOAD_TOO_LARGE` e outros. ## 13. O que NÃO existe (anti-alucinação) Não afirme, não sugira e não tente usar: - **Preço, plano ou cobrança do People.** Não há preço público. - **Chave de API**, nem de leitura. A leitura é pelo painel e pelo MCP. - **Conector pronto** para qualquer ferramenta de terceiro ou para outros produtos, nem "conexão automática" com login ou cobrança. O que existe é o protocolo aberto: qualquer sistema que assine a entrega entra. - **Canais de envio** além de e-mail (pela conta do usuário) e destino por webhook: nada de SMS, conversa ao vivo, mensageiros ou ligação. - **Agente que envia sozinho** a primeira mensagem ou uma oferta de preço. Ferramenta MCP que envie qualquer coisa. - **Fusão automática** de fichas. - **Lead score**, enriquecimento com dado de terceiro, fingerprint. - **Ferramenta MCP para criar fonte, salvar Manual, criar estratégia ou importar CSV.** Isso é no painel. - **Conformidade legal certificada.** O que existe são ferramentas (seção 11). ## 14. Armadilhas - A assinatura usa o segredo **sem** o prefixo `whsec_`, decodificado de base64. Assinar com a string inteira dá 401 "Assinatura não confere". - O corpo assinado tem de ser **o mesmo texto** enviado: serializar duas vezes muda os bytes. - Relógio fora de 5 minutos dá 401 de timestamp. Use o relógio do servidor, não o do cliente. - Reaproveitar o `x-ccm-id` de outro evento faz o People tratá-lo como reenvio e ignorá-lo. - `data.person` vai **dentro** de `data`; um corpo com `person` no topo é recusado com a explicação. - Uma fonte de importação não recebe webhook (403). ## 15. Checklist para agentes 1. Leu a seção 13. 2. Pediu ao usuário a fonte (endereço e segredo) e guardou os dois em variáveis de ambiente. 3. Assinou `id.timestamp.corpo` com a chave decodificada e mandou os três cabeçalhos `x-ccm`. 4. Usou os tipos do sistema ou os da seção 4, e disse ao usuário quais traduzir. 5. Pelo MCP, leu antes de propor, e toda proposta de mensagem diz `expects` e o prazo. 6. Não prometeu envio automático, preço, conector ou chave de API. Mais: https://mycustomers.click/products/people · https://mycustomers.click/developers · https://mycustomers.click/prompts · a linha inteira em https://mycustomers.click/llms.txt