1. Forge
  2. Desenvolvedores
Documentação aberta · API v1

Integre a sua aplicação ao Forge

Envie vendas da sua loja virtual ou marketplace, leads para campanhas e avisos de WhatsApp. Uma chave de API, JSON simples e chamadas seguras para repetir.

Visão geral

A API de integração permite que sistemas externos (loja virtual, marketplace, ERP, automações) enviem dados ao Forge. Todas as rotas usam a mesma chave de API da empresa e o mesmo formato de resposta.

Endereço base
https://forge.carvalhosilvatech.com.br
Formato
JSON (Content-Type: application/json), propriedades em camelCase
Autenticação
Chave de API da empresa (fgk_...)
Limite
120 requisições por minuto por endereço IP
RotaPara que serve
POST /api/integracoes/vendasEnviar uma venda já paga. Ela vai para a conferência no Forge e só vira pedido depois da confirmação.
POST /api/integracoes/contatosCriar ou atualizar um lead com tags e dados, para disparar campanhas.
POST /api/integracoes/contatos/remover-tagsTirar o lead de um fluxo (por exemplo, quando ele comprou).
POST /api/integracoes/notificacoesEnviar uma mensagem de WhatsApp ao cliente, pelo número conectado da empresa.

Começando

1. Crie a chave de API

Um Administrador da empresa cria a chave no Forge, em WhatsApp → Avisos aos clientes → Integração com outras ferramentas → Nova chave.

  • A chave é exibida uma única vez. Guarde em uma variável de ambiente ou cofre de segredos.
  • Cada empresa pode ter até 5 chaves ativas. Use uma chave por aplicação, para revogar uma sem afetar as outras.
  • A chave pode ser revogada a qualquer momento, e a revogação vale na hora.

A empresa é sempre a dona da chave. Não existe campo de empresa no corpo das requisições.

2. Autentique cada chamada

Envie a chave em um dos cabeçalhos:

X-Api-Key: fgk_sua_chave
Authorization: Bearer fgk_sua_chave

Faça as chamadas somente do servidor da sua aplicação. Nunca coloque a chave em JavaScript de navegador, aplicativo móvel ou repositório, e não a registre em logs.

3. Faça a primeira chamada

curl -X POST https://forge.carvalhosilvatech.com.br/api/integracoes/vendas \
  -H "X-Api-Key: $FORGE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "origem": "loja-virtual",
    "idExterno": "PED-1234",
    "cliente": { "nome": "Maria Silva", "email": "[email protected]" },
    "itens": [{ "sku": "GAT-01", "quantidade": 1, "precoUnitario": 50.00 }],
    "pagamento": { "forma": "pix" }
  }'

Resposta esperada: 202 Accepted. A venda aparece em Vendas → Vendas recebidas.

Convenções e erros

Todas as respostas JSON usam o mesmo envelope:

{
  "success": true,
  "message": "Texto legível para humanos.",
  "error": null,
  "timestamp": "2026-11-04T12:00:00Z",
  "data": { }
}

Em caso de falha, success é false e message explica o motivo.

StatusSignificadoO que fazer
200 / 202Recebido e processado (ou na fila).Nada. Guarde o id retornado para conciliação.
400Dado inválido; message diz qual.Corrija o dado. Não repita a mesma requisição.
401Chave ausente, inválida ou revogada.Não repita. Confira a chave e avise a equipe.
429Limite excedido (por minuto ou por dia, conforme a rota). Pode vir sem corpo JSON.Aguarde e tente de novo, com espera crescente.
5xxErro inesperado no Forge.Tente de novo com espera crescente.

Idempotência

Redes falham e a sua aplicação pode não saber se uma chamada chegou. Por isso cada rota tem uma chave de repetição: origem + idExterno nas vendas, o e-mail nos leads e referencia nos avisos. Repetir a mesma chamada é seguro e não duplica nada.

Estratégia de repetição recomendada

  • Defina um timeout de 10 a 15 segundos.
  • Repita apenas timeout, 429 e 5xx, com espera crescente (por exemplo 1 s, 5 s, 30 s, 2 min, 10 min) e no máximo 5 tentativas.
  • Chame o Forge fora do caminho crítico do seu checkout (fila ou job em segundo plano). Uma falha do Forge nunca deve impedir uma venda sua.

