Introduction
A custodial multi-chain wallet API. One user, one seed, six chains.
WalletsTech is a custodial HD wallet service. You create a user with one API call; the service derives a wallet on every supported chain from a single bip39 seed, encrypts and stores the keys, and returns the seed to you exactly once. From then on you check balances, send transfers, estimate fees and read history — all addressed by userId and assetId.
You never handle a private key and you never build a transaction. You ask for a transfer; the service signs it and broadcasts it.
Supported chains
Plus USDT and USDC on every chain that has them. See Asset IDs for the full list and the integer that selects each one.
Your endpoint
The base URL is different for every client. Your endpoint is issued to you along with your credentials — there is no shared public host, so there is no URL to copy from these pages. Wherever the examples say $BASE_URL, substitute the one you were given, and keep it in configuration rather than hard-coded in your source.
Only the host differs. Every path, body, header and response documented here is identical on every deployment.
How a request works
Every endpoint is a POST with a JSON body, including the read-only ones. /auth is the only exception: it takes no body and carries its credentials in headers.
Every response uses the same envelope. Success puts the payload in result:
Failure puts a safe, client-facing message in message:
A requestId is on every response, success or failure. Send your own with an X-Request-Id header and we echo it back and write it to our audit log — quote it when you report a problem and we can find the exact request.
Authentication
Every endpoint except /auth requires a bearer token:
Call /auth with your client id and api key to get one. Tokens are valid for 15 minutes. There is no refresh token and no refresh endpoint — when one expires you call /auth again. See Authentication for the token lifecycle, and for the difference between your API credentials and a user’s wallet password (they are unrelated, and confusing them is the most common integration mistake).
Amounts
Amounts are human-decimal strings — never base units, never floats. Send "0.5", not 500000000000000000 and not the JSON number 0.5.
Balances, fees and transaction amounts all come back the same way, as decimal strings. This is deliberate. Floating-point numbers cannot represent most decimal values exactly, and a rounding error in an on-chain amount is money that is really gone. Keep amounts as strings end to end, and use a decimal library if you need to do arithmetic on them.
What we never do
- We never return your keys. The seed phrase from
/createis the one and only time key material leaves the service. There is no export endpoint —/seedexists and permanently returns403. - We never accept a private key from you. The sender of a transfer is resolved from your
userId, server-side. - We never log your secrets. Passwords, seeds, mnemonics and private keys are stripped before anything is written to a log.
Your password encrypts the keystore and is unrecoverable. It is required to send funds. Store it, and store the seed phrase from /create — if you lose both, nobody can recover the funds, including us.