Withdraw Funds
Initiate a Rails Yield withdrawal — set a withdrawal target, derive the master-account password hash, and track funds becoming available as channels unwind.
Withdrawals in Rails Yield are not instant. Bitcoin is committed to Lightning channels and Magma leases; to release it, channels must close or leases must unwind. You signal intent by raising a withdrawal target, and automation drains liquidity back to on-chain balance over time.
Sequence
Password hash
The withdrawal mutation requires the master-account password_hash, derived client-side from the account password using Argon2id (master key + password as salt). The hash is sent to the server, never the plaintext password. See Security for the derivation details.
This is not just authentication; it's the entropy that gates withdrawal. There is no recovery path if the password is lost. Store and derive it securely.
Mutation
mutation IncreaseWithdrawalTarget($input: IncreaseWithdrawalInput!) {
node {
withdrawal {
increase_withdrawal_target(input: $input) {
amount
}
}
}
}curl -X POST https://rails.amboss.tech/graphql \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $AMBOSS_DASHBOARD_TOKEN" \
-d '{
"query": "mutation($input: IncreaseWithdrawalInput!) { node { withdrawal { increase_withdrawal_target(input: $input) { amount } } } }",
"variables": {
"input": {
"node_id": "<NODE_ID>",
"amount_sats": "5000000",
"password_hash": "<argon2id-derived hash>"
}
}
}'const { node } = await client.request(INCREASE_WITHDRAWAL_TARGET, {
input: {
node_id: process.env.NODE_ID,
amount_sats: "5000000",
password_hash: passwordHash,
},
});
console.log("new target:", node.withdrawal.increase_withdrawal_target.amount);IncreaseWithdrawalInput
| Field | Type | Description |
|---|---|---|
node_id | String! | UUID of the node to withdraw from. |
amount_sats | String! | Total target as a string-encoded integer. The new target is current + amount_sats. |
password_hash | String | Master-account Argon2id hash. Required for production teams. |
amount_sats increases the running target rather than setting it absolutely. To "withdraw an additional 1 BTC", pass 100000000. The response amount is the new total target.
Tracking progress
Poll withdrawal_target and funds.available until they converge:
query WithdrawalProgress($nodeId: String!, $input: LiquidityProviderInput) {
node {
deployed_node(node_id: $nodeId) {
withdrawal_target
funds_available_at
}
}
user {
liquidity_provider(input: $input) {
funds {
available { sats usd }
reserved { sats usd }
total { sats usd }
}
}
}
}| Field | What it tells you |
|---|---|
withdrawal_target | The total sats requested for withdrawal. |
funds.available.sats | Sats currently on-chain and withdrawable (not waiting on a channel close). |
funds.reserved.sats | Sats still locked in channels. |
funds_available_at | ISO timestamp of the projected full unwind (latest channel lease close + a force-close buffer). |
Move funds to your wallet
Once funds.available.sats covers the target, send the Bitcoin out using the LND macaroon directly - Rails does not handle the on-chain send. From the dashboard, the "Withdraw" dialog walks through this; from the API:
curl --header "Grpc-Metadata-macaroon: $MACAROON_HEX" \
-X POST $LND_REST/v1/transactions \
-d '{"addr":"bc1q...","amount":"5000000","sat_per_vbyte":"5"}'The Rails-issued macaroon does not grant on-chain spend. For Fully Managed nodes, withdrawals route through Rails' withdrawal pipeline (triggered by the increase_withdrawal_target mutation); for Third Party Hosted you spend with your own admin macaroon.
Common scenarios
Partial withdraw
Set amount_sats to less than the total balance. Automation will close just enough channels to cover the request, preserving routing capacity.
Max withdraw
Set amount_sats to funds.total.sats - funds.available.sats (i.e. the reserved portion). All channels will close.
Cancelling a target
There is no direct "decrease" mutation; the target is monotonically increasing. Practically, contact support before a large change-of-mind to avoid unnecessary channel closures.
Error reference
| Error | Cause |
|---|---|
Incorrect password | password_hash does not match the team's stored Argon2id hash. |
Node not found | node_id is not owned by your team. |
Insufficient funds | Target exceeds total balance. |
Next steps
Monitor Earnings
Track Rails Yield node performance — balances, routing and liquidity revenue, charts, and transaction history — via the dashboard and the GraphQL API.
API Reference
Rails Yield GraphQL API — endpoint, authentication, rate limits, error format, and per-resource reference for nodes, liquidity, and direct LND access.