Skip to content

Accept quote and track trade

POST /quotes/{quote_id}/accept

Use this to start execution for a firm quote.

Header:

  • Idempotency-Key (required)

Parameters

Parameter Type Required Description
slippage_bps string Yes Slippage tolerance in basis points (e.g. "10", "2.5")
client_order_id string No Client-provided order identifier for correlation

Example request:

Request
curl -X POST https://routes.srcry.xyz/v1/quotes/qt_01J.../accept \
  -H "Authorization: Bearer $ROUTES_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: unique-key-123" \
  -d '{
  "slippage_bps": "10",
  "client_order_id": "ord_uniq_123"
}'
Request
import httpx

response = httpx.post(
    "https://routes.srcry.xyz/v1/quotes/qt_01J.../accept",
    headers={
        "Authorization": f"Bearer {api_key}",
        "Idempotency-Key": "unique-key-123",
    },
    json={
        "slippage_bps": "10",
        "client_order_id": "ord_uniq_123"
    },
)
Request
const response = await fetch("https://routes.srcry.xyz/v1/quotes/qt_01J.../accept", {
  method: "POST",
  headers: {
    "Authorization": `Bearer ${apiKey}`,
    "Content-Type": "application/json",
    "Idempotency-Key": "unique-key-123",
  },
  body: JSON.stringify({
    slippage_bps: "10",
    client_order_id: "ord_uniq_123"
  }),
});
Request body
{
  "slippage_bps": "10",
  "client_order_id": "ord_uniq_123"
}

Example response:

{
  "request_id": "req_01J...",
  "trade": {
    "trade_id": "trd_01J...",
    "status": "executing",
    "quote_id": "qt_01J...",
    "client_order_id": "ord_uniq_123",
    "poll_after_ms": 5000
  }
}

Response fields

Field Type Description
request_id string Request identifier
trade.trade_id string Trade identifier
trade.status string Current trade status
trade.quote_id string Source quote identifier
trade.client_order_id string Client-provided identifier
trade.failure_code string Failure reason (terminal only): execution_failed, settlement_failed, settlement_timeout, settlement_orphaned, deposit_insufficient_confirmations
trade.settlement.out_tx_hash string Transaction hash for account → MM leg (the source asset leaving the account)
trade.settlement.out_confirmations integer Current confirmation count for out leg
trade.settlement.out_finalized boolean Whether out leg has reached chain finality
trade.settlement.in_tx_hash string Transaction hash for MM → account leg (the destination asset arriving at the destination)
trade.settlement.in_confirmations integer Current confirmation count for in leg
trade.settlement.in_finalized boolean Whether in leg has reached chain finality
trade.fees.platform_bps string Platform fee in basis points
trade.fees.integrator_bps string Integrator fee in basis points
trade.fees.total_bps string Combined fee in basis points
trade.fees.platform_atoms string Platform fee in output asset atoms
trade.fees.integrator_atoms string Integrator fee in output asset atoms
trade.fees.total_atoms string Total fee in output asset atoms
trade.poll_after_ms integer Milliseconds until next poll

Settlement leg example: for a USDC (Solana) → BTC swap, out_tx_hash is the Solana transaction sending USDC from the account to the market maker, and in_tx_hash is the Bitcoin transaction delivering BTC from the market maker to the registered destination.

GET /trades/{trade_id}

Use this to track execution state. Settlement time varies by route — on-chain swaps may take seconds to minutes depending on chain finality.

poll_after_ms is included on non-terminal responses and is route-aware: a local Solana swap might return 500, while a cross-chain hybrid route might return 15000. Use webhooks as the primary path for real-time notifications; use poll_after_ms as a polling fallback.

Non-terminal states:

  • executing — solver/MM is executing the swap
  • filled — MM has committed to filling the order; funds credited as pending in ledger
  • pending_settle — MM has initiated on-chain settlement

Terminal states:

  • settled — settlement confirmed on-chain
  • failed — execution or settlement did not complete

The failure_code field indicates the reason. When a trade fails, the source credit is not consumed — create a new RFQ with the same credit_id to retry.

Recoverable — retry automatically:

  • execution_failed — swap execution did not complete. Create a new RFQ and accept.
  • deposit_insufficient_confirmations — counterparty requires more confirmations for this deposit. Wait for additional confirmations and retry.

Non-recoverable — escalate for manual review:

  • settlement_failed — settlement transaction failed on-chain
  • settlement_timeout — settlement not confirmed within expected window
  • settlement_orphaned — a previously-confirmed settlement tx was dropped (reorg)

Trade lifecycle:

    ┌───────────┐
    │ executing │
    └─────┬─────┘
          │
    ┌─────▼─────┐
    │  filled   │
    └─────┬─────┘
          │
  ┌───────▼────────┐
  │ pending_settle │
  └───┬─────────┬──┘
      │         │
  ┌───▼────┐ ┌──▼─────┐
  │ settled│ │ failed │
  └────────┘ └────────┘

Note: failed is reachable from executing, filled, or pending_settle.

Non-terminal example:

{
  "request_id": "req_01J...",
  "trade": {
    "trade_id": "trd_01J...",
    "status": "pending_settle",
    "poll_after_ms": 10000
  }
}

Terminal example (settled):

{
  "request_id": "req_01J...",
  "trade": {
    "trade_id": "trd_01J...",
    "status": "settled",
    "settlement": {
      "out_tx_hash": "0xabc123...",
      "out_confirmations": 64,
      "out_finalized": true,
      "in_tx_hash": "0xdef456...",
      "in_confirmations": 42,
      "in_finalized": true
    },
    "fees": {
      "platform_bps": "5",
      "integrator_bps": "10",
      "total_bps": "15",
      "platform_atoms": "50000",
      "integrator_atoms": "100000",
      "total_atoms": "150000"
    }
  }
}

Terminal example (failed):

{
  "request_id": "req_01J...",
  "trade": {
    "trade_id": "trd_01J...",
    "status": "failed",
    "failure_code": "settlement_timeout"
  }
}