Vendas

POST /api/integracoes/vendas

Envia ao Forge uma venda já paga. A venda não vira pedido sozinha: ela cai na caixa de entrada (Vendas → Vendas recebidas), onde a equipe confere os dados, vincula cliente e produtos, escolhe canal, taxas e embalagem e confirma. Só então vira um pedido de venda comum, com baixa de estoque e produção como qualquer outro.

Fluxo

  1. Sua aplicação envia a venda. O Forge responde 202 e a coloca como pendente.
  2. O Forge sugere vínculos: o cliente (por CPF/CNPJ e, na falta, por e-mail) e o produto de cada item (por vínculo já confirmado e, na falta, por SKU igual). Nada é criado sozinho.
  3. A equipe confirma no Forge. O pedido nasce como pago. O vínculo do SKU com o produto fica salvo para as próximas vendas.

Corpo da requisição

{
  "origem": "loja-virtual",
  "idExterno": "PED-1234",
  "dataVenda": "2026-11-03T10:00:00Z",
  "cliente": {
    "nome": "Maria Silva",
    "cpfCnpj": "123.456.789-09",
    "email": "[email protected]",
    "telefone": "11999998888",
    "endereco": {
      "cep": "01001000",
      "logradouro": "Praça da Sé",
      "numero": "100",
      "complemento": "Ap 4",
      "bairro": "Sé",
      "cidade": "São Paulo",
      "estado": "SP"
    }
  },
  "itens": [
    { "sku": "GAT-01", "descricao": "Gatinha articulada", "quantidade": 2, "precoUnitario": 50.00 }
  ],
  "frete": 20.00,
  "desconto": 10.00,
  "pagamento": { "forma": "pix" },
  "observacoes": "Presente"
}
CampoTipoObrigatórioRegras
origemtextoSimNome da sua aplicação, texto livre, até 50 caracteres. Guardado em minúsculas.
idExternotextoSimNúmero do pedido na sua aplicação, até 100 caracteres. Junto com origem, identifica a venda e evita duplicidade.
dataVendadata ISO 8601NãoEm UTC (ex.: 2026-11-03T10:00:00Z). Vazia = momento do recebimento.
cliente.nometextoSimAté 200 caracteres.
cliente.cpfCnpjtextoNãoQualquer formatação. Ajuda a reconhecer um cliente já cadastrado.
cliente.emailtextoNãoNa falta de documento, ajuda a reconhecer o cliente.
cliente.telefonetextoNãoCom DDD. Até 20 caracteres.
cliente.enderecoobjetoNãocep, logradouro, numero, complemento, bairro, cidade e estado (sigla de 2 letras). Usado ao cadastrar o cliente.
itenslistaSimAo menos um item.
itens[].skutextoSimCódigo do produto na sua aplicação, até 100 caracteres. Se for igual ao SKU de um produto do Forge, ele é sugerido.
itens[].quantidadeinteiroSimMaior que zero.
itens[].precoUnitarionúmeroSimPreço unitário cobrado, zero ou mais. Use ponto como separador decimal.
itens[].descricaotextoNãoMostrada na conferência. Vazia = o SKU.
fretenúmeroNãoFrete cobrado do cliente.
descontonúmeroNãoDesconto total do pedido.
pagamento.formatextoSimpix, cartao, dinheiro, boleto ou marketplace.
observacoestextoNãoAté 2.000 caracteres.

O total é calculado pelo Forge: soma(quantidade × precoUnitario) − desconto + frete. Toda venda enviada é tratada como paga: não envie vendas aguardando pagamento. Campos desconhecidos são ignorados.

Resposta

HTTP/1.1 202 Accepted

{
  "success": true,
  "message": "Venda recebida e aguardando conferência no Forge.",
  "error": null,
  "timestamp": "2026-11-04T12:00:00Z",
  "data": { "id": "6f0e5a8c-0000-0000-0000-000000000000", "duplicada": false }
}
  • data.id: identificador da venda recebida no Forge. Guarde para suporte e conciliação.
  • data.duplicada: true quando o mesmo origem + idExterno já havia sido recebido. Nada foi criado de novo, e os dados enviados agora são ignorados: vale o primeiro envio.

