Skip to content

Parameter effects and outputs

What each request parameter changes and what comes back — the side effects and response fields for the account, wallet, and signing endpoints, and how signing stands in for transactions.

Updated View as Markdown

The API reference lists each endpoint’s request and response shapes. This page reads the other direction: for the account, wallet, and signing endpoints, what does changing a given parameter actually do (its effect and side effects), and what appears in the response (its output). Every row reflects current behavior; see the linked API pages for the full schemas.

Two conventions used below:

  • Effect — what the parameter changes, including error paths and custody or quota side effects.
  • Output — the response field(s) the parameter drives. A parameter with no output row is never echoed.

Creating an account

POST /v1/accounts — see Accounts. Creating an account always derives its first wallet, charged to the tenant’s maxWallets allowance before any key material is generated — so a create with no wallet headroom left returns 409 quota_wallets_exceeded and nothing is created.

Parameter Effect Output
displayName Normalized (NFKD) to 3–64 characters and must keep at least one Latin letter; the account slug is derived from it. A name that cannot normalize returns 400 invalid_parameter. account.slug (server-generated), account.displayName
kind HD makes a mnemonic account you can derive more wallets from; PK is a single imported key, where derive is refused 422 unsupported_for_kind and import is used instead. A PK create without secret is 400 invalid_body. account.kind
secret On HD, omit it to have the service generate a mnemonic; on PK it is the private key and is required. The secret itself is never returned — it leaves only through the sealed export path. drives generatedSecret (true when omitted, i.e. generated)
defaultNetwork Fixes the chain each derived address signs on, and therefore the default chainId for typed-data signing. A well-formed slug for a network the workspace lacks is 400 unsupported_network. Not changeable after creation. account.defaultNetwork; every address.network / address.chainId
hasOwnPassword The Cold Vault tier: the account gets a password separate from the session and is locked immediately after creation (no custody window), so it must be unlocked before first use. Requires accountPassword. Omitted or false creates the account unlocked with a custody window. account.hasOwnPassword; a Cold Vault create returns account.locked: true
accountPassword The Cold Vault password, held to the same policy as a workspace password (under 12 characters is 422 weak_password). Required when hasOwnPassword is set and rejected without it (400 invalid_body). Used once, never stored. —

Unlocking and locking an account

POST /v1/accounts/{slug}/unlock and .../lock — see Workspace token routes. Both return 204 with no body and are scope-free (any workspace token).

Parameter Effect Output
accountPassword (unlock) Opens the account and starts a fixed custody window (accountAbsoluteSec). Re-verifying an account that is already live does not renew its deadline. The workspace idle clock slides on admission even when the password then turns out wrong. Shares the tenant mint/KDF budget, so it can return 429 mint_rate_limited. A wrong password is 401 bad_password with a per-account backoff (1/2/4/8s → 429 account_unlock_rate_limited); the fifth consecutive failure — or the mint-budget limit, whichever is lower — retires the whole session, after which calls return 401 session_expired. 204
(lock, no body) Locks the account immediately and zeroizes its in-memory key material. A manual lock is not auto-reopened even while a durable scoped key pins the session. 204

Wallet endpoints

See Accounts. Every wallet-producing call reserves the tenant’s cross-workspace maxWallets headroom before the core call, so a call over the ceiling is 409 quota_wallets_exceeded and derives nothing.

Endpoint / parameter Effect Output
POST .../wallets — count (1–500) Derives count wallets on an HD account (PK is 422 unsupported_for_kind). before and after — the account’s total wallet count on each side, not the number added
POST .../wallets/allocate (no body) Hands out the next unallocated wallet of an HD account: in buffer mode a pre-derived one, refilling asynchronously; otherwise derived on demand. Marks the wallet with an internal reserved tag. the allocated wallet
POST .../wallets/seed-allocated — count (0–100,000) Migration prep: marks the lowest count wallet ids as already allocated so allocate skips them. Idempotent; a count above the account’s wallet total is 400. allocated, total
POST .../wallets/import — privateKey, vm? Imports one wallet into a PK account (HD is 422 unsupported_for_kind); an unparseable key is 400 invalid_private_key. vm (evm or svm) pins the scheme for an ambiguous key form, otherwise it is inferred. A PK wallet carries an address on both chains. the imported wallet
PUT .../wallets/{id}/tags — tags (max 32) Replaces the whole caller-visible tag list rather than merging; each tag is trimmed, Unicode-normalized, and de-duplicated. Reserved sys:* tags are stripped from the input and preserved from the existing set. the wallet with its public tags

Signing (and how it stands in for transactions)

POST /v1/sign/* — see Sign. tee-docker signs; it never builds, simulates, submits, or broadcasts, and there are no /transactions or balance routes. The transaction-signing surface is /sign/digest (EVM) and /sign/bytes (Solana): you build and hash the transaction yourself, have the service sign, then assemble the signed transaction and broadcast it from your own client.

Across all four routes, address (1–128 chars) is resolved by public key across the whole workspace, and its owning account is unlocked lazily — so a locked Cold Vault owner returns 423 account_locked and an unknown or other-tenant address returns 404 account_not_found. Every route requires the sign scope and is workspace-token-only: a scoped API key is refused 403 scope_denied regardless of tier. Every response echoes the resolved address.

Endpoint / parameter Effect Output
/sign/message — message, encoding? encoding is personal_sign, raw, or ed25519. With an encoding the service uses the encoded path and the response gains a messageHash; without one it uses the address’s default scheme and returns no messageHash. An encoding the address’s VM cannot perform is 501 unsupported_operation. signature, and messageHash only when an encoding was given
/sign/typed-data — typedData, chainId? EVM only (422 unsupported_for_kind otherwise). The envelope must carry domain, types, primaryType, and message, and primaryType must name a struct in types. chainId defaults to the address’s own network — there is no silent mainnet default. If the payload’s domain.chainId is readable and disagrees with the signing chain, the request is 400 chain_id_mismatch naming both. The caller’s exact object is signed; validation never rewrites the signed bytes. signature, domainSeparator, structHash
/sign/digest — digest EVM (secp256k1) only. digest must be a lowercase 0x-hex 32-byte value and is signed verbatim — no keccak, no EIP-191 prefix. Build the transaction v from recovery (the yParity: use it directly for typed transactions, or 35 + 2·chainId + recovery for legacy EIP-155). r, s, recovery, signature
/sign/bytes — message, encoding? Solana (ed25519) only. message is hex (default, lowercase 0x) or base64 per encoding, decoded with a strict round-trip, and must be 1 byte to 16 KiB. The exact bytes are signed verbatim — you compile the Solana message, the service signs, and you attach the signature. signature (base58) and signatureHex
Navigation

Type to search…

↑↓ navigate↵ selectEsc close