---
title: "Threshold signing, round 1"
method: POST
path: "/v1/keys/{key_id}/tss/sign/begin"
tags: ["Key Custody"]
---

# Threshold signing, round 1

`POST /v1/keys/{key_id}/tss/sign/begin`

## Request

- Base URL: `https://api.1claw.co`
- URL: `https://api.1claw.co/v1/keys/{key_id}/tss/sign/begin`
- Auth: HTTP bearer

Needs `X-Passkey-Token` from a tx-assert with `action: tss_sign` and
`tx_digest` = hex SHA-256 of `message`. The message must be exactly one
returned by `POST /v1/treasury/wallets/{chain}/tss/prepare` for this key,
within the prepared session's lifetime; any other message is refused
with 403. It must also be a shape this path signs (for Solana: System
transfers from the wallet, optionally with a memo, the wallet as the
only signer, legacy message); anything else, such as a token approval
or an authority change, is refused with 400. Every transfer destination
is checked against the OFAC SDN list before the vault commits. Returns
the vault's signing commitments; nonces are single-use and expire with
the session.

## Headers

- `X-Passkey-Token` string, required

## Request body

- object
  - `message` string, required: Base64 bytes to sign (the serialised transaction message).

## Response `201`

Session opened

- TssSignBeginResponse
  - `session_id` string, uuid, required
  - `key_id` string, uuid, required
  - `message_digest` string, required: Hex SHA-256 of the message; what the passkey token was bound to.
  - `server_commitments` string, required: Base64 FROST signing commitments from the vault (first payload).
  - `chain` string, required
  - `wallet_address` string, required: The wallet the transaction must spend from.
  - `signing_payload` string, required: Base64 bytes the threshold signature covers, derived from the message by the chain's rule (Solana: the message; XRPL: its signing data; Cardano: blake2b-256 of the body; Bitcoin: the first input's BIP341 sighash). The device derives them itself and refuses on mismatch.
  - `signing_payloads` string[], required: Every payload (Base64), one per input for a Bitcoin transaction; `signing_payload` is the first. The device signs each with its own round.
  - `server_commitments_all` string[], required: The vault's commitments, one per payload; `server_commitments` is the first.
  - `expires_at` string, date-time, required

## Other responses

- `400`: Invalid request
- `401`: Authentication required or invalid
- `403`: Insufficient permissions
- `404`: Resource not found

## Changes

- **2026-10-20** `5fa0918f3b41`: 10 info
  - the response property `chain` became required for the status `201`
  - the response property `expires_at` became required for the status `201`
  - the response property `key_id` became required for the status `201`
  - the response property `message_digest` became required for the status `201`
  - …6 more

[Operation history](https://skmtc.dev/1claw/apis/1claw-api/changes/v1/keys/:key_id/tss/sign/begin/post.md)

---

[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)
