Core concepts
Five ideas cover the whole API.
API keys
Section titled “API keys”You authenticate every request by signing it with an Ed25519 key. You generate the keypair, register the public half with XKOVA, and keep the private seed. XKOVA stores only public keys — it can verify your requests but can never impersonate you. See Authentication.
Vaults
Section titled “Vaults”A vault is a key managed by MPC — generated and held as shares so no single party can sign alone. A vault has:
- a tier (
hosted/self/customer_tee) — fixed at creation, deciding who must authorize a signature (see How it works); - a status —
creating→active,resharingduring a key rotation,frozenif halted; - a stable public key — unchanged by rotations, so addresses never move.
Key generation runs asynchronously: a new vault returns creating and becomes
active shortly after.
Wallets
Section titled “Wallets”A wallet is a chain address derived under a vault. One vault can hold many
wallets across chains (avalanche_c, base, bitcoin); they all share the
vault’s underlying key and its controls. Deriving a wallet is instant.
Intents
Section titled “Intents”An intent is the canonical, byte-exact description of a transaction — chain, vault, path, recipient, amount, asset, idempotency key. You sign the intent with your API key and send that signature; XKOVA binds it to exactly the transaction it will broadcast, so the recipient and amount cannot be altered after you approve. The SDK builds and signs intents for you.
- On EVM you may send convenience fields (
to,amount,asset) and the API forms the intent, or send the exact intent bytes yourself. - On Bitcoin you always send the signed intent bytes (the idempotency key is carried inside it).
Transactions and states
Section titled “Transactions and states”Submitting a transaction is asynchronous — it returns 202 and then moves through
these states:
| State | Meaning |
|---|---|
created | accepted, queued for checks |
policy_checked | passed policy + limits |
awaiting_cosigner | MPC signing in progress |
signed | signature produced |
broadcast | accepted by the network’s validity checks and sent |
confirmed / final | on-chain |
failed | broadcast or chain error |
rejected | blocked by policy, limits, or a bad intent |
Track a transaction by polling GET /transactions/{txId} or, better, with
webhooks.
Policy and spend limits
Section titled “Policy and spend limits”A vault enforces controls before any signature: a recipient/asset policy,
per-transaction and per-day spend limits, and — for hosted vaults — an
end-user token per signature. A blocked transaction ends rejected with a
reason; no partial signature is ever produced.
Idempotency
Section titled “Idempotency”Every money-moving request carries an idempotency key you choose. Retrying with the same key returns the same transaction rather than sending twice — so a network hiccup or a retry never double-spends. Reusing a key with different content is an error.