Otto WalletsDocs
⌘ K
Docs/API Quickstart
Server integration

Start with the Otto Wallet API

This route is for teams that want direct backend control over signing, retries, and wallet orchestration while staying on the same public contract used by the SDK.

Auth API key + HMAC
Best for Backends and workers
Surface Public Swagger contract
Overview

The API and SDK share the same contract

Use the API directly when you want explicit ownership of HTTP calls. Use the SDK when you want the same public contract with signing already wrapped. The resources are the same: vaults, wallets, transactions, gas station, MPC, and webhooks.

1

Generate workspace credentials in the dashboard

Every public integration starts with a workspace-issued API key and secret. The key identifies the caller. The secret signs the request payload.

AUTHRequired headersX-API-Key · X-Signature
X-API-Key: test_xxx
X-Signature: <base64 hmac sha256>
Content-Type: application/json
2

Sign the canonical payload on the server

Otto verifies the signature against the serialized JSON body. That means your backend, worker, or secure server runtime should be the only place where the secret exists.

If you do not want to own this signing logic yourself, the SDK wraps the same flow for you with @ottowallets/sdk.
3

Create a vault, then generate a wallet under it

POSTFirst flow/vault/create → /wallet/generate-address-hd

Create vault body

NameTypeRequiredDescription
namestringYesHuman-readable treasury name.

Generate wallet body

NameTypeRequiredDescription
networkstringYesNetwork slug like ethereum.
vault_idstringYesVault identifier returned by the previous call.
namestringNoOptional display label for the managed wallet.
4

Preview first, then execute under policy

The safe pattern is to preview a transfer, validate fee and readiness, then submit the execution request. Authentication proves identity, but policy still decides what can actually run.

POSTPreview transfer/wallet/transfer-preview
{
  "from": "0xSender",
  "to": "0xReceiver",
  "amount": "0.50",
  "tokenAddress": null
}
A 403 usually means roles, policies, assignments, or environment scope denied the action, not just a missing credential.