Endpoints
API Usage
Once you have access to the Staking API with a validated user and existing API keys, you can start using this service.
Try it live
Every endpoint on this page can be executed from the interactive Swagger console, using your own X-API-KEY.
The machine-readable OpenAPI schema is available at:
Authentication
In order to use the Staking API endpoints you need to include your API KEY.
Heads up! To obtain a valid API key required for authentication, please refer to the Authentication > Create API keys section of the documentation.
Header:
| Name | Description | Example value | Required |
|---|---|---|---|
X-API-KEY | Your api key value | <API_KEY_VALUE> | ✅ |
X-NETWORK | Blockchain network/chain identifier | 560048 | ⚪ |
X-IDENTITY | Caller-defined identity stored in the audit log | user-1234 | ⚪ |
X-NETWORK header
Set the X-NETWORK header to the Ethereum chain that you want to target.
Supported value: 560048 (Ethereum Hoodi). Lido stVault is not deployed on Ethereum Mainnet (1).
Always send this header. When you omit it, the API uses the default Ethereum network of your account. That network is not necessarily a network where Lido stVault is deployed. A request for a network without a Lido stVault deployment returns 422. See Errors.
X-IDENTITY header
Use the X-IDENTITY header to attribute a request to the end user or account that acts through your integration. The value is caller-defined. The API stores it with the request in the audit log.
The header is optional and does not change the response. Use an opaque internal identifier, such as a user ID or an account reference. Do not send personal data such as emails or names. If you omit the header, the API attributes the request only to your API key.
Amounts and units
All amounts are JSON numbers in whole token units. Do not send wei.
| Amount | Token | Decimals on chain |
|---|---|---|
amount (stake), stv_assets, pool withdrawal assets and claimable_assets | ETH | 18 |
mint_wsteth_amount, wsteth, amount (burn-wsteth), exit request assets, pending_deposit_assets | wstETH | 18 |
shares, active_shares, claimable_shares | Mellow vault shares | 18 |
minted_steth_shares, steth_shares_to_rebalance | stETH shares | 18 |
stv, stv_amount, pool withdrawal stv | STV | 27 |
The STV token uses 27 decimals, not 18. The API converts whole STV to base units. If you read STV on chain, divide by 10^27.
List available networks
Use this helper endpoint to read the networks where Lido stVault is deployed and enabled.
- Endpoint:
/api/v1/ethereum/lido-stvault/networks
Description
The response lists only the Ethereum networks that have a Lido stVault deployment. An Ethereum network without a deployment is not in the list.
Returned
Array of StakewiseNetworkResponseDto items:
| Field | Type | Required | Description |
|---|---|---|---|
name | string | ✅ | Name of the network entry, for example ethereum-hoodi. |
type | string | ✅ | Type of the blockchain. The value is always EVM. |
chain_id | string | ✅ | Chain identifier. Send this value in the X-NETWORK header. |
is_default | boolean | ✅ | true when the network is the default Ethereum network of your account. |
Example
curl "https://staking-api.stakely.io/api/v1/ethereum/lido-stvault/networks" \
-H "X-API-KEY: $STAKELY_API_KEY"
Response:
[
{
"name": "ethereum-hoodi",
"type": "EVM",
"chain_id": "560048",
"is_default": false
}
]
The value of is_default depends on the configuration of your account.
Staking information
Get the staking parameters of this protocol:
- Endpoint:
/api/v1/ethereum/lido-stvault/staking-info
Description
Staking parameters for Lido stVault: activation, deactivation and withdrawal times in minutes, fees, stake limits and the current APY. A field is null when the value is not published or not verified for this vault. The API does not copy Ethereum native staking values into these fields.
Returned
| Field | Type | Required | Description |
|---|---|---|---|
stake_activation_max_time | number | ✅ | Maximum time, in minutes, for a new stake to become active. 0 because the pool mints STV in the stake transaction. |
stake_deactivation_max_time | number | ✅ | Maximum time, in minutes, for an exit to complete. null because the protocol publishes no maximum time. |
withdrawal_max_time | number | ✅ | Maximum time, in minutes, between a completed exit and the withdraw transaction. 0 because you can withdraw as soon as the exit request is claimable. |
staking_reward_fee | number | ✅ | Fee on the staking rewards of the staked ETH, as a percentage of those rewards. It does not include the fees that apply only to minted wstETH. |
withdrawal_fee | number | ✅ | Fee on a withdrawal, as a percentage of the withdrawn amount. null when the value is not published for this vault. Gas costs are not included. |
staking_apr | number | ✅ | Annual percentage rate without compounding, as a percentage. null because the data feed publishes only the APY for this vault. |
staking_apy | number | ✅ | Current annual percentage yield, as a percentage. null when the data feed has no value. |
max_slashing_percentage | number | ✅ | Maximum percentage of the stake that the protocol can slash. This field does not model the loss risk of the strategy or of a forced rebalance. |
min_stake_amount | string | ✅ | Minimum amount that the stake action accepts, as a decimal string in ETH. |
max_stake_amount | string | ✅ | Maximum amount that the stake action accepts, as a decimal string in ETH. null means no upper limit. |
users | number | ✅ | Always null on this endpoint. The data feed publishes this figure per chain, not per protocol. |
tvl_usd | number | ✅ | Always null on this endpoint, for the same reason as users. |
tvl_token | number | ✅ | Always null on this endpoint, for the same reason as users. |
Example
curl "https://staking-api.stakely.io/api/v1/ethereum/lido-stvault/staking-info" \
-H "X-API-KEY: $STAKELY_API_KEY"
Response:
{
"stake_activation_max_time": 0,
"stake_deactivation_max_time": null,
"withdrawal_max_time": 0,
"staking_reward_fee": 3,
"withdrawal_fee": null,
"staking_apr": null,
"staking_apy": 1.51,
"max_slashing_percentage": 0,
"min_stake_amount": "0",
"max_stake_amount": null,
"users": null,
"tvl_usd": null,
"tvl_token": null
}
stake_deactivation_max_time is null because the exit queues settle in batches and the protocol publishes no maximum time. staking_apy changes over time. The value above is an example.
Position of an address
Get the full Lido stVault position of an address:
- Endpoint:
/api/v1/ethereum/lido-stvault/balance/{address}
Description
The response contains both layers of the position: the STV and its ETH value, and the Mellow vault shares. It also contains the wstETH that the call forwarder holds outside the Mellow vault, the liability, the pending deposit request and all open exit requests. Each exit request has the request_id that the withdraw action needs.
The response also lists the unclaimed requests in the pool withdrawal queue that address owns, in pool_withdrawal_requests. Each request has the request_id that the claim pool withdrawal action needs. A request made with another recipient is listed on the balance of that recipient, not on the balance of the address that made it.
Lido stVault does not have the unified staking-balance endpoint. This endpoint is the only position read for this protocol.
Request parameters
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
address | path | string | ✅ | Address to read the position of. |
Returned
| Field | Type | Required | Description |
|---|---|---|---|
address | string | ✅ | Address that was queried. |
call_forwarder | string | ✅ | Call forwarder contract that holds the position of this address. A block explorer shows the position on this contract, not on address. |
stv | number | ✅ | STV that the position holds, in whole STV. The STV token uses 27 decimals. |
stv_assets | number | ✅ | ETH value of the STV of the position, in ETH. |
shares | number | ✅ | Total Mellow vault shares of the position: active_shares plus claimable_shares. |
active_shares | number | ✅ | Mellow vault shares that are settled and earn. |
claimable_shares | number | ✅ | Mellow vault shares of a settled deposit request that wait for the claim action. |
wsteth | number | ✅ | wstETH that the call forwarder holds, in wstETH. The withdraw action releases the wstETH of an exit request here. |
minted_steth_shares | number | ✅ | Liability of the position: stETH shares that the position owes to the pool for the minted wstETH. A forced rebalance acts on this amount. |
pending_deposit_assets | number | ✅ | wstETH of the pending deposit request. null when there is no deposit request. |
pending_deposit_is_claimable | boolean | ✅ | true when the claim action can claim the deposit request. false when there is no deposit request or the queue has not settled it. |
exit_requests | LidoStvaultExitRequestDto[] | ✅ | Open exit requests of the position in the Mellow redeem queue. |
pool_withdrawal_requests | LidoStvaultPoolWithdrawalRequestDto[] | ✅ | Unclaimed requests in the pool withdrawal queue that this address owns. A request made with another recipient is listed under that recipient. |
Each item in exit_requests is a LidoStvaultExitRequestDto:
| Field | Type | Required | Description |
|---|---|---|---|
request_id | string | ✅ | Identifier of the exit request. Send it to the withdraw action as request_id. It is the queue timestamp of the request as a 32-byte hex value. |
requested_at | string | ✅ | ISO-8601 instant at which the request entered the queue. |
shares | number | ✅ | Mellow vault shares that the request locks. |
assets | number | ✅ | wstETH that the request releases when it is claimable. 0 until the queue settles the batch. |
is_claimable | boolean | ✅ | true when the withdraw action can finalize the request. |
Each item in pool_withdrawal_requests is a LidoStvaultPoolWithdrawalRequestDto:
| Field | Type | Required | Description |
|---|---|---|---|
request_id | string | ✅ | Pool withdrawal request id, as a decimal string. Pass it to the claim-pool-withdrawal endpoint as request_id. |
requested_at | string | ✅ | ISO-8601 instant at which the request was created. |
stv | number | ✅ | STV locked by this request, in whole STV. |
assets | number | ✅ | ETH value of the request when it was created, in ether units. |
claimable_assets | number | ✅ | ETH the claim pays out right now, in ether units. 0 until the request is finalized. |
is_claimable | boolean | ✅ | Whether the request is finalized and can be claimed through the claim-pool-withdrawal endpoint. |
Example
curl "https://staking-api.stakely.io/api/v1/ethereum/lido-stvault/balance/0x0345fA5dc69C9cA90a441215E2fA8A0B36469286" \
-H "X-API-KEY: $STAKELY_API_KEY" \
-H "X-NETWORK: 560048"
Response:
{
"address": "0x0345fA5dc69C9cA90a441215E2fA8A0B36469286",
"call_forwarder": "0x9cD60e23691E8fA7D1B0b00E0385ff4cea9a754E",
"stv": 1.6078296358850168,
"stv_assets": 1.641468631102123,
"shares": 0.34031217781489914,
"active_shares": 0.10783468296662402,
"claimable_shares": 0.2324774948482751,
"wsteth": 0,
"minted_steth_shares": 0.7591681880455217,
"pending_deposit_assets": 0.2324774948482751,
"pending_deposit_is_claimable": true,
"exit_requests": [
{
"request_id": "0x0000000000000000000000000000000000000000000000000000000069b086e0",
"requested_at": "2026-03-10T21:02:24.000Z",
"shares": 0.4188560101709146,
"assets": 0.4188560102128002,
"is_claimable": true
}
],
"pool_withdrawal_requests": [
{
"request_id": "42",
"requested_at": "2026-07-30T09:14:18.000Z",
"stv": 0.9796,
"assets": 1,
"claimable_assets": 0,
"is_claimable": false
}
]
}
The position has a deposit request that is ready for the claim action and an exit request that is ready for the withdraw action. It also has a pool withdrawal request that the queue has not finalized yet.
Stake action
Craft a stake transaction:
- Endpoint:
/api/v1/ethereum/lido-stvault/action/stake
Description
This endpoint crafts a transaction that stakes ETH into the STV pool. The transaction is ready to be signed. The transaction sends amount as its value, and the pool mints STV to the call forwarder of address.
When mint_wsteth_amount is greater than 0, the same transaction also mints that amount of wstETH against the position and deposits it into the Mellow vault. This part is leverage. Read the warning in the staking flow before you use it. The Mellow deposit settles later and needs the claim action.
The API checks that address holds enough ETH for amount before it crafts the transaction.
Request body parameters
| Field | Type | Required | Description |
|---|---|---|---|
address | string | ✅ | Address that signs the transaction and owns the position. |
amount | number | ✅ | ETH to stake, in ETH. The transaction sends it as its value, and the pool mints STV for it. |
mint_wsteth_amount | number | ⚪ | wstETH to mint against the position and deposit into the Mellow vault, in wstETH. This is leverage. The pool reserve ratio limits it. The default is 0, which stakes ETH only. |
referral | string | ⚪ | Referral address that the pool and the deposit queue record. The default is the zero address. |
Returned
| Field | Type | Required | Description |
|---|---|---|---|
serialized_tx_hex | string | ✅ | Unsigned transaction, RLP-serialized, as a hex string with the 0x prefix. Send it to the prepare action without changes. |
unsigned_tx_hash_hex | string | ✅ | Hash to sign, as a hex string with the 0x prefix. It is the EIP-155 signing hash of the transaction. |
payload | object | ✅ | Fields of the transaction: type, nonce, gasLimit, gasPrice, to, value, data and chainId. Use it to examine the transaction before you sign. |
All action endpoints of this protocol return this same object. The transaction is a legacy (type 0x0) transaction with EIP-155 replay protection. payload.to is always the strategy contract.
Example
curl -X POST "https://staking-api.stakely.io/api/v1/ethereum/lido-stvault/action/stake" \
-H "X-API-KEY: $STAKELY_API_KEY" \
-H "X-NETWORK: 560048" \
-H "Content-Type: application/json" \
-d '{
"address": "0xC8B1554FAfF9271AC663d22a6938B5fCB36d9058",
"amount": 0.01
}'
Response:
{
"serialized_tx_hex": "0xf9011072843d54b88083045a9694bf4797de82787a60101e5e45cec7f29b27d83d98872386f26fc10000b8e43fec5c610000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000808080",
"unsigned_tx_hash_hex": "0xfff70d3db2d92f7a56338dcba4bd83e837a4aea96f8055a10c35c9eecd001dbf",
"payload": {
"type": "0x0",
"nonce": "0x72",
"gasLimit": "0x45a96",
"to": "0xbf4797de82787a60101e5e45cec7f29b27d83d98",
"value": "0x2386f26fc10000",
"data": "0x3fec5c610000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000",
"chainId": 560048,
"gasPrice": "0x3d54b880"
}
}
This example, the prepare example and the broadcast example below correspond to one real stake of 0.01 ETH on Hoodi. You can see the transaction at 0xd7f308d4…f8857d78.
Claim action
Craft a claim transaction:
- Endpoint:
/api/v1/ethereum/lido-stvault/action/claim
Description
This endpoint crafts a transaction that claims the Mellow vault shares of a settled deposit request. You need it only after a stake with mint_wsteth_amount greater than 0.
Read pending_deposit_is_claimable from the position endpoint. Call this endpoint when the value is true. The API returns 400 when the address has no deposit request, or when the deposit queue has not settled the request yet.
Request body parameters
| Field | Type | Required | Description |
|---|---|---|---|
address | string | ✅ | Address that owns the deposit request and signs the transaction. |
Returned
The same EthActionResponseDto object as the stake action.
Example
curl -X POST "https://staking-api.stakely.io/api/v1/ethereum/lido-stvault/action/claim" \
-H "X-API-KEY: $STAKELY_API_KEY" \
-H "X-NETWORK: 560048" \
-H "Content-Type: application/json" \
-d '{
"address": "0x0345fA5dc69C9cA90a441215E2fA8A0B36469286"
}'
Unstake action
Craft an unstake transaction:
- Endpoint:
/api/v1/ethereum/lido-stvault/action/unstake
Description
This endpoint crafts a transaction that requests an exit from the Mellow vault for a number of Mellow vault shares. The request enters the Mellow redeem queue. You cannot cancel it.
This action does not exit the STV position. To exit the STV position, use the pool withdrawal action.
The API returns 400 when shares is 0 or is greater than the shares of the position.
Request body parameters
| Field | Type | Required | Description |
|---|---|---|---|
address | string | ✅ | Address that owns the position and signs the transaction. |
shares | number | ✅ | Mellow vault shares to redeem. Take the available amount from shares in the position endpoint. |
Returned
The same EthActionResponseDto object as the stake action.
Example
curl -X POST "https://staking-api.stakely.io/api/v1/ethereum/lido-stvault/action/unstake" \
-H "X-API-KEY: $STAKELY_API_KEY" \
-H "X-NETWORK: 560048" \
-H "Content-Type: application/json" \
-d '{
"address": "0x0345fA5dc69C9cA90a441215E2fA8A0B36469286",
"shares": 0.1
}'
Withdraw action
Craft a withdraw transaction:
- Endpoint:
/api/v1/ethereum/lido-stvault/action/withdraw
Description
This endpoint crafts a transaction that finalizes one exit request. The Mellow redeem queue releases the wstETH of the request to the call forwarder of address. The wstETH does not go to the wallet of address. After the transaction, the position endpoint reports the amount in wsteth. To repay the liability of the position with that wstETH, use the burn wstETH action.
Take request_id from exit_requests in the position endpoint. Call this endpoint when is_claimable of that request is true. The API returns 400 when the address has no exit request with that request_id, or when the request is not claimable yet.
Request body parameters
| Field | Type | Required | Description |
|---|---|---|---|
address | string | ✅ | Address that owns the exit request and signs the transaction. |
request_id | string | ✅ | Identifier of the exit request, from exit_requests[].request_id in the position endpoint. |
Returned
The same EthActionResponseDto object as the stake action.
Example
curl -X POST "https://staking-api.stakely.io/api/v1/ethereum/lido-stvault/action/withdraw" \
-H "X-API-KEY: $STAKELY_API_KEY" \
-H "X-NETWORK: 560048" \
-H "Content-Type: application/json" \
-d '{
"address": "0x0345fA5dc69C9cA90a441215E2fA8A0B36469286",
"request_id": "0x0000000000000000000000000000000000000000000000000000000069b086e0"
}'
Burn wstETH action
Craft a wstETH burn transaction:
- Endpoint:
/api/v1/ethereum/lido-stvault/action/burn-wsteth
Description
This endpoint crafts a transaction that burns wstETH that the call forwarder holds to repay the liability of the position (minted_steth_shares). Use it after the withdraw action releases wstETH from the Mellow vault. When the liability is repaid, the STV that covered it can leave the position through the pool withdrawal action.
The API returns 400 when amount is 0, when it is more than the wsteth of the position, or when it is more than the liability.
Request body parameters
| Field | Type | Required | Description |
|---|---|---|---|
address | string | ✅ | Address that owns the position |
amount | number | ✅ | Amount of wstETH to burn, in ether units. It must already sit on the position (wsteth on the balance endpoint) and cannot exceed the minted liability (minted_steth_shares). |
Returned
The same EthActionResponseDto object as the stake action.
Example
curl -X POST "https://staking-api.stakely.io/api/v1/ethereum/lido-stvault/action/burn-wsteth" \
-H "X-API-KEY: $STAKELY_API_KEY" \
-H "X-NETWORK: 560048" \
-H "Content-Type: application/json" \
-d '{
"address": "0x0345fA5dc69C9cA90a441215E2fA8A0B36469286",
"amount": 0.01
}'
Pool withdrawal action
Craft a pool withdrawal transaction:
- Endpoint:
/api/v1/ethereum/lido-stvault/action/withdraw-pool
Description
This endpoint crafts a transaction that requests a withdrawal of STV through the withdrawal queue of the pool. The queue converts the STV back into ETH. This is the exit of the STV position.
The transaction creates a request in the pool withdrawal queue. recipient owns that request. The ETH does not arrive with this transaction. The request appears in pool_withdrawal_requests of the position of recipient. When the queue finalizes it, claim the ETH with the claim pool withdrawal action.
Rules that the pool withdrawal queue applies:
- The ETH value of one request must be at least 0.001 ETH.
- The ETH value of one request must be at most 10,000 ETH. Use more than one request for a larger amount.
- If the position has a liability (
minted_steth_sharesgreater than0), the STV that stays in the position must still cover that liability. If it does not, repay the liability first with the burn wstETH action, or setsteth_shares_to_rebalance. The queue then uses part of the withdrawn STV to repay that amount of stETH shares.
The API returns 400 when stv_amount is 0 or is greater than the stv of the position.
Request body parameters
| Field | Type | Required | Description |
|---|---|---|---|
address | string | ✅ | Address that owns the position and signs the transaction. |
stv_amount | number | ✅ | STV to withdraw, in whole STV. The STV token uses 27 decimals, not 18. |
steth_shares_to_rebalance | number | ⚪ | stETH shares of the liability to repay with the withdrawn STV. The default is 0. |
recipient | string | ⚪ | Address that owns the request in the pool withdrawal queue and can claim its ETH. The default is address. |
Returned
The same EthActionResponseDto object as the stake action.
Example
curl -X POST "https://staking-api.stakely.io/api/v1/ethereum/lido-stvault/action/withdraw-pool" \
-H "X-API-KEY: $STAKELY_API_KEY" \
-H "X-NETWORK: 560048" \
-H "Content-Type: application/json" \
-d '{
"address": "0x0345fA5dc69C9cA90a441215E2fA8A0B36469286",
"stv_amount": 0.5
}'
Claim pool withdrawal action
Craft a pool withdrawal claim transaction:
- Endpoint:
/api/v1/ethereum/lido-stvault/action/claim-pool-withdrawal
Description
This endpoint crafts a transaction that claims the ETH of a finalized request in the pool withdrawal queue. It is the last step of the exit to ETH that the pool withdrawal action starts.
The transaction goes to the pool withdrawal queue contract, not to the strategy contract. The owner of the request must sign it. The owner is the recipient of the pool withdrawal action, which is address by default.
Take request_id from pool_withdrawal_requests in the position endpoint of the owner. Call this endpoint when is_claimable of that request is true. The API returns 400 when the request does not exist, belongs to another address, is already claimed, or is not finalized yet.
Request body parameters
| Field | Type | Required | Description |
|---|---|---|---|
address | string | ✅ | Address that owns the pool withdrawal request: the recipient chosen when it was requested, which defaults to the requesting address. Only the owner can claim. |
request_id | string | ✅ | Pool withdrawal request id, as a decimal string. It is reported as request_id under pool_withdrawal_requests by the balance endpoint. |
recipient | string | ⚪ | Address that will receive the ETH. Defaults to the owner address. |
Returned
The same EthActionResponseDto object as the stake action. For this action, payload.to is the pool withdrawal queue.
Example
curl -X POST "https://staking-api.stakely.io/api/v1/ethereum/lido-stvault/action/claim-pool-withdrawal" \
-H "X-API-KEY: $STAKELY_API_KEY" \
-H "X-NETWORK: 560048" \
-H "Content-Type: application/json" \
-d '{
"address": "0x0345fA5dc69C9cA90a441215E2fA8A0B36469286",
"request_id": "42"
}'
Refresh report action
Craft a vault report refresh transaction:
- Endpoint:
/api/v1/ethereum/lido-stvault/action/refresh-report
Description
This endpoint crafts a transaction that applies the entry of the vault from the latest Lido oracle report. Lido V3 uses a lazy oracle: each time Lido publishes a new report, the report of the vault is stale until a transaction applies it. While the report is stale, the pool refuses the stake action and the pool withdrawal action with the reason VaultReportStale.
Any address can send this transaction. The address does not need a position. To recover from VaultReportStale:
- Craft this transaction, then sign and broadcast it.
- Wait until the transaction is mined.
- Craft the refused action again.
The API reads the latest report on chain, gets the entry and the merkle proof of the vault from the Lido stVaults API, and validates them before it crafts the transaction.
- The API returns
400when the report of the vault is already fresh. - The API returns
422when the latest report has no entry for the vault, or when the protocol rejects the refresh. For example, the reason isInvalidProofwhen Lido publishes a newer report in the meantime. Craft the transaction again. - The API returns
502when the Lido stVaults API does not return a usable report.
Request body parameters
| Field | Type | Required | Description |
|---|---|---|---|
address | string | ✅ | Address that will sign and pay for the refresh transaction. Applying the report is permissionless, so it does not need to hold a position. |
Returned
The same EthActionResponseDto object as the stake action. For this action, payload.to is the Lido lazy oracle contract.
Example
curl -X POST "https://staking-api.stakely.io/api/v1/ethereum/lido-stvault/action/refresh-report" \
-H "X-API-KEY: $STAKELY_API_KEY" \
-H "X-NETWORK: 560048" \
-H "Content-Type: application/json" \
-d '{
"address": "0x0345fA5dc69C9cA90a441215E2fA8A0B36469286"
}'
Prepare action
Join the signature and the unsigned transaction:
- Endpoint:
/api/v1/ethereum/lido-stvault/action/prepare
Description
This endpoint joins the unsigned transaction and the parts of the signature into one signed transaction.
- Send
randsas hex strings, with or without the0xprefix. - Send
vas the recovery id (0or1), as27or28, or in EIP-155 form:chain_id * 2 + 35 + recovery. On Hoodi, the EIP-155 value is1120131or1120132. The API convertsvto the EIP-155 value. Any other value returns400.
Request body parameters
| Field | Type | Required | Description |
|---|---|---|---|
serialized_tx_hex | string | ✅ | The serialized_tx_hex value that the action endpoint returned. |
r | string | ✅ | r part of the ECDSA signature, as a hex string with or without the 0x prefix. |
s | string | ✅ | s part of the ECDSA signature, as a hex string with or without the 0x prefix. |
v | number | ✅ | v part of the ECDSA signature: the recovery id (0 or 1), 27 or 28, or the EIP-155 value chain_id * 2 + 35 + recovery. |
Returned
| Field | Type | Required | Description |
|---|---|---|---|
signed_tx_hex | string | ✅ | Signed transaction as a hex string without the 0x prefix, ready for the broadcast action. |
Example
curl -X POST "https://staking-api.stakely.io/api/v1/ethereum/lido-stvault/action/prepare" \
-H "X-API-KEY: $STAKELY_API_KEY" \
-H "X-NETWORK: 560048" \
-H "Content-Type: application/json" \
-d '{
"serialized_tx_hex": "0xf9011072843d54b88083045a9694bf4797de82787a60101e5e45cec7f29b27d83d98872386f26fc10000b8e43fec5c610000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000808080",
"r": "8c94d16ea6c70a070b521602b92da6791caf58d5596c18725000e556516dccaf",
"s": "0fc58b090b7ec46f8ba40374c76b96d8b986c8d7cbb57a01bd199945fb28cf4d",
"v": 1120131
}'
Response:
{
"signed_tx_hex": "f9015372843d54b88083045a9694bf4797de82787a60101e5e45cec7f29b27d83d98872386f26fc10000b8e43fec5c61000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000083111783a08c94d16ea6c70a070b521602b92da6791caf58d5596c18725000e556516dccafa00fc58b090b7ec46f8ba40374c76b96d8b986c8d7cbb57a01bd199945fb28cf4d"
}
Broadcast action
Broadcast a signed transaction:
- Endpoint:
/api/v1/ethereum/lido-stvault/action/broadcast
Description
This endpoint submits a signed transaction to the network. Usually you send the signed_tx_hex that the prepare action returns. The API accepts the value with or without the 0x prefix.
Request body parameters
| Field | Type | Required | Description |
|---|---|---|---|
signed_tx_hex | string | ✅ | Signed transaction as a hex string, with or without the 0x prefix. |
Returned
| Field | Type | Required | Description |
|---|---|---|---|
tx_hash | string | ✅ | Hash of the transaction that the API submitted. |
Example
curl -X POST "https://staking-api.stakely.io/api/v1/ethereum/lido-stvault/action/broadcast" \
-H "X-API-KEY: $STAKELY_API_KEY" \
-H "X-NETWORK: 560048" \
-H "Content-Type: application/json" \
-d '{
"signed_tx_hex": "f9015372843d54b88083045a9694bf4797de82787a60101e5e45cec7f29b27d83d98872386f26fc10000b8e43fec5c61000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000083111783a08c94d16ea6c70a070b521602b92da6791caf58d5596c18725000e556516dccafa00fc58b090b7ec46f8ba40374c76b96d8b986c8d7cbb57a01bd199945fb28cf4d"
}'
Response:
{
"tx_hash": "0xd7f308d45b98413270df126dcc6467bd99d1ad40706d50e56f3fae9df8857d78"
}
Errors
The action endpoints and the position endpoint of this protocol return errors in this shape:
{
"status": 422,
"errors": {
"message": "The protocol rejected this action (VaultReportStale): the vault oracle report is stale, so the pool refuses deposits and withdrawals until it is refreshed. Refresh it with `action/refresh-report` and retry once that transaction is mined.",
"reason": "VaultReportStale"
}
}
| Field | Description |
|---|---|
status | HTTP status code. |
errors.message | Description of the problem. It includes the requested amount and the available amount when the problem is an insufficient balance. |
errors.reason | Name of the contract error. The field is present only when the protocol rejects the action and the API can decode the error. |
The API simulates each transaction on chain before it returns it. If the simulation fails, the API returns 422 and no transaction. This prevents a transaction that reverts and costs gas.
| Status | Cause |
|---|---|
400 | The request is not valid for the current position: nothing to stake, insufficient ETH, STV or Mellow vault shares, no deposit request to claim, deposit request not settled, unknown request_id, exit request not claimable, pool withdrawal request not finalized or owned by another address, wstETH burn above the wsteth of the position or above the liability, or vault report already fresh. |
422 | A field of the request body is not valid. errors then contains one entry for each field that is not valid, with the field name as the key. |
422 | Lido stVault is not deployed on the requested network. The message lists the configured networks. |
422 | The protocol rejects the action in the current on-chain state. errors.reason contains the contract error. |
502 | The refresh report action did not get a usable report from the Lido stVaults API. |
Two errors use the common error format and not the shape above: 401 when the X-API-KEY header is missing or not valid, and 404 when X-NETWORK is not an Ethereum network that is enabled for your account.
Values of errors.reason that the API explains in errors.message:
reason | Meaning |
|---|---|
VaultReportStale | The oracle report of the vault is stale. The pool refuses deposits and withdrawals until a transaction applies the latest report. Use the refresh report action, then try again. |
InvalidProof | The refresh report action used a report that is no longer the latest. Craft the refresh report action again. |
SupplyFailed | The stake cannot proceed. The supply feature is paused, the deposit queue is not active, the oracle report is not usable, or a previous deposit request is still pending. |
RedeemFailed | The exit request cannot proceed. The redeem feature is paused or the redeem queue is not active. |
WithdrawalFailed | The exit request cannot proceed. The redeem feature is paused or the redeem queue is not active. |
InsufficientMellowShares | The position holds fewer Mellow vault shares than the requested exit. |
InsufficientStv | The position holds fewer STV than the request needs. |
InsufficientMintingCapacity | The requested mint_wsteth_amount exceeds the amount that the pool reserve ratio permits for this position. |
UndercollateralizedAccount | The position is undercollateralized and must be rebalanced first. |
FeaturePauseEnforced | The feature that the action needs is paused. |
NotAllowListed, NotInAllowList | The caller is not on the allow list of the contract. |
Other contract errors return 422 with the error name in errors.reason and no explanation.