API Reference
Account
Linked Exchanges

List Linked Exchanges

GET /api/v1/credentials

Scope: account:read

Returns metadata about the exchange credentials linked to each of your wallets. Raw keys are never exposed by the API — only the last 4 characters are returned for UI identification.

Response

200 OK

[
  {
    "exchange": "hyperliquid",
    "wallet_addr": "0x...",
    "key_preview": "...28ba",
    "permissions": "trade",
    "added_at": "2026-03-08T22:29:56Z",
    "last_used": "2026-03-09T00:25:39Z",
    "status": "active",
    "client_encrypted_blob": "U1BSRFIy...",
    "client_blob_version": 2
  }
]
FieldDescription
exchangeLowercase exchange identifier (hyperliquid, extended, lighter, orderly, aster)
wallet_addrThe wallet address this credential belongs to
key_previewLast 4 characters of the public key portion — for identification only
permissionstrade (only permission Spreadr requests)
added_atWhen you added the credential
last_usedMost recent successful decrypt for an execution. Null if never used.
statusCurrently always active — credentials are deleted, not soft-disabled
client_encrypted_blobOptional. The browser-vault copy of the keys, encrypted client-side (AES-256-GCM under a key derived from the wallet signature and the per-user vault salt); the API cannot decrypt it. Used by RESTORE KEYS in the app.
client_blob_versionOptional. 2 when client_encrypted_blob is a v2 envelope (base64 starting U1BSRFIy); absent for a v1 blob, which the app re-encrypts on the next restore via PUT …/client-blob.

Why not return more of the key?

The API layer can store encrypted credentials but cannot decrypt them — decryption only happens inside a running trade, cryptographically bound to your user identity. The API simply has no way to return a plaintext key. See Security for the full credential isolation model.

Example

curl -H "X-API-Key: sprdr_..." https://api.spreadr.xyz/api/v1/credentials