Skip to content

Wallets and multisend ​

Read the smart wallets available to your integration, then use multiSendFromWallet to send from one wallet to several EVM destinations. Each batch executes atomically on one chain and returns a job ID for tracking.

Read available wallets ​

AgioCard_vw_partner_wallet exposes wallets within your managed customer scope. Use their IDs and token balances when constructing a transfer.

graphql
query Wallets($offset: Int!) {
  AgioCard_vw_partner_wallet(order_by: { id: asc }, limit: 20, offset: $offset) {
    id
    wallet_address
    chain_id
    chain_name
    status
    wallet_type
    total_balance_usd
    token_balances {
      token_chain_id
      chain_id
      token_symbol
      token_balance
      token_balance_usd
      token_address
      is_native
      decimals
      smart_wallet_trading_enabled
      verified
    }
  }
}
json
{ "offset": 0 }

Increase offset by 20 until the page is shorter than 20. Add where: { id: { _eq: 1234 } } to look up a known wallet.

FieldUse
Wallet idNumeric sourceWalletId for multisend
Wallet chain_idWallet registration network
Token token_chain_idAgio asset-and-chain record ID; use as tokenChainId
Token chain_idExecution network for that token
token_balanceAmount held, in token units
token_balance_usdUSD value of the token balance
smart_wallet_trading_enabled, verifiedBoth must be true for multisend eligibility

tokenChainId is an Agio record ID, not an EVM chain number. A wallet's registration chain can also differ from the execution chain. Select the token record for the network you intend to use.

Send a batch ​

graphql
mutation SendBatch($input: MultiSendFromWalletInput!) {
  multiSendFromWallet(input: $input) {
    success
    jobId
    alreadyEnqueued
    retryAfterSec
    errorCode
    errorMessage
  }
}
json
{
  "input": {
    "sourceWalletId": 1234,
    "transfers": [
      { "tokenChainId": 42, "destination": "0x1111111111111111111111111111111111111111", "amount": "100.5" },
      { "tokenChainId": 42, "destination": "0x2222222222222222222222222222222222222222", "amount": "250" }
    ],
    "idempotencyKey": "9bc10f33-52d5-4816-a34d-24a580790c61"
  }
}

The source wallet must be accessible to your partner organization. Every transfer must resolve to the same execution chain; split transfers across chains into separate batches. Destinations must be valid nonzero EVM addresses. amount is a positive decimal string in token units and cannot exceed the token's decimal precision.

After success: true, store jobId and poll the job. A success: false result means the request did not complete successfully; inspect its code and, after an uncertain internal failure, check the existing batch before submitting again.

Retry the same batch ​

Choose a globally unique idempotencyKey, such as a UUID, for each logical batch and persist it before submitting. Reuse that exact key and payload after a timeout. A repeated key refers to the existing job, even if the submitted payload changes; do not use one key for different transfers.

The key is optional, at most 128 characters, and contains no whitespace. When omitted, Agio derives it from your partner organization, source wallet, and normalized transfers. Amounts such as "100.5" and "100.50" normalize to the same base units. To intentionally send an otherwise identical second batch, give it a new explicit key.

A duplicate submission normally returns success: true, alreadyEnqueued: true, and the original jobId. Poll that job. Changing the key after an uncertain outcome can send the funds twice.

Poll job status ​

graphql
query BatchStatus($jobId: String!) {
  multiSendJobStatus(jobId: $jobId) {
    success
    jobId
    status
    txHash
    failedReason
    attempts
    errorCode
    errorMessage
  }
}
json
{ "jobId": "<multisend jobId>" }
StatusAction
pending, runningWait and poll again
submittedKeep checking the same job; broadcast may already have occurred
completedRecord txHash and reconcile destination balances
failedRead the diagnostic and resolve the failure before creating another batch
insufficient_balanceFund the source wallet, then create a new logical batch

Poll every few seconds with backoff for a long-running job. failedReason is diagnostic text, not a stable machine code. errorCode reports a failure to read the job, such as NOT_FOUND, rather than the transfer outcome.

Uncertain broadcast

A batch can remain submitted when its confirmation outcome is unknown. Do not create a replacement batch with a new key. Reconcile the source wallet's on-chain history or contact Agio before sending again.

Bulk-fund cardholders ​

Use each application's deposit address and chain as a destination. Group addresses by chain and select the token record accepted as collateral by those cardholders' program. Multisend eligibility alone does not establish that a token is accepted as card collateral.

Send one transfer per deposit address. After the job completes, check each destination's token balance and cardholder spending power. A collateral deposit address is separate from a source smart wallet; use a wallet ID from the available-wallets query as sourceWalletId.

Limits and validation ​

ControlDefault
Transfers per batch1–20
Total batch value$500,000
Enqueue rate per partner organization5 requests per 10 minutes
Endpoint request body512 KB

These are server defaults and can vary by environment. The worker checks live balances and USD value before broadcast. If a required USD price is unavailable, the batch is rejected. A successful enqueue does not bypass those checks.

Error codes ​

CodeAction
FORBIDDENCheck partner access to the source wallet
VALIDATION_ERRORCorrect transfer count, address, amount, precision, token ID, or key
MIXED_CHAINSSplit the batch by execution chain
TOKEN_CHAIN_NOT_ELIGIBLESelect a verified token enabled for smart-wallet trading
RATE_LIMITEDWait retryAfterSec, then retry the same key and payload
NOT_FOUNDCheck jobId; jobs outside your organization are not visible
INTERNAL_ERRORCheck the existing batch and reconcile before submitting again

Next: Receive and reconcile webhooks.