Skip to main content
Exit endpoints allow you to unilaterally move bitcoin back on-chain without server cooperation. Use these when the Ark server is unavailable or uncooperative.

Emergency exit process

The emergency exit process has three phases:
  1. Start - Register VTXOs for exit using /start/vtxos or /start/all
  2. Progress - The daemon automatically advances exits through multiple on-chain transactions. You can also manually trigger progress with /progress
  3. Claim - Once all exits reach the claimable state, call /claim/vtxos or /claim/all to sweep the outputs to an on-chain address
The daemon automatically progresses registered exits in the background at the cadence defined by SLOW_INTERVAL. The daemon does not auto-claim—you must call the claim endpoint manually.

Get exit status

GET /api/v1/exits/status/{vtxo_id}
Returns the current state of an emergency exit for the specified VTXO, including which phase the exit is in (start, processing, awaiting-delta, claimable, claim-in-progress, or claimed). Optionally includes the full state transition history and the exit transaction packages with their CPFP children.

Path parameters

  • vtxo_id (string, required) - The VTXO ID to check

Query parameters

  • history (boolean, optional) - Include detailed state transition history. Default: false
  • transactions (boolean, optional) - Include exit transactions and their CPFP children. Default: false

Response

{
  "vtxo_id": "0123456789abcdef...",
  "state": "claimable",
  "claimable_height": 800512,
  "history": [
    {
      "state": "start",
      "timestamp": "2026-03-03T10:00:00Z"
    },
    {
      "state": "processing",
      "timestamp": "2026-03-03T10:30:00Z"
    },
    {
      "state": "claimable",
      "timestamp": "2026-03-03T12:00:00Z"
    }
  ],
  "transactions": [
    {
      "txid": "abc123...",
      "fee_sat": 500,
      "children": []
    }
  ]
}
States:
  • start - Exit has been registered
  • processing - Exit transactions are being created and broadcast
  • awaiting-delta - Exit transactions are confirmed, waiting for timelock to expire
  • claimable - Ready to claim
  • claim-in-progress - Claim transaction has been broadcast
  • claimed - Exit complete

Example

curl http://localhost:3000/api/v1/exits/status/0123456789abcdef

curl "http://localhost:3000/api/v1/exits/status/0123456789abcdef?history=true&transactions=true"

Errors

  • 400 - Invalid VTXO ID
  • 404 - VTXO not found

List all exit statuses

GET /api/v1/exits/status
Returns the current state of every emergency exit in the wallet. Each entry includes which phase the exit is in (start, processing, awaiting-delta, claimable, claim-in-progress, or claimed), and optionally the full state transition history and the exit transaction packages with their CPFP children.

Query parameters

  • history (boolean, optional) - Include detailed state transition history. Default: false
  • transactions (boolean, optional) - Include exit transactions and their CPFP children. Default: false

Response

[
  {
    "vtxo_id": "0123456789abcdef...",
    "state": "claimable",
    "claimable_height": 800512
  },
  {
    "vtxo_id": "fedcba9876543210...",
    "state": "processing",
    "claimable_height": null
  }
]

Example

curl http://localhost:3000/api/v1/exits/status

curl "http://localhost:3000/api/v1/exits/status?history=true"

Start exit for specific VTXOs

POST /api/v1/exits/start/vtxos
Registers the specified VTXOs for emergency exit. The daemon automatically progresses registered exits in the background at the cadence defined by SLOW_INTERVAL, creating and broadcasting the required transactions in sequence. Once all exit transactions are confirmed and the timelock has elapsed, call claim to sweep the resulting outputs to an on-chain address.

Request body

{
  "vtxos": [
    "0123456789abcdef...",
    "fedcba9876543210..."
  ]
}
Parameters:
  • vtxos (array of strings, required) - VTXO IDs to exit

Response

{
  "message": "Exit started successfully"
}

Example

curl -X POST http://localhost:3000/api/v1/exits/start/vtxos \
  -H "Content-Type: application/json" \
  -d '{
    "vtxos": [
      "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
    ]
  }'

