Documentação da API

API do Fluv Hub: pedidos, produtos, fotos e estoque

Com um token, o sistema da sua loja (ou o seu site) manda as vendas, cadastra e atualiza produtos com fotos e variações e muda o estoque no Fluv Hub. Tudo em JSON, por HTTPS.

Onde pegar o token: Lojas & Marketplaces › Conectar conta › Loja virtual › API própria › botão </>

3 rotas, 1 tokenAtualizado em

Visão geral

São três endereços. O mesmo token serve para os três; o de produtos e o de estoque só funcionam depois de ligados no cartão da loja.

RotaPara quêPrecisa ligar?
/pedidos.phpMandar as vendas da loja (e mudar o status: pago, enviado, cancelado). O estoque baixa sozinho.Não — já vem ligada
/produtos.phpCriar e atualizar produtos, variações e fotos.Sim: "Receber produtos pela API"
/estoque.phpDizer o saldo certo de um SKU, ou somar/tirar unidades.Sim: "Receber estoque pela API"

Endereço base: https://fluvhub.com/sistema/apps/lojas_virtuais/api

A API nunca apaga. Não existe DELETE: produto sai de venda com "ativo": false, variação que você não mandar fica como está, e todo saldo mudado aparece no histórico do produto com o nome da sua loja.

Começar em 3 passos

  1. Crie a conexão. No Fluv Hub, vá em Lojas & Marketplaces › Conectar conta › Loja virtual e escolha API própria. Dê um nome (ex.: "Meu site") e clique em Criar.
  2. Copie o token. No cartão da loja, o botão </> mostra os três endereços e o token (começa com fh_). O botão "Copiar tudo para o dev" junta tudo num texto só.
  3. Ligue o que vai usar. Na engrenagem do cartão, ligue "Receber produtos pela API" e/ou "Receber estoque pela API". Os dois nascem desligados. Ligar o estoque pede um usuário que possa alterar estoque.

Teste a conexão (não grava nada):

Terminal
curl https://fluvhub.com/sistema/apps/lojas_virtuais/api/produtos.php \
  -H "Authorization: Bearer fh_SEU_TOKEN"
Resposta
{ "ok": true, "loja": "Meu site", "mensagem": "Conectado. Envie produtos por POST; consulte com ?codigo=<SKU>.", "estoque_pela_api": true }

Token e segurança

  • Mande o token no cabeçalho Authorization: Bearer fh_… (ou X-Fluv-Token: fh_…).
  • Nunca no endereço. Produtos e estoque recusam ?token= com 401, porque endereço fica gravado em log. (Pedidos ainda aceita, para quem já usava, mas prefira o cabeçalho.)
  • Só HTTPS. Chamada sem HTTPS em produtos e estoque volta 403.
  • O token diz qual é a loja e a empresa. Nenhum campo do corpo troca isso.
  • Guarde o token no servidor, nunca no JavaScript do navegador do cliente.
  • Vazou? Cartão da loja › </> › Gerar outro token. O antigo para na hora.
  • Toda chamada fica registrada (loja, rota, resultado). Saldo e cadastro mudados aparecem no histórico do produto como "API <nome da loja>".

Regras de toda chamada

  • Corpo em JSON UTF-8, com Content-Type: application/json. Máximo de 2 MB por chamada.
  • Um item ou um lote. Mande um objeto, ou uma lista: {"pedidos": […]}, {"produtos": […]}, {"itens": […]} — até 100 por chamada.
  • Limite: 120 chamadas por minuto por loja. Passou, volta 429: espere e mande em lote.
  • Números com ponto: 59.90. "59,90" é recusado (é ambíguo).
  • Teste sem gravar: acrescente ?teste=1 no endereço (ou "teste": true no corpo). A resposta diz o que aconteceria.
  • Pode repetir. Mandar o mesmo pedido, produto ou saldo de novo não duplica nada.

A resposta

Cada item do lote volta em resultados, na mesma ordem (indice), com ok e o que foi feito (acao) ou o motivo (erro). Um item errado não impede os outros.

