Integração via API REST

Endereço da API: https://distsys.com — nos exemplos ele aparece como {{baseUrl}}, a mesma variável da collection do Postman.

Como funciona

A API permite que os sistemas da sua corporação (ERP, PDV, WMS, BI) conversem com a Distsys sem intervenção manual. Os dados são organizados assim:

  • Corporação — a empresa dona da conta. Cada credencial de API pertence a uma corporação e só enxerga os dados dela.
  • Lojas (stores) — as unidades (CNPJs) da corporação. Cada loja conecta as suas contas nos marketplaces.
  • Itens (items) — o cadastro de produtos da corporação, identificado pelo código do seu ERP e compartilhado por todas as lojas.
  • Preço e estoque — são de cada loja: o mesmo item pode ter preço e estoque diferentes em cada unidade.
  • Anúncios (offers) — os anúncios da loja em cada marketplace, importados automaticamente das contas conectadas ou cadastrados pela API, e vinculados aos itens.
  • Vendas (sales) — os pedidos da loja, importados dos marketplaces ou enviados pela API (vendas de outros canais, nota fiscal e andamento da entrega).

Início rápido

  1. Um administrador da corporação entra na Distsys, abre a página da corporação e cria uma credencial de API no card Credenciais de API, escolhendo os escopos (permissões) e, se quiser, as lojas permitidas.
  2. Copie o client_id e o client_secret. O segredo aparece uma única vez.
  3. O seu sistema troca a credencial por um token em POST /oauth2/token.
  4. Use o token no cabeçalho Authorization: Bearer <token> em todas as chamadas a /v1. Ele vale 15 minutos: peça um novo quando expirar.

Collection do Postman

Distsys API v1 — collection com todos os exemplos

Autenticação, lojas, itens, preços e estoques, anúncios e vendas.

Baixar collection
  1. No Postman, clique em Import e escolha o arquivo baixado.
  2. Na aba Variables da collection, preencha clientId e clientSecret (e ajuste baseUrl, se necessário).
  3. Execute 1. Autenticação › Obter token: o token é salvo em accessToken e usado automaticamente pelas demais requisições.
  4. As requisições de criação gravam os ids retornados (storeId, offerId, saleId) para as seguintes. Você também pode rodar a pasta inteira no Runner.

1. Autenticação (OAuth 2.0 Client Credentials)

Envie o client_id e o client_secret em HTTP Basic (recomendado) ou no corpo do formulário. O parâmetro opcional scope pede só parte dos escopos da credencial.

curl -X POST {{baseUrl}}/oauth2/token \
  -u "$CLIENT_ID:$CLIENT_SECRET" \
  -d grant_type=client_credentials
{
  "access_token": "eyJraWQiOi...",
  "token_type": "Bearer",
  "expires_in": 900,
  "scope": "stores:read items:read items:write stock:write"
}

O token é um JWT assinado (RS256). A chave pública está em GET /oauth2/jwks. Se a credencial for revogada, os tokens dela deixam de valer na hora.

Escopos

EscopoPermite
stores:readLer lojas
stores:writeCadastrar e alterar lojas
items:readLer itens, preços e estoques
items:writeCadastrar e alterar itens
offers:readLer anúncios
offers:writeCadastrar e alterar anúncios
prices:writeAtualizar preços por loja
stock:writeAtualizar estoques por loja
sales:readLer vendas
sales:writeCadastrar e alterar vendas

Convenções e erros

  • JSON em UTF-8. Envie Content-Type: application/json nos corpos.
  • Valores monetários com ponto e até 2 casas: 59.90.
  • Datas em ISO-8601 com fuso: 2026-10-22T10:15:30-03:00.
  • Listas paginadas: page (a partir de 0) e size (padrão 100, máximo 500). Resposta: {"data": [...], "page": 0, "size": 100, "total": 250}.
  • POST cria (resposta 201 com o cabeçalho Location); PATCH altera só os campos enviados; PUT em itens cria ou atualiza pelo código.
  • Operações em lote aceitam até 500 entradas e processam cada uma separadamente (succeeded, failed e o erro de cada código).

Erros seguem o formato application/problem+json (RFC 7807) com um code estável:

{
  "status": 403,
  "title": "Forbidden",
  "detail": "O token não tem o escopo items:write.",
  "code": "insufficient_scope"
}
HTTPcodeQuando
400invalid_requestCampo obrigatório ausente ou valor inválido.
401invalid_tokenToken ausente, expirado ou de credencial revogada.
403insufficient_scopeO token não tem o escopo exigido.
403store_restrictedCredencial restrita a lojas tentando cadastrar loja.
404not_foundRecurso inexistente ou de outra corporação/loja não permitida.
409conflictCNPJ, anúncio (externalId) ou pedido já cadastrado.

2. Lojas (stores)

MétodoCaminhoEscopoDescrição
GET/v1/storesstores:readLista as lojas permitidas à credencial.
GET/v1/stores/{storeId}stores:readDetalha uma loja.
POST/v1/storesstores:writeCadastra uma loja na corporação (credenciais sem restrição de lojas).
PATCH/v1/stores/{storeId}stores:writeAltera os campos enviados.
POST {{baseUrl}}/v1/stores
{
  "name": "Loja Centro",
  "taxNumber": "12.345.678/0001-90",
  "zipCode": "01001-000",
  "state": "SP",
  "city": "São Paulo",
  "address": "Praça da Sé, 100",
  "phone": "(11) 3333-4444",
  "stateTaxNumber": "123.456.789.000"
}
201 Created
{
  "id": "6ada1f7f8b57d20833b729ea",
  "name": "Loja Centro",
  "taxNumber": "12.345.678/0001-90",
  "city": "São Paulo",
  "state": "SP",
  "connectedMarketplaces": [],
  "zipCode": "01001-000",
  "address": "Praça da Sé, 100",
  "phone": "(11) 3333-4444",
  "site": null,
  "stateTaxNumber": "123.456.789.000",
  "cityTaxNumber": null
}
A conexão da loja com os marketplaces (Mercado Livre, Amazon, Magalu...) é feita pela tela da loja, pois exige a autorização do vendedor em cada marketplace.

