Pular para o conteúdo

Negócios (Deals)

O recurso Negócio (deal) representa uma oportunidade de venda. Todo negócio pertence a um pipeline (funnel_id) e ocupa um estágio (stage_id) desse pipeline até ser ganho ou perdido. A rota base é /crm/deals.

CampoTipoObrigatórioDescrição
idstring (UUID)leituraIdentificador do negócio.
funnel_idstring (UUID)simPipeline do negócio.
stage_idstring (UUID)simEstágio atual, deve pertencer a funnel_id.
assignee_idstring (UUID) | nullnãoUsuário responsável. Definir ou trocar exige escopo crm.leads.transfer.
assignee_namestring | nullleituraNome do responsável (só presente quando a resposta carrega o vínculo).
company_namestring | nullnãoNome da empresa do cliente. Máx. 200 caracteres.
contact_namestringsimNome do contato. Máx. 200 caracteres.
client_emailstring | nullnãoE-mail do contato. Máx. 200 caracteres.
client_phonestring | nullnãoTelefone do contato. Máx. 50 caracteres.
prospected_valueintegernãoValor prospectado em centavos. Padrão 0.
budgetintegernãoOrçamento do cliente em centavos. Padrão 0.
contact_datestring (data)simData do primeiro contato (YYYY-MM-DD).
expected_close_datestring (data) | nullnãoData prevista de fechamento. Deve ser igual ou posterior a contact_date.
statusstringsimValor do catálogo de status do pipeline (ex.: sem_contato, ganho). Ver catálogos por pipeline.
temperaturefrio | morno | quente | nullnãoTemperatura do negócio.
sourcestring | nullnãoOrigem, valor do catálogo do pipeline quando informado.
loss_reasonstring | nullnãoMotivo da perda, valor do catálogo do pipeline quando informado.
probabilityintegernãoProbabilidade de fechamento, 0 a 100. Sem valor explícito, herda default_probability do estágio.
notesstring | nullnãoObservações livres. Máx. 5000 caracteres.
custom_fieldsobjetonãoCampos customizados do pipeline: { "<chave>": <valor> }. Ver campos customizados.
created_atstring (ISO-8601)leituraData de criação.
updated_atstring (ISO-8601)leituraData da última atualização.
GET /crm/deals

Listar negócios

Lista os negócios da empresa, paginado.

Parâmetros de query

CampoTipoObrigatórioDescrição
per_page integer — Itens por página. De 1 a 100, padrão 20.
pipeline_id string — Filtra pelos negócios de um pipeline.
stage_id string — Filtra pelos negócios de um estágio.
curl -X GET https://api.maestron.com.br/api/v1/crm/deals \
  -H "Authorization: Bearer SEU_TOKEN"
<?php
$client = new \GuzzleHttp\Client();
$response = $client->request('GET', 'https://api.maestron.com.br/api/v1/crm/deals', [
    'headers' => [
        'Authorization' => 'Bearer SEU_TOKEN',
        'Accept' => 'application/json',
    ],
]);
$data = json_decode($response->getBody(), true);
import requests
headers = {"Authorization": "Bearer SEU_TOKEN"}
response = requests.get(
    "https://api.maestron.com.br/api/v1/crm/deals",
    headers=headers,
)
data = response.json()
const response = await fetch("https://api.maestron.com.br/api/v1/crm/deals", {
  method: "GET",
  headers: {
    "Authorization": "Bearer SEU_TOKEN",
  },
});
const data = await response.json();
using var client = new HttpClient();
client.DefaultRequestHeaders.Authorization =
    new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", "SEU_TOKEN");
var response = await client.GetAsync("https://api.maestron.com.br/api/v1/crm/deals");
var data = await response.Content.ReadAsStringAsync();
GET /crm/deals HTTP/1.1
Host: api.maestron.com.br
Authorization: Bearer SEU_TOKEN

Respostas

