Skip to main content
POST
https://api.bipa.tech
/
v1
/
quotes
/
{quote_id}
/
execute
curl -X POST https://api.bipa.tech/v1/quotes/quote_abc123xyz/execute \
  -H "Authorization: Bearer bipa_live_sk_..."
{
  "id": "trade_xyz789",
  "quote_id": "quote_abc123xyz",
  "customer_id": "cus_a1b2c3d4e5f6",
  "status": "completed",
  "from_asset": "BRL",
  "to_asset": "BTC",
  "from_amount": "100000",
  "to_amount": "24628",
  "from_decimals": 2,
  "to_decimals": 8,
  "executed_price": "40200000",
  "fees": {
    "total": "1000",
    "total_bps": 100,
    "partner": "500",
    "partner_bps": 50,
    "bipa": "500",
    "bipa_bps": 50
  },
  "created_at": "2024-01-15T10:30:30Z",
  "completed_at": "2024-01-15T10:30:31Z"
}

Request

Execute a quote before it expires (30 seconds). This creates a trade that converts the customer’s balance at the quoted price.

Path parameters

quote_id
string
required
The quote ID to execute (e.g., quote_abc123xyz)
The customer must have sufficient balance in the source asset. The quote must not be expired (30 second validity).

Response

Returns the completed trade object.
id
string
Unique trade identifier
quote_id
string
The executed quote ID
customer_id
string
Customer who executed the trade
status
string
Trade status: completed or failed
from_asset
string
Source asset
to_asset
string
Target asset
from_amount
string
Amount debited (smallest unit)
to_amount
string
Amount credited (smallest unit)
from_decimals
integer
Decimal places for source asset
to_decimals
integer
Decimal places for target asset
executed_price
string
The price at which the trade executed (smallest unit)
fees
object
Fee breakdown (same structure as quote)
created_at
string
ISO 8601 timestamp
completed_at
string
ISO 8601 completion timestamp
curl -X POST https://api.bipa.tech/v1/quotes/quote_abc123xyz/execute \
  -H "Authorization: Bearer bipa_live_sk_..."
{
  "id": "trade_xyz789",
  "quote_id": "quote_abc123xyz",
  "customer_id": "cus_a1b2c3d4e5f6",
  "status": "completed",
  "from_asset": "BRL",
  "to_asset": "BTC",
  "from_amount": "100000",
  "to_amount": "24628",
  "from_decimals": 2,
  "to_decimals": 8,
  "executed_price": "40200000",
  "fees": {
    "total": "1000",
    "total_bps": 100,
    "partner": "500",
    "partner_bps": 50,
    "bipa": "500",
    "bipa_bps": 50
  },
  "created_at": "2024-01-15T10:30:30Z",
  "completed_at": "2024-01-15T10:30:31Z"
}

Complete flow example

Here’s a complete example with proper error handling:
import requests
from decimal import Decimal

class BipaQuoteClient:
    def __init__(self, api_key: str):
        self.headers = {
            "Authorization": f"Bearer {api_key}",
            "Content-Type": "application/json"
        }
        self.base_url = "https://api.bipa.tech/v1"

    def to_human(self, amount: str, decimals: int) -> Decimal:
        return Decimal(amount) / Decimal(10 ** decimals)

    def convert(
        self,
        customer_id: str,
        from_asset: str,
        to_asset: str,
        amount: str,
        amount_asset: str,
        amount_type: str = "gross",
        partner_fee_bps: int = 0
    ) -> dict:
        # Step 1: Create quote
        quote = requests.post(
            f"{self.base_url}/quotes",
            headers=self.headers,
            json={
                "customer_id": customer_id,
                "from_asset": from_asset,
                "to_asset": to_asset,
                "amount": amount,
                "amount_asset": amount_asset,
                "amount_type": amount_type,
                "partner_fee_bps": partner_fee_bps
            }
        ).json()

        if "error" in quote:
            raise Exception(f"Quote error: {quote['error']['message']}")

        # Display quote details
        from_human = self.to_human(quote["from_amount"], quote["from_decimals"])
        to_human = self.to_human(quote["to_amount"], quote["to_decimals"])
        fee_human = self.to_human(quote["fees"]["total"], quote["from_decimals"])

        print(f"Quote {quote['id']}:")
        print(f"  Pay: {from_human} {from_asset}")
        print(f"  Receive: {to_human} {to_asset}")
        print(f"  Fee: {fee_human} {from_asset} ({quote['fees']['total_bps']} bps)")
        print(f"    Partner: {self.to_human(quote['fees']['partner'], quote['from_decimals'])} {from_asset}")
        print(f"    Bipa: {self.to_human(quote['fees']['bipa'], quote['from_decimals'])} {from_asset}")
        print(f"  Expires: {quote['expires_at']}")

        # Step 2: Execute quote
        trade = requests.post(
            f"{self.base_url}/quotes/{quote['id']}/execute",
            headers=self.headers
        ).json()

        if "error" in trade:
            raise Exception(f"Trade error: {trade['error']['message']}")

        return trade


# Usage
client = BipaQuoteClient("bipa_live_sk_...")

# Buy BTC with R$ 1,000 + 0.5% partner fee
trade = client.convert(
    customer_id="cus_a1b2c3d4e5f6",
    from_asset="BRL",
    to_asset="BTC",
    amount="100000",      # R$ 1,000
    amount_asset="BRL",
    amount_type="gross",
    partner_fee_bps=50    # 0.5%
)

print(f"\nTrade completed: {trade['id']}")

Handling expired quotes

Quotes are valid for 30 seconds. Implement retry logic for production:
async function executeWithRetry(
  quoteParams: QuoteParams,
  maxRetries: number = 3
): Promise<Trade> {
  for (let attempt = 0; attempt < maxRetries; attempt++) {
    // Create fresh quote
    const quote = await createQuote(quoteParams);

    try {
      // Try to execute
      const trade = await executeQuote(quote.id);
      return trade;
    } catch (error) {
      if (error.code === "quote_expired" && attempt < maxRetries - 1) {
        console.log("Quote expired, retrying with fresh quote...");
        continue;
      }
      throw error;
    }
  }

  throw new Error("Max retries exceeded");
}
Quotes are valid for 30 seconds. In production, always handle the quote_expired error and automatically request a new quote.