---
title: "Sign withdrawal step"
method: POST
path: "/v1/treasury/withdrawals/{id}/steps/{stepId}/sign"
tags: ["Treasury"]
---

# Sign withdrawal step

`POST /v1/treasury/withdrawals/{id}/steps/{stepId}/sign`

## Request

- Base URL: `https://api.tesser.xyz`
- URL: `https://api.tesser.xyz/v1/treasury/withdrawals/{id}/steps/{stepId}/sign`
- Auth: HTTP bearer
- TypeScript: <https://skmtc.dev/tesser/apis/tesser-api/docs/v1/treasury/withdrawals/:id/steps/:stepId/sign/post.ts> (a function with typed inputs; its response is checked against the schema)

Submit a signature for a self-custodial wallet-source withdrawal step. Webhook updates will be sent as the signature is validated and submitted onchain.

## Path parameters

- `id` string, required
- `stepId` string, required

## Request body

- SignWithdrawalStepRequest
  - `signature` string, required: Base64-encoded JSON envelope `{ body, stamp }` where `body` is the JSON-encoded Turnkey ACTIVITY_TYPE_SIGN_TRANSACTION_V2 activity and `stamp` is the X-Stamp header value produced by stamping that body. Tesser forwards the envelope to Turnkey to obtain the signed transaction.

## Response `200`

Signature accepted. In turn: the wallet step (`step_sequence` 1) is `confirmed` with its broadcast `transaction_hash`; finality and the payout step (`step_sequence` 2) follow asynchronously. Queued behind an earlier nonce from the same wallet: the wallet step is `signed` with `transaction_hash` null until it broadcasts.

