Requires a Silver Membership or above — both to apply and for every authenticated call. If the key owner’s Membership lapses, the project freezes until they resubscribe.
/v1.
Getting access
Access is granted per project. You need all four:1
An active Membership, Silver or above
Checked on every call, not just at approval.
2
An approved developer application
Submitted from the Vito API page in your dashboard. Reviewed manually by the Vetox team.
3
Accepted API Developer Terms
Acknowledged when you submit the application.
4
The scopes your project needs
Granted by Vetox staff based on what you described.
Scopes
Authentication
Send your secret key as a Bearer token:- IP allowlist — restrict calls to specific server IPs
- Rate limits — per-project ceilings that scale with the owner’s Membership tier
Keys, rotation and storage
- Keep it server-side only — anyone holding it can charge your users
- Rotate from the API Keys tab. The previous key keeps working for a 24-hour grace period so you can deploy without downtime
- The webhook signing secret rotates separately, with its own 24-hour overlap
- If it leaks, rotate immediately
Official Node.js SDK
The official@vetox-bot/vito package wraps all nine endpoints plus webhook verification. It handles the Idempotency-Key header, retries with exponential backoff, timeouts, and error classification for you.
Installation
fetch and node:crypto — and ships both ESM and CommonJS with full TypeScript definitions.
Initialization
apiKey and the SDK reads VITO_API_KEY from the environment. The key format is validated at construction, so a malformed key fails immediately instead of costing you a round trip and a 401.
Client options
Available methods
Every method returns the unwrapped
data field directly — you never unpack success or data yourself. Each also accepts per-call options: { timeoutMs, maxRetries, signal, headers }, and the write methods additionally accept { idempotencyKey }.Usage examples
Checking the key at startup
Reading a balance
Charging a user (selling an item)
Crediting a user
Paging through transactions
Idempotency and retries
The SDK sends anIdempotency-Key header on every write (deduct, credit, transfer). If you do not supply one it generates the key once per call and replays that same key on every retry, so a retry can never settle the operation twice.
Supply your own key when the same logical operation may be retried from a new process — a job runner, a queue redelivery, or a scheduled sweep:
auth.rotateKey() is excluded deliberately — a retry there mints a second key and invalidates the one the first attempt returned.Verifying webhooks with the SDK
constructEvent checks the 5-minute replay window, compares in constant time against every h1 in the header — so it works through the 24-hour secret-rotation overlap automatically — then parses and returns the typed event.
In a Next.js App Router route handler, use the variant that reads the raw body itself:
Delivery is at-least-once. De-duplicate on
event.eventId before you run any side effect.Error handling
Everything the SDK throws extendsVitoError and carries code, status, type, requestId and retryable.
Cancelling a call
VitoConnectionError with code VITO_SDK_ABORTED.
Charging a user
1
Your app calls POST /v1/deduct
With the user, the amount, the originating
guildId, and item details.2
Vito returns a confirmUrl
A pending confirmation, valid for 10 minutes. The user is also DMed.
3
The user approves with their PIN
On
vetox.io.4
Vito settles and notifies
The balance is deducted, the transaction recorded, and a signed webhook sent if you have one configured.
5
Your app verifies and completes
Check the signature, then unlock the content or deliver the item.
Request parameters — /v1/deduct
Crediting a user
POST /v1/add credits a user from your own balance — for rewards or refunds. Same fields as /deduct except guildId and product.
Unlike a charge, a credit has no confirmation step — it settles immediately. Requires the
credit:create scope and sufficient balance, or the call returns 402 VITO_INSUFFICIENT_OWNER_FUNDS.Fees
Every charge settles to you, minus the platform fee — the same schedule as in-app Vito transfers, based on your Membership tier:Amounts of 5 Vito or less are fee-free, and credits via
/v1/add are always fee-free.Webhooks
Add one or morehttps callback URLs in the Settings tab. Vito delivers a signed POST whenever a confirmation reaches a terminal state.
Verifying the signature
Each delivery carries anX-Vito-Signature header:
X-Vito-Event-Id as your de-duplication key, since a retry re-sends the same id:
Recompute the HMAC over
<ts>:<rawBody> with your signing secret and compare in constant time.
Events
Five event types, all sharing one payload shape.data.status carries the outcome.
Webhooks retry 5 times with backoff. Acknowledge with a 2xx quickly and do your fulfilment asynchronously.
Error codes
Every response is wrapped in an envelope. A success carriesdata; a failure carries error, never both:
Rate limits
There is also a per-IP limit of half your per-minute allowance, floored at 30.
Send an
Idempotency-Key header to de-duplicate retries safely.Endpoints
Limits
- Confirmations expire after 10 minutes — treat unconfirmed requests as abandoned
amountmust be a positive integermetadatais capped at 10 keys- Per-transaction and daily caps are set by Vetox staff and shown read-only in the Settings tab
Security checklist
Keep secrets server-side
Keep secrets server-side
The API key and signing secret never belong in client code. Rotate immediately if either leaks.
Verify every webhook
Verify every webhook
Check the signature against the raw body and reject deliveries older than ~5 minutes.
Settle only on completed
Settle only on completed
Never fulfil on the
/deduct response — the charge is not final until confirmation.completed.Least privilege
Least privilege
Request only the scopes you actually use, and enable the IP allowlist.
Troubleshooting
I lost my key
I lost my key
It cannot be recovered — only a hash is stored. Rotate to get a new one.
Webhook signatures fail after rotating
Webhook signatures fail after rotating
Accept both secrets during the 24-hour overlap.
A charge never completes
A charge never completes
The user did not approve it. Confirmations expire after 10 minutes.
No webhooks arrive
No webhooks arrive
A project needs both a callback URL and a signing secret. With only one, nothing is delivered.
402 VITO_INSUFFICIENT_OWNER_FUNDS
402 VITO_INSUFFICIENT_OWNER_FUNDS
/v1/add is funded from your own balance, not created from nothing. Top up.Vito
Balances, the PIN and fees.
Payment Requests
What the user sees when you charge them.
@vetox-bot/vito on npm
The official Node.js package — one install, full integration.