---
title: "Start a 2-party threshold key generation"
method: POST
path: "/v1/keys/tss/keygen/begin"
tags: ["Key Custody"]
---

# Start a 2-party threshold key generation

`POST /v1/keys/tss/keygen/begin`

## Request

- Base URL: `https://api.1claw.co`
- URL: `https://api.1claw.co/v1/keys/tss/keygen/begin`
- Auth: HTTP bearer

Begins a distributed key generation between the vault (party 1) and the
caller's browser (party 2, `@1claw/tss-wasm`). The result is a
`custody: client_tss` treasury wallet whose private key never exists
anywhere: the vault keeps one FROST share, the caller keeps the other,
wrapped under their passkey's PRF output. Requires a passkey with
`prf_supported: true` and no active wallet on the chain. Chains: `solana`
(Ed25519). Sessions expire after 10 minutes.

## Request body

- object
  - `chain` 'solana' | 'xrp' | 'xrp-testnet' | 'cardano' | 'cardano-preprod', required
  - `replace_existing` boolean: Re-key ceremony: replace the active server-custody wallet on this chain. On `complete` its balance is swept to the new address by the old key's last signature and the old wallet is deactivated (audit `treasury_wallet.rekeyed`).
  - `key_kind` 'treasury_wallet' | 'agent_signing_key': `agent_signing_key` creates a self-custody signing key for `agent_id`: shares 2 and 3 are the caller's, the agent co-signs only through a runtime share holder the caller provisions, and only the caller can back it up or restore it (audited `signing_key.recovered`, webhook of the same name).
  - `agent_id` string, uuid: Required for `agent_signing_key`.
  - `approval_id` string, uuid: Re-key only. A re-key moves the whole balance into a key whose shares 2 and 3 sit on the customer's kit, so it is gated as an export, at begin and before the device makes a kit: wallet access (`export` and `send`) on the old wallet, the `treasury_wallet.export` control-plane consensus policy, and the activity policy for `export`. When consensus is required the call answers 202 with `pending_approval_id`; once approved, call begin again with that id here.

## Response `201`

Session opened; the vault's round-1 package

- object
  - `session_id` string, uuid
  - `chain` string
  - `curve` string
  - `server_identifier` integer
  - `client_identifier` integer
  - `recovery_identifier` integer: The device runs both `client_identifier` (its everyday share) and `recovery_identifier` (the share that goes only into the customer's offline recovery kit). 2-of-3: any two shares sign; the vault alone cannot.
  - `min_signers` integer
  - `max_signers` integer
  - `server_round1` string: Base64 FROST DKG round-1 package.
  - `expires_at` string, date-time

## Other responses

- `202`: Re-key only: the org requires M-of-N consensus on `treasury_wallet.export`. Nothing was started; call again with `approval_id` once the approval is granted.
- `400`: Invalid request
- `401`: Authentication required or invalid
- `403`: Insufficient permissions
- `409`: Resource already exists or conflict

---

[API](https://skmtc.dev/1claw/apis/1claw-api.md) · [All operations](https://skmtc.dev/1claw/apis/1claw-api/llms.txt) · [OpenAPI document](https://skmtc.dev/1claw/apis/1claw-api/revisions/5fa0918f3b41?raw)
