Skip to main content
Exige uma Assinatura Silver ou superior — tanto para se candidatar quanto para cada chamada autenticada. Se a Assinatura do dono da chave expirar, o projeto é congelado até ele reassinar.
Uma API REST que permite ao seu aplicativo trabalhar com o saldo de Vito de um usuário a partir do Discord: ler, cobrar, creditar ou mover entre usuários. Todos os endpoints retornam JSON e são versionados sob /v1.
Vito nunca se converte em dinheiro real, nem vem dele. Ele só circula entre saldos da Vetox.
Todos os endpoints ficam sob https://api.vetox.io/public/vito.Os caminhos escritos nesta página — /v1/deduct, /v1/balance/:discordId e os demais — são relativos a esse prefixo, que é o que o SDK acrescenta por você. Se for chamar direto, use a URL completa:
https://api.vetox.io/v1/deduct não é uma rota e devolve 404.
Está desenvolvendo em Node.js? Não escreva as chamadas REST na mão — use o pacote oficial @vetox-bot/vito. Ele cobre os nove endpoints e a verificação de webhooks, e cuida de idempotência e retentativas por você. Veja SDK oficial para Node.js logo abaixo.

Obter acesso

O acesso é concedido por projeto. Você precisa dos quatro requisitos:
1

Uma Assinatura ativa, Silver ou superior

Verificada a cada chamada, não apenas na aprovação.
2

Uma solicitação de desenvolvedor aprovada

Enviada pela página Vito API no seu painel. Revisada manualmente pela equipe Vetox.
3

Os Termos de Desenvolvedor da API aceitos

Confirmados ao enviar a solicitação.
4

Os scopes de que seu projeto precisa

Concedidos pela equipe Vetox com base no que você descreveu.
Seja concreto sobre o que você está construindo e como vai guardar a chave. São as solicitações vagas que acabam recusadas.

Scopes

Autenticação

Envie sua chave secreta como token Bearer:
Duas camadas opcionais reforçam ainda mais um projeto:
  • Lista de IPs permitidos — restringe as chamadas a IPs de servidor específicos
  • Limites de taxa — tetos por projeto que aumentam conforme o nível de Assinatura do dono

Chaves, rotação e armazenamento

Sua chave e seu segredo de assinatura são exibidos exatamente uma vez. Após a aprovação você tem uma janela de 7 dias para revelá-los na aba de chaves API. A Vetox guarda apenas um hash e não consegue exibi-los de novo — se perder a janela, será preciso rotacionar.
  • Mantenha-a apenas no servidor — quem a tiver pode cobrar dos seus usuários
  • Rotacione pela aba de chaves API. A chave anterior continua funcionando por um período de carência de 24 horas, para você implantar sem indisponibilidade
  • O segredo de assinatura dos webhooks é rotacionado separadamente, com sua própria sobreposição de 24 horas
  • Se vazar, rotacione imediatamente

SDK oficial para Node.js

O pacote oficial @vetox-bot/vito encapsula os nove endpoints e também a verificação de webhooks. Ele cuida por você do cabeçalho Idempotency-Key, das retentativas com backoff exponencial, dos timeouts e da classificação dos erros.

Instalação

Exige Node.js 20 ou mais recente. O pacote não tem nenhuma dependência em tempo de execução — usa o fetch embutido e o node:crypto — e é distribuído em ESM e CommonJS, com definições TypeScript completas.

Inicialização

Se você omitir apiKey, o SDK lê VITO_API_KEY do ambiente. O formato da chave é validado na construção, então uma chave malformada falha na hora em vez de custar uma ida e volta na rede e um 401.
A chave move dinheiro — mantenha-a sempre no servidor, nunca em um bundle de cliente ou no navegador. console.log(vito) imprime [redacted] no lugar da chave, e o SDK recusa qualquer baseUrl com http:// para um host não local, para que a chave não trafegue em texto claro.

Opções do cliente

Métodos disponíveis

