Skip to main content
With your signed payload ready, submit it to the /v1/execute endpoint. Biconomy’s MEE network handles all the blockchain complexity.

Execute Request

The request body is simple: the entire quote response with your signed payloads:
const result = await fetch('https://api.biconomy.io/v1/execute', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    ...quote,                        // Spread the entire quote
    payloadToSign: signedPayloads    // Replace with signed version
  })
}).then(r => r.json());

Complete Example

// 1. Get quote
const quote = await fetch('https://api.biconomy.io/v1/quote', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    mode: 'smart-account',
    ownerAddress: account.address,
    composeFlows: [{
      type: '/instructions/intent-simple',
      data: {
        srcChainId: 8453,
        dstChainId: 10,
        srcToken: USDC_BASE,
        dstToken: USDT_OPTIMISM,
        amount: '100000000',
        slippage: 0.01
      }
    }]
  })
}).then(r => r.json());

// 2. Sign
const payload = quote.payloadToSign[0];
const signature = await walletClient.signTypedData({
  ...payload.signablePayload,
  account
});

// 3. Execute
const result = await fetch('https://api.biconomy.io/v1/execute', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    ...quote,
    payloadToSign: [{ ...payload, signature }]
  })
}).then(r => r.json());

// 4. Check result
if (result.success) {
  console.log('Supertransaction hash:', result.supertxHash);
  console.log('Track at:', `https://meescan.biconomy.io/details/${result.supertxHash}`);
} else {
  console.error('Execution failed:', result.error);
}

Response

{
  "success": true,
  "supertxHash": "0x9a72f87a93c55d8f88e3f8c2a7b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2",
  "error": null
}
FieldDescription
successWhether execution was accepted
supertxHashUnique identifier for tracking
errorError message if failed
success: true means the transaction was accepted for execution, not that it’s complete. Use the supertxHash to track actual completion.

Tracking Execution

MEE Explorer

View real-time status at:
https://meescan.biconomy.io/details/{supertxHash}

Polling Status

async function waitForCompletion(supertxHash, apiKey, timeout = 120000) {
  const startTime = Date.now();
  
  while (Date.now() - startTime < timeout) {
    const status = await fetch(
      `https://network.biconomy.io/v1/explorer/${supertxHash}`,
      { headers: { 'Authorization': `Bearer ${apiKey}` } }
    ).then(r => r.json());
    
    if (status.status === 'SUCCESS') {
      return { success: true, data: status };
    }
    
    if (status.status === 'FAILED') {
      return { success: false, error: status.error };
    }
    
    // Still pending, wait and retry
    await new Promise(r => setTimeout(r, 3000));
  }
  
  throw new Error('Timeout waiting for execution');
}

// Usage
const completion = await waitForCompletion(result.supertxHash, API_KEY);
if (completion.success) {
  console.log('Transaction complete!');
}

Using AbstractJS SDK

If you’re using the SDK, there’s a built-in method:
import { createMeeClient } from '@biconomy/abstractjs';

const meeClient = createMeeClient({...});

const receipt = await meeClient.waitForSupertransactionReceipt({
  hash: result.supertxHash,
  timeout: 120000
});

console.log('Status:', receipt.status);

Error Handling

const result = await fetch('/v1/execute', {
  method: 'POST',
  body: JSON.stringify({ ...quote, payloadToSign: signedPayloads })
}).then(async r => {
  if (!r.ok) {
    const error = await r.json();
    throw new Error(error.message || 'Execution failed');
  }
  return r.json();
});

if (!result.success) {
  // Handle specific errors
  if (result.error?.includes('insufficient balance')) {
    console.log('User needs more tokens');
  } else if (result.error?.includes('signature')) {
    console.log('Signature invalid or expired');
  } else {
    console.log('Execution failed:', result.error);
  }
}

Common Issues

  • Make sure you’re signing the exact payload from the quote
  • Check you’re using the correct signing method for the quoteType
  • Quotes expire—get a fresh one if too much time has passed
  • Verify user has enough tokens for the operation
  • Remember fees are deducted from balance too
  • For EOA mode, check fundingTokens matches actual balance
  • Quotes are valid for ~30 seconds
  • Get a new quote if user takes too long to sign
  • Consider showing a countdown in your UI
  • success: true only means the tx was accepted
  • Check MEE Explorer for actual execution status
  • On-chain conditions may have changed (slippage, liquidity)

Full Flow Summary

// Complete implementation
async function executeSupertransaction(composeFlows, account, walletClient) {
  // 1. Quote
  const quote = await fetch('https://api.biconomy.io/v1/quote', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json', 'X-API-Key': API_KEY },
    body: JSON.stringify({
      mode: 'smart-account',
      ownerAddress: account.address,
      composeFlows
    })
  }).then(r => r.json());
  
  // 2. Sign
  const payload = quote.payloadToSign[0];
  const signature = await walletClient.signTypedData({
    ...payload.signablePayload,
    account
  });
  
  // 3. Execute
  const result = await fetch('https://api.biconomy.io/v1/execute', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      ...quote,
      payloadToSign: [{ ...payload, signature }]
    })
  }).then(r => r.json());
  
  if (!result.success) {
    throw new Error(result.error);
  }
  
  // 4. Wait for completion
  const completion = await waitForCompletion(result.supertxHash, API_KEY);
  
  return {
    hash: result.supertxHash,
    status: completion.success ? 'complete' : 'failed'
  };
}

Next Steps