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.
Esquema do item
Seção intitulada “Esquema do item”| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
id | string (UUID) | leitura | Identificador do item. |
product_id | string (UUID) | null | não | Produto do estoque vinculado. null = item só-CRM. Um produto só pode estar no catálogo uma vez. |
name | string | sim (se sem product_id) | Nome comercial. Máx. 200 caracteres. |
type | string | sim (se sem product_id) | produto ou servico. |
price | integer | sim (se sem product_id) | Preço em centavos. ≥ 0. |
active | boolean | não | Padrão true. |
created_at | string (ISO-8601) | leitura | Data de criação. |
updated_at | string (ISO-8601) | leitura | Data da última atualização. |
Listar itens
Seção intitulada “Listar itens”Listar itens do catálogo
Retorna os itens do catálogo da empresa, paginado, ordenados por nome.
Parâmetros de query
| Campo | Tipo | Obrigatório | Descriçã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
} Obter um item
Seção intitulada “Obter um item”Obter item do catálogo
Parâmetros de caminho
| Campo | Tipo | Obrigatório | Descriçã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
} Criar item
Seção intitulada “Criar item”Envie name, type e price, ou um product_id (os demais são copiados do produto). idempotency_key é opcional — ver Sandbox & Idempotência.
Criar item do catálogo
Corpo (body)
| Campo | Tipo | Obrigatório | Descriçã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."
]
}
} Atualizar item
Seção intitulada “Atualizar item”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.
Atualizar item do catálogo
Parâmetros de caminho
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
id | string | Sim | ID do item (UUID). |
Corpo (body)
| Campo | Tipo | Obrigatório | Descriçã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
} Remover item
Seção intitulada “Remover item”Remover item do catálogo
Parâmetros de caminho
| Campo | Tipo | Obrigatório | Descriçã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.