Erros desta rota

StatusQuando
400origem, idExterno ou cliente.nome ausentes; lista de itens vazia; SKU ausente; quantidade menor que 1; preço, frete ou desconto negativos; forma de pagamento desconhecida; campo acima do tamanho máximo.
401Chave de API ausente, inválida ou revogada.
429Mais de 500 vendas por 24 horas para a empresa, ou mais de 120 requisições por minuto do mesmo IP.

Exemplos de código

// Node.js 18+
async function enviarVenda(pedido) {
  const resposta = await fetch('https://forge.carvalhosilvatech.com.br/api/integracoes/vendas', {
    method: 'POST',
    headers: {
      'X-Api-Key': process.env.FORGE_API_KEY,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      origem: 'loja-virtual',
      idExterno: String(pedido.numero),
      dataVenda: pedido.pagoEm.toISOString(),
      cliente: {
        nome: pedido.cliente.nome,
        cpfCnpj: pedido.cliente.documento,
        email: pedido.cliente.email,
        telefone: pedido.cliente.telefone,
        endereco: pedido.entrega,
      },
      itens: pedido.itens.map(i => ({
        sku: i.sku,
        descricao: i.nome,
        quantidade: i.quantidade,
        precoUnitario: i.preco,
      })),
      frete: pedido.frete,
      desconto: pedido.desconto,
      pagamento: { forma: 'pix' },
    }),
    signal: AbortSignal.timeout(15000),
  });

  if (resposta.status === 202) return resposta.json();
  if (resposta.status === 429 || resposta.status >= 500) {
    throw new Error(`Falha temporária (${resposta.status}). Repita com o mesmo idExterno.`);
  }
  const erro = await resposta.json().catch(() => ({}));
  throw new Error(`Forge recusou a venda (${resposta.status}): ${erro.message ?? 'sem detalhes'}`);
}

O que a integração deve saber

  • Envie só vendas pagas. O pedido nasce como pago, com baixa de estoque e aviso (se a equipe escolher) no momento da confirmação.
  • Reconhecimento de cliente e produto é sugestão, não criação. Se o SKU ou o cliente não forem reconhecidos, a venda espera a equipe vincular. Na segunda venda do mesmo SKU, o produto já vem vinculado.
  • Mantenha o idExterno estável. Para a mesma venda, sempre o mesmo valor; é o que impede duplicidade.
  • Ainda não existe consulta de status por API, endpoint para cancelar ou alterar uma venda já enviada, nem webhook de retorno. A conferência e o acompanhamento são feitos na tela do Forge.

Leads e tags

Envie leads (cadastros, carrinhos abandonados, compradores) com tags e dados. Uma campanha de e-mail ou WhatsApp cuja tag de entrada seja uma dessas tags inscreve o lead no fluxo automaticamente. Quando o lead sai do fluxo (por exemplo, comprou), a sua aplicação avisa e o Forge cancela os envios pendentes.

Criar ou atualizar um lead

POST /api/integracoes/contatos

O lead é identificado pelo e-mail, único por empresa. Se existir, é atualizado; se não, é criado. A chamada é idempotente.

CampoTipoObrigatórioRegras
emailtextoSimE-mail válido, até 254 caracteres. Guardado em minúsculas.
nometextoNãoAté 200 caracteres. Ausente não apaga o nome já salvo.
telefonetextoNãoDe 10 a 15 dígitos (de preferência com o código do país: 5511999999999). Fora disso é ignorado em silêncio e o lead é salvo mesmo assim.
tagslista de textoNãoAté 20 por requisição, até 50 caracteres cada. Normalizadas para minúsculas.
dadosobjeto texto→textoNãoVariáveis usadas nas mensagens ({{produto}}). Até 30 campos; todos os valores devem ser texto (envie "149.90", não 149.90).
aceitaEmail, aceitaWhatsappbooleanoNãoConsentimento. Ausente mantém o valor atual; em lead novo assume verdadeiro (WhatsApp só se houver telefone válido).
origemConsentimentotextoNãoAté 100 caracteres, ex.: checkout. Padrão: integracao.
curl -X POST https://forge.carvalhosilvatech.com.br/api/integracoes/contatos \
  -H "X-Api-Key: $FORGE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "email": "[email protected]",
    "nome": "Maria Souza",
    "telefone": "(11) 99999-0000",
    "tags": ["carrinho-abandonado"],
    "dados": {
      "produto": "Suporte de headset 3D",
      "valor_carrinho": "89.90",
      "link_carrinho": "https://loja.exemplo.com/carrinho/retomar/abc123"
    },
    "aceitaEmail": true,
    "aceitaWhatsapp": true,
    "origemConsentimento": "checkout"
  }'