{
  "message": "Negócios.",
  "data": [
    {
      "id": "f1a2b3c4-5d6e-4f7a-8b9c-0d1e2f3a4b5c",
      "funnel_id": "b7e8c1a2-3d4f-4a5b-8c9d-0e1f2a3b4c5d",
      "stage_id": "a1c2d3e4-5f6a-4b7c-8d9e-0f1a2b3c4d5e",
      "assignee_id": null,
      "assignee_name": null,
      "company_name": "Acme Ltda",
      "contact_name": "Maria Silva",
      "client_email": "maria@acme.com.br",
      "client_phone": "+55 11 99999-0000",
      "prospected_value": 1500000,
      "budget": 0,
      "contact_date": "2026-06-20",
      "expected_close_date": null,
      "status": "sem_contato",
      "temperature": "morno",
      "source": "site",
      "loss_reason": null,
      "probability": 10,
      "notes": null,
      "created_at": "2026-06-20T14:30:00Z",
      "updated_at": "2026-06-20T14:30:00Z"
    }
  ],
  "meta": {
    "current_page": 1,
    "per_page": 20,
    "total": 1,
    "last_page": 1
  }
}
{
  "message": "Não autenticado.",
  "data": null
}
{
  "message": "A chave não tem o escopo necessário.",
  "data": null
}
GET /crm/deals/{id}

Obter negócio

Retorna um negócio pelo ID.

Parâmetros de caminho

CampoTipoObrigatórioDescrição
id string Sim ID do negócio (UUID).
curl -X GET https://api.maestron.com.br/api/v1/crm/deals/{id} \
  -H "Authorization: Bearer SEU_TOKEN"
<?php
$client = new \GuzzleHttp\Client();
$response = $client->request('GET', 'https://api.maestron.com.br/api/v1/crm/deals/{id}', [
    'headers' => [
        'Authorization' => 'Bearer SEU_TOKEN',
        'Accept' => 'application/json',
    ],
]);
$data = json_decode($response->getBody(), true);
import requests
headers = {"Authorization": "Bearer SEU_TOKEN"}
response = requests.get(
    "https://api.maestron.com.br/api/v1/crm/deals/{id}",
    headers=headers,
)
data = response.json()
const response = await fetch("https://api.maestron.com.br/api/v1/crm/deals/{id}", {
  method: "GET",
  headers: {
    "Authorization": "Bearer SEU_TOKEN",
  },
});
const data = await response.json();
using var client = new HttpClient();
client.DefaultRequestHeaders.Authorization =
    new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", "SEU_TOKEN");
var response = await client.GetAsync("https://api.maestron.com.br/api/v1/crm/deals/{id}");
var data = await response.Content.ReadAsStringAsync();
GET /crm/deals/{id} HTTP/1.1
Host: api.maestron.com.br
Authorization: Bearer SEU_TOKEN

Respostas

{
  "message": "Negócio.",
  "data": {
    "id": "f1a2b3c4-5d6e-4f7a-8b9c-0d1e2f3a4b5c",
    "contact_name": "Maria Silva",
    "status": "sem_contato"
  }
}
{
  "message": "Não autenticado.",
  "data": null
}
{
  "message": "Recurso não encontrado.",
  "data": null
}

Retorna todas as atividades do negócio, sem paginação.

GET /crm/deals/{id}/activities

Atividades do negócio

Lista todas as atividades vinculadas ao negócio.

Parâmetros de caminho

CampoTipoObrigatórioDescrição
id string Sim ID do negócio (UUID).
curl -X GET https://api.maestron.com.br/api/v1/crm/deals/{id}/activities \
  -H "Authorization: Bearer SEU_TOKEN"
<?php
$client = new \GuzzleHttp\Client();
$response = $client->request('GET', 'https://api.maestron.com.br/api/v1/crm/deals/{id}/activities', [
    'headers' => [
        'Authorization' => 'Bearer SEU_TOKEN',
        'Accept' => 'application/json',
    ],
]);
$data = json_decode($response->getBody(), true);
import requests
headers = {"Authorization": "Bearer SEU_TOKEN"}
response = requests.get(
    "https://api.maestron.com.br/api/v1/crm/deals/{id}/activities",
    headers=headers,
)
data = response.json()
const response = await fetch("https://api.maestron.com.br/api/v1/crm/deals/{id}/activities", {
  method: "GET",
  headers: {
    "Authorization": "Bearer SEU_TOKEN",
  },
});
const data = await response.json();
using var client = new HttpClient();
client.DefaultRequestHeaders.Authorization =
    new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", "SEU_TOKEN");
var response = await client.GetAsync("https://api.maestron.com.br/api/v1/crm/deals/{id}/activities");
var data = await response.Content.ReadAsStringAsync();
GET /crm/deals/{id}/activities HTTP/1.1
Host: api.maestron.com.br
Authorization: Bearer SEU_TOKEN

Respostas

{
  "message": "Atividades do negócio.",
  "data": []
}
{
  "message": "Não autenticado.",
  "data": null
}
{
  "message": "Recurso não encontrado.",
  "data": null
}
POST /crm/deals