Errors

  • 400 - No VTXO IDs provided or invalid VTXO ID
  • 404 - One of the VTXOs wasn’t found

Start exit for all VTXOs

POST /api/v1/exits/start/all
Registers all wallet VTXOs for emergency exit. The daemon automatically progresses registered exits in the background at the cadence defined by SLOW_INTERVAL, creating and broadcasting the required transactions in sequence. Once all exit transactions are confirmed and the timelock has elapsed, call claim to sweep the resulting outputs to an on-chain address.

Response

{
  "message": "Exit started successfully"
}

Example

curl -X POST http://localhost:3000/api/v1/exits/start/all

Progress exits

POST /api/v1/exits/progress
Triggers all in-progress exits to advance by one step. The daemon already progresses exits automatically in the background—use this endpoint when you want immediate progress rather than waiting for the next automatic cycle. On each call, the endpoint checks whether previously broadcast transactions have confirmed and, if so, creates and broadcasts the next transaction in the sequence. The on-chain wallet must have sufficient bitcoin to cover transaction fees.

Request body

{
  "fee_rate": 5000
}
Parameters:
  • fee_rate (integer, optional) - Desired feerate in sats/kvB. If omitted, uses current network feerates

Response

{
  "done": true,
  "claimable_height": 800512,
  "exits": [
    {
      "vtxo_id": "0123456789abcdef...",
      "state": "claimable"
    }
  ]
}
Fields:
  • done (boolean) - true when all exits reach the claimable state (i.e., no pending exits remain)
  • claimable_height (integer or null) - Block height when all exits become claimable
  • exits (array) - Status of each exit that was progressed

Example

curl -X POST http://localhost:3000/api/v1/exits/progress \
  -H "Content-Type: application/json" \
  -d '{}'

# With custom fee rate
curl -X POST http://localhost:3000/api/v1/exits/progress \
  -H "Content-Type: application/json" \
  -d '{"fee_rate": 10000}'

Claim specific exited VTXOs

POST /api/v1/exits/claim/vtxos
Sweeps the specified claimable exit outputs into a single on-chain transaction sent to the specified address. Unlike progress, the daemon does not claim automatically—this endpoint must be called manually. Poll the status endpoint or call progress and check for done: true to know when VTXOs are ready to claim. This is the final step of the emergency exit process—the bitcoin is not considered back on-chain until this transaction confirms.

Request body

{
  "vtxos": [
    "0123456789abcdef...",
    "fedcba9876543210..."
  ],
  "destination": "bc1q...",
  "fee_rate": 5000
}
Parameters:
  • vtxos (array of strings, required) - VTXO IDs to claim
  • destination (string, required) - Bitcoin address to send claimed funds
  • fee_rate (integer, optional) - Desired feerate in sats/kvB. If omitted, uses current network feerates

Response

{
  "message": "Exit claimed successfully"
}

Example

curl -X POST http://localhost:3000/api/v1/exits/claim/vtxos \
  -H "Content-Type: application/json" \
  -d '{
    "vtxos": [
      "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
    ],
    "destination": "bc1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh"
  }'

Errors

  • 400 - One of the provided VTXOs isn’t claimable, or invalid destination address

Claim all exited VTXOs

POST /api/v1/exits/claim/all
Sweeps all claimable exit outputs into a single on-chain transaction sent to the specified address. Unlike progress, the daemon does not claim automatically—this endpoint must be called manually. Poll the status endpoint or call progress and check for done: true to know when VTXOs are ready to claim. This is the final step of the emergency exit process—the bitcoin is not considered back on-chain until this transaction confirms.

Request body

{
  "destination": "bc1q...",
  "fee_rate": 5000
}
Parameters:
  • destination (string, required) - Bitcoin address to send claimed funds
  • fee_rate (integer, optional) - Desired feerate in sats/kvB. If omitted, uses current network feerates

Response

{
  "message": "Exit claimed successfully"
}

Example

curl -X POST http://localhost:3000/api/v1/exits/claim/all \
  -H "Content-Type: application/json" \
  -d '{
    "destination": "bc1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh"
  }'

Errors

  • 400 - Invalid destination address

Build docs developers (and LLMs) love