OnmIAOnmIA API Docs

Fidelidade

Consultar e operar o programa de fidelidade de um cliente — saldo, extrato, cupons, crédito, débito livre e resgate. Idempotência e resolução por phone/external_id.

A API de Fidelidade expõe o programa, o saldo, o extrato e os cupons de um cliente, e permite creditar/debitar pontos e validar/resgatar cupons.

  • Leituras exigem o escopo loyalty:read.
  • Escritas exigem loyalty:write.
  • Uma chave loyalty:read chamando um endpoint de escrita recebe 403 INSUFFICIENT_SCOPE.

Todos os endpoints usam o mesmo envelope de erro do restante da API: { "error": { "code": "...", "message": "..." } }. A referência completa de schemas está no OpenAPI.

Consulta on-demand (polling)

Hoje o ERP consulta o saldo quando precisa (polling). Não há webhook que empurre mudanças de saldo da OnmIA para o ERP — esse push (order.created para fidelidade) está no roadmap (UCP-INT-v121-W-C). Por ora, leia o saldo on-demand via GET /loyalty/balance.

Resolução do cliente

As rotas que operam sobre um cliente o localizam por phone ou external_id (a chave do cliente no seu ERP, em customers.external_id). A busca é somente leitura (find-only): a fidelidade atua sobre um cliente já existente — nunca cria cliente. Cliente não encontrado retorna 404 CUSTOMER_NOT_FOUND.

  • phone: aceito em qualquer formato (+55 (37) 99112-9034, 37991129034, 5537991129034); o servidor normaliza para E.164 BR e tolera a variação do nono dígito.
  • external_id: tem precedência quando enviado; se não casar e você também mandou phone, cai para a busca por telefone.

Leitura (loyalty:read)

Programa + níveis

curl -sS https://api.onmia.com.br/integration/v1/loyalty/program \
  -H "X-API-Key: $ONMIA_API_KEY"

Retorna o programa ativo (merchant-wide) e os tiers. Nenhum programa ativo: 404 NO_PROGRAM.

Saldo do cliente

curl -sS "https://api.onmia.com.br/integration/v1/loyalty/balance?phone=5537991129034" \
  -H "X-API-Key: $ONMIA_API_KEY"
{
  "customer_id": "6c57c2e8-…",
  "enrolled": true,
  "points_balance": 320,
  "points_lifetime": 1180,
  "cashback_balance": 0,
  "tier": { "name": "Prata", "level": 2, "multiplier": 1.2 },
  "referral_code": "JADER10"
}

Cliente existente mas não inscrito: enrolled: false com saldos zerados e tier: null. Falta phone/external_id: 400 VALIDATION_ERROR.

Extrato

curl -sS "https://api.onmia.com.br/integration/v1/loyalty/transactions?phone=5537991129034&limit=50" \
  -H "X-API-Key: $ONMIA_API_KEY"

limit de 1 a 100 (default 50), mais recente primeiro. Cada item traz type, points, reason, order_id, created_at.

Cupons do cliente

curl -sS "https://api.onmia.com.br/integration/v1/loyalty/coupons?external_id=ERP-CLI-3310" \
  -H "X-API-Key: $ONMIA_API_KEY"

Lista os cupons ativos visíveis ao cliente. A lista honra o escopo de loja da chave: cupons de loja só aparecem se a loja estiver no store_ids da chave; cupons merchant-wide (store_id: null) aparecem sempre.

Escrita (loyalty:write)

Creditar / debitar pontos (idempotente)

curl -sS https://api.onmia.com.br/integration/v1/loyalty/points \
  -H "X-API-Key: $ONMIA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "phone": "5537991129034",
    "points": 100,
    "reason": "Bonus aniversario",
    "idempotency_key": "erp-bonus-2026-06-13-3310"
  }'

points é um inteiro com sinal (+ credita, - debita; não pode ser zero) — alternativamente type (credit/debit) + amount positivo.

CampoObrigatórioRegras
phone / external_idsim (um dos dois)Resolução do cliente.
pointssim*Inteiro com sinal. *Alternativa: type + amount. Não pode ser zero.
reasonnãoDescrição do lançamento.
idempotency_keyrecomendadoMesma chave reaplicada = um único efeito (replay).
order_idnãoUUID do pedido associado ao débito (resgate).

O idempotency_key torna o lançamento seguro para retry: reenviar a mesma chave não credita/debita de novo (retorna idempotent_replay: true com o saldo inalterado).

{
  "new_balance": 420,
  "points_applied": 100,
  "idempotent_replay": false,
  "transaction": { "id": "…", "points": 100, "created_at": "2026-06-13T14:10:00.000Z" }
}

Débito livre vs. resgate:

  • Débito livre (points < 0 sem order_id) = ajuste manual de saldo (ex.: correção, estorno). Débito maior que o saldo → 422 INSUFFICIENT_BALANCE.
  • Débito com order_id = resgate de pontos vinculado a um pedido.

Corrida concorrente no crédito: 409 CONFLICT (re-tente).

O saldo de pontos é um valor financeiro. Use sempre idempotency_key por lançamento — retries de rede nunca devem duplicar crédito ou débito.

Validar cupom

curl -sS https://api.onmia.com.br/integration/v1/loyalty/coupons/validate \
  -H "X-API-Key: $ONMIA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "code": "BEMVINDO10", "phone": "5537991129034", "order_total": 90.0 }'

Retorna { valid, discount, reason, coupon }. Não consome o cupom — só checa as regras (validade, mínimo, limites). phone/external_id são opcionais (validação anônima permitida; informe o cliente quando o cupom tiver limite por cliente). Cupom inválido → valid: false com reason; cupom inexistente → 404 COUPON_INVALID.

Resgatar cupom (idempotente)

curl -sS https://api.onmia.com.br/integration/v1/loyalty/coupons/redeem \
  -H "X-API-Key: $ONMIA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "code": "BEMVINDO10",
    "phone": "5537991129034",
    "order_id": "949e4706-c108-4a6c-b9cd-4e89c043935d",
    "discount": 8.8,
    "idempotency_key": "erp-redeem-4412"
  }'

Marca o uso do cupom para o cliente + pedido. Idempotente por (cupom, order_id). Resposta: { redeemed, idempotent_replay, discount_applied }.

  • Cupom de loja fora do escopo da chave: 403 FORBIDDEN_STORE.
  • Cupom inexistente: 404 COUPON_INVALID.
  • Cupom inativo/expirado ou limite atingido: 422 COUPON_INVALID.

Códigos de erro da fidelidade

CódigoStatusSignificado
VALIDATION_ERROR400Falta phone/external_id, payload inválido, points zero.
CUSTOMER_NOT_FOUND404Cliente não localizado (find-only — a API não cria cliente).
NO_PROGRAM404Nenhum programa de fidelidade ativo.
INSUFFICIENT_BALANCE422Débito maior que o saldo de pontos.
COUPON_INVALID404/422Cupom inexistente (404) ou inativo/expirado/limite atingido (422).
FORBIDDEN_STORE403Cupom de loja fora do escopo da chave (resgate).
CONFLICT409Corrida concorrente no crédito de pontos; re-tente.
INSUFFICIENT_SCOPE403Chave sem loyalty:read/loyalty:write para a operação.
POINTS_UNAVAILABLE / COUPON_UNAVAILABLE503Indisponível por falha transitória; re-tente com backoff.

On this page