Criar negócio

Cria um negócio em um pipeline e estágio existentes. idempotency_key é opcional — ver Sandbox & Idempotência.

Corpo (body)

CampoTipoObrigatórioDescrição
funnel_id string Sim Pipeline do negócio (UUID).
stage_id string Sim Estágio, deve pertencer a funnel_id.
contact_name string Sim Nome do contato.
contact_date string Sim Data do primeiro contato (YYYY-MM-DD).
status string Sim Valor do catálogo de status do pipeline.
company_name string — Nome da empresa do cliente.
client_email string — E-mail do contato.
client_phone string — Telefone do contato.
assignee_id string — Responsável (UUID). Exige escopo crm.leads.transfer.
prospected_value integer — Valor prospectado em centavos.
budget integer — Orçamento do cliente em centavos.
expected_close_date string — Data prevista de fechamento (>= contact_date).
temperature string — frio, morno ou quente.
source string — Origem, valor do catálogo do pipeline.
probability integer — 0 a 100. Sem valor, herda do estágio.
notes string — Observações livres.
custom_fields objeto — Campos customizados do pipeline: { "<chave>": <valor> }. Ver Campos customizados.
idempotency_key string — Opcional — evita duplicar em retry.
curl -X POST https://api.maestron.com.br/api/v1/crm/deals \
  -H "Authorization: Bearer SEU_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "funnel_id": "b7e8c1a2-3d4f-4a5b-8c9d-0e1f2a3b4c5d",
    "stage_id": "a1c2d3e4-5f6a-4b7c-8d9e-0f1a2b3c4d5e",
    "contact_name": "Maria Silva",
    "company_name": "Acme Ltda",
    "client_email": "maria@acme.com.br",
    "contact_date": "2026-06-20",
    "status": "sem_contato",
    "temperature": "morno",
    "source": "site",
    "prospected_value": 1500000,
    "custom_fields": {
      "setor": "Varejo",
      "numero_de_lojas": 12
    },
    "idempotency_key": "3f7b1c9a-2d4e-4f6a-8b0c-5d9e1f3a7c2b"
  }'
<?php
$client = new \GuzzleHttp\Client();
$response = $client->request('POST', 'https://api.maestron.com.br/api/v1/crm/deals', [
    'headers' => [
        'Authorization' => 'Bearer SEU_TOKEN',
        'Accept' => 'application/json',
    ],
    'json' => [
        'funnel_id' => 'b7e8c1a2-3d4f-4a5b-8c9d-0e1f2a3b4c5d',
        'stage_id' => 'a1c2d3e4-5f6a-4b7c-8d9e-0f1a2b3c4d5e',
        'contact_name' => 'Maria Silva',
        'company_name' => 'Acme Ltda',
        'client_email' => 'maria@acme.com.br',
        'contact_date' => '2026-06-20',
        'status' => 'sem_contato',
        'temperature' => 'morno',
        'source' => 'site',
        'prospected_value' => 1500000,
        'custom_fields' => [object Object],
        'idempotency_key' => '3f7b1c9a-2d4e-4f6a-8b0c-5d9e1f3a7c2b',
    ],
]);
$data = json_decode($response->getBody(), true);
import requests
headers = {"Authorization": "Bearer SEU_TOKEN"}
payload = {
    "funnel_id": "b7e8c1a2-3d4f-4a5b-8c9d-0e1f2a3b4c5d",
    "stage_id": "a1c2d3e4-5f6a-4b7c-8d9e-0f1a2b3c4d5e",
    "contact_name": "Maria Silva",
    "company_name": "Acme Ltda",
    "client_email": "maria@acme.com.br",
    "contact_date": "2026-06-20",
    "status": "sem_contato",
    "temperature": "morno",
    "source": "site",
    "prospected_value": 1500000,
    "custom_fields": [object Object],
    "idempotency_key": "3f7b1c9a-2d4e-4f6a-8b0c-5d9e1f3a7c2b",
}
response = requests.post(
    "https://api.maestron.com.br/api/v1/crm/deals",
    headers=headers,
    json=payload,
)
data = response.json()
const response = await fetch("https://api.maestron.com.br/api/v1/crm/deals", {
  method: "POST",
  headers: {
    "Authorization": "Bearer SEU_TOKEN",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "funnel_id": "b7e8c1a2-3d4f-4a5b-8c9d-0e1f2a3b4c5d",
    "stage_id": "a1c2d3e4-5f6a-4b7c-8d9e-0f1a2b3c4d5e",
    "contact_name": "Maria Silva",
    "company_name": "Acme Ltda",
    "client_email": "maria@acme.com.br",
    "contact_date": "2026-06-20",
    "status": "sem_contato",
    "temperature": "morno",
    "source": "site",
    "prospected_value": 1500000,
    "custom_fields": {
      "setor": "Varejo",
      "numero_de_lojas": 12
    },
    "idempotency_key": "3f7b1c9a-2d4e-4f6a-8b0c-5d9e1f3a7c2b"
  }),
});
const data = await response.json();
using var client = new HttpClient();
client.DefaultRequestHeaders.Authorization =
    new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", "SEU_TOKEN");
