API pública do Grix v1 — referência para quem integra
Versão 1.1 · 13/11/2026 · Base: ADR-0026 (API, avisos e MCP), AU-13/AU-14 do plano de atendimento universal. Atualizada após o PDS-03 (retirada dos chamados), o fluxo de Pedidos (PED/PDS) e a troca do nome para Grix (ADR-0069).
Esta é a direção seu sistema → Grix: ler catálogo, pedidos e eventos da loja, receber avisos assinados e conectar o assistente de IA do lojista pelo MCP. A direção oposta — o Grix usando o seu sistema no atendimento — está no contrato v1 e no guia da primeira integração. As duas direções compartilham os mesmos serviços de negócio, a mesma medição e a mesma regra: dado externo é dado, nunca instrução.
- Especificação OpenAPI 3.0 (JSON):
GET /desenvolvedores/documentacao/api-v1 - Esta referência publicada:
/desenvolvedores/documentacao/api-publica - Base das rotas: o endereço do site (produção:
https://grix.app)
1. Autenticação e chaves
Cada empresa (lojista) cria as próprias chaves na área da loja, em Integrações → Chaves da API. A chave bruta aparece uma única vez, na criação; o Grix guarda apenas o hash SHA-256 e o prefixo de exibição. Chave revogada deixa de autenticar imediatamente.
| Ambiente | Prefixo | Efeito |
|---|---|---|
| Produção | grix_live_ | Dados reais da empresa |
| Sandbox | grix_test_ | Nenhum dado real da empresa: itens ficam no armazenamento isolado (api_sandbox_objeto) e as demais leituras devolvem vazio; inscrições de aviso ficam marcadas com o ambiente sandbox e também exigem prova de posse. Mesmos contratos e validações. |
Envie a chave em um dos cabeçalhos:
X-API-Key: grix_live_…Authorization: Bearer grix_live_…Escopos
Cada chave carrega uma lista de escopos; a rota exige o escopo correspondente. Sem ele, 401.
| Escopo | Permite |
|---|---|
empresa:leitura | Dados da empresa e unidades |
catalogo:leitura | Itens e variantes |
catalogo:escrita | Criar itens |
ofertas:leitura | Ofertas e preços |
midia:leitura | Fotos aprovadas dos itens |
contatos:leitura | Pedidos, orçamentos e agendamentos (minimizados) |
operacoes:leitura | Operações de integração (sem payloads) |
eventos:leitura | Fluxo de saída por cursor |
avisos:gerenciar | Inscrições de webhook, reenvio |
catalogo:proposta | MCP: propor alteração de preço para revisão humana |
mcp:acesso | MCP da área da loja (OAuth) |
solicitacoes:leitura / solicitacoes:escrita | Legado. Autenticam e recebem o 410 estável da fila retirada (PDS-03); não há mais leitura nem escrita de chamados |
relatorios:leitura | Legado. O relatório de demanda da fila retirada responde 410 |
GET /api/v1/empresa aceita qualquer chave válida da empresa; as demais rotas exigem o escopo listado.
2. Limites, paginação e idempotência
- Rate limit: 60 leituras e 20 escritas por minuto por chave; 600 requisições/minuto por empresa; teto por ciclo de cobrança (
api.teto_ciclo, padrão 50 000). Acima do limite:429com mensagem. - Paginação por cursor:
limite(padrão 50, máximo 200) ecursor. A resposta trazproximo_cursor(nullquando não há mais páginas). Em/api/v1/eventoso cursor é numérico. - Idempotência: toda criação/comando (
POST) exigeIdempotency-Key(até 128 caracteres). Repetir a chave com o mesmo conteúdo devolve a resposta gravada; com conteúdo diferente,409. Requisição ainda em processamento com a mesma chave:409— tente de novo. - Corpo: JSON, até 32 KB. Erros vêm como
{"erro": "mensagem útil"}.
3. Recursos
Empresa e unidades
| Rota | Escopo | Resultado |
|---|---|---|
GET /api/v1/empresa | chave válida | razao_social, nome_fantasia, cnpj, criado_em |
GET /api/v1/empresa/unidades | empresa:leitura | Unidades (id, nome, whatsapp, criado_em) |
Catálogo
| Rota | Escopo | Resultado |
|---|---|---|
GET /api/v1/catalogo/itens | catalogo:leitura | Itens publicados, por cursor |
POST /api/v1/catalogo/itens | catalogo:escrita | Cria item (idempotente) |
GET /api/v1/catalogo/itens/{id}/variantes | catalogo:leitura | Variantes do item |
GET /api/v1/catalogo/ofertas?item_id= | ofertas:leitura | Ofertas (até 200, mais recentes primeiro) |
GET /api/v1/catalogo/midia?item_id= | midia:leitura | Mídias aprovadas do item |
Campos do item: id, nome, descricao, sku, cenario_id (tipo de ficha), natureza (produto, servico, plano), tipo_preco (fixo, a_partir_de, sob_orcamento, gratuito), preco (decimal em texto, ex. "389.90"), preco_centavos (inteiro, quando fixo ou quando há preço da unidade), moeda (BRL), a_partir_de (booleano), criado_em, atualizado_em.
- Com
?loja_id=<unidade>,preco/preco_centavospassam a ser os da unidade edisponivel_unidadeé incluído. - Preço é sempre da loja; o Grix não cria cobrança nem confirma pagamento (ADR-0060, seção 8).
- Mídia:
url_publica,tipo_mime,largura,altura,proporcao,tamanho_bytes,tag,alt_texto,ilustrativa(destaque quando não é foto real do produto).
Criação de item (POST): nome obrigatório; sku gerado quando ausente; natureza, tipo_preco e preco_centavos validados pelo contrato (valores fora da lista: 422); cenario_id opcional (usa a ficha geral). As mesmas validações valem no sandbox.
Pedidos, orçamentos e agendamentos (contatos)
GET /api/v1/contatos — escopo contatos:leitura.
Filtros: tipo (reserva, pedido, orcamento, agendamento), estado (novo, confirmado, concluido, cancelado), loja_id, além de limite/cursor. Valores fora da lista: 422; unidade de outra empresa: 404.
Campos: id, loja_id, tipo, protocolo (ex. GRIX-…, o mesmo exibido ao visitante e à loja), resumo, valor_total (decimal em texto, previsão da loja), moeda, itens (lista com nome, quantidade e opções), estado, desfecho (vendido, nao_vendido, vendeu_outro ou null), criado_em, atualizado_em.
Minimização (LGPD): a resposta nunca traz nome, telefone nem e-mail do visitante. O desfecho é o resultado da venda informado pela loja, só para relatório — não muda o estado nem alimenta cobrança (ADR-0060). Mudanças chegam pelos eventos contato.criado e contato.atualizado (seção 4).
Operações de integração
GET /api/v1/operacoes — escopo operacoes:leitura. Operações da camada de integração da empresa (capacidade, ferramenta, estado, tentativas, referencia_externa, datas), sem payloads de entrada ou resultado. O detalhe completo fica na área da loja.
Eventos de saída
GET /api/v1/eventos?cursor=<n>&limite=<n> — escopo eventos:leitura.
Fluxo durável com os mesmos IDs dos avisos (webhooks): quem não recebe chamadas da internet lê por aqui, e quem perdeu avisos recupera pelo cursor. Cada evento: id (estável), cursor, tipo, dados, criado_em.
Avisos (webhooks)
| Rota | Escopo | Resultado |
|---|---|---|
GET /api/v1/avisos/inscricoes | avisos:gerenciar | Inscrições do ambiente da chave, com situação operacional |
POST /api/v1/avisos/inscricoes | avisos:gerenciar | Cria inscrição após prova de posse (idempotente) |
POST /api/v1/avisos/inscricoes/{id}/reenvio | avisos:gerenciar | Reenvia uma entrega preservando o ID (evento_id no corpo) |
A listagem mostra ativo, falhas_consecutivas, suspenso_ate e datas — nunca o segredo. Pausar, reativar e ver entregas também estão na área da loja, em Integrações → Avisos.
Recursos retirados (PDS-03)
A fila nativa de chamados (suporte/orçamento/acompanhamento) foi retirada do produto. As rotas permanecem apenas para devolver o erro estável 410 após autenticação e escopo, sem escrita nem vazamento de registros:
GET/POST /api/v1/solicitacoesGET /api/v1/solicitacoes/{id}POST /api/v1/solicitacoes/{id}/transicoesGET /api/v1/relatorios/demanda
Corpo do 410: {"erro": "Abertura e acompanhamento de chamados foram retirados. Para falar com a equipe, use os canais públicos da loja."}. A demanda atual é lida em /api/v1/contatos (pedidos) e /api/v1/eventos. Registros históricos continuam acessíveis aos mecanismos autorizados de privacidade, exportação e auditoria da área da loja.
4. Catálogo de eventos
| Tipo | Situação | Quando é emitido |
|---|---|---|
contato.criado | vivo | Novo pedido, orçamento ou agendamento registrado (confirmação no atendimento ou formulário) |
contato.atualizado | vivo | Situação do pedido/agendamento mudou (inclusive pela agenda) ou desfecho da venda foi registrado |
atendimento.pediu_pessoa | vivo | Visitante entrou na fila de atendimento humano da loja |
solicitacao.criada | legado | Fila de chamados retirada; inscrições antigas seguem válidas, mas nenhum fluxo novo emite |
solicitacao.atualizada | legado | Idem |
Exemplo de dados de contato.atualizado:
{
"contato_id": "…",
"protocolo": "GRIX-…",
"tipo": "reserva",
"loja_id": "…",
"estado": "confirmado",
"desfecho": "vendido"
}Regras do fluxo:
- O evento só avisa. O payload traz identificadores e estado, nunca dado pessoal nem o conteúdo da conversa. Releia o recurso pela API antes de agir; o conteúdo do aviso não é tomado como verdade.
- ID estável por conteúdo:
id = sha256(tipo + payload canônico). O mesmo fato repetido não gera evento duplicado; use oidpara deduplicar no seu lado. - Entrega pelo menos uma vez, fora de ordem; o cursor de
/api/v1/eventosrecupera o que chegou enquanto seu sistema estava fora. - Os tipos da ADR-0026 ligados à fila antiga (
pergunta.registrada,orcamento.solicitado,proposta.confirmada,reserva.confirmada,agendamento.confirmado) consolidaram-se emcontato.*com o campotipo, acompanhando o fluxo de Pedidos.
5. Recebendo avisos com segurança
Cadastro e prova de posse
POST /api/v1/avisos/inscricoes com {"url_endpoint": "https://…", "eventos": ["contato.criado", …]}. Sem a lista eventos, valem contato.criado e contato.atualizado. Tipos fora do catálogo: 422.
O endpoint precisa ser HTTPS público (IP privado/local é bloqueado — proteção SSRF) e responder ao desafio de posse: o Grix envia POST {"tipo": "desafio_posse", "desafio": "<hex>"} e exige resposta 2xx cujo corpo contenha o próprio desafio. Só então a inscrição é criada.
O segredo de assinatura é devolvido na resposta da criação (segredo, 64 caracteres hex) e na repetição idempotente exata dela (mesma Idempotency-Key e mesmo corpo), para o caso de a primeira resposta ter se perdido. Guarde-o; listagens e diagnósticos nunca o devolvem, e ele não fica gravado no registro de idempotência — vive apenas na inscrição. Sem ele não é possível validar as entregas.
Entrega e assinatura
Cada entrega é um POST no seu endpoint:
Content-Type: application/json
X-Grix-Evento: <id do evento, o mesmo do cursor>
X-Grix-Assinatura: t=<unix>,v1=<hmac>{"id": "<evento_id>", "tipo": "contato.criado", "dados": {…}}v1 é o HMAC-SHA256 de "<t>.<corpo bruto>" com o segredo da inscrição. Validação em PHP:
[$t, $v1] = …; // extraídos de X-Grix-Assinatura
$esperado = hash_hmac('sha256', $t . '.' . $corpoBruto, $segredo);
if (!hash_equals($esperado, $v1)) { http_response_code(401); exit; }
if (abs(time() - (int)$t) > 300) { http_response_code(401); exit; } // janela sugerida
// deduplique pelo id; responda 2xx rápido e processe fora da requisiçãoTentativas, suspensão e reenvio
- Responda
2xxem até 5 s. Outras respostas (ou timeout) geram nova tentativa com recuo exponencial (1 min, 2 min, 4 min… até 1 h), 25 tentativas ou 24 h — o que vier primeiro; depois a entrega vai afalhou. - 10 falhas consecutivas suspendem a inscrição por 24 h. Reativar pela área da loja zera as falhas.
- Reenvio manual (
…/reenvioou área da loja) preserva o ID do evento e registra tentativa nova. - A inscrição é por ambiente: chave de sandbox gerencia inscrições de sandbox.
6. Servidor MCP da área da loja
Para o assistente de IA do lojista (não para o visitante). Endpoint: POST /mcp/area-loja (Streamable HTTP, protocolo MCP 2025-11-25, servidor grix-area-loja).
- OAuth 2.1 com escopo
mcp:acesso; a autorização é concedida pelo dono na área da loja, com a unidade escolhida. Metadados em/.well-known/oauth-protected-resource/mcp/area-loja. - Somente credenciais de produção; chave de sandbox é recusada.
- Mesmas regras da API: uma regra de negócio, várias entradas — o MCP chama os mesmos serviços.
| Ferramenta | Escopo | Efeito |
|---|---|---|
ler_catalogo | catalogo:leitura | Itens publicados com preço tipado (preco, moeda, a_partir_de), busca por nome/SKU |
propor_alteracao_catalogo | catalogo:proposta | Registra proposta de preço aguardando aprovação expressa do lojista na área da loja; nunca aplica sozinho |
As ferramentas ler_solicitacoes, obter_solicitacao e relatorio_demanda foram retiradas (PDS-03) e respondem a mensagem estável da retirada.
7. Erros
| Código | Quando |
|---|---|
400 | JSON inválido |
401 | Chave ausente, inválida, revogada ou sem o escopo da rota |
404 | Recurso inexistente ou de outra empresa |
409 | Idempotency-Key com outro conteúdo, ou requisição em processamento |
410 | Recurso retirado (PDS-03), após autenticação e escopo |
413 | Corpo acima de 32 KB |
422 | Validação do contrato (campos, enums, filtros, posse do endpoint, tipo de evento) |
429 | Rate limit da chave, da empresa ou teto do ciclo |
500 | Erro interno (mensagem pública, sem detalhe técnico) |
8. Responsabilidade da loja (ADR-0060)
O Grix não é plataforma digital: a loja vende, cobra e entrega. Pela API:
- O Grix não cria cobrança, Pix, link nem boleto pela loja, não recebe, retém, repassa nem divide valores e não dá pagamento por confirmado sozinho.
- Preço, desconto, prazo, troca e cancelamento são da loja; o Grix mostra e registra.
valor_totale totais somados são previsão; o valor final é da loja. - Entrega é sempre da loja. O
desfechoregistrado pela loja é relatório e não alimenta cobrança do Grix.
Integrações que precisem do estado de pagamento devem obtê-lo do sistema da própria loja e registrá-lo lá; o Grix pode repassar o link ou a forma de pagamento que a loja criou no sistema dela.
9. Segurança e dados pessoais
- Só HTTPS; endpoints de aviso passam pela proteção SSRF (endereço público, DNS fixado, sem redirecionamento).
- Segredos nunca voltam em listagens, eventos, diagnósticos ou logs — só a dica da credencial e, uma única vez, o segredo do webhook na criação.
- Contatos e eventos saem minimizados: sem nome, telefone, e-mail ou conteúdo de conversa. O lojista é o controlador dos dados dos clientes dele; todo acesso fica registrado.
- Texto vindo de sistemas externos é dado delimitado, nunca instrução do atendente.
10. Versionamento e compatibilidade
- Rotas em
/api/v1; contrato público versionado (esta referência + OpenAPI). Mudança incompatível sobe a versão, com aviso prévio antes de descontinuar. - Recurso retirado não some em silêncio: responde
410estável após autenticação e escopo, como fez o PDS-03. - Versão da especificação OpenAPI:
info.version(hoje1.1.0).
11. Exemplo de ponta a ponta
# 1. Ler o catálogo da empresa (chave criada na área da loja)
curl -H "X-API-Key: grix_live_…" "https://grix.app/api/v1/catalogo/itens?limite=50"
# 2. Ler pedidos novos da unidade
curl -H "X-API-Key: grix_live_…" \
"https://grix.app/api/v1/contatos?tipo=reserva&estado=novo&loja_id=<unidade>"
# 3. Inscrever um webhook (o endpoint deve ecoar o desafio de posse)
curl -X POST -H "X-API-Key: grix_live_…" -H "Idempotency-Key: erp-avisos-1" \
-H "Content-Type: application/json" \
-d '{"url_endpoint":"https://erp.exemplo.com/grix/avisos","eventos":["contato.criado","contato.atualizado","atendimento.pediu_pessoa"]}' \
"https://grix.app/api/v1/avisos/inscricoes"
# guarde o campo "segredo" da resposta — não aparece de novo
# 4. Recuperar eventos perdidos pelo cursor
curl -H "X-API-Key: grix_live_…" "https://grix.app/api/v1/eventos?cursor=0&limite=200"Histórico desta referência
- 1.1 (13/11/2026): acompanha o produto atual — pedidos com protocolo, filtros e desfecho (PDS/PED); chamados e relatório de demanda retirados com
410estável (PDS-03); catálogo de eventos vivos (contato.*,atendimento.pediu_pessoa) emitidos pelos fluxos reais; segredo do webhook devolvido uma única vez também pela API; validações de contrato no criação de item e nos tipos de evento; campos novos de catálogo e mídia; MCP com preço tipado; nome Grix (ADR-0069). - 1.0 (18/10/2026): primeira publicação (AU-13, release
20261018062949): chaves com escopos, sandbox, idempotência, limites, cursor, avisos assinados com prova de posse.