Pular para o conteúdo

Catálogo do CRM

O catálogo do CRM é a lista de produtos e serviços que a empresa vende, na visão comercial: nome, tipo (produto ou servico) e preço em centavos. É o que alimenta os itens de um negócio e de um orçamento no painel.

Um item pode, opcionalmente, apontar para um produto do estoque (product_id) — nesse caso nome, tipo e preço ausentes no corpo são copiados do produto no momento da criação; qualquer um deles enviado explicitamente vira um override comercial. Um item sem product_id é um item “só-CRM”.

Escopo: crm.view para leitura, crm.catalog.manage para escrita — ver Escopos & Permissões.

CampoTipoObrigatórioDescrição
idstring (UUID)leituraIdentificador do item.
product_idstring (UUID) | nullnãoProduto do estoque vinculado. null = item só-CRM. Um produto só pode estar no catálogo uma vez.
namestringsim (se sem product_id)Nome comercial. Máx. 200 caracteres.
typestringsim (se sem product_id)produto ou servico.
priceintegersim (se sem product_id)Preço em centavos. ≥ 0.
activebooleannãoPadrão true.
created_atstring (ISO-8601)leituraData de criação.
updated_atstring (ISO-8601)leituraData da última atualização.
GET /crm/catalog-items

Listar itens do catálogo

Retorna os itens do catálogo da empresa, paginado, ordenados por nome.

Parâmetros de query

CampoTipoObrigatórioDescrição
type string — Filtra por produto ou servico.
active boolean — Filtra por ativo/inativo.
per_page integer — Itens por página. Entre 1 e 100. Padrão 20.
curl -X GET https://api.maestron.com.br/api/v1/crm/catalog-items \
  -H "Authorization: Bearer SEU_TOKEN"