var payload = new StringContent(
    "{\"funnel_id\":\"b7e8c1a2-3d4f-4a5b-8c9d-0e1f2a3b4c5d\",\"stage_id\":\"a1c2d3e4-5f6a-4b7c-8d9e-0f1a2b3c4d5e\",\"contact_name\":\"Maria Silva\",\"company_name\":\"Acme Ltda\",\"client_email\":\"maria@acme.com.br\",\"contact_date\":\"2026-06-20\",\"status\":\"sem_contato\",\"temperature\":\"morno\",\"source\":\"site\",\"prospected_value\":1500000,\"custom_fields\":{\"setor\":\"Varejo\",\"numero_de_lojas\":12},\"idempotency_key\":\"3f7b1c9a-2d4e-4f6a-8b0c-5d9e1f3a7c2b\"}",
    System.Text.Encoding.UTF8, "application/json");
var response = await client.PostAsync("https://api.maestron.com.br/api/v1/crm/deals", payload);
var data = await response.Content.ReadAsStringAsync();
POST /crm/deals HTTP/1.1
Host: api.maestron.com.br
Authorization: Bearer SEU_TOKEN
Content-Type: application/json

{
  "funnel_id": "b7e8c1a2-3d4f-4a5b-8c9d-0e1f2a3b4c5d",
  "stage_id": "a1c2d3e4-5f6a-4b7c-8d9e-0f1a2b3c4d5e",
  "contact_name": "Maria Silva",
  "company_name": "Acme Ltda",
  "client_email": "maria@acme.com.br",
  "contact_date": "2026-06-20",
  "status": "sem_contato",
  "temperature": "morno",
  "source": "site",
  "prospected_value": 1500000,
  "custom_fields": {
    "setor": "Varejo",
    "numero_de_lojas": 12
  },
  "idempotency_key": "3f7b1c9a-2d4e-4f6a-8b0c-5d9e1f3a7c2b"
}

Respostas

{
  "message": "Negócio criado.",
  "data": {
    "id": "f1a2b3c4-5d6e-4f7a-8b9c-0d1e2f3a4b5c",
    "status": "sem_contato",
    "probability": 10
  }
}
{
  "message": "Não autenticado.",
  "data": null
}
{
  "message": "A chave não tem o escopo crm.leads.transfer necessário para definir um responsável.",
  "data": null
}
{
  "message": "Os dados informados são inválidos.",
  "data": null,
  "errors": {
    "contact_name": [
      "O campo contact_name é obrigatório."
    ],
    "stage_id": [
      "O campo stage_id selecionado é inválido."
    ]
  }
}

Envie apenas os campos a alterar. Regras finas de escopo se aplicam da mesma forma que na criação — ver a nota acima.

PATCH /crm/deals/{id}

Atualizar negócio

Atualização parcial. Sem idempotency_key (PATCH já é naturalmente idempotente).

Parâmetros de caminho

CampoTipoObrigatórioDescrição
id string Sim ID do negócio (UUID).

Corpo (body)

CampoTipoObrigatórioDescrição
prospected_value integer — Valor prospectado em centavos.
probability integer — 0 a 100.
notes string — Observações livres.
custom_fields objeto — Substitui o mapa inteiro de campos customizados. Ver Campos customizados.
curl -X PATCH https://api.maestron.com.br/api/v1/crm/deals/{id} \
  -H "Authorization: Bearer SEU_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "prospected_value": 1800000,
    "probability": 60,
    "notes": "Cliente pediu revisão de escopo.",
    "custom_fields": {
      "setor": "Serviços",
      "numero_de_lojas": 3
    }
  }'
