Inyo

Referência da API

Todo endpoint fica sob /organizations/{tenant}/ no host da API de wallet (https://{FQDN}). Todas as requisições exigem o header X-API-KEY. Todos os POSTs exigem um header Idempotency-Key.


Carteiras

MétodoCaminhoDescrição
GET/walletsLista as carteiras do seu tenant
POST/walletsCria uma carteira (owner_type, owner_ref, name)
GET/wallets/{id}Consulta uma carteira
GET/wallets/{id}/balanceSaldos por ativo (?asset=USD opcional)
GET/wallets/{id}/entriesEntries do ledger — paginadas (50 por página), filtráveis por asset, journal_kind e intervalo de datas

Carteiras criadas pela API sempre têm kind: operational. Outros tipos de conta (sub-contas de retenção, suspense, origem externa) são gerenciados pelo sistema e aparecem apenas nas entries do ledger.

Movimentação de Dinheiro

MétodoCaminhoDescrição
POST/depositsRegistra uma origem externa e a divide entre carteiras atomicamente
POST/holdsPré-autoriza (cria uma retenção/hold)
GET/holds/{id}Consulta uma retenção (hold) com seu histórico de capturas
POST/holds/{id}/captureCaptura parte ou a totalidade de uma retenção para uma conta de destino
POST/holds/{id}/voidCancela (void) a parte restante (não capturada) de uma retenção
POST/captures/{captureJournalUuid}/refundReembolsa contra uma captura específica (parcial permitido)
POST/transfersTransferência entre carteiras no mesmo ativo
POST/fx-conversionsConversão entre ativos com rate e rate_source explícitos

Tipos de journal: deposit, preauth, capture, void, refund, transfer, fx_conversion.

Status de retenção (hold): open, partially_captured, captured, voided. (expired é reservado; a expiração não é aplicada automaticamente hoje — cancele (void) retenções expiradas explicitamente.)

Tipos de origem de depósito: wire, ach_debit, card, stablecoin_deposit.


Valores e Ativos

  • Todos os valores são strings no JSON, decimais com até 8 casas. Os campos amount das respostas também são strings — nunca faça parse deles como números JSON (perda de precisão).
  • Ativos suportados: USD, USDC, EUR, MXN.
  • Os saldos são atualizados atomicamente com a gravação do journal — uma resposta de sucesso significa que o saldo reflete a operação.

Tratamento de Erros

Todos os erros retornam um corpo JSON:

{
  "error": "ERROR_CODE",
  "message": "Human-readable explanation."
}
HTTPerrorQuando acontece
400MISSING_IDEMPOTENCY_KEYPOST sem o header Idempotency-Key
401UNAUTHORIZEDX-API-KEY ausente ou inválida
403FORBIDDENA API key não corresponde ao {tenant} na URL
404NOT_FOUNDA carteira, retenção (hold) ou captura referenciada não existe (ou não pertence ao seu tenant)
409INVALID_HOLD_STATECapturar uma retenção cancelada, cancelar uma já capturada, etc.
422VALIDATION_ERRORO payload falhou na validação — o campo errors lista os problemas por campo
422INSUFFICIENT_FUNDSA pré-autorização ou transferência excede o saldo available da carteira
422INVALID_ASSETasset_code desconhecido ou não suportado
422INVALID_ACCOUNTA conta referenciada não é válida para a operação
422LEDGER_IMBALANCEAs divisões não somam o valor da origem, ou outra violação de partidas dobradas
500INTERNAL_ERRORErro no servidor — contate o suporte com o timestamp e os detalhes da requisição

Para VALIDATION_ERROR, a resposta inclui um detalhamento por campo:

{
  "error": "VALIDATION_ERROR",
  "message": "The wallet id field must be a uuid.",
  "errors": {
    "wallet_id": ["The wallet id field must be a uuid."]
  }
}

Idempotência

Todo endpoint POST exige um header Idempotency-Key. Se você enviar duas requisições com a mesma chave, a segunda retorna exatamente a resposta da primeira — nenhum journal duplicado é criado.

Por que isso importa: falhas de rede são silenciosas. Uma requisição que expira após o envio, mas antes de receber a resposta, deixa você sem saber se a operação foi bem-sucedida. Retentar com a mesma chave é sempre seguro.

Como nomear chaves: qualquer string única de até 191 caracteres. A boa prática é um identificador estável e significativo por operação:

  • deposit-BANK-WIRE-98765432 para um wire específico
  • capture-INV-4521 para uma fatura específica
  • refund-INV-4521-partial-1 para um reembolso específico

Nunca reutilize uma chave em operações diferentes. Reutilizar invoice-4521-refund para um reembolso de $50 e depois para um de $100 retorna a resposta dos $50 na segunda vez — o reembolso de $100 nunca acontece.

As chaves são armazenadas por journal, com escopo do seu tenant, e nunca expiram.


Rastreabilidade

  • Toda resposta de journal inclui parentJournalId quando reverte ou dá continuidade a outra operação — siga a cadeia reembolso → captura → pré-autorização para uma trilha de auditoria completa.
  • Toda entry inclui lineageRef — os IDs de origem (consumidos em FIFO) que financiaram aquele movimento específico.
  • Journals de depósito incluem o UUID da origem criada em metadata.source_uuid para referência cruzada.

Notas de Roadmap

  • Webhooks para mudanças de saldo estão no roadmap — enquanto isso, faça polling de saldos ou entries.
  • Escrow no estilo marketplace (visível para ambas as partes) está planejado como uma modalidade separada das retenções tipo cartão — contate a Inyo se você precisar disso.