---
title: "Drain native balance to a destination address (works on suspended wallets)"
method: POST
path: "/contracts/v1/signers/{signer_id}/drain"
tags: ["Contracts"]
---

# Drain native balance to a destination address (works on suspended wallets)

`POST /contracts/v1/signers/{signer_id}/drain`

## Request

- Base URL: `https://api.run402.com`
- URL: `https://api.run402.com/contracts/v1/signers/{signer_id}/drain`
- Auth: HTTP bearer

Drain the wallet's entire native-token balance to a destination address. Works on suspended wallets — the safety valve, so a project whose allowance runs out can still recover its on-chain funds. Project lifecycle must still allow control-plane writes. Header X-Confirm-Drain: <signer_id> required. Optional Idempotency-Key is request-fingerprinted; mismatched replays return 409 carrying the stored call's status/call_error/tx_hash, and a matched replay of a drain that failed before broadcast re-executes under the same call_id. Cost: chain gas at-cost + $0.000005 signing fee.

## Path parameters

- `signer_id` string, required

## Headers

- `X-Confirm-Drain` string, required
- `Idempotency-Key` string

## Request body

- object
  - `destination_address` string, required

## Response `202`

Drain transaction submitted

- ContractCallSubmitted
  - `call_id` string, required
  - `tx_hash` string, required
  - `status` 'pending' | 'failed', required

## Other responses

- `400`: Invalid destination or missing confirmation header
- `403`: Project is past_due/frozen/dormant — control-plane gated
- `409`: Nothing to drain
- `410`: Wallet deleted

---

[API](https://skmtc.dev/run402/apis/run402-api.md) · [All operations](https://skmtc.dev/run402/apis/run402-api/llms.txt) · [OpenAPI document](https://skmtc.dev/run402/apis/run402-api/revisions/893607557f50?raw)
