Account
Page number (default: 1)
1Number of items per page (default: 10)
10Sort field and order. Use - prefix for descending. Example: -createdAt, createdAt
-createdAtFields to select (comma separated). Use + prefix to include hidden fields. Example: name,status,+holders
Relations to populate (comma separated). Example: wallet,token
No content
GET /api/account HTTP/1.1
Host: api.bound.exchange
Authorization: Bearer YOUR_SECRET_TOKEN
Accept: */*
No content
No content
GET /api/account/me HTTP/1.1
Host: api.bound.exchange
Accept: */*
No content
Returns sessionId, salt, and serverPublic (B) to begin SRP proof of the existing password.
Returns sessionId, salt, and serverPublic (B)
No content
POST /api/account/srp/change-password/init HTTP/1.1
Host: api.bound.exchange
Accept: */*
Returns sessionId, salt, and serverPublic (B)
No content
Client proves knowledge of the old password via M1, then submits new salt, verifier, and encrypted blob atomically.
Session ID returned by POST /auth/srp/change-password/init
Client ephemeral public key A = g^a mod N (base64)
Client proof M1 = H(H(N)⊕H(g) || H(I) || salt || A || B || K) (base64)
New SRP salt generated client-side (base64, 32 bytes)
New SRP verifier v = g^x mod N (base64)
Keystore blob re-encrypted with new derived key (base64, max 13708 chars)
New password hint
Password changed — returns serverProof (M2) for client verification
No content
POST /api/account/srp/change-password/verify HTTP/1.1
Host: api.bound.exchange
Content-Type: application/json
Accept: */*
Content-Length: 158
{
"sessionId": "text",
"clientPublic": "text",
"clientProof": "text",
"newSrpSalt": "text",
"newSrpVerifier": "text",
"newEncryptedBlob": "text",
"newPasswordHint": "text"
}Password changed — returns serverProof (M2) for client verification
No content
Wallet-auth accounts only. Client re-encrypts the blob with the NEW wallet derivation key client-side; server verifies the NEW wallet control proof (fresh nonce) and atomically replaces encryptedBlob + auth-wallet fields. Old-wallet derivation signature is never sent.
Address of the NEW auth wallet
Public key of the NEW auth wallet (verifies EVM/Solana signatures)
metamask | phantom | xverse | okx | unisat
challengeId from GET /auth/wallet/challenge?address=
NEW wallet signature over the issued server nonce (control proof)
Keystore blob re-encrypted client-side with the NEW wallet derivation key
Auth wallet rotated
No content
Method not allowed, signature invalid, challenge invalid, taken, or not a wallet keystore
Unauthorized
POST /api/account/wallet/rotate HTTP/1.1
Host: api.bound.exchange
Authorization: Bearer YOUR_SECRET_TOKEN
Content-Type: application/json
Accept: */*
Content-Length: 132
{
"address": "text",
"chain": "evm",
"publicKey": "text",
"provider": "text",
"challengeId": "text",
"signature": "text",
"encryptedBlob": "text"
}No content
2FA state toggled
No content
Invalid OTP code or setup not completed
POST /api/account/2fa/toggle HTTP/1.1
Host: api.bound.exchange
Content-Type: application/json
Accept: */*
Content-Length: 2
{}No content
The inscriptionId to set as avatar. Pass null or omit to remove the avatar.
Avatar updated
No content
Inscription not found or not owned by caller
PATCH /api/account/avatar HTTP/1.1
Host: api.bound.exchange
Content-Type: application/json
Accept: */*
Content-Length: 24
{
"inscriptionId": "text"
}No content
Default token removed successfully
No content
Invalid slot or tokenId
Unauthorized
DELETE /api/account/default-token HTTP/1.1
Host: api.bound.exchange
Content-Type: application/json
Accept: */*
Content-Length: 32
{
"slot": "usdc",
"tokenId": "text"
}No content
Default token set successfully
No content
Token not found, unsupported chain, or token invalid for slot
Unauthorized
PATCH /api/account/default-token HTTP/1.1
Host: api.bound.exchange
Content-Type: application/json
Accept: */*
Content-Length: 32
{
"slot": "usdc",
"tokenId": "text"
}No content
Queues a verification email to the new address (and a notice to the current address, if one exists). Returns { srpSession } for SRP accounts; passkey and wallet accounts return {} (they re-authenticate with JWT + emailed token only). Emailless passkey/wallet accounts may use this to set an email for the first time.
New email address to associate with the account
Returns { srpSession } for SRP accounts, {} for passkey/wallet accounts
No content
New email already taken or same as current email
Rate limit exceeded
POST /api/account/change-email/init HTTP/1.1
Host: api.bound.exchange
Content-Type: application/json
Accept: */*
Content-Length: 19
{
"newEmail": "text"
}No content
Finalises the email update. SRP accounts: srpData (sessionId, clientPublic, clientProof, newSrpVerifier) is required, and the srpSession from the init response provides sessionId, salt, and serverPublic. Passkey and wallet accounts re-authenticate with JWT + emailed token only (no step-up) — they send neither srpData nor any passkey fields.
Verification token from the change-email email link
New email address being verified (cross-verified against the token)
Email updated successfully
No content
Invalid or expired token, email mismatch, or missing re-auth fields
POST /api/account/change-email/verify HTTP/1.1
Host: api.bound.exchange
Content-Type: application/json
Accept: */*
Content-Length: 129
{
"token": "text",
"email": "text",
"srpData": {
"newSrpVerifier": "text",
"sessionId": "text",
"clientPublic": "text",
"clientProof": "text"
}
}No content
Last updated