---
title: "Recover a failed deposit with an owner signature"
method: POST
path: "/deposits/recover"
tags: ["Processing"]
---

# Recover a failed deposit with an owner signature

`POST /deposits/recover`

Return a failed or rejected deposit's source-chain funds to a destination the user signed for, authorized by the deposit RECIPIENT's EIP-712 signature rather than by the API key. The server reconstructs the RecoverDeposit typed data from the stored deposit row and verifies the signature against that row's `recipient` — on the deposit's TARGET chain, where the recipient wallet lives — accepting a raw ECDSA signature (embedded EOA), an ERC-1271 signature (deployed smart account) or an ERC-6492 wrapper (counterfactual account). It then runs the same claim + transfer path as the refund endpoint. Because the signature is the authorization boundary, this route is safe to expose to a browser and a read-scoped `x-api-key` is sufficient. EVM on both source and target chains.

## Headers

- `x-api-key` string — API key for authentication (omit when sending Authorization)
- `authorization` string — Bearer platform token (e.g. forwarded by user-service). Takes precedence over `x-api-key` when both are present.

## Request body

- RecoverDepositRequestBody
  - `depositId` string, required — Deposit id, as returned by `GET /deposits`. Identifies the row directly: one transaction can produce several deposits, so a {chain, txHash, account, token} tuple does not.
  - `destination` string, required — Address to receive the recovered tokens on the deposit's source chain. Covered by the signature, so the caller cannot redirect an authorized recovery.
  - `signature` string, required — Signature by the deposit recipient over the RecoverDeposit typed data, in whatever form that account verifies: raw ECDSA (EOA), ERC-1271 (deployed smart account), or ERC-6492-wrapped (undeployed).

## Response `200`

Deposit recovered; funds returned on the source chain

- RefundDepositResponse
  - `message` string, required
  - `transactionHash` string, required
  - `amount` string, required

## Other responses

- `400` — Deposit not recoverable (DEPOSIT_NOT_RECOVERABLE) or unsupported for signed recovery (RECOVERY_UNSUPPORTED)
- `401` — Authentication required or invalid
- `403` — API key lacks the deposits:write scope
- `409` — The refund may have been submitted and is held for reconciliation (REFUND_RECONCILIATION_REQUIRED)
- `422` — The signature does not authorize this recovery (SIGNATURE_INVALID)
- `500` — Recovery transfer failed (REFUND_FAILED)
- `503` — Smart-account signature verification is temporarily unavailable (VERIFICATION_UNAVAILABLE)

---

[API](https://skmtc.net/rhinestonewtf/apis/deposit-service-api.md) · [All operations](https://skmtc.net/rhinestonewtf/apis/deposit-service-api/llms.txt) · [OpenAPI document](https://skmtc-service-staging.skmtc.workers.dev/v1/apis/rhinestonewtf/deposit-service-api/revisions/ce4e0abfe33a/schema)