Resposta de um lote
{
  "ok": false,
  "teste": false,
  "resultados": [
    { "indice": 0, "ok": true,  "codigo": "CAMISA-P", "acao": "criado" },
    { "indice": 1, "ok": false, "codigo": "CAMISA-M", "erro": "preco tem de ser número (use ponto: 59.90)" }
  ]
}
HTTPQuer dizer
200Tudo certo.
207Parte do lote entrou, parte não — veja resultados.
422Nada entrou — cada item diz o porquê.
400JSON inválido.
401Token ausente, errado, ou mandado no endereço.
403Rota desligada no cartão, estoque comandado pelo ERP, conta de demonstração ou sem HTTPS. O erro diz qual.
404Consulta (GET) de algo que não existe.
405Método errado (use POST para mandar e GET para consultar).
413Mais de 100 itens ou mais de 2 MB.
423A loja está pausada no Fluv Hub.
429Passou de 120 chamadas por minuto.

Pedidos

POST https://fluvhub.com/sistema/apps/lojas_virtuais/api/pedidos.php

Cada venda da loja vira um pedido em Pedidos, pronto para nota fiscal e etiqueta. Com o sku igual ao do Fluv Hub, o estoque baixa sozinho.

Corpo
{
  "id": "1042",
  "numero": "1042",
  "data": "2026-11-03T10:30:00-03:00",
  "status": "pago",
  "cliente": { "nome": "Maria Silva", "documento": "123.456.789-09",
               "email": "maria@email.com", "telefone": "11999998888" },
  "entrega": { "cep": "01001-000", "logradouro": "Praça da Sé", "numero": "100",
               "complemento": "", "bairro": "Sé", "cidade": "São Paulo", "uf": "SP" },
  "itens": [ { "sku": "CAMISA-P", "nome": "Camisa P", "quantidade": 2, "preco": 59.90, "desconto": 0 } ],
  "frete": 15.00,
  "desconto": 0,
  "total": 134.80,
  "pagamento": "Pix",
  "rastreio": "",
  "observacoes": ""
}
CampoTipoO que é
id obrigatóriotextoO id do pedido na sua loja. É a chave: o mesmo id de novo atualiza, nunca duplica.
itens[] obrigatóriolistaAo menos 1 item com quantidade e sku ou nome. preco é o unitário; desconto, o do item.
statustextopendente, pago (padrão), enviado, entregue ou cancelado. Aceita também em inglês (paid, shipped, cancelled…).
numerotextoO número que o cliente vê.
datadata e horaISO 8601, ex.: 2026-11-03T10:30:00-03:00.
clienteobjetonome, documento (CPF/CNPJ), email, telefone.
entregaobjetocep, logradouro, numero, complemento, bairro, cidade, uf.
frete, desconto, totalnúmeroValores do pedido em reais.
pagamentotextoForma de pagamento (ex.: Pix, Cartão 3x).
rastreio, observacoestextoCódigo de rastreio e observações.

Mudar o status

Mande o mesmo id com o status novo. cancelado cancela no Fluv Hub e devolve o estoque; enviado e entregue andam a situação para frente (nunca para trás).

acao de cada resultado: criado, atualizado, igual (nada mudou) ou ignorado (pedido pendente com a loja configurada para receber só pagos, ou cancelamento de um pedido que nunca entrou).

Consultar

GET https://fluvhub.com/sistema/apps/lojas_virtuais/api/pedidos.php?id=1042

numero_fluvhub é o número do pedido dentro do Fluv Hub (o prefixo da loja + o seu número).

Resposta
{ "ok": true, "pedido": { "id": "1042", "numero": "1042", "numero_fluvhub": "SITE-1042", "status": "pago", "total": 134.8, "recebido_em": "2026-11-03 10:30:12" } }

Produtos

POST https://fluvhub.com/sistema/apps/lojas_virtuais/api/produtos.php

Cria ou atualiza pelo codigo (o SKU). Existe = muda só os campos que você mandou; o resto fica como está. Não existe = cria (aí nome é obrigatório).