- WithdrawalResponse
  - `data` Withdrawal, required
    - `id` string, required: Unique withdrawal identifier
    - `workspace_id` string, required: Workspace ID the withdrawal belongs to
    - `organization_reference_id` string, nullable: External reference ID for tracking
    - `direction` 'outbound', required: Resource direction.
    - `desired` WithdrawalDesiredOverlay, required: Caller's stated intent at creation. Frozen, never overwritten.
      - `from` WithdrawalDesiredFromLegResponse, required: Source side.
        - `account_id` string, nullable, required: Account ID.
        - `amount` string, nullable, required: Amount.
        - `currency` string, nullable, required: Currency code.
        - `network` string, nullable, required: Blockchain network.
      - `to` WithdrawalDesiredToLegResponse, required: Destination side.
        - `account_id` string, nullable, required: Account ID.
        - `amount` string, nullable, required: Amount.
        - `currency` string, nullable, required: Currency code.
        - `network` string, nullable, required: Blockchain network.
    - `estimated` WithdrawalEstimatedOverlay, required: Tesser's projection for how the withdrawal will proceed.
      - `from` WithdrawalEstimatedFromLeg, required: Source side.
        - `account_id` string, nullable, required: Account ID.
        - `amount` string, nullable, required: Amount.
        - `currency` string, nullable, required: Currency code.
        - `network` string, nullable, required: Blockchain network.
      - `to` WithdrawalEstimatedToLeg, required: Destination side.
        - `account_id` string, nullable, required: Account ID.
        - `amount` string, nullable, required: Amount.
        - `currency` string, nullable, required: Currency code.
        - `network` string, nullable, required: Blockchain network.
    - `actual` WithdrawalActualOverlay, required: What actually settled. Populated when the withdrawal reaches a terminal state.
      - `from` WithdrawalActualFromLeg, required: Source side.
        - `account_id` string, nullable, required: Account ID.
        - `amount` string, nullable, required: Amount.
        - `currency` string, nullable, required: Currency code.
        - `network` string, nullable, required: Blockchain network.
      - `to` WithdrawalActualToLeg, required: Destination side.
        - `account_id` string, nullable, required: Account ID.
        - `amount` string, nullable, required: Amount.
        - `currency` string, nullable, required: Currency code.
        - `network` string, nullable, required: Blockchain network.
    - `balance_status` 'unreserved' | 'awaiting_funds' | 'reserved', nullable, required: Balance reservation status.
    - `balance_reserved_at` string, date-time, nullable, required: Timestamp when balance was reserved.
    - `steps` WithdrawalStep[], required: Withdrawal execution steps.
      - `id` string, required: Unique step identifier
      - `withdrawal_id` string, required: ID of the parent withdrawal
      - `step_sequence` integer, required: Order of this step in the withdrawal flow (1-based)
      - `step_type` 'transfer' | 'swap', required: Type of step
      - `estimated` WithdrawalStepEstimatedOverlay, required: Planned values for this step.
        - `from` WithdrawalStepEstimatedFromLeg, required: Source side.
          - `account_id` string, nullable, required: Account ID.
          - `amount` string, nullable, required: Amount.
          - `currency` string, nullable, required: Currency code.
          - `network` string, nullable, required: Blockchain network.
        - `to` WithdrawalStepEstimatedToLeg, required: Destination side.
          - `account_id` string, nullable, required: Account ID.
          - `amount` string, nullable, required: Amount.
          - `currency` string, nullable, required: Currency code.
          - `network` string, nullable, required: Blockchain network.
      - `actual` WithdrawalStepActualOverlay, required: Settled values once the step reaches a terminal state. All-null until then.
        - `from` WithdrawalStepActualFromLeg, required: Source side.
          - `account_id` string, nullable, required: Account ID.
          - `amount` string, nullable, required: Amount.
          - `currency` string, nullable, required: Currency code.
          - `network` string, nullable, required: Blockchain network.
        - `to` WithdrawalStepActualToLeg, required: Destination side.
          - `account_id` string, nullable, required: Account ID.
          - `amount` string, nullable, required: Amount.
          - `currency` string, nullable, required: Currency code.
          - `network` string, nullable, required: Blockchain network.
      - `transaction_hash` string, nullable: Blockchain transaction hash
      - `unsigned_transaction` string, nullable: Unsigned transaction bytes for client signing. Present only for Turnkey-signed steps in signature_requested status.
      - `fees` StepFee[], required: Fees associated with this step
        - `fee_amount` string, required: Fee amount.
        - `fee_currency` string, required: Fee currency code.
        - `fee_type` string, required: Fee type (e.g., 'gas', 'provider', 'tesser_fee').
        - `fee_metadata` object: Additional metadata for the fee (JSON object).
      - `provider_key` 'circle_mint' | 'kraken' | 'turnkey' | 'openfx' | 'zuba', nullable: Provider used for this step
      - `status` 'created' | 'signature_requested' | 'signed' | 'submitted' | 'confirmed' | 'completed' | 'failed', required: Current status of this step
      - `status_reasons` StatusReason[], nullable: Reasons for the current status
        - `error_code` string, required
        - `error_message` string, required
      - `created_at` string, date-time, required: Step creation timestamp
      - `updated_at` string, date-time, required: Step last update timestamp
      - `signature_requested_at` string, date-time, nullable: Timestamp when a signature was requested for the step
      - `signed_at` string, date-time, nullable: Timestamp when the step was cryptographically signed
      - `submitted_at` string, date-time, nullable: Timestamp when step was submitted
      - `confirmed_at` string, date-time, nullable: Timestamp when step was confirmed
      - `completed_at` string, date-time, nullable: Timestamp when step completed
      - `failed_at` string, date-time, nullable: Timestamp when step failed
    - `created_at` string, required: ISO 8601 timestamp of creation.
    - `updated_at` string, required: ISO 8601 timestamp of last update.
    - `expires_at` string, nullable, required: ISO 8601 timestamp when the withdrawal expires.

## Other responses

- `400`: Invalid request data
- `401`: Authentication required or invalid credentials
- `404`: The withdrawal does not exist in this workspace (`treasury-1200`), or the referenced step does not exist on it (`treasury-1203`).
- `409`: Source wallet's live on-chain balance is below the withdrawal amount at sign time. Retry once the wallet is funded; `withdrawal.balance_updated` fires with `balance_status` `awaiting_funds`.
- `500`: Internal server error

## Changes

- **2026-11-07** `14f951e986b1`: 1 info
  - endpoint added

[Operation history](https://skmtc.dev/tesser/apis/tesser-api/changes/v1/treasury/withdrawals/:id/steps/:stepId/sign/post.md)

---

[API](https://skmtc.dev/tesser/apis/tesser-api.md) - [All operations](https://skmtc.dev/tesser/apis/tesser-api/llms.txt) - [OpenAPI document](https://skmtc.dev/tesser/apis/tesser-api/revisions/46461e694e2a?raw)
