Negócios
O Negócio é a oportunidade aberta sobre um Contato — uma inscrição, uma rematrícula. Esta página cobre criar, atualizar e ler negócios a partir do seu sistema.
Todos os caminhos são relativos a API_BASE/public/v1/crm, e toda requisição leva a API
key: Authorization: Bearer wf_sua_chave_aqui. Chave, escopo e token de conta de serviço
estão em Autenticação.
Antes de criar: os ids
O POST pede o contato, o pipelineId e o stageId:
- Contato: o que você já usa para endereçar um contato — o
iddo Workfuse, ouexternalId,emailoutaxId. pipelineId: aparece na URL do pipeline no painel (/pipelines/{id}).stageIdeownerId: o painel não mostra esses ids. Leia doGET /deals/{dealId}de um negócio que já existe na instituição, ou peça ao administrador da sua instituição.
Criar um negócio
POST /deals · síncrono
curl -X POST "API_BASE/public/v1/crm/deals" \
-H "Authorization: Bearer wf_sua_chave_aqui" \
-H "Content-Type: application/json" \
-d '{
"contact": { "id": "aluno-4471", "idProperty": "externalId" },
"pipelineId": "clzp1x8k20001s6vp3d9w5r2a",
"stageId": "clzs4m7q10002s6vp9f3k8b6c",
"externalId": "inscricao-88431",
"properties": { "curso_de_interesse": "Engenharia Civil" }
}'
O exemplo não manda ownerId: o negócio fica com o dono padrão da instituição.
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
contact | object | sim* | Como achar o contato, dentro da instituição da sua API key. |
contact.id | string | sim | O id do Workfuse, ou o valor de idProperty. |
contact.idProperty | enum | não | externalId, email ou taxId. Sem ele, id é o id do Workfuse. |
pipelineId | string | sim* | O pipeline do negócio. Precisa estar ativo. |
stageId | string | sim* | A etapa inicial. Precisa ser deste pipeline e da sua instituição. |
ownerId | string | não | O dono do negócio, um usuário da equipe da organização. Omitido, vale o dono padrão da instituição. Sem os dois, 422 DEAL_OWNER_REQUIRED. |
externalId | string | não | O id do negócio no seu sistema. Único dentro da instituição. |
properties | object | não | Propriedades customizadas, pela chave. Só vale chave do catálogo de Negócio da instituição. |
* Obrigatório, mas a ausência responde 422 (DEAL_API_FIELDS_REQUIRED, com
details.fields listando o que faltou), não 400.
O dono padrão é configurado na instituição (defaultDealOwnerId). Se ela tem um, o
ownerId é dispensável.
Resposta 201:
{
"id": "clzq9n2v50003s6vpe7h1j4m8",
"externalId": "inscricao-88431",
"ownerId": "clzu3c6t80004s6vp2b5x9n1d",
"pipelineId": "clzp1x8k20001s6vp3d9w5r2a",
"stageId": "clzs4m7q10002s6vp9f3k8b6c",
"contactId": "clz9q2k8r0001s6vp2h4m7x1e",
"properties": {
"curso_de_interesse": "Engenharia Civil"
},
"createdAt": "2026-10-09T13:02:11.482Z",
"updatedAt": "2026-10-09T13:02:11.482Z"
}
- A resposta traz só o que está preenchido. Campo sem valor não vem como
null: simplesmente não aparece. contactIdé o contato primário do negócio.namesó aparece se alguém deu nome ao negócio no painel. A API não define nome.propertiesleva só as customizadas.contact,pipelineId,stageId,ownerIdeexternalIdficam fora dela.
Erros
Recusado com 4xx, nada é gravado: as propriedades são escritas na mesma transação do negócio.
| HTTP | errorCode | Quando |
|---|---|---|
400 | — | Corpo malformado (ex.: pipelineId que não é string). |
404 | DEAL_CONTACT_NOT_FOUND | O contato não existe nesta instituição. |
409 | DEAL_EXTERNAL_ID_CONFLICT | Já existe negócio com esse externalId na instituição. |
422 | DEAL_API_FIELDS_REQUIRED | Falta contact, pipelineId ou stageId. |
422 | DEAL_OWNER_REQUIRED | Sem ownerId e sem dono padrão na instituição. |
422 | DEAL_OWNER_NOT_ORGANIZATION_STAFF | O ownerId não é usuário da equipe da organização. |
422 | DEAL_STAGE_NOT_IN_PIPELINE | A etapa não existe, é de outro pipeline ou de outra instituição. |
422 | DEAL_PIPELINE_INACTIVE | O pipeline está inativo. |
422 | DEAL_WITHOUT_IDENTIFIED_CONTACT | O contato não tem e-mail, CPF nem telefone. |
422 | DEAL_PROPERTY_KEYS_UNKNOWN | Chave fora do catálogo de Negócio. details.keys lista as chaves. |
422 | PROPERTY_VALUE_NOT_IN_OPTIONS | Valor fora das opções de um SELECT ou MULTI_SELECT. |
422 | PROPERTY_INVALID_VALUE | Valor que não serve para o tipo da propriedade. details.reason diz o motivo. |
Os erros do gate (401, 403) e o formato de cada resposta estão em
Erros.
Atualizar um negócio
PATCH /deals/{dealId} · síncrono
curl -X PATCH "API_BASE/public/v1/crm/deals/clzq9n2v50003s6vpe7h1j4m8" \
-H "Authorization: Bearer wf_sua_chave_aqui" \
-H "Content-Type: application/json" \
-d '{ "properties": { "curso_de_interesse": "Arquitetura" } }'
É merge, não substituição. Só as chaves enviadas mudam. Para limpar uma propriedade,
mande null.
Só propriedades customizadas mudam. O PATCH nunca troca a etapa, o pipeline, o nome, o
externalId nem o dono. Se você mandar ownerId, stageId, pipelineId, name ou
externalId no corpo, a API ignora o campo, sem erro e responde 200. O campo
properties é obrigatório.
Endereçar pelo seu id
Use idProperty para endereçar o negócio pelo externalId, sem saber o id do Workfuse:
curl -X PATCH "API_BASE/public/v1/crm/deals/inscricao-88431?idProperty=externalId" \
-H "Authorization: Bearer wf_sua_chave_aqui" \
-H "Content-Type: application/json" \
-d '{ "properties": { "curso_de_interesse": "Arquitetura" } }'
externalId é o único valor aceito em idProperty. Escape o valor na URL. Sem
idProperty, o segmento da URL é sempre o id do Workfuse.
Resposta 200 — o negócio inteiro, no mesmo formato do POST.
Erros
| HTTP | errorCode | Quando |
|---|---|---|
400 | — | Corpo malformado, ou sem properties. |
404 | DEAL_NOT_FOUND | O negócio não existe, ou é de outra instituição. |
422 | DEAL_PROPERTY_KEYS_UNKNOWN | Chave fora do catálogo de Negócio. Nenhuma chave do corpo é gravada. |
422 | PROPERTY_VALUE_NOT_IN_OPTIONS / PROPERTY_INVALID_VALUE | Valor fora das opções ou do tipo da propriedade. |
Ler um negócio
GET /deals/{dealId} · síncrono
curl "API_BASE/public/v1/crm/deals/inscricao-88431?idProperty=externalId" \
-H "Authorization: Bearer wf_sua_chave_aqui"
Aceita o mesmo ?idProperty=externalId do PATCH. A resposta tem o formato da do POST.
Responde 404 (DEAL_NOT_FOUND) para negócio de outra instituição: do seu lado é
indistinguível de inexistente, e é de propósito.
Negócio e eventos
Um evento atualiza propriedades de um negócio que já existe e
nunca cria um. Para criar, use o POST /deals desta página.
O que esta API não faz
- Não apaga negócio. Não há
DELETEaqui. - Não lista nem busca negócios. Você endereça um por
idou porexternalId. - Não move de etapa nem troca de dono. Isso é feito no painel.
- Não define nome. O nome do negócio é do painel.
- Não vincula outros contatos. O contato do
POSTé o primário. - Não cria propriedade customizada. O catálogo é da instituição, em Configurações →
Propriedades. Chave que não existe lá devolve
422.
Se você vem do HubSpot
| No HubSpot | Aqui |
|---|---|
POST /crm/v3/objects/deals | POST /crm/deals |
pipeline e dealstage dentro de properties; sem pipeline, vale o padrão | pipelineId e stageId fora de properties, os dois obrigatórios |
hubspot_owner_id em properties | ownerId fora de properties, opcional: omitido, vale o dono padrão da instituição |
dealname | Não existe: a API não define nome |
associations[] | contact, um contato primário, obrigatório |
PATCH muda dealstage e o dono | Aqui o PATCH só muda propriedades customizadas |
idProperty (propriedade única customizada, na leitura em lote) | ?idProperty=externalId no GET e no PATCH de um negócio |
Os caminhos usam a v3, igual a Contatos: o HubSpot hoje
publica /crm/objects/2026-09/deals e passou a v3 para legacy. Medido em
developers.hubspot.com em 09/10/2026.