Builds a Solana staking transaction message for the caller to sign and submit. Building a payload does not broadcast a transaction or confirm an on-chain change.
Choose Mainnet or Devnet from the Base URL dropdown on the right before using Try It. Devnet is the Solana test environment. Use an API key and any required account addresses for your selection. Changing Base URL does not change the API key or addresses you have entered.
Supply your API credentials in the api-key header and send the request body as JSON. Instructions operating on an existing stake account must provide a top-level stakePubkey alongside feePayer and instructions.
After building, sign the transaction through your wallet or custody integration, submit it to the selected Solana network, and confirm execution.
Instruction inputs
These sketches illustrate individual instruction inputs. They are not complete JSON requests.
Create and delegate new stake account
{
type: 'createAndDelegate'
input: {
fromPubkey: pubkey of funding address,
stakeAuthority: address authorized to delegate and undelegate stake,
withdrawAuthority: address authorized to withdraw stake,
lamports: amount of lamports to stake (1 sol = 1000000000 lamports),
reference: an arbitrary reference used to identify/group the stake within the MAVAN platform,
label: an arbitrary label/memo for use within the MAVAN platform
}
}
Create a new stake account (same input data as 'createAndDelegate')
{
type: 'create'
input: {
fromPubkey: pubkey of funding address,
stakeAuthority: address authorized to delegate and undelegate stake,
withdrawAuthority: address authorized to withdraw stake,
lamports: amount of lamports to stake (1 sol = 1000000000 lamports),
reference: an arbitrary reference used to identify/group the stake within the MAVAN platform,
label: an arbitrary label/memo for use within the MAVAN platform
}
}
Delegate an existing stake account
{
type: 'delegate'
input: {
authorizedPubkey: address authorized to delegate and undelegate stake
}
}
Undelegate (deactivate) an existing stake account
{
type: 'undelegate'
input: {
authorizedPubkey: address authorized to delegate and undelegate stake
}
}
Withdraw inactive stake (deactivated stake balance or any other excess SOL held by account)
{
type: 'withdraw'
input: {
toPubkey: recipient of withdrawn funds,
authorizedPubkey: address authorized to withdraw stake,
lamports: amount of lamports to withdraw (1 sol = 1000000000 lamports),
}
}
Change withdraw or stake authority address of an existing stake account
This must be signed by the existing authority address of the stake account
{
type: 'authorize'
input: {
authorizedPubkey: the current authority address of the stake account,
newAuthorizedPubkey: the new authority address of the stake account,
stakeAuthorizationType: the authority type to change (0 for stake authority, 1 for withdraw authority),
}
}
Split an existing stake account
Creates a new child stake account and moves the requested amount from the source account into it. The child inherits the source account's stake and withdraw authorities and, for delegated stake, its delegation history.
To split one source account into several new accounts, supply one split instruction per new account in the same request. Split instructions cannot be combined with other instruction types.
For production integrations, use an active source account. Requests involving undelegated or activating accounts may fail. For a partial split of active stake, each child's delegated stake and the parent's remaining delegated stake must meet the network's current minimum delegation.
The stake authority (authorizedPubkey) funds each new account's rent-exempt reserve separately from the split amount, and feePayer pays transaction fees. feePayer can be a different address from authorizedPubkey; in that case, collect both signatures before submitting. The examples use the same address for both roles. Rent and minimum delegation are network parameters; do not hard-code them.
To try a split, first call Get Solana Stake Accounts (GET /solana/stakes) with the same API key. Choose an eligible ACTIVE account and copy its stakePubkey into the request. Set instructions[0].input.authorizedPubkey to that account's stakeAuthority; the example below also uses that authority as feePayer, which must have enough SOL for rent and fees. Confirm the current parent balance and delegation state through Solana RPC, then choose a valid split amount; the listing can be stale. Replace every <...> placeholder in the example with a real public key; entering an API key does not replace them automatically.
{
"feePayer": "<FEE_PAYER_AND_STAKE_AUTHORITY>",
"stakePubkey": "<PARENT_STAKE_ACCOUNT>",
"instructions": [
{
"type": "split",
"input": {
"authorizedPubkey": "<FEE_PAYER_AND_STAKE_AUTHORITY>",
"lamports": "1050000000",
"reference": "client-split-1",
"label": "Split child"
}
}
]
}authorizedPubkeyis the source account's stake authority and must sign.lamportsmust be a positive base-10 integer string, without leading zeros, and must not exceed9007199254740991. The example moves 1.05 SOL; check the remaining delegation before using that amount.referenceandlabelare optional. Omitted metadata is inherited or defaulted by the service. A supplied parent label normally gains" (split)"when inherited; a blank parent can produce"Split stake".- Supply an explicit child label to override inheritance. An empty string is accepted.
Example success response, HTTP 201:
{
"data": {
"serialized": "<HEX_ENCODED_V0_MESSAGE>",
"stakePubkey": "<NEW_CHILD_STAKE_ACCOUNT>",
"stakePubkeys": ["<NEW_CHILD_STAKE_ACCOUNT>"],
"signatures": []
}
}The request's stakePubkey identifies the parent. The response's data.stakePubkeys lists every new child in instruction order, and data.stakePubkey is the first of them. Each child address is derived from authorizedPubkey with a seed (createWithSeed), so the gateway returns no child key and no additional account signature is needed. The empty signatures array does not remove the caller's signing requirement.
Each build can generate a different child address. Keep the returned address paired with the exact payload from that response. The new account exists on-chain only after the transaction is submitted and succeeds.
Decode, sign, submit and confirm the returned message as described in Signing and submitting split and merge payloads below.
Merge compatible stake accounts
Merges the source account into a surviving destination account. The source account is closed when the transaction succeeds on-chain.
The top-level stakePubkey is the destination that survives. input.sourceStakePubkey is the source account that closes. authorizedPubkey is the stake authority and must sign.
Accounts must have compatible stake and withdraw authorities, lockup settings and delegation state. Active-stake merges also require compatible validator and vote-credit state. Matching authorities alone does not establish eligibility.
A child split from active stake inherits delegation history and can be merged back without waiting an additional epoch, provided the accounts remain compatible.
The example below uses the same address for the fee payer and stake authority. Replace every <...> placeholder with a real public key before submitting a request.
{
"feePayer": "<FEE_PAYER_AND_STAKE_AUTHORITY>",
"stakePubkey": "<SURVIVING_STAKE_ACCOUNT>",
"instructions": [
{
"type": "merge",
"input": {
"authorizedPubkey": "<FEE_PAYER_AND_STAKE_AUTHORITY>",
"sourceStakePubkey": "<STAKE_ACCOUNT_TO_CLOSE>"
}
}
]
}The response's data.stakePubkey identifies the surviving destination. Decode, sign, submit and confirm the returned message as described in Signing and submitting split and merge payloads below.
The stake-account listing may retain the source as DISSOLVED with its historical balance. Exclude that row when calculating current holdings.
Signing and submitting split and merge payloads
data.serialized is a hexadecimal-encoded Solana v0 message, not a serialized transaction including its signature envelope.
For split and merge payloads, construct a transaction using @solana/web3.js v1.x:
import { MessageV0, VersionedTransaction } from '@solana/web3.js';
const message = MessageV0.deserialize(
Buffer.from(response.data.serialized, 'hex'),
);
const transaction = new VersionedTransaction(message);Use your wallet or custody integration to sign the required message signers, submit the transaction to the matching Solana network, and confirm execution. Do not pass data.serialized directly to VersionedTransaction.deserialize().
Current integration limitations
The split and merge examples each use one instruction per request and the same address for the fee payer and stake authority. Requests involving undelegated or activating accounts may fail to build through the production gateway.
Building a transaction can create a provisional REQUESTED record, including on some failed builds. A listing row is not proof of execution.
Some invalid inputs and unsupported account states currently return HTTP 500 rather than a specific validation error. Verify the request fields and account state before rebuilding.
Devnet can reject a repeated split build while a child remains pending. Do not assume Mainnet and Devnet behave identically in that case.
| Time | Status | User Agent | |
|---|---|---|---|
Retrieving recent requests… | |||
400Invalid request. Some invalid inputs and unsupported account states currently return HTTP 500 instead.
500Transaction message could not be built. This can also indicate invalid inputs or unsupported account state. A provisional stake-account record may have been created.
