Multisig Wallets

Create a multisig wallet

Create the organization multisig wallet for a network, with the number of signatures a transfer will require (M of N). Nothing is deployed on-chain yet: the account is created once M signers have bound a key from the signer app and been validated — its address and threshold are fixed at that point. Available from the Agent Wallet Growth plan, or on a grant by Keyban.

post/v1/multisig-wallets

Request

  • Base URL: https://api.prod.keyban.io
  • URL: https://api.prod.keyban.io/v1/multisig-wallets
  • Auth: one of:
    • API key in header X-Api-Key
    • bearer (a scheme the document does not define)

Request body

labelstring required

Admin-chosen display name shown in the treasury UI (not unique, never used for lookups)

network'EthereumAnvil' | 'BaseSepolia' | 'BaseMainnet' | 'XdcApothem' | 'XdcMainnet' required

EVM network the wallet lives on. One multisig wallet per organization × network.

thresholdinteger required

Signatures required to move funds (M of N). The account deploys once M signers are validated, and the value is fixed at initialization. Capped at 10 to keep the enrollment ceremony workable.

invitedEmailsstring[]

Organization members invited to enrol a signing key on the freshly created treasury, one email per person. Each must already be an admin or owner of the organization — enrolment is the invitee’s own authenticated call, so an outsider could never complete it. Duplicates are ignored. Inviting is best-effort: a mail failure never undoes the treasury.

Example request

{
  "label": "Main treasury",
  "network": "BaseSepolia",
  "threshold": 2,
  "invitedEmails": [
    "jeanne.martin@example.com",
    "karim.benali@example.com"
  ]
}

Response

Multisig wallet created, awaiting its signers. The creator is invited to enrol on it as part of the same transaction (enrolment is invitation-only), without a mail to themselves. Any invitedEmails are processed after the wallet exists and never affect this status: a rejected address or a mail outage still returns the treasury.

idstring uuid required

Entity UUID

createdAtstring date-time required

Creation date (ISO 8601)

updatedAtstring date-time required

Last update date (ISO 8601)

labelstring required

Human-readable label for the wallet

addressstring required

On-chain address of the wallet. Empty until its signers hold keys and the deployment lands.

status'awaiting_signer' | 'deploying' | 'active' | 'failed' required

Current deployment status of the wallet.

network'EthereumAnvil' | 'BaseSepolia' | 'BaseMainnet' | 'XdcApothem' | 'XdcMainnet' required

EVM network of the wallet.

thresholdinteger required

Signatures required to authorize a transfer (M of N), as recorded at deployment. Not re-read from chain: an out-of-band operator change is not reflected here.

mayEnrollboolean required

Relative to whoever reads this response — not a property of the treasury. The same treasury serves true to one admin and false to another, and the value changes for a given reader over time. True when the session user holds a live (unconsumed) invitation on this treasury and has no live signer enrolment on it, i.e. exactly when POST /multisig-wallets/{id}/signers would get past the invitation guard. Enrolment is reserved to invitees, so a client should only offer the ceremony when this is true. Always false for an API key: there is no session user to be invited, and an API key can never enrol.

awaitingMySignatureboolean required

Relative to whoever reads this response — not a property of the treasury. Two signers of the same treasury legitimately read different values, and the value flips for a given reader as transfers come and go. True when the session user is an active signer here — a key already in the on-chain signer set, the only one the account accepts a signature from — and a transfer of this treasury is still pending without their own signature on it: exactly the state where POST /multisig-wallets/{id}/intents/{intentId}/approvals is waiting for them. It goes back to false the moment they sign, even while the lot keeps collecting the remaining signatures. A signer app can badge the treasuries that need its owner without opening each transfer list. Always false for an API key: there is no session user to owe a signature, and a key can never sign.

Example response

{
  "address": "0x36bc36646e0f00e567a126e116f0d1a0dc21c810",
  "status": "active",
  "network": "BaseSepolia",
  "threshold": 2,
  "mayEnroll": true,
  "awaitingMySignature": true
}

Changes

No recorded changes to this operation across all 1 revision of this API.