<?php
$client = new \GuzzleHttp\Client();
$response = $client->request('GET', 'https://api.maestron.com.br/api/v1/crm/catalog-items', [
    '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/catalog-items",
    headers=headers,
)
data = response.json()
const response = await fetch("https://api.maestron.com.br/api/v1/crm/catalog-items", {
  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/catalog-items");
var data = await response.Content.ReadAsStringAsync();
GET /crm/catalog-items HTTP/1.1
Host: api.maestron.com.br
Authorization: Bearer SEU_TOKEN

Respostas

{
  "message": "Itens do catálogo.",
  "data": [
    {
      "id": "d1e2f3a4-5b6c-4d7e-8f9a-0b1c2d3e4f5a",
      "product_id": null,
      "name": "Consultoria de implantação",
      "type": "servico",
      "price": 250000,
      "active": true,
      "created_at": "2026-02-01T10:00:00Z",
      "updated_at": "2026-02-01T10:00: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/catalog-items/{id}

Obter item do catálogo

Parâmetros de caminho

CampoTipoObrigatórioDescrição
id string Sim ID do item (UUID).
curl -X GET https://api.maestron.com.br/api/v1/crm/catalog-items/{id} \
  -H "Authorization: Bearer SEU_TOKEN"
<?php
$client = new \GuzzleHttp\Client();
$response = $client->request('GET', 'https://api.maestron.com.br/api/v1/crm/catalog-items/{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/catalog-items/{id}",
    headers=headers,
)
data = response.json()
const response = await fetch("https://api.maestron.com.br/api/v1/crm/catalog-items/{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/catalog-items/{id}");
var data = await response.Content.ReadAsStringAsync();
GET /crm/catalog-items/{id} HTTP/1.1
Host: api.maestron.com.br
Authorization: Bearer SEU_TOKEN

Respostas

{
  "message": "Item do catálogo.",
  "data": {
    "id": "d1e2f3a4-5b6c-4d7e-8f9a-0b1c2d3e4f5a",
    "product_id": null,
    "name": "Consultoria de implantação",
    "type": "servico",
    "price": 250000,
    "active": true,
    "created_at": "2026-02-01T10:00:00Z",
    "updated_at": "2026-02-01T10:00:00Z"
  }
}
{
  "message": "Não autenticado.",
  "data": null
}
{
  "message": "Recurso não encontrado.",
  "data": null
}

Envie name, type e price, ou um product_id (os demais são copiados do produto). idempotency_key é opcional — ver Sandbox & Idempotência.

POST /crm/catalog-items

Criar item do catálogo

Corpo (body)

CampoTipoObrigatórioDescrição
name string — Nome comercial. Obrigatório se product_id ausente.
type string — produto ou servico. Obrigatório se product_id ausente.
price integer — Preço em centavos. Obrigatório se product_id ausente.
product_id string — Produto do estoque a vincular. Copia nome/tipo/preço ausentes.
active boolean — Padrão true.
idempotency_key string — Opcional — evita duplicar o item em um retry.
curl -X POST https://api.maestron.com.br/api/v1/crm/catalog-items \
  -H "Authorization: Bearer SEU_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Licença anual",
    "type": "produto",
    "price": 120000
  }'
<?php
$client = new \GuzzleHttp\Client();
$response = $client->request('POST', 'https://api.maestron.com.br/api/v1/crm/catalog-items', [
    'headers' => [
        'Authorization' => 'Bearer SEU_TOKEN',
        'Accept' => 'application/json',
    ],
    'json' => [
        'name' => 'Licença anual',
        'type' => 'produto',
        'price' => 120000,
    ],
]);
$data = json_decode($response->getBody(), true);
import requests
headers = {"Authorization": "Bearer SEU_TOKEN"}
payload = {
    "name": "Licença anual",
    "type": "produto",
    "price": 120000,
}
response = requests.post(
    "https://api.maestron.com.br/api/v1/crm/catalog-items",
    headers=headers,
    json=payload,
)
data = response.json()
const response = await fetch("https://api.maestron.com.br/api/v1/crm/catalog-items", {
  method: "POST",
  headers: {
    "Authorization": "Bearer SEU_TOKEN",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "name": "Licença anual",
    "type": "produto",
    "price": 120000
  }),
});
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(
    "{\"name\":\"Licença anual\",\"type\":\"produto\",\"price\":120000}",
    System.Text.Encoding.UTF8, "application/json");
var response = await client.PostAsync("https://api.maestron.com.br/api/v1/crm/catalog-items", payload);
var data = await response.Content.ReadAsStringAsync();
POST /crm/catalog-items HTTP/1.1
Host: api.maestron.com.br
Authorization: Bearer SEU_TOKEN
Content-Type: application/json

{
  "name": "Licença anual",
  "type": "produto",
  "price": 120000
}

Respostas

{
  "message": "Item do catálogo criado.",
  "data": {
    "id": "e2f3a4b5-6c7d-4e8f-9a0b-1c2d3e4f5a6b",
    "product_id": null,
    "name": "Licença anual",
    "type": "produto",
    "price": 120000,
    "active": true,
    "created_at": "2026-06-20T14:30:00Z",
    "updated_at": "2026-06-20T14:30:00Z"
  }
}
{
  "message": "Não autenticado.",
  "data": null
}
{
  "message": "A chave não tem o escopo necessário.",
  "data": null
}
{
  "message": "Os dados informados são inválidos.",
  "data": null,
  "errors": {
    "type": [
      "O campo tipo não contém um valor válido."
    ],
    "price": [
      "O campo preço deve ter um valor superior ou igual a 0."
    ]
  }
}

Envie product_id: null para desfazer o vínculo com o estoque — a entrada volta a ser um item só-CRM, mantendo nome e preço atuais.

PATCH /crm/catalog-items/{id}

Atualizar item do catálogo

Parâmetros de caminho

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

Corpo (body)

CampoTipoObrigatórioDescrição
name string — Nome comercial.
type string — produto ou servico.
price integer — Preço em centavos.
product_id string — null desfaz o vínculo; um UUID vincula (produto ainda não usado no catálogo).
active boolean — Ativo/inativo.
curl -X PATCH https://api.maestron.com.br/api/v1/crm/catalog-items/{id} \
  -H "Authorization: Bearer SEU_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "price": 99900,
    "active": false
  }'
<?php
$client = new \GuzzleHttp\Client();
$response = $client->request('PATCH', 'https://api.maestron.com.br/api/v1/crm/catalog-items/{id}', [
    'headers' => [
        'Authorization' => 'Bearer SEU_TOKEN',
        'Accept' => 'application/json',
    ],
    'json' => [
        'price' => 99900,
        'active' => false,
    ],
]);
$data = json_decode($response->getBody(), true);
import requests
headers = {"Authorization": "Bearer SEU_TOKEN"}
payload = {
    "price": 99900,
    "active": False,
}
response = requests.patch(
    "https://api.maestron.com.br/api/v1/crm/catalog-items/{id}",
    headers=headers,
    json=payload,
)
data = response.json()
const response = await fetch("https://api.maestron.com.br/api/v1/crm/catalog-items/{id}", {
  method: "PATCH",
  headers: {
    "Authorization": "Bearer SEU_TOKEN",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "price": 99900,
    "active": false
  }),
});
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(
    "{\"price\":99900,\"active\":false}",
    System.Text.Encoding.UTF8, "application/json");
var response = await client.SendAsync(new HttpRequestMessage(
    new HttpMethod("PATCH"), "https://api.maestron.com.br/api/v1/crm/catalog-items/{id}") { Content = payload });
var data = await response.Content.ReadAsStringAsync();
PATCH /crm/catalog-items/{id} HTTP/1.1
Host: api.maestron.com.br
Authorization: Bearer SEU_TOKEN
Content-Type: application/json

{
  "price": 99900,
  "active": false
}

Respostas

{
  "message": "Item do catálogo atualizado.",
  "data": {
    "id": "e2f3a4b5-6c7d-4e8f-9a0b-1c2d3e4f5a6b",
    "product_id": null,
    "name": "Licença anual",
    "type": "produto",
    "price": 99900,
    "active": false,
    "created_at": "2026-06-20T14:30:00Z",
    "updated_at": "2026-06-20T15:00:00Z"
  }
}
{
  "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
}
DELETE /crm/catalog-items/{id}

Remover item do catálogo

Parâmetros de caminho

CampoTipoObrigatórioDescrição
id string Sim ID do item (UUID).
curl -X DELETE https://api.maestron.com.br/api/v1/crm/catalog-items/{id} \
  -H "Authorization: Bearer SEU_TOKEN"
<?php
$client = new \GuzzleHttp\Client();
$response = $client->request('DELETE', 'https://api.maestron.com.br/api/v1/crm/catalog-items/{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/catalog-items/{id}",
    headers=headers,
)
data = response.json()
const response = await fetch("https://api.maestron.com.br/api/v1/crm/catalog-items/{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/catalog-items/{id}");
var data = await response.Content.ReadAsStringAsync();
DELETE /crm/catalog-items/{id} HTTP/1.1
Host: api.maestron.com.br
Authorization: Bearer SEU_TOKEN

Respostas

{
  "message": "Item do catálogo 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
}

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