CadastroProduto
CRUD de produto (tabela SB1) via MsExecAuto
do MATA010, encapsulado pelo wrapper U_MT010MVC
(src/lib/MAT/MT010MVC.prw). Identificador externo é o
próprio código de produto B1_COD, informado pelo cliente
no path (igual ao formulário padrão do Protheus). Não há geração
automática de chave — conflito de chave em POST resulta em
409 direto.
Endpoint OAuth2
Sem credenciais? Você pode pegar o token rodando
./src/scripts/get-token.sh na biblioteca e
colar o access_token aqui no campo de refresh
(ou clique em "Logout" para limpar e voltar ao fake).
Vinculação com o ERP
Convenções
Identificador externo. A chave externa é o próprio
B1_COD (passado no path como {produto}),
igual ao formulário padrão do Protheus. Tamanho máximo conforme
TamSX3("B1_COD") (tipicamente 15 caracteres). Não há
geração automática de código — conflito de chave em POST
devolve 409 sem retry.
Tabela sem loja. Diferente de SA1/SA2,
a SB1 não tem campo de loja. O índice 1 é
B1_FILIAL+B1_COD e o índice 2 é
B1_FILIAL+B1_DESC — toda busca por descrição passa pelo
índice 2 com prefix normalizado (sem acento, uppercase) via
U_NoAcento.
Whitelist conservador. O allowlist
(CAMPOS_ALLOW) cobre apenas os campos básicos do
MATA010: B1_DESC, B1_TIPO,
B1_UM, B1_LOCPAD, B1_GRUPO,
B1_POSIPI, B1_ORIGEM, B1_RASTRO
e o par B1_MSBLQL/B1_MSBLQD. Campos custom
(B1_X*) ficam fora da biblioteca; entram em projeto
cliente. Campos no payload fora do allowlist são silenciosamente
descartados pelo parser.
Bloqueio TOTVS. A rev3 incorporou o padrão
B1_MSBLQL/B1_MSBLQD via U_C980Blq.
Em produto bloqueado, o PUT só aceita campos do par de
bloqueio (caminho de desbloqueio); qualquer outro campo no payload
retorna 422 com o motivo. B1_MSBLQD é
parseado a partir de string ISO YYYY-MM-DD. O campo
ainda não entra em CAMPOS_GET enquanto
U_RestMontaRegistro não suportar serialização
Date-aware (tarefa transversal, fora do escopo deste
endpoint).
Sem id técnico universal. Esta versão não expõe
rota /_byid. Ids técnicos como recno ou
B1_MSUID não fazem parte do contrato — o cliente
referencia produto sempre pelo B1_COD.
Paginação. /_list usa
page/pageSize com default 50
e máximo 500. Não há delta-sync por recno
nesta revisão — a sincronização incremental, quando necessária, é
implementada do lado consumidor a partir do B1_COD
(ordenação estável pela chave do índice 1).
Produto
CRUD por B1_CODDescrição
Retorna o produto pesquisado pelo código B1_COD.
Aplica filtro de filial (xFilial("SB1")) e respeita o
whitelist de CAMPOS_GET definido no .prw.
O parâmetro opcional fields reduz o conjunto de
campos retornados.
O envelope é { success: true, data: Produto }.
B1_MSBLQD não é retornado nesta revisão (depende de
serialização Date-aware ainda não disponível).
Path parameter
TamSX3("B1_COD") (tipicamente 15 caracteres).Cenário
direta
retorna todos os campos do whitelist; com-fields
projeta um subset via query; expand-complemento
anexa complemento: {B5_CEME, B5_MARCA} a partir
de SB5 (rev5/expand).
Query parameters
CAMPOS_GET.complemento — anexa
complemento: { B5_CEME, B5_MARCA } de SB5.
Sem registro em SB5 → complemento: null.
Custo: 1 DbSeek por item retornado.
Exemplo da requisição (cenário ativo)
GET https://erpapi.jetme.com.br/api/99/01/WsProduto/ZZ_TEST_001 Authorization: Bearer eyJhbGciOiJIUzI1NiIs… Accept: application/json
GET https://erpapi.jetme.com.br/api/99/01/WsProduto/ZZ_TEST_001?fields=B1_COD,B1_DESC,B1_UM,B1_TIPO Authorization: Bearer eyJhbGciOiJIUzI1NiIs… Accept: application/json
GET https://erpapi.jetme.com.br/api/99/01/WsProduto/ZZ_TEST_001?expand=complemento Authorization: Bearer eyJhbGciOiJIUzI1NiIs… Accept: application/json
Respostas
{ success: true, data: Produto }.fields contém coluna fora do allowlist. Tier: validation-error.B1_COD informado. Tier: not-found.Descrição
Inclui um produto novo via MATA010 em modo
3 (MODEL_OPERATION_INSERT). A chave
externa B1_COD vem do path — se vier também no
payload, é silenciosamente ignorada pelo parser.
- Whitelist de campos: ver
ProdutoPayload. - Sem
GetSXENum— código é definido pelo cliente. - Conflito de chave devolve
409direto, sem retry. - Validações X3 (
B1_GRUPOemSBM,B1_LOCPADemNNR, enumsB1_TIPO/B1_ORIGEM) são aplicadas peloMsExecAuto.
Path parameter
Request body
CAMPOS_ALLOW. Schema completo em
ProdutoPayload.
Body fields (variam por cenário)
PA, MP, ME, SV.0..8).{S,L,N}. Valor fora retorna 422 (rev4/fValDom).com-rastro-lote, deve ser L (lote) ou S (sublote).{S,N}; valor fora retorna 422 (rev4/fValDom).POST https://erpapi.jetme.com.br/api/99/01/WsProduto/ZZ_TEST_001 Authorization: Bearer eyJhbGciOiJIUzI1NiIs… Content-Type: application/json Accept: application/json { "B1_DESC": "TESTE_REST PRODUTO", "B1_TIPO": "PA", "B1_UM": "UN", "B1_LOCPAD": "00", "B1_GRUPO": "", "B1_ORIGEM": "0", "B1_RASTRO": "N" }
POST https://erpapi.jetme.com.br/api/99/01/WsProduto/ZZ_TEST_001 Authorization: Bearer eyJhbGciOiJIUzI1NiIs… Content-Type: application/json Accept: application/json { "B1_DESC": "PARAFUSO SEXTAVADO M8 X 25", "B1_TIPO": "MP", "B1_UM": "PC", "B1_LOCPAD": "00", "B1_GRUPO": "0001", "B1_POSIPI": "73181500", "B1_ORIGEM": "0", "B1_RASTRO": "N" }
POST https://erpapi.jetme.com.br/api/99/01/WsProduto/ZZ_TEST_001 Authorization: Bearer eyJhbGciOiJIUzI1NiIs… Content-Type: application/json { "B1_DESC": "PRODUTO COM ENDERECO", "B1_TIPO": "MP", "B1_UM": "UN", "B1_LOCPAD": "00", "B1_ORIGEM": "0", "B1_RASTRO": "N", "B1_LOCALIZ": "S" }
POST https://erpapi.jetme.com.br/api/99/01/WsProduto/ZZ_TEST_001 Authorization: Bearer eyJhbGciOiJIUzI1NiIs… Content-Type: application/json { "B1_DESC": "MATERIA-PRIMA COM LOTE", "B1_TIPO": "MP", "B1_UM": "KG", "B1_LOCPAD": "00", "B1_ORIGEM": "0", "B1_RASTRO": "L" }
Respostas
CrudResponse com data contendo o B1_COD confirmado.B1_COD informado (chave única do índice 1). Tier: business-error.MsExecAuto do MATA010 rejeitou (campo obrigatório ausente, enum inválido, B1_GRUPO inexistente em SBM, B1_LOCPAD inexistente em NNR, etc). Tier: business-error.Descrição
Altera campos do produto via MATA010 em modo
4 (MODEL_OPERATION_UPDATE). Aceita
qualquer subconjunto do whitelist CAMPOS_ALLOW.
Campos fora do allowlist são silenciosamente ignorados.
Restrições. A chave B1_COD não
pode ser alterada via PUT — o seek é feito pelo código do path.
O par B1_MSBLQL/B1_MSBLQD tem
tratamento dedicado: em produto bloqueado, o PUT só aceita
esses dois campos (caminho de desbloqueio);
qualquer outro campo retorna 422 com o motivo do
bloqueio (formato U_C980Blq).
Path parameter
Request body
Body fields (variam por cenário)
1 = Inativo (bloqueia), 2 = Ativo (libera).YYYY-MM-DD (bloqueia até essa data) ou "" para limpar.PUT https://erpapi.jetme.com.br/api/99/01/WsProduto/ZZ_TEST_001 Authorization: Bearer eyJhbGciOiJIUzI1NiIs… Content-Type: application/json Accept: application/json { "B1_DESC": "TESTE_REST PRODUTO ALTERADO", "B1_UM": "UN" }
PUT https://erpapi.jetme.com.br/api/99/01/WsProduto/ZZ_TEST_001 Authorization: Bearer eyJhbGciOiJIUzI1NiIs… Content-Type: application/json Accept: application/json { "B1_MSBLQL": "2" }
PUT https://erpapi.jetme.com.br/api/99/01/WsProduto/ZZ_TEST_001 Authorization: Bearer eyJhbGciOiJIUzI1NiIs… Content-Type: application/json Accept: application/json { "B1_MSBLQL": "1", "B1_MSBLQD": "2026-12-31" }
PUT https://erpapi.jetme.com.br/api/99/01/WsProduto/ZZ_TEST_001 Authorization: Bearer eyJhbGciOiJIUzI1NiIs… Content-Type: application/json Accept: application/json { "B1_MSBLQL": "2", "B1_MSBLQD": "" }
Respostas
CrudResponse.SBM/NNR) ou produto bloqueado com payload tocando campo fora do par B1_MSBLQL/B1_MSBLQD. Tier: business-error.Descrição
Exclui o produto via MATA010 em modo 5
(MODEL_OPERATION_DELETE). O MsExecAuto
do MATA010 rejeita exclusão quando há dependências (saldos em
estoque, movimentos, estruturas de produto, itens de pedido /
nota vinculados).
O wrapper U_MT010MVC em modo DELETE
não aplica SetValue sobre os
campos — basta o alias SB1 estar posicionado pelo
endpoint antes da chamada (fix incorporado durante o smoke de
05/05/2026, conforme APRENDIZADOS.md).
Path parameter
Cenário
Exemplo da requisição (cenário ativo)
DELETE https://erpapi.jetme.com.br/api/99/01/WsProduto/ZZ_TEST_001 Authorization: Bearer eyJhbGciOiJIUzI1NiIs… Accept: application/json
Respostas
CrudResponse.Listagem
Listagem paginada e typeaheadDescrição
Lista produtos com filtros opcionais por cod
(prefix sobre o índice 1) ou desc (prefix
normalizado sobre o índice 2 — sem acento, uppercase, via
U_NoAcento). Sem filtro, retorna a página corrente
ordenada por B1_FILIAL+B1_COD.
Cenário
por-pagina: sem filtros, navega pela base.
por-prefixo: filtra cod ou
desc. com-fields: projeção.
Query parameters
B1_COD (índice 1).B1_DESC — sem acento, uppercase (índice 2).CAMPOS_GET.1, mínimo 1).50, máx 500).complemento anexa {B5_CEME, B5_MARCA}
de SB5 em cada item (rev5). Custo: 1 DbSeek por linha.
Exemplo da requisição (cenário ativo)
GET https://erpapi.jetme.com.br/api/99/01/WsProduto/_list?page=1&pageSize=50 Authorization: Bearer eyJhbGciOiJIUzI1NiIs… Accept: application/json
GET https://erpapi.jetme.com.br/api/99/01/WsProduto/_list?cod=ZZ_&pageSize=200 Authorization: Bearer eyJhbGciOiJIUzI1NiIs… Accept: application/json
GET https://erpapi.jetme.com.br/api/99/01/WsProduto/_list?fields=B1_COD,B1_DESC,B1_UM Authorization: Bearer eyJhbGciOiJIUzI1NiIs… Accept: application/json
Respostas
pageSize > 500, fields com coluna fora do allowlist).Descrição
Busca rápida (typeahead) para autocomplete de UI. Retorna
lista enxuta com apenas cod e desc —
não devolve o schema completo de Produto. Em modo
contains, o scan é limitado pelo cap interno
(SEARCH_SCAN_CAP = 2000 registros) para evitar
varredura completa em bases grandes.
Cenário
prefix: busca pelo início (default, usa índices).
contains: busca em qualquer posição (scan
limitado a SEARCH_SCAN_CAP=2000).
Query parameters
2 caracteres.prefix.prefixcontains10, máx 25).complemento anexa {B5_CEME, B5_MARCA}
de SB5 em cada sugestão (rev5). Usar com parcimônia em
typeahead — 1 DbSeek extra por item.
Exemplo da requisição (cenário ativo)
GET https://erpapi.jetme.com.br/api/99/01/WsProduto/_search?q=paraf&limit=10 Authorization: Bearer eyJhbGciOiJIUzI1NiIs… Accept: application/json
GET https://erpapi.jetme.com.br/api/99/01/WsProduto/_search?q=paraf&match=contains&limit=25 Authorization: Bearer eyJhbGciOiJIUzI1NiIs… Accept: application/json
Respostas
success, count, data[] com cod / desc.q ausente ou < 2 caracteres, match fora do enum, limit > 25.Schemas
Definições canônicas — campos com origemSX3 rastreável
/{produto},
/_list). Campos efetivamente retornados dependem de
CAMPOS_GET e do filtro fields.
B1_MSBLQD não entra nesta versão (dependente de
serialização Date-aware no helper
U_RestMontaRegistro).
PA (produto acabado), MP (matéria-prima), ME (material de embalagem), SV (serviço).SAH).NNR).SBM).0 = nacional padrão.N = sem rastro, S = rastreado por sublote, L = rastreado por lote. Valor fora do domínio retorna 422 antes do MATA010 (rev4 / fValDom).SLNS = sim, N = não (default). Valor fora do domínio retorna 422 antes do MATA010 (rev4 / fValDom).SN1 = inativo (bloqueado), 2 = ativo (default no dicionário).12POST e PUT.
Whitelist definida em CAMPOS_ALLOW no
.prw; campos fora do whitelist são silenciosamente
descartados pelo parser. B1_COD vem do path — se
vier no payload, é ignorado.
PA, MP, ME, SV.SAH).NNR). Obrigatório nesta build — quando vazio ou inválido, o validador retorna VLDDATA_OBRIGAT B1_LOCPAD OBRIGAT.SBM quando informado). Aceita string vazia.0 a 8 conforme tabela da SEFAZ.S = sublote, L = lote, N = não utiliza. Valor fora do domínio retorna 422 antes do MATA010 (rev4 / fValDom).SLNS = sim, N = não (default). Valor fora do domínio retorna 422 antes do MATA010 (rev4 / fValDom).SN1 = inativo, 2 = ativo. Em produto bloqueado, é um dos dois únicos campos aceitos no PUT (caminho de desbloqueio).12YYYY-MM-DD. Parser converte para Date internamente via sToD. Em produto bloqueado, é o outro campo aceito no PUT (junto de B1_MSBLQL).data
traz a chave do produto confirmada (POST) ou string vazia
(PUT/DELETE).
true em respostas de sucesso.B1_COD confirmado. Em PUT/DELETE pode ser string vazia ou objeto auxiliar.U_RestErro
(RestUtils.prw). data pode conter o token
interno da causa (ex: trecho do NomeAutoLog via
fMT010Log) para tratamento programático, quando
aplicável.
false em erros.MsExecAuto via fMT010Log).Cenários
Catálogo de combinações de payload/query reconhecidas pelos métodos. Cada cenário usa o mesmo schema mas demonstra um uso típico distinto. Tier semântico no slug (-minimo, -com-*, -invalido); endpoint no type-pill.
CAMPOS_ALLOW realmente necessários para incluir o
produto. B1_RASTRO="N" (sem rastro),
B1_LOCALIZ omitido (default "N").
Quando usar: produto comum, sem controle de lote nem endereçamento.
0..8).N = sem rastro.B1_LOCALIZ="S"). Habilita reservas em endereços
(SBE/SBF) e exige confirmação de
endereço em movimentações.
Pré-validação: rev4/
fValDom
rejeita 422 se B1_LOCALIZ não estiver em
{S,N}.
N ou conforme uso.B1_RASTRO="L"). Movimentações exigem lote
(B7_LOTECTL no inventário, D3_LOTECTL
em movimentos).
Pré-validação: rev4/
fValDom
rejeita 422 se B1_RASTRO não estiver em
{S,L,N}.
Nota: SB1 nesta base não tem campo dependente do flag — diferente do que a PEN supunha.
L = lote; S = sublote.B1_RASTRO fora do domínio {S,L,N}.
fValDom (rev4) intercepta antes do
MATA010 e devolve 422 com mensagem
clara — em vez do HELP opaco
"FWFormFieldsModel id não é válido".
Mensagem: "B1_RASTRO inválido: 'X'. Valores aceitos: S (sublote), L (lote), N (não utiliza)."
S/L/N.B1_LOCALIZ fora do domínio {S,N}.
fValDom intercepta e devolve 422.
Mensagem: "B1_LOCALIZ inválido: 'X'. Valores aceitos: S (sim), N (não)."
S/N.Pré-condição:
B1_MSBLQL != "1" e
dDataBase <= B1_MSBLQD (registro não-bloqueado).
B1_MSBLQL="1".
Em produto bloqueado, este é um dos dois únicos
payloads aceitos (o outro é
bloquear-com-data).
Qualquer outro campo no payload provoca 422
(bloqueado-rejeita).
2 = Ativo (libera).B1_MSBLQL="1" (Inativo) e B1_MSBLQD
no futuro — o bloqueio fica ativo enquanto
dDataBase > B1_MSBLQD.
Variante:
desbloqueio
libera; B1_MSBLQD="" limpa a data (vide YAML
limparData).
1 = Inativo.YYYY-MM-DD.B1_MSBLQL/B1_MSBLQD. O endpoint
consulta U_C980Blq("SB1"); se bloqueado +
fSoBlq falso, retorna 422 com o
motivo do bloqueio.
Mensagem: "Produto bloqueado: <motivo>. Apenas B1_MSBLQL e B1_MSBLQD podem ser alterados."
MATA010 em modo
5 (MODEL_OPERATION_DELETE). Sem
body. Identidade vem da URL (B1_COD).
Pré-condição: sem movimentos dependentes no estoque (
SB2/SB7/SD*); senão o
MVC rejeita.
CAMPOS_GET para o
B1_COD informado. Sem body; identidade na URL.
Retorna 404 quando inexistente.
SB1
ordenado por B1_COD. Use
page/pageSize para navegar
(pageSize default 50, máx 500).
cod=ZZ retorna
tudo que começa com ZZ) ou descrição
(desc=PARAFUSO). Combinável com paginação.
Quando usar: escopo administrativo (limpeza de sentinels, conferência de família).
fields=B1_COD,B1_DESC,B1_UM reduz
payload aos campos pedidos (interseção com
CAMPOS_GET). Útil em integrações de baixa
banda ou em front que só precisa de um subset.
q de 2 chars; varre até
SEARCH_SCAN_CAP registros para não travar.
prefix (default) ou contains.