Cada método devolve direto o campo data já desembrulhado — você nunca precisa abrir success nem data na mão. Todos também aceitam opções por chamada: { timeoutMs, maxRetries, signal, headers }, e os métodos de escrita aceitam ainda { idempotencyKey }.

Exemplos de uso

Conferir a chave na inicialização

Ler um saldo

Cobrar de um usuário (vender um item)

Registre o pedido aqui apenas como pendente. A cobrança ainda não aconteceu — entregue no webhook confirmation.completed, não nesta resposta.

Creditar um usuário

Percorrer as transações

Idempotência e retentativas

O SDK envia um cabeçalho Idempotency-Key em toda escrita (deduct, credit, transfer). Se você não fornecer um, ele gera a chave uma única vez por chamada e reenvia exatamente a mesma chave em cada retentativa, de modo que uma retentativa nunca consegue liquidar a operação duas vezes. Forneça sua própria chave quando a mesma operação lógica puder ser repetida a partir de um novo processo — um executor de tarefas, uma reentrega de fila ou uma varredura agendada:
auth.rotateKey() fica de fora de propósito — uma retentativa ali emite uma segunda chave e invalida a que a primeira tentativa devolveu.
Se Retry-After for maior que maxRetryDelayMs (ou seja, sua cota por hora realmente acabou), o SDK lança VitoRateLimitError na hora, em vez de dormir durante todo o orçamento da sua requisição.

Verificar webhooks com o SDK

O constructEvent confere a janela de replay de 5 minutos, compara em tempo constante com todas as assinaturas h1 do cabeçalho — portanto funciona automaticamente durante a sobreposição de 24 horas de uma rotação — e então analisa o payload e devolve o evento tipado. Em um route handler do Next.js (App Router), use a variante que lê o corpo bruto sozinha:
A assinatura cobre os bytes brutos. No Express, monte express.raw({ type: 'application/json' }) na rota do webhook — o express.json() consome o corpo e daí em diante toda verificação falha. No Next.js, não chame request.json() antes do constructEventFromRequest.
A entrega é pelo menos uma vez. Deduplique por event.eventId antes de executar qualquer efeito colateral.

Tratamento de erros

Tudo o que o SDK lança herda de VitoError e carrega code, status, type, requestId e retryable.
Registre sempre o requestId — é o que o suporte precisa para rastrear uma chamada específica.

Cancelar uma chamada

Cancelar também interrompe qualquer retentativa pendente e lança VitoConnectionError com o código VITO_SDK_ABORTED.

Cobrar de um usuário

Sua chave sozinha não move os Vito de um usuário. Toda cobrança exige que o usuário a aprove com o PIN da carteira dele, em vetox.io — nunca dentro do seu app nem dentro do Discord.
1

Seu app chama POST /v1/deduct

Com o usuário, o valor, o guildId de origem e os detalhes do item.
2

O Vito retorna uma confirmUrl

Uma confirmação pendente, válida por 10 minutos. O usuário também recebe uma DM.
3

O usuário aprova com o PIN dele

Em vetox.io.
4

O Vito liquida e notifica

O saldo é debitado, a transação registrada e um webhook assinado é enviado, caso você tenha um configurado.
5

Seu app verifica e conclui

Confira a assinatura e então libere o conteúdo ou entregue o item.
Conclua sua ação somente em confirmation.completed — nunca na resposta do /deduct. Nesse ponto a cobrança ainda não é definitiva.

Parâmetros da requisição — /v1/deduct

Creditar um usuário

POST /v1/add credita Vito a um usuário a partir do seu próprio saldo — para recompensas ou estornos. Os mesmos campos do /deduct, exceto guildId e product.
Diferente de uma cobrança, um crédito não tem etapa de confirmação: é liquidado na hora. Exige o scope credit:create e saldo suficiente, senão a chamada retorna 402 VITO_INSUFFICIENT_OWNER_FUNDS.

Taxas

Toda cobrança é liquidada para você já descontada a taxa da plataforma — o mesmo esquema das transferências de Vito dentro do app, conforme o seu nível de Assinatura:
Valores de 5 Vito ou menos são isentos de taxa, e créditos via /v1/add são sempre isentos.

Webhooks

Adicione uma ou mais URLs de callback https na aba de configurações. O Vito entrega um POST assinado sempre que uma confirmação chega a um estado final.
Os webhooks só são disparados se o seu projeto tiver ao mesmo tempo uma URL de callback e um segredo de assinatura. Revele o segredo (whsec_…) uma única vez na aba de chaves API.

Verificar a assinatura

Cada entrega traz um cabeçalho X-Vito-Signature:
Outros dois cabeçalhos acompanham cada entrega — use X-Vito-Event-Id como chave de deduplicação, já que uma retentativa reenvia o mesmo id:
Durante uma rotação do segredo de assinatura, o cabeçalho carrega mais de uma assinatura, a mais nova primeiro:
Aceite a entrega se qualquer h1 conferir. Um verificador que lê apenas o primeiro vai rejeitar todos os webhooks até implantar o segredo novo — o que anula justamente o propósito da sobreposição de 24 horas.
No Node.js: o Webhooks.constructEvent do @vetox-bot/vito faz tudo isso por você — a janela de replay, a comparação com todas as assinaturas h1 e a checagem em tempo constante — e devolve o evento tipado. O código abaixo serve para uma implementação manual ou para outra linguagem.
Recalcule o HMAC sobre <ts>:<rawBody> com seu segredo de assinatura e compare em tempo constante.
Verifique contra o corpo bruto, antes de qualquer parsing de JSON ou middleware que o reescreva.

Eventos

Cinco tipos de evento, todos com o mesmo formato de payload. data.status carrega o desfecho.
Os webhooks são retentados 5 vezes com backoff. Responda 2xx rapidamente e faça sua entrega de forma assíncrona.

Códigos de erro

Toda resposta vem encapsulada. Um sucesso traz data e uma falha traz error, nunca os dois:
Todo código tem o prefixo VITO_. Compare a string completa — um RATE_LIMITED ou FORBIDDEN isolado nunca aparece na resposta.

Limites de taxa

Há também um limite por IP igual à metade da sua cota por minuto, com piso de 30.
Sob carga, os endpoints de escrita falham de forma fechada — a cobrança é recusada em vez de arriscar um gasto duplicado. Os de leitura falham de forma aberta. Trate uma escrita recusada como “não aconteceu” e tente de novo.
Envie um cabeçalho Idempotency-Key para deduplicar retentativas com segurança.

Endpoints

Limites

  • Confirmações expiram após 10 minutos — trate as não confirmadas como abandonadas
  • amount precisa ser um inteiro positivo
  • metadata é limitado a 10 chaves
  • Os tetos por transação e diários são definidos pela equipe Vetox e aparecem somente para leitura na aba de configurações

Checklist de segurança

A chave API e o segredo de assinatura nunca pertencem ao código do cliente. Rotacione na hora se algum vazar.
Cheque a assinatura contra o corpo bruto e recuse entregas com mais de ~5 minutos.
Nunca entregue com base na resposta do /deduct — a cobrança só é definitiva em confirmation.completed.
Peça apenas os scopes que você realmente usa e ative a lista de IPs permitidos.

Solução de problemas

A Assinatura do dono expirou. Ela é reverificada a cada chamada.
Não dá para recuperar — só um hash é armazenado. Rotacione para obter uma nova.
Aceite os dois segredos durante a sobreposição de 24 horas.
O usuário não aprovou. Confirmações expiram após 10 minutos.
Um projeto precisa de URL de callback e segredo de assinatura. Com apenas um dos dois, nada é entregue.
É a taxa de liquidação. Use valores de 5 Vito ou menos para evitá-la, ou embuta no seu preço.
/v1/add é custeado pelo seu próprio saldo, não criado do nada. Recarregue.

Vito

Saldos, o PIN e as taxas.

Solicitações de pagamento

O que o usuário vê quando você cobra dele.

@vetox-bot/vito no npm

O pacote Node.js oficial — uma instalação, integração completa.