<?php
$client = new \GuzzleHttp\Client();
$response = $client->request('PATCH', 'https://api.maestron.com.br/api/v1/crm/deals/{id}', [
    'headers' => [
        'Authorization' => 'Bearer SEU_TOKEN',
        'Accept' => 'application/json',
    ],
    'json' => [
        'prospected_value' => 1800000,
        'probability' => 60,
        'notes' => 'Cliente pediu revisão de escopo.',
        'custom_fields' => [object Object],
    ],
]);
$data = json_decode($response->getBody(), true);
import requests
headers = {"Authorization": "Bearer SEU_TOKEN"}
payload = {
    "prospected_value": 1800000,
    "probability": 60,
    "notes": "Cliente pediu revisão de escopo.",
    "custom_fields": [object Object],
}
response = requests.patch(
    "https://api.maestron.com.br/api/v1/crm/deals/{id}",
    headers=headers,
    json=payload,
)
data = response.json()
const response = await fetch("https://api.maestron.com.br/api/v1/crm/deals/{id}", {
  method: "PATCH",
  headers: {
    "Authorization": "Bearer SEU_TOKEN",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "prospected_value": 1800000,
    "probability": 60,
    "notes": "Cliente pediu revisão de escopo.",
    "custom_fields": {
      "setor": "Serviços",
      "numero_de_lojas": 3
    }
  }),
});
const data = await response.json();
using var client = new HttpClient();
client.DefaultRequestHeaders.Authorization =
    new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", "SEU_TOKEN");
var payload = new StringContent(
    "{\"prospected_value\":1800000,\"probability\":60,\"notes\":\"Cliente pediu revisão de escopo.\",\"custom_fields\":{\"setor\":\"Serviços\",\"numero_de_lojas\":3}}",
    System.Text.Encoding.UTF8, "application/json");
var response = await client.SendAsync(new HttpRequestMessage(
    new HttpMethod("PATCH"), "https://api.maestron.com.br/api/v1/crm/deals/{id}") { Content = payload });
var data = await response.Content.ReadAsStringAsync();
PATCH /crm/deals/{id} HTTP/1.1
Host: api.maestron.com.br
Authorization: Bearer SEU_TOKEN
Content-Type: application/json

{
  "prospected_value": 1800000,
  "probability": 60,
  "notes": "Cliente pediu revisão de escopo.",
  "custom_fields": {
    "setor": "Serviços",
    "numero_de_lojas": 3
  }
}

Respostas

{
  "message": "Negócio atualizado.",
  "data": {
    "id": "f1a2b3c4-5d6e-4f7a-8b9c-0d1e2f3a4b5c",
    "probability": 60
  }
}
{
  "message": "Não autenticado.",
  "data": null
}
{
  "message": "A chave não tem o escopo crm.leads.close necessário para marcar negócios como ganho ou perdido.",
  "data": null
}
{
  "message": "Recurso não encontrado.",
  "data": null
}
{
  "message": "Os dados informados são inválidos.",
  "data": null,
  "errors": {
    "probability": [
      "O campo probability deve estar entre 0 e 100."
    ]
  }
}

Cada pipeline pode definir campos customizados de negócio — no painel Maestron, em Configurar funil → Campos (permissão crm.fields.manage). A API pública lê e grava os valores desses campos pelo objeto custom_fields, mas não gerencia as definições.

  • A chave de cada entrada é o key do campo (ex.: numero_de_lojas); o valor é do tipo da definição: text/textarea/url/phone (string), number (número), money (inteiro em centavos), boolean, date (YYYY-MM-DD), select (uma opção), multiselect (lista de opções).
  • Um valor incompatível com o tipo, uma opção fora da lista de um select/multiselect, ou a ausência de um campo marcado como obrigatório retornam 422 com o erro em custom_fields.<chave>.
  • Chave sem definição no pipeline é ignorada silenciosamente (não é erro).
  • No PATCH, enviar custom_fields substitui o objeto inteiro — mande sempre o conjunto completo dos campos que quer manter.
  • Campos inativos não aceitam valor e não aparecem na resposta.
{
"custom_fields": {
"setor": "Varejo",
"numero_de_lojas": 12,
"ticket_medio": 4500000,
"usa_erp": true,
"modulos_de_interesse": ["Estoque", "Financeiro"]
}
}
DELETE /crm/deals/{id}

Remover negócio

Remove (soft delete) um negócio.

Parâmetros de caminho