3. Itens (items)

Os itens são da corporação e identificados pelo código do seu ERP ({code}, até 60 caracteres; codifique na URL caracteres especiais).

MétodoCaminhoEscopoDescrição
GET/v1/items?updatedSince=&page=&size=items:readLista os itens (filtro opcional por data de alteração).
GET/v1/items/{code}items:readDetalha um item.
PUT/v1/items/{code}items:writeCadastra ou atualiza o item (idempotente).
POST/v1/items/batchitems:writeCadastra ou atualiza até 500 itens.
PUT {{baseUrl}}/v1/items/CAM-001
{
  "description": "Camiseta básica algodão",
  "ean13": "7891234567895",
  "brand": "Marca X",
  "enabled": true
}
POST {{baseUrl}}/v1/items/batch
{
  "items": [
    { "code": "CAM-002", "description": "Camiseta gola V" },
    { "code": "CAM-003", "description": "Camiseta manga longa", "ean13": "7891234567802" }
  ]
}

200 OK
{ "succeeded": 2, "failed": 0, "results": [ { "code": "CAM-002", "success": true, "error": null }, ... ] }

Preços e estoques por loja

O item precisa estar cadastrado antes. Preço e estoque são gravados na loja informada.

MétodoCaminhoEscopoDescrição
GET/v1/stores/{storeId}/itemsitems:readItens com o preço e o estoque da loja.
GET/v1/stores/{storeId}/items/{code}items:readPreço e estoque de um item na loja.
PUT/v1/stores/{storeId}/items/{code}/priceprices:write{"price": 59.90}
PUT/v1/stores/{storeId}/items/{code}/stockstock:write{"quantity": 12}
POST/v1/stores/{storeId}/prices/batchprices:write{"items": [{"code": "CAM-001", "price": 59.90}]}
POST/v1/stores/{storeId}/stock/batchstock:write{"items": [{"code": "CAM-001", "quantity": 12}]}

4. Anúncios (offers)

Os anúncios das contas conectadas são importados automaticamente. Pela API você também pode cadastrar e alterar anúncios da loja e vinculá-los aos itens (itemCode; envie "" para desvincular).

MétodoCaminhoEscopoDescrição
GET/v1/stores/{storeId}/offers?marketplace=&itemCode=offers:readLista os anúncios da loja.
GET/v1/stores/{storeId}/offers/{offerId}offers:readDetalha um anúncio.
POST/v1/stores/{storeId}/offersoffers:writeCadastra um anúncio.
PATCH/v1/stores/{storeId}/offers/{offerId}offers:writeAltera os campos enviados.
POST {{baseUrl}}/v1/stores/{storeId}/offers
{
  "marketplace": "mercadolivre",
  "externalId": "MLB1234567890",
  "sku": "CAM-001",
  "title": "Camiseta básica algodão",
  "price": 59.90,
  "stock": 10,
  "status": "ACTIVE",
  "url": "https://produto.mercadolivre.com.br/MLB-1234567890",
  "itemCode": "CAM-001"
}

Marketplaces: mercadolivre, amazon, magalu, shopee, shein, casasbahia, tiktokshop. Status: ACTIVE, PAUSED, INACTIVE, CLOSED.

O cadastro pela API registra o anúncio na Distsys; a publicação automática de novos anúncios nos marketplaces será disponibilizada em uma próxima versão. Anúncios de contas conectadas são atualizados pela sincronização com o marketplace.

5. Vendas (sales)

As vendas dos marketplaces conectados são importadas automaticamente. Pela API você também pode lançar vendas de outros canais e atualizar status, nota fiscal e datas de pagamento e envio.

MétodoCaminhoEscopoDescrição
GET/v1/stores/{storeId}/sales?status=&marketplace=&createdFrom=&createdTo=sales:readLista as vendas (mais recentes primeiro).
GET/v1/stores/{storeId}/sales/{saleId}sales:readDetalha uma venda.
POST/v1/stores/{storeId}/salessales:writeCadastra uma venda (única por marketplace + número do pedido).
PATCH/v1/stores/{storeId}/sales/{saleId}sales:writeAltera status, nota fiscal, datas, comprador ou valor.
POST {{baseUrl}}/v1/stores/{storeId}/sales
{
  "marketplace": "mercadolivre",
  "externalOrderId": "2000001234567890",
  "buyerName": "Maria Silva",
  "totalAmount": 119.80,
  "status": "PAID",
  "createdAt": "2026-10-22T09:30:00-03:00",
  "paidAt": "2026-10-22T09:31:00-03:00"
}
PATCH {{baseUrl}}/v1/stores/{storeId}/sales/{saleId}
{
  "status": "SHIPPED",
  "invoiceKey": "35261012345678000190550010000012341000012345",
  "invoiceNumber": "1234",
  "shippedAt": "2026-10-23T14:00:00-03:00"
}

Status aceitos: NEW, PAID, INVOICED, SHIPPED, DELIVERED, CANCELLED, REFUNDED. A chave da nota fiscal (invoiceKey) tem 44 dígitos.