Resposta 200: data.contatoId, data.criado (verdadeiro se o lead é novo) e data.inscricoesCriadas (ids das inscrições criadas nesta chamada; lista vazia é normal e não é erro).

Consentimento é responsabilidade da loja (LGPD). Envie true somente se o cliente concordou. Quem se descadastrou nunca volta a consentir por esta API.

Tirar o lead do fluxo

POST /api/integracoes/contatos/remover-tags

Remove as tags e cancela as inscrições ativas, e os envios ainda agendados, das campanhas cuja tag de entrada foi removida. É idempotente: e-mail ou tag inexistente não é erro.

curl -X POST https://forge.carvalhosilvatech.com.br/api/integracoes/contatos/remover-tags \
  -H "X-Api-Key: $FORGE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "email": "[email protected]", "tags": ["carrinho-abandonado"] }'

Resposta 200: contatoEncontrado, tagsRemovidas e inscricoesCanceladas.

Regra de ouro: todo evento que abre um fluxo precisa de um evento que o fecha. Se você envia carrinho-abandonado, chame remover-tags quando a compra acontecer, ou o cliente continuará recebendo lembretes.

Avisos de WhatsApp

POST /api/integracoes/notificacoes

Pede ao Forge que envie uma mensagem de WhatsApp a um cliente, pelo número conectado da empresa (em WhatsApp → Conexão). A resposta é assíncrona: 202 significa recebido e na fila, não entregue.

CampoTipoObrigatórioRegras
telefonetextoSimCom DDD, qualquer formatação. Mínimo de 10 dígitos. Com 10 ou 11 dígitos, o Forge acrescenta 55.
mensagemtextoSimAté 1.000 caracteres. Aceita a formatação do WhatsApp (*negrito*, _itálico_).
referenciatextoNãoAté 100 caracteres. Evita envio duplicado: com a mesma referência, a resposta traz duplicada: true. Uma referência usada nunca é reaproveitada, mesmo se o envio falhou; para reenviar, use outra (pedido-123-enviado-2).
curl -X POST https://forge.carvalhosilvatech.com.br/api/integracoes/notificacoes \
  -H "X-Api-Key: $FORGE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "telefone": "(11) 99999-9999",
    "mensagem": "Olá, Maria! Seu pedido *#123* foi enviado.",
    "referencia": "pedido-123-enviado"
  }'
  • Limite: 200 mensagens a cada 24 horas por empresa (janela móvel). Acima disso, 429.
  • Entrega: o Forge envia a fila a cada minuto. Se falhar, tenta no total 3 vezes (esperas de 15 e 30 minutos) e então marca como Falhou. Acompanhe em WhatsApp → Avisos aos clientes → Últimos envios.
  • Ainda não existe consulta de status por API nem webhook de retorno.
  • Envie só mensagens de transação (pedido, pagamento, entrega) para quem espera o contato. Mensagens em massa aumentam o risco de bloqueio do número pelo WhatsApp.

Boas práticas

  • Chave de API em variável de ambiente, usada apenas no servidor.
  • Envio em segundo plano, com timeout e repetição só para timeout, 429 e 5xx.
  • idExterno, e-mail e referencia estáveis e únicos por evento, para a repetição nunca duplicar.
  • Sem dados pessoais nem chave de API em logs.
  • Uma chave por aplicação; revogue na hora se houver suspeita de vazamento (crie outra e atualize a aplicação).
  • Teste com uma venda de teste e confira em Vendas → Vendas recebidas antes de ligar em produção. Reenvie a mesma venda para confirmar que duplicada vem verdadeiro.

Dúvidas ou algo que a API ainda não cobre? Escreva para [email protected] com o id retornado pela chamada e o horário.