Portfolio wallet withdrawals can require cryptographic approval through Turnkey before execution. When that happens, Ground creates a Turnkey signing activity and your server approves it using the Turnkey SDK.Documentation Index
Fetch the complete documentation index at: https://docs.groundtech.co/llms.txt
Use this file to discover all available pages before exploring further.
Ground uses Turnkey to manage signing flows, but you do not need a direct relationship with Turnkey to sign approvals.
When approvals happen
- Withdrawals (
POST /v2/wallets/{id}/withdrawals): each payout leg transitions topending_customer_approvalwhen it’s ready for signing. Strategy updates (PATCH /v2/wallets/{id}/strategy) return the updated wallet object directly. They do not surface a Turnkey payout approval flow.
walletId + chain. If you create multiple withdrawals rapidly, later payouts queue behind the earlier approval automatically.
Detecting a pending approval
When a payout leg needs approval,payoutLegs[].status and the external payout step status become pending_customer_approval.
Fetch GET /turnkey/activities/pending to retrieve the approval details, including the Turnkey activity ID, fingerprint, withdrawal ID, withdrawal leg ID, destination chain/token/address, and display amount.
Poll GET /v2/wallets/:id/withdrawals/:withdrawalId or subscribe to the portfolio_wallet.withdrawal.status_changed webhook to detect when a payout enters pending_customer_approval; use /turnkey/activities/pending for the activity data needed to approve it.
Approving an activity
- Capture the pending payout leg/step from the withdrawal response or webhook, then fetch the matching activity from
/turnkey/activities/pending. - Fetch the activity from Turnkey to get its
fingerprint. - Verify the transaction details (see best practice below).
- Submit an approval vote via the Turnkey SDK.
- Processing continues automatically once approved.
Node
activity.status: ACTIVITY_STATUS_CONSENSUS_NEEDED, additional approval votes are required per your Turnkey policy/quorum. Poll getActivity until approved, or subscribe to Turnkey webhooks.
Verify before you approve
When your server receives apending_customer_approval signal, it should programmatically verify the transaction before approving. This is critical because an approval is an irreversible cryptographic signature — once signed and broadcast, the transaction cannot be reversed.
What to verify:
- Destination address — confirm the pending activity’s
destinationAddressmatches the address your system originally submitted in the withdrawal request. Reject if it doesn’t match. - Amount — confirm the activity
displayAmountNativeUnits/plannedSourceNativeUnitsis reasonable for the withdrawal and yield source. Do not assume it must exactly match the originally requested amount for asynchronous sources. - Chain and token — confirm
destinationChainanddestinationTokenmatch your expectations. - Withdrawal correlation — match the
turnkeyActivityIdback to a withdrawal your system actually initiated. Reject orphaned or unexpected approval requests.
Automation patterns
Two patterns work well for handling approvals:- Webhook-driven — subscribe to
portfolio_wallet.withdrawal.status_changed. When a payout leg or step enterspending_customer_approval, fetch the pending activity, verify it, and approve it. - Polling-driven — poll
GET /v2/wallets/:id/withdrawals/:withdrawalIdand checkpayoutLegs[].status/payoutLegs[].steps[].status.
Status updates
Subscribe to these events to monitor progress:portfolio_wallet.withdrawal.status_changedportfolio_wallet.withdrawal.payout.status_changed
failed with a failureReason.