CRM Oficina Martech
ReferênciaNegócios

Criar negócio

POST /deals — cria um negócio em uma etapa do pipeline, vinculando ou criando o contato, com idempotência por external_id.

POST/dealsBeta

Escopo necessário: deals:write

Cria um negócio (deal) em uma etapa do pipeline. A organização é resolvida a partir da própria API key — não envie organization_id.

Vínculo de contato: informe contact.id (UUID existente) ou contact.email/contact.phone. Se o contato não existir, ele é criado e vinculado na mesma chamada (mesma lógica do POST /contacts).

Endpoint

POST https://crm.oficinamartech.com/api/v1/deals

Corpo da requisição

CampoTipoObrigatórioDescrição
pipeline_idstring (UUID)✅Pipeline do negócio.
stage_idstring (UUID)✅Etapa; deve pertencer ao pipeline_id.
titlestring (até 300)△Título do negócio. Se omitido e houver contato, gera #N - Nome automaticamente.
valuenumber❌Valor. Default: 0.
currencystring (ISO 4217)❌Moeda. Default: BRL.
statusopen | won | lost❌Se omitido, é derivado da etapa (is_won/is_lost) ou open.
expected_close_datestring (YYYY-MM-DD)❌Data prevista de fechamento.
assigned_tostring (UUID)❌Operador responsável. Se omitido, segue a regra de atribuição do pipeline.
sourcestring (até 120)❌Rótulo de origem. Default: api.
external_idstring (até 200)❌Id externo para idempotência (veja abaixo).
custom_fieldsobject (mapa chave→valor)❌Gravado em metadata do negócio. Veja Campos personalizados.
contactobject❌Contato a vincular/criar. Veja Contato.

△ = title é obrigatório a menos que você envie um contact (o título é gerado a partir dele).

Contato

O objeto contact exige um identificador (id, email ou phone):

CampoTipoDescrição
idstring (UUID)Vincula um contato existente. Se não existir → 404.
emailstring (email)Resolve/cria o contato por email (primeira chave de match).
phonestringResolve/cria por telefone (E.164, com variantes do 9º dígito).
namestringNome (na criação).
sourcestringOrigem do contato.
utmobject{ source, medium, campaign, term, content }.
fbclid/gclidstringClick ids — gravam um toque de atribuição.
custom_fieldsobjectCampos personalizados de contato (validados).

Campos personalizados

As chaves de custom_fields são gravadas em metadata do negócio. Chaves cadastradas como campo personalizado de negócio (Configurações → Campos personalizados, entity deal) são validadas (incluindo opções de select/multiselect); chaves sem cadastro são aceitas livremente.

Idempotência

Envie external_id para tornar a criação idempotente: se já existir um negócio criado via API com o mesmo external_id na organização, ele é atualizado (resposta 200) em vez de duplicado. Sem external_id, cada chamada cria um novo negócio (201).

Resposta

201 Created (novo) ou 200 OK (idempotente atualizado):

{
  "data": {
    "id": "9b2e1c40-58cc-4372-a567-0e02b2c3d479",
    "organization_id": "...",
    "pipeline_id": "...",
    "stage_id": "...",
    "contact_id": "...",
    "title": "Proposta plano Pro",
    "value": 1990.0,
    "currency": "BRL",
    "status": "open",
    "source": "api",
    "expected_close_date": "2026-07-31",
    "metadata": { "campanha": "black-friday" },
    "created_via": "api",
    "dedup_key": "lead-2026-000123",
    "created_at": "2026-06-14T12:00:00.000Z",
    "updated_at": "2026-06-14T12:00:00.000Z"
  },
  "created": true,
  "contact": { "id": "...", "created": false }
}
CampoTipoDescrição
dataobjectO negócio criado/atualizado.
createdbooleantrue se criou; false se atualizou um negócio idempotente.
contactobject | nullContato vinculado (id + created indicando se foi criado).

Exemplos

curl -X POST "https://crm.oficinamartech.com/api/v1/deals" \
  -H "Authorization: Bearer $OFM_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "pipeline_id": "1f0b...e3",
    "stage_id": "2a7c...91",
    "title": "Proposta plano Pro",
    "value": 1990.0,
    "external_id": "lead-2026-000123",
    "custom_fields": { "campanha": "black-friday" },
    "contact": {
      "email": "maria@example.com",
      "name": "Maria Silva",
      "phone": "+55 11 99999-9999"
    }
  }'

Códigos de erro específicos

StatuscodeCausa
400—JSON inválido, ou faltou title sem contact
400pipeline_not_foundpipeline_id não existe nesta organização
400stage_not_foundstage_id não pertence ao pipeline_id
400invalid_custom_field_valuesValor fora das opções de um campo select/multiselect de negócio
400invalid_phonecontact.phone não pôde ser normalizado
400unknown_custom_fieldsChave de contact.custom_fields não cadastrada
401missing_api_keyHeader Authorization ausente
403missing_scopeChave sem o escopo deals:write
404contact_not_foundcontact.id não encontrado na organização
409duplicate_dealCorrida de idempotência com o mesmo external_id
500—Erro interno

Veja Códigos de erro para o formato completo.

Notas

  • A organização vem da API key — uma chave só cria negócios na própria organização.
  • O status é derivado da etapa quando omitido; etapas is_won/is_lost definem won_at/lost_at.
  • A atribuição do operador segue a regra do pipeline quando assigned_to não é enviado.
  • Quando um contato é criado/atualizado pelo objeto contact, a chamada também aparece na aba Atividades do contato (mesmo registro do POST /contacts).

On this page