Corpo
{
  "codigo": "CAMISA-P",
  "nome": "Camisa P",
  "descricao": "<p>Algodão 100%</p>",
  "preco": 59.90,
  "custo": 21.00,
  "marca": "Minha Marca",
  "categoria": "Camisetas",
  "unidade": "UN",
  "peso": 0.25,
  "altura_cm": 3, "largura_cm": 20, "comprimento_cm": 30,
  "ncm": "61091000",
  "gtin": "7891234567895",
  "estoque_minimo": 2,
  "ativo": true,
  "estoque": 10,
  "fotos": ["https://cdn.minhaloja.com/camisa-p-1.jpg", "https://cdn.minhaloja.com/camisa-p-2.jpg"]
}
CampoTipoO que é
codigo obrigatóriotexto (até 60)O SKU. É a chave do produto.
nometexto (até 255)Obrigatório só para criar.
descricaotexto / HTMLAceita HTML simples (negrito, listas, parágrafos). Script e afins são removidos.
preconúmeroPreço de venda.
custonúmeroCusto de compra (vai para o Preço Sugerido). 0 não apaga o custo de hoje.
marca, categoria, unidadetextoCategoria que não existe é criada com o nome que você mandou. Unidade padrão: UN.
pesonúmero (kg)Peso com embalagem.
altura_cm, largura_cm, comprimento_cmnúmero (cm)Medidas da embalagem.
ncm, cesttextoPara a nota fiscal. Pontos são tirados (6109.10.00 → 61091000).
gtintextoCódigo de barras (EAN): 8, 12, 13 ou 14 dígitos.
estoque_minimointeiroEstoque mínimo do produto (o mesmo campo do cadastro).
ativotrue / falsefalse tira de venda (é assim que se "apaga").
estoqueinteiroSaldo certo. Só muda com "Receber estoque pela API" ligado — veja Estoque. Sem este campo, o saldo nunca é tocado.
fotoslista de endereçosVeja Fotos.
variacoeslistaVeja Variações.
  • Não mande null para "limpar" um campo (é recusado). Para não mudar, simplesmente não mande o campo.
  • Campo que não existe volta como aviso em avisos, não como erro.
  • acao: criado ou atualizado (com ?teste=1: criaria / atualizaria).
  • SKU de produto que vem do ERP integrado (Bling, Tiny…) é recusado: ele é cuidado lá.
  • O limite de produtos do seu plano vale igual ao da tela. Cada variação conta como um SKU.
  • Com estoque junto e a rota de estoque desligada, o produto salva e estoque.erro diz por que o saldo não mudou.

Consultar

GET https://fluvhub.com/sistema/apps/lojas_virtuais/api/produtos.php?codigo=CAMISA-P

Devolve o produto como está hoje: os mesmos campos, o saldo, as fotos (endereços públicos, a primeira é a capa) e, no produto com grade, as variacoes com saldo e fotos de cada uma.

Variações (cor, tamanho…)

Mande a grade no produto-mãe. Cada variação tem o próprio codigo (SKU) e até 2 atributos.

Corpo
{
  "codigo": "CAMISETA",
  "nome": "Camiseta Básica",
  "preco": 59.90,
  "fotos": ["https://cdn.minhaloja.com/camiseta.jpg"],
  "variacoes": [
    { "codigo": "CAM-AZ-M", "atributos": { "Cor": "Azul", "Tamanho": "M" }, "estoque": 3,
      "fotos": ["https://cdn.minhaloja.com/camiseta-azul.jpg"] },
    { "codigo": "CAM-AZ-G", "atributos": { "Cor": "Azul", "Tamanho": "G" }, "estoque": 5 },
    { "codigo": "CAM-PR-M", "atributos": { "Cor": "Preta", "Tamanho": "M" }, "preco": 64.90, "estoque": 0 }
  ]
}
  • Em cada variação: codigo e atributos (obrigatórios ao criar), e se quiser preco, custo, gtin, peso, medidas, estoque_minimo, ativo, estoque e fotos.
  • Nome, descrição, NCM e categoria são do produto-mãe.
  • Variação que já existe é encontrada pelo código. As que você não mandar ficam como estão — dá para mandar só a que mudou.
  • Produto com variações não tem estoque próprio: mande estoque em cada variação.
  • Atalho: mandar o código de uma variação direto no topo ({"codigo": "CAM-AZ-M", "preco": 69.9}) atualiza só ela.
  • A resposta traz estoque_variacoes e fotos_variacoes com o resultado de cada uma.

Fotos

