Crypto-as-a-Service
Stake Go Account Assets
Overview
Offer your clients the ability to stake assets held in Go Accounts. Your clients earn rewards by delegating assets to a validator on-chain. BitGo manages the staking process on your behalf. Staking from a Go Account uses a three-step manual flow: generate a staking request, sign the payload, and finalize by sending the half-signed payload to BitGo.
Staking protocols differ by asset. For example, some assets may require you to specify a staking time limit, require separate transactions to claim your rewards, or have a cooldown period after unstaking before the assets are available for further transactions. To learn asset-specific staking details, you can call the List coins available for staking endpoint.
Note
Go Account staking is currently in beta and is only available in the test environment.
Prerequisites
- Get Started
- Create Go Accounts
- Fund Go Accounts
- Enable staking in your enterprise by contacting sales@bitgo.com
Stake Assets
1. Create Staking Request
Create a staking request by specifying the staking details and sending them to BitGo.
Endpoint: Generate staking request for Go Account
export COIN="<ASSET_ID>"
export GO_ACCOUNT_ID="<YOUR_GO_ACCOUNT_ID>"
export ACCESS_TOKEN="<YOUR_ACCESS_TOKEN>"
export AMOUNT="<AMOUNT_IN_BASE_UNITS>"
curl -X POST \
https://app.bitgo-test.com/api/go-staking/v1/$COIN/accounts/$GO_ACCOUNT_ID/requests/preview \
-H 'Content-Type: application/json' \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-d '{
"amount": "'"$AMOUNT"'"
}'
Step Result
BitGo uses the data you pass to build an unsigned staking request. The following example is the response when previewing a staking request for 0.01 TSOL.
{
"payload": "{\"coin\":\"ofctsol\",\"recipients\":[{\"address\":\"BpkMFStkryPDkVYqTbEGLqWD3FLoPLCwTV4sdN1XKBPF\",\"amount\":\"1000000\"}],\"fromAccount\":\"62182dc6685f820007002502234b4dfc\",\"nonce\":\"8d819cce-a7e1-4e24-a29d-22f4b003130f\",\"timestamp\":\"2025-07-25T20:26:52.574Z\",\"feeString\":\"0\",\"shortCircuitBlockchainTransfer\":false,\"isIntraJXTransfer\":false}",
"feeInfo": {
"feeString": "0"
},
"coin": "ofc",
"token": "ofctsol"
}
2. Sign Staking Request
Use your Go Account passphrase to authenticate the transaction. To ensure your passphrase isn't passed over the Internet, you must use BitGo Express in external-signing mode or the JavaScript SDK.
export BITGO_EXPRESS_HOST="<YOUR_LOCAL_HOST>"
export ACCESS_TOKEN="<YOUR_ACCESS_TOKEN>"
export WALLET_ID="<YOUR_WALLET_ID>"
curl -X POST \
http://$BITGO_EXPRESS_HOST/api/v2/ofc/signPayload \
-H 'Content-Type: application/json' \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-d '{
"walletId": "'"$WALLET_ID"'",
"walletPassphrase": "<YOUR_GO_ACCOUNT_PASSPHRASE>",
"payload": "<PAYLOAD_FROM_PREVIOUS_STEP>"
}'
const halfSignedTransaction = (await wallet.prebuildAndSignTransaction({
walletPassphrase: '<WALLET_PASSPHRASE>',
prebuildTx: {
payload: '<PAYLOAD_OBJECT>',
}
}));
Step Result
{
"payload": "<ORIGINAL_PAYLOAD_STRING>",
"signature": "1f8e22206d9c95cff29154679f9d0b03bbb33e38b1f801090d0fb4f2e9464b969c263497689af974d13915dc72e00ffb3dfdac05c312ba9711e77014ffe2431c75"
}
3. Send Staking Request
Send the half-signed staking request to BitGo for final signing with the BitGo key.
Endpoint: Finalize staking request for Go Account
export COIN="<ASSET_ID>"
export GO_ACCOUNT_ID="<YOUR_GO_ACCOUNT_ID>"
export ACCESS_TOKEN="<YOUR_ACCESS_TOKEN>"
export AMOUNT="<AMOUNT_IN_BASE_UNITS>"
export HALF_SIGNED_PAYLOAD="<HALF_SIGNED_PAYLOAD>"
curl -X POST \
https://app.bitgo-test.com/api/go-staking/v1/$COIN/accounts/$GO_ACCOUNT_ID/requests/finalize \
-H 'Content-Type: application/json' \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-d '{
"type": "STAKE",
"amount": "'"$AMOUNT"'",
"frontTransferSendRequest": {
"halfSigned": "'"$HALF_SIGNED_PAYLOAD"'"
}
}'
Step Result
If your staking request doesn't require approval, BitGo applies the final signature using the BitGo key and broadcasts the transaction to the blockchain, transferring assets on-chain from your Go Account to the validator. If you Create Policy Rules to require approvals, the staking request remains in a PENDING_APPROVAL status until an admin approves it.
{
"id": "5bdeed2f-a173-4ca1-936b-a36399af8152",
"type": "STAKE",
"coin": "tsol",
"status": "NEW",
"goSpecificStatus": "NEW",
"statusModifiedDate": "2025-07-25T20:30:57.046379144Z",
"createdDate": "2025-07-25T20:30:57.046365Z",
"amount": 1000000,
"frontTransferSendRequest": {
"halfSigned": {
"payload": "{\"coin\":\"ofctsol\",\"recipients\":[{\"address\":\"BpkMFStkryPDkVYqTbEGLqWD3FLoPLCwTV4sdN1XKBPF\",\"amount\":\"1000000\"}],\"fromAccount\":\"62182dc6685f820007002502234b4dfc\",\"nonce\":\"8d819cce-a7e1-4e24-a29d-22f4b003130f\",\"timestamp\":\"2025-07-25T20:26:52.574Z\",\"feeString\":\"0\",\"shortCircuitBlockchainTransfer\":false,\"isIntraJXTransfer\":false}",
"signature": "1f8e22206d9c95cff29154679f9d0b03bbb33e38b1f801090d0fb4f2e9464b969c263497689af974d13915dc72e00ffb3dfdac05c312ba9711e77014ffe2431c75"
}
}
}
4. Approve Request (Optional)
If you have a policy that requires approval, you must approve the staking request before BitGo adds the final signature with the BitGo key.
Note
If you configure an approval requirement for staking requests, you can't approve your own transactions - another admin must approve them.
Endpoint: Update Pending Approval
export APPROVAL_ID="<APPROVAL_ID>"
export ACCESS_TOKEN="<YOUR_ACCESS_TOKEN>"
export OTP="<YOUR_OTP>"
curl -X PUT \
https://app.bitgo-test.com/api/v2/pendingApprovals/$APPROVAL_ID \
-H 'Content-Type: application/json' \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-d '{
"state": "approved",
"otp": "'"$OTP"'"
}'
Step Result
{
"id": "e055adbc-66a3-4ccd-9a9d-726a05bca0cf",
"coin": "hteth",
"wallet": "2032e75g451052000636831abd797bd3",
"enterprise": "1032e75c451052000436831deb797af1",
"creator": "62ab90e06dfda30007974f0a52a12995",
"createDate": "2022-01-10T14:32:28Z",
"state": "approved",
"scope": "wallet",
"userIds": [
"62ab90e06dfda30007974f0a52a12995",
"621d08a634ad8a0007fcddffd7c429cc"
],
"approvalsRequired": 1
}
Unstake Assets
When you submit an unstaking request, BitGo makes a series of transfers. However, you only need to create the initial unstaking request - no signatures are required.
1. Create Unstaking Request
Create an unstaking request by specifying the unstaking details and sending them to BitGo.
Endpoint: Finalize staking request for Go Account
export COIN="<ASSET_ID>"
export GO_ACCOUNT_ID="<YOUR_GO_ACCOUNT_ID>"
export ACCESS_TOKEN="<YOUR_ACCESS_TOKEN>"
export AMOUNT="<AMOUNT_IN_BASE_UNITS>"
curl -X POST \
https://app.bitgo-test.com/api/go-staking/v1/$COIN/accounts/$GO_ACCOUNT_ID/requests/finalize \
-H 'Content-Type: application/json' \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-d '{
"type": "UNSTAKE",
"amount": "'"$AMOUNT"'"
}'
Step Result
BitGo generates an unstaking request.
{
"id": "487fb12a-e11e-4c3d-9f6c-4c85214af88d",
"type": "UNSTAKE",
"coin": "tsol",
"status": "NEW",
"goSpecificStatus": "NEW",
"statusModifiedDate": "2025-08-15T19:36:15.560401474Z",
"createdDate": "2025-08-15T19:36:15.560363Z",
"amount": 3000000
}
View Rewards
After staking, you can view your overall positions, including active delegations, pending amounts, and accrued rewards.
export GO_ACCOUNT_ID="<YOUR_GO_ACCOUNT_ID>"
export ACCESS_TOKEN="<YOUR_ACCESS_TOKEN>"
curl -X GET \
"https://app.bitgo-test.com/api/go-staking/v1/accounts/$GO_ACCOUNT_ID/coins" \
-H 'Content-Type: application/json' \
-H "Authorization: Bearer $ACCESS_TOKEN"
Step Result
{
"coins": [
{
"coin": "ofctsol",
"activeStake": 0,
"pendingStake": 0,
"pendingUnstake": 0,
"rewards": 0,
"attributes": {
"permissionAttributes": {
"staking": {
"enabled": true,
"allowClientToUseOwnValidator": false
},
"unstaking": {
"enabled": false,
"disabledReason": "Not actively staking TSOL"
}
},
"spendableAttributes": {
"staking": {
"fee": 0,
"max": 0,
"min": 0,
"netMax": 46000000,
"netMin": 0,
"minStakeMore": 0
},
"unstaking": {
"max": 0,
"min": 0,
"multipleDelegations": false,
"requiresAmount": true,
"requiresDelegationId": false,
"requiresDelegationIds": false
}
},
"disclaimerAttributes": {
"staking": {
"info": [
"Staking takes up to the next epoch to activate (~2.1 days) and earn rewards."
],
"rewardPercentageRate": 7,
"stakeWarmupPeriodDesc": "1 epoch (2.1 days)"
},
"unstaking": {
"info": [
"Unstaking takes up to the next epoch to deactivate (~2.1 days) and withdraw."
],
"unStakeCooldownPeriodDesc": "1 epoch (2.1 days)"
},
"nextRewards": {
"rewardCycle": 181440
}
}
}
}
],
"page": 1,
"totalPages": 1,
"totalElements": 1
}
See Also
- CaaS Overview
- API Reference: Generate staking request for Go Account
- API Reference: Finalize staking request for Go Account
- API Reference: Get staking wallet attributes for Go Account
- API Reference: List staking requests by asset for Go Account
- API Reference: List staking requests for Go Account
- API Reference: List staking rewards for Go Account
- API Reference: Update Pending Approval
- API Reference: List coins available for staking