CampoTipoObrigatórioDescrição
id string Sim ID do negócio (UUID).
curl -X DELETE https://api.maestron.com.br/api/v1/crm/deals/{id} \
  -H "Authorization: Bearer SEU_TOKEN"
<?php
$client = new \GuzzleHttp\Client();
$response = $client->request('DELETE', 'https://api.maestron.com.br/api/v1/crm/deals/{id}', [
    'headers' => [
        'Authorization' => 'Bearer SEU_TOKEN',
        'Accept' => 'application/json',
    ],
]);
$data = json_decode($response->getBody(), true);
import requests
headers = {"Authorization": "Bearer SEU_TOKEN"}
response = requests.delete(
    "https://api.maestron.com.br/api/v1/crm/deals/{id}",
    headers=headers,
)
data = response.json()
const response = await fetch("https://api.maestron.com.br/api/v1/crm/deals/{id}", {
  method: "DELETE",
  headers: {
    "Authorization": "Bearer SEU_TOKEN",
  },
});
const data = await response.json();
using var client = new HttpClient();
client.DefaultRequestHeaders.Authorization =
    new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", "SEU_TOKEN");
var response = await client.DeleteAsync("https://api.maestron.com.br/api/v1/crm/deals/{id}");
var data = await response.Content.ReadAsStringAsync();
DELETE /crm/deals/{id} HTTP/1.1
Host: api.maestron.com.br
Authorization: Bearer SEU_TOKEN

Respostas

{
  "message": "Negócio removido.",
  "data": null
}
{
  "message": "Não autenticado.",
  "data": null
}
{
  "message": "A chave não tem o escopo necessário.",
  "data": null
}
{
  "message": "Recurso não encontrado.",
  "data": null
}

O stage_id de destino deve pertencer ao mesmo funnel_id do negócio. Quando o estágio muda, probability é atualizada com default_probability do novo estágio (se definido).

PATCH /crm/deals/{id}/stage

Mover negócio de estágio

Move o negócio para outro estágio do mesmo pipeline.

Parâmetros de caminho

CampoTipoObrigatórioDescrição
id string Sim ID do negócio (UUID).

Corpo (body)

CampoTipoObrigatórioDescrição
stage_id string Sim Estágio de destino, do mesmo pipeline do negócio.
curl -X PATCH https://api.maestron.com.br/api/v1/crm/deals/{id}/stage \
  -H "Authorization: Bearer SEU_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "stage_id": "c3d4e5f6-7a8b-4c9d-0e1f-2a3b4c5d6e7f"
  }'
<?php
$client = new \GuzzleHttp\Client();
$response = $client->request('PATCH', 'https://api.maestron.com.br/api/v1/crm/deals/{id}/stage', [
    'headers' => [
        'Authorization' => 'Bearer SEU_TOKEN',
        'Accept' => 'application/json',
    ],
    'json' => [
        'stage_id' => 'c3d4e5f6-7a8b-4c9d-0e1f-2a3b4c5d6e7f',
    ],
]);
$data = json_decode($response->getBody(), true);
import requests
headers = {"Authorization": "Bearer SEU_TOKEN"}
payload = {
    "stage_id": "c3d4e5f6-7a8b-4c9d-0e1f-2a3b4c5d6e7f",
}
response = requests.patch(
    "https://api.maestron.com.br/api/v1/crm/deals/{id}/stage",
    headers=headers,
    json=payload,
)
data = response.json()
const response = await fetch("https://api.maestron.com.br/api/v1/crm/deals/{id}/stage", {
  method: "PATCH",
  headers: {
    "Authorization": "Bearer SEU_TOKEN",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "stage_id": "c3d4e5f6-7a8b-4c9d-0e1f-2a3b4c5d6e7f"
  }),
});
const data = await response.json();
using var client = new HttpClient();
client.DefaultRequestHeaders.Authorization =
    new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", "SEU_TOKEN");
var payload = new StringContent(
    "{\"stage_id\":\"c3d4e5f6-7a8b-4c9d-0e1f-2a3b4c5d6e7f\"}",
    System.Text.Encoding.UTF8, "application/json");
var response = await client.SendAsync(new HttpRequestMessage(
    new HttpMethod("PATCH"), "https://api.maestron.com.br/api/v1/crm/deals/{id}/stage") { Content = payload });
var data = await response.Content.ReadAsStringAsync();
PATCH /crm/deals/{id}/stage HTTP/1.1
Host: api.maestron.com.br
Authorization: Bearer SEU_TOKEN
Content-Type: application/json

{
  "stage_id": "c3d4e5f6-7a8b-4c9d-0e1f-2a3b4c5d6e7f"
}

Respostas

{
  "message": "Negócio movido de etapa.",
  "data": {
    "id": "f1a2b3c4-5d6e-4f7a-8b9c-0d1e2f3a4b5c",
    "stage_id": "c3d4e5f6-7a8b-4c9d-0e1f-2a3b4c5d6e7f",
    "probability": 50
  }
}
{
  "message": "Não autenticado.",
  "data": null
}
{
  "message": "A chave não tem o escopo necessário.",
  "data": null
}
{
  "message": "Recurso não encontrado.",
  "data": null
}
{
  "message": "A etapa selecionada não pertence ao funil do negócio.",
  "data": null
}

As três ações resolvem o status do negócio a partir do kind (ganho, perdido ou aberto) do catálogo do pipeline. status explícito é opcional — só é obrigatório quando o pipeline tem mais de um status daquele kind marcado como padrão. Escopo: crm.leads.close.

POST /crm/deals/{id}/win

Marcar como ganho

Marca o negócio com um status de kind ganho. status é opcional — ver a nota acima.

Parâmetros de caminho

CampoTipoObrigatórioDescrição
id string Sim ID do negócio (UUID).

Corpo (body)

CampoTipoObrigatórioDescrição
status string — Valor explícito do catálogo, precisa ser de kind ganho.
idempotency_key string — Opcional — evita reprocessar em retry.
curl -X POST https://api.maestron.com.br/api/v1/crm/deals/{id}/win \
  -H "Authorization: Bearer SEU_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "idempotency_key": "9a1b3c5d-7e2f-4a6b-8c0d-1e3f5a7b9c2d"
  }'
<?php
$client = new \GuzzleHttp\Client();
$response = $client->request('POST', 'https://api.maestron.com.br/api/v1/crm/deals/{id}/win', [
    'headers' => [
        'Authorization' => 'Bearer SEU_TOKEN',
        'Accept' => 'application/json',
    ],
    'json' => [
        'idempotency_key' => '9a1b3c5d-7e2f-4a6b-8c0d-1e3f5a7b9c2d',
    ],
]);
$data = json_decode($response->getBody(), true);
import requests
headers = {"Authorization": "Bearer SEU_TOKEN"}
payload = {
    "idempotency_key": "9a1b3c5d-7e2f-4a6b-8c0d-1e3f5a7b9c2d",
}
response = requests.post(
    "https://api.maestron.com.br/api/v1/crm/deals/{id}/win",
    headers=headers,
    json=payload,
)
data = response.json()
const response = await fetch("https://api.maestron.com.br/api/v1/crm/deals/{id}/win", {
  method: "POST",
  headers: {
    "Authorization": "Bearer SEU_TOKEN",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "idempotency_key": "9a1b3c5d-7e2f-4a6b-8c0d-1e3f5a7b9c2d"
  }),
});
const data = await response.json();
using var client = new HttpClient();
client.DefaultRequestHeaders.Authorization =
    new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", "SEU_TOKEN");
var payload = new StringContent(
    "{\"idempotency_key\":\"9a1b3c5d-7e2f-4a6b-8c0d-1e3f5a7b9c2d\"}",
    System.Text.Encoding.UTF8, "application/json");
var response = await client.PostAsync("https://api.maestron.com.br/api/v1/crm/deals/{id}/win", payload);
var data = await response.Content.ReadAsStringAsync();
POST /crm/deals/{id}/win HTTP/1.1
Host: api.maestron.com.br
Authorization: Bearer SEU_TOKEN
Content-Type: application/json

{
  "idempotency_key": "9a1b3c5d-7e2f-4a6b-8c0d-1e3f5a7b9c2d"
}

Respostas

{
  "message": "Negócio marcado como ganho.",
  "data": {
    "id": "f1a2b3c4-5d6e-4f7a-8b9c-0d1e2f3a4b5c",
    "status": "ganho"
  }
}
{
  "message": "Não autenticado.",
  "data": null
}
{
  "message": "A chave não tem o escopo necessário.",
  "data": null
}
{
  "message": "Recurso não encontrado.",
  "data": null
}
{
  "message": "O funil deste negócio não tem um status padrão do tipo \"ganho\" — informe \"status\" explicitamente.",
  "data": null
}
POST /crm/deals/{id}/lose

Marcar como perdido

Marca o negócio com um status de kind perdido.

Parâmetros de caminho

CampoTipoObrigatórioDescrição
id string Sim ID do negócio (UUID).

Corpo (body)

CampoTipoObrigatórioDescrição
status string — Valor explícito do catálogo, precisa ser de kind perdido.
curl -X POST https://api.maestron.com.br/api/v1/crm/deals/{id}/lose \
  -H "Authorization: Bearer SEU_TOKEN"
<?php
$client = new \GuzzleHttp\Client();
$response = $client->request('POST', 'https://api.maestron.com.br/api/v1/crm/deals/{id}/lose', [
    'headers' => [
        'Authorization' => 'Bearer SEU_TOKEN',
        'Accept' => 'application/json',
    ],
]);
$data = json_decode($response->getBody(), true);
import requests
headers = {"Authorization": "Bearer SEU_TOKEN"}
response = requests.post(
    "https://api.maestron.com.br/api/v1/crm/deals/{id}/lose",
    headers=headers,
)
data = response.json()
const response = await fetch("https://api.maestron.com.br/api/v1/crm/deals/{id}/lose", {
  method: "POST",
  headers: {
    "Authorization": "Bearer SEU_TOKEN",
  },
});
const data = await response.json();
using var client = new HttpClient();
client.DefaultRequestHeaders.Authorization =
    new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", "SEU_TOKEN");
var response = await client.PostAsync("https://api.maestron.com.br/api/v1/crm/deals/{id}/lose", null);
var data = await response.Content.ReadAsStringAsync();
POST /crm/deals/{id}/lose HTTP/1.1
Host: api.maestron.com.br
Authorization: Bearer SEU_TOKEN

Respostas

{
  "message": "Negócio marcado como perdido.",
  "data": {
    "id": "f1a2b3c4-5d6e-4f7a-8b9c-0d1e2f3a4b5c",
    "status": "perdido"
  }
}
{
  "message": "Não autenticado.",
  "data": null
}
{
  "message": "A chave não tem o escopo necessário.",
  "data": null
}
{
  "message": "Recurso não encontrado.",
  "data": null
}
{
  "message": "O status informado não pertence a este funil ou não é do tipo \"perdido\".",
  "data": null
}
POST /crm/deals/{id}/reopen

Reabrir negócio

Marca o negócio com um status de kind aberto.

Parâmetros de caminho

CampoTipoObrigatórioDescrição
id string Sim ID do negócio (UUID).

Corpo (body)

CampoTipoObrigatórioDescrição
status string — Valor explícito do catálogo, precisa ser de kind aberto.
curl -X POST https://api.maestron.com.br/api/v1/crm/deals/{id}/reopen \
  -H "Authorization: Bearer SEU_TOKEN"
<?php
$client = new \GuzzleHttp\Client();
$response = $client->request('POST', 'https://api.maestron.com.br/api/v1/crm/deals/{id}/reopen', [
    'headers' => [
        'Authorization' => 'Bearer SEU_TOKEN',
        'Accept' => 'application/json',
    ],
]);
$data = json_decode($response->getBody(), true);
import requests
headers = {"Authorization": "Bearer SEU_TOKEN"}
response = requests.post(
    "https://api.maestron.com.br/api/v1/crm/deals/{id}/reopen",
    headers=headers,
)
data = response.json()
const response = await fetch("https://api.maestron.com.br/api/v1/crm/deals/{id}/reopen", {
  method: "POST",
  headers: {
    "Authorization": "Bearer SEU_TOKEN",
  },
});
const data = await response.json();
using var client = new HttpClient();
client.DefaultRequestHeaders.Authorization =
    new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", "SEU_TOKEN");
var response = await client.PostAsync("https://api.maestron.com.br/api/v1/crm/deals/{id}/reopen", null);
var data = await response.Content.ReadAsStringAsync();
POST /crm/deals/{id}/reopen HTTP/1.1
Host: api.maestron.com.br
Authorization: Bearer SEU_TOKEN

Respostas

{
  "message": "Negócio reaberto.",
  "data": {
    "id": "f1a2b3c4-5d6e-4f7a-8b9c-0d1e2f3a4b5c",
    "status": "sem_contato"
  }
}
{
  "message": "Não autenticado.",
  "data": null
}
{
  "message": "A chave não tem o escopo necessário.",
  "data": null
}
{
  "message": "Recurso não encontrado.",
  "data": null
}

Para o detalhamento de cada código de status, consulte Erros.