Mande fotos como uma lista de endereços https://. O Fluv Hub baixa cada imagem, confere e guarda — a foto aparece no cadastro e vai para os anúncios como qualquer foto subida na tela.

Trecho do produto
"fotos": [
  "https://cdn.minhaloja.com/camisa-p-frente.jpg",
  "https://cdn.minhaloja.com/camisa-p-costas.jpg"
]
  • A galeria fica igual à lista, na ordem: a primeira é a capa. Foto que estava e não veio sai (inclusive a que foi subida à mão na tela).
  • Não mandou fotos? As fotos ficam como estão. Lista vazia [] é recusada (tirar todas, só pela tela).
  • O mesmo endereço não é baixado de novo. Pode mandar o catálogo inteiro toda hora. Trocou a imagem? Troque o endereço (ex.: …/camisa.jpg?v=2).
  • Até 12 fotos por produto e 4 próprias por variação (as do produto-mãe valem para ela).
  • Formatos JPG, PNG, WEBP ou GIF, até 15 MB, com pelo menos 300 px no menor lado (o ideal é 1200 px ou mais). A imagem é convertida para JPG de até 2000 px.
  • O endereço tem de abrir a imagem direto, sem login, com o nome do site (não IP).
  • Foto que falha não muda nada: se um endereço não abre ou a imagem não serve, o produto inteiro não é alterado e o erro diz qual (fotos[1]) e por quê.
  • Até 100 fotos novas por chamada. Num lote grande com muita foto nova, os produtos que passarem disso voltam com erro: mande-os na chamada seguinte.
  • Com ?teste=1 o endereço é conferido, mas nada é baixado: a resposta diz quantas fotos seriam baixadas (fotos.baixaria).
Resultado do produto
{ "indice": 0, "ok": true, "codigo": "CAMISA-P", "acao": "atualizado",
  "fotos": { "ok": true, "total": 2, "novas": 1, "removidas": 1 } }

Estoque

POST https://fluvhub.com/sistema/apps/lojas_virtuais/api/estoque.php

É o mesmo ajuste da tela de Estoque: o número segue para os anúncios ligados ao produto (Mercado Livre, Shopee, Magalu, TikTok Shop…), kits recalculam e o histórico do produto registra a mudança.

Saldo certo
{ "sku": "CAMISA-P", "estoque": 12 }
Somar ou tirar
{ "sku": "CAMISA-P", "somar": -2 }
Lote
{ "itens": [
  { "sku": "CAMISA-P", "estoque": 5 },
  { "sku": "CAMISA-M", "somar": 3, "motivo": "contagem" }
] }
CampoTipoO que é
sku obrigatóriotextoO SKU no Fluv Hub.
estoqueinteiro ≥ 0O saldo certo. Use este ou somar.
somarinteiroQuanto entrou (positivo) ou saiu (negativo).
motivotextoajuste (padrão) ou contagem (balanço/inventário).
entrada_ja_contadatextosim ou nao. Só quando a resposta trouxer uma pergunta (veja abaixo).
  • Só funciona com o estoque "Pelo Fluv Hub" ou "Misto" em Integrações › Modo de Operação. Em "Pelo sistema de gestão", quem manda é o ERP: volta 403.
  • Saldo que ficaria negativo é recusado e nada muda.
  • SKU que divide o saldo com outro (produto vinculado) ajusta o principal — a resposta diz qual em ajustado_em.
  • Kit (combo) não recebe número: o saldo dele vem dos componentes.
  • Se o produto acabou de receber entrada pelo anúncio, o item volta com pergunta: mande de novo com "entrada_ja_contada": "sim" (já está no saldo) ou "nao" (somar).
Resultado
{ "indice": 0, "sku": "CAMISA-P", "ok": true, "alterado": true,
  "estoque_antes": 10, "estoque_agora": 12, "resumo": "…" }

Com ?teste=1, cada item traz estoque_antes, estoque_depois, o_que_acontece e mudam_junto (SKUs que dividem o saldo), sem gravar.

Consultar

GET https://fluvhub.com/sistema/apps/lojas_virtuais/api/estoque.php?sku=CAMISA-P

Resposta
{ "ok": true, "sku": "CAMISA-P", "estoque": 12, "anuncios": [ … ] }

Traz também estoque_compartilhado_com quando o SKU divide o saldo e combo quando é kit.

