Wallets
Wallets are high-frequency balance accounts. They accept writes at high throughput and post aggregated journal entries to the ledger automatically after a short delay.
Base URL:
https://api.trancent.dev— all paths below are relative to this.
See Wallets concept page for an overview of how wallets work.
Wallet key format
All wallet endpoints take a walletKey path parameter with the format:
{ledgerId}:{callerKey} ledgerId— the UUID for the ledger, shown on the ledger detail page in the dashboardcallerKey— any opaque string you use to identify the wallet (e.g.user_abc123,sub_xyz)
Wallets are auto-created on first write — no provisioning needed.
Credit
Add to a wallet balance.
POST /v1/wallets/:walletKey/credit
Authorization: Bearer tk_live_<secret>
X-Timestamp: <unix-seconds>
X-Signature: <hmac-sha256>
Content-Type: application/json Request body
{
"amount": "1000",
"assetCode": "USD",
"externalId": "grant_abc123",
"metadata": "{"reason": "monthly grant"}"
} Fields
| Field | Type | Required | Description |
|---|---|---|---|
amount | string (integer) | Yes | Amount to credit in smallest unit (e.g. cents). Must be a positive integer. |
assetCode | string | Yes | Asset type — ISO 4217 currency code (e.g. USD) or non-monetary code (e.g. TOKENS, API_CALLS). |
externalId | string | No | Idempotency key. Duplicate IDs return status: "duplicate" without modifying the balance. |
metadata | string | No | Arbitrary JSON string stored with the transaction for audit purposes. |
Response — 200 OK
{
"status": "accepted",
"balance": "10000",
"available": "10000"
} | Field | Description |
|---|---|
status | "accepted" — write recorded. "duplicate" — externalId already used; balance unchanged. |
balance | Current total balance as integer string. Always up to date. |
available | Balance minus any active reservation holds. |
Debit
Subtract from a wallet balance.
POST /v1/wallets/:walletKey/debit
Authorization: Bearer tk_live_<secret>
X-Timestamp: <unix-seconds>
X-Signature: <hmac-sha256>
Content-Type: application/json Request body and response shape are identical to Credit. amount reduces the balance rather than increasing it.
Get balance
Query the current balance without writing.
GET /v1/wallets/:walletKey/balance
Authorization: Bearer tk_live_<secret>
X-Timestamp: <unix-seconds>
X-Signature: <hmac-sha256> Response — 200 OK
{
"balance": "10000",
"available": "8000"
} | Field | Description |
|---|---|
balance | Current total balance. Always up to date. |
available | balance minus active reservation holds. |
A fresh wallet (never written to) returns "0" for all fields.
Real-time balance stream (WebSocket)
Subscribe to live balance updates as writes are accepted.
GET /v1/wallets/:walletKey/ws
Authorization: Bearer tk_live_<secret>
X-Timestamp: <unix-seconds>
X-Signature: <hmac-sha256>
Upgrade: websocket The connection is authenticated with the same HMAC-SHA256 signing as REST requests. See Authentication.
Messages received
{
"type": "balance",
"balance": "12000",
"available": "12000"
} A balance message is pushed whenever a write is accepted or a batch is posted to the ledger.
Idempotency
Pass externalId on every credit or debit to make the write idempotent. If the same externalId is submitted again:
- The response returns
status: "duplicate" - The balance is not changed
- No error is returned
This makes it safe to retry on network failures without double-counting.
Error responses
| Status | Meaning |
|---|---|
400 | Missing or invalid amount or assetCode |
401 | Missing, invalid, or expired API key / signature |
All errors return JSON:
{ "error": "amount must be a positive integer string" } Example: grant and spend tokens
POST https://api.trancent.dev/v1/wallets/a1b2c3d4-...:user_42/credit
Authorization: Bearer tk_live_<secret>
X-Timestamp: 1741478400
X-Signature: <hmac>
Content-Type: application/json
{ "amount": "50000", "assetCode": "TOKENS", "externalId": "grant_monthly_2026-03" } POST https://api.trancent.dev/v1/wallets/a1b2c3d4-...:user_42/debit
Authorization: Bearer tk_live_<secret>
X-Timestamp: 1741478401
X-Signature: <hmac>
Content-Type: application/json
{ "amount": "100", "assetCode": "TOKENS", "externalId": "api_call_req_xyz" } GET https://api.trancent.dev/v1/wallets/a1b2c3d4-...:user_42/balance
Authorization: Bearer tk_live_<secret>
X-Timestamp: 1741478402
X-Signature: <hmac> {
"balance": "49900",
"available": "49900"
}