Erros e o que fazer

MensagemO que fazer
Token ausente ou inválidoConfira o cabeçalho Authorization: Bearer fh_… (sem aspas, com o token inteiro).
Envie o token no cabeçalho…Tire o ?token= do endereço e gere outro token (o antigo pode ter ido para algum log).
Token não reconhecidoO token foi trocado. Pegue o novo no botão </> do cartão.
Desligado no Fluv Hub…Ligue "Receber produtos/estoque pela API" na engrenagem do cartão da loja.
Estoque pelo sistema de gestãoMude para "Pelo Fluv Hub" ou "Misto" em Integrações › Modo de Operação, ou mande o estoque para o ERP.
… tem de ser número (use ponto: 59.90)Mande número JSON (59.9), não texto com vírgula.
nome é obrigatório para criar o produtoProduto novo precisa de nome.
Limite de produtos do planoCada variação conta como um SKU. Aumente o plano ou desative SKUs que não usa.
fotos[i]: …Abra o endereço no navegador: tem de mostrar só a imagem, por https, sem login, com 300 px ou mais.
O saldo ficaria negativoConfira o saldo com GET antes de tirar unidades.
Precisa de resposta: …Mande o item de novo com "entrada_ja_contada": "sim" ou "nao".
Muitas chamadas / Limite de 120 por minutoJunte em lotes de até 100 e espere 1 minuto.

Exemplos de código

Atualizar preço, saldo e fotos de um produto. Troque fh_SEU_TOKEN pelo seu token.

curl -X POST https://fluvhub.com/sistema/apps/lojas_virtuais/api/produtos.php \
  -H "Authorization: Bearer fh_SEU_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"codigo":"CAMISA-P","preco":59.9,"estoque":12,"fotos":["https://cdn.minhaloja.com/camisa-p-1.jpg"]}'

Mandar um pedido

Terminal
curl -X POST https://fluvhub.com/sistema/apps/lojas_virtuais/api/pedidos.php \
  -H "Authorization: Bearer fh_SEU_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"id":"1042","status":"pago","cliente":{"nome":"Maria"},"itens":[{"sku":"CAMISA-P","quantidade":1,"preco":59.9}],"total":59.9}'

Cancelar o mesmo pedido

Terminal
curl -X POST https://fluvhub.com/sistema/apps/lojas_virtuais/api/pedidos.php \
  -H "Authorization: Bearer fh_SEU_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"id":"1042","status":"cancelado"}'

Sincronizar o estoque de vários SKUs

Terminal
curl -X POST https://fluvhub.com/sistema/apps/lojas_virtuais/api/estoque.php \
  -H "Authorization: Bearer fh_SEU_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"itens":[{"sku":"CAMISA-P","estoque":12},{"sku":"CAMISA-M","estoque":4}]}'
Dica de integração: mande o pedido assim que ele for pago e o estoque só quando ele mudar por fora das vendas (compra, devolução, contagem). A venda que entra pela rota de pedidos já baixa o saldo — mandar o estoque de novo depois de cada venda não é preciso.

Perguntas rápidas

Quanto custa usar a API?

Nada a mais: a API faz parte do Fluv Hub. Valem os limites do seu plano (por exemplo, o número de produtos).

A API apaga produto?

Não. Não existe rota de apagar. Para tirar um produto de venda, mande "ativo": false. Variação que você não mandar fica como está.

Posso mandar o catálogo inteiro toda hora?

Pode. Produto igual não muda nada, e foto com o mesmo endereço não é baixada de novo. Mande em lotes de até 100 e respeite 120 chamadas por minuto.

O estoque que mando vai para os marketplaces?

Vai. É o mesmo ajuste da tela de Estoque: o número segue para os anúncios ligados ao produto (menos os do Full).

Meu token vazou. E agora?

Em Lojas & Marketplaces, abra o cartão da loja, clique em </> e depois em "Gerar outro token". O antigo para de funcionar na hora.

Uso Bling ou Tiny. Posso mandar estoque pela API?

Só se o estoque estiver "Pelo Fluv Hub" ou "Misto" em Integrações › Modo de Operação. Em "Pelo sistema de gestão", quem manda no saldo é o ERP e a rota de estoque responde 403.