Skip to Content
API ReferenceOrder Status & History

GET /api/v1/mev/orders/:orderId

Poll the status of a submitted order to track its progress through MEV-protected execution.

Use this endpoint to monitor your order status from submission through confirmation. Poll every 5-10 seconds until reaching a terminal state.


Endpoint Details

GET https://api.unikron.ch/api/v1/mev/orders/:orderId

Authentication Required: Yes (API Key via X-API-Key header)


Request Parameters

Path Parameters

ParameterTypeRequiredDescription
orderIdstringYesOrder ID from submit response

Headers

HeaderRequiredDescriptionExample
X-API-KeyYesYour UNIKRON API keyuk_live_abc123...

Code Examples

JavaScript / TypeScript

const API_KEY = process.env.UNIKRON_API_KEY; const API_URL = "https://api.unikron.ch"; async function getOrderStatus(orderId: string) { const response = await fetch(`${API_URL}/api/v1/mev/orders/${orderId}`, { headers: { "X-API-Key": API_KEY, }, }); if (!response.ok) { throw new Error(`HTTP ${response.status}: ${await response.text()}`); } const { ok, data } = await response.json(); if (!ok) { throw new Error(`API Error: ${data.error}`); } return data; } // Example: Poll until confirmed async function waitForConfirmation(orderId: string) { while (true) { const order = await getOrderStatus(orderId); console.log(`Status: ${order.status}`); // Terminal states if (order.status === "confirmed") { console.log(" Transaction confirmed!"); console.log(`TX Hash: ${order.txHash}`); console.log(`Block: ${order.blockNumber}`); return order; } if (order.status === "failed") { console.error(" Transaction failed"); throw new Error(order.error || "Transaction failed"); } // Wait 10 seconds before next poll await new Promise((resolve) => setTimeout(resolve, 10000)); } } // Usage const orderId = "ord_abc123xyz"; try { const result = await waitForConfirmation(orderId); console.log("Order complete:", result); } catch (error) { console.error("Order failed:", error); }

Response Format

Success Response (200 OK)

{ "ok": true, "data": { "orderId": "ord_abc123xyz", "status": "confirmed", "txHash": "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef", "blockNumber": 18500000, "gasUsed": "340196", "effectiveGasPrice": "25000000000", "createdAt": "2024-01-15T10:30:00Z", "submittedAt": "2024-01-15T10:30:05Z", "confirmedAt": "2024-01-15T10:32:15Z", "orderParams": { "fromToken": "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2", "toToken": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", "amount": "1000000000000000000", "minReturnAmount": "3693000000" } } }

Response Fields Reference

FieldTypeDescription
orderIdstringUnique order identifier
statusstringCurrent order status (see status table below)
txHashstringTransaction hash (available after submission)
blockNumbernumberBlock number (available after confirmation)
gasUsedstringGas used (available after confirmation)
effectiveGasPricestringActual gas price paid (available after confirmation)
createdAtstringISO 8601 order creation timestamp
submittedAtstringISO 8601 submission timestamp
confirmedAtstringISO 8601 confirmation timestamp (if confirmed)
orderParamsobjectOriginal order parameters

Order Status Values

Status Flow: pending → submitted → mining → confirmed ↓ failed

StatusDescriptionNext ActionDuration
pendingWaiting to submit to MEV BlockerKeep polling0-5 seconds
submittedSent to MEV BlockerKeep polling5-15 seconds
miningIncluded in block builder auctionKeep polling15-45 seconds
confirmedTransaction confirmed on blockchainDone - successTerminal state
failedTransaction reverted or rejectedCheck error, retryTerminal state
cancelledOrder cancelled by user or system-Terminal state

Polling Best Practices

Recommended Polling Strategy:

  • Poll every 5-10 seconds (10 seconds recommended)
  • Stop polling after reaching terminal states: confirmed, failed, or cancelled
  • Set a timeout of 5 minutes maximum
  • Implement exponential backoff on API errors
  • Cache the last status to avoid redundant processing
const POLLING_CONFIG = { interval: 10000, // 10 seconds timeout: 300000, // 5 minutes maxRetries: 3, // Retry failed API calls exponentialBackoff: true, }; async function pollWithConfig(orderId) { const startTime = Date.now(); let retries = 0; while (true) { // Check timeout if (Date.now() - startTime > POLLING_CONFIG.timeout) { throw new Error("Polling timeout exceeded"); } try { const status = await getOrderStatus(orderId); // Terminal states if (["confirmed", "failed", "cancelled"].includes(status.status)) { return status; } // Reset retries on success retries = 0; } catch (error) { retries++; if (retries >= POLLING_CONFIG.maxRetries) { throw error; } // Exponential backoff const backoff = Math.pow(2, retries) * 1000; await new Promise((r) => setTimeout(r, backoff)); continue; } // Wait before next poll await new Promise((r) => setTimeout(r, POLLING_CONFIG.interval)); } }

Error Responses

404 Not Found - Order Not Found

{ "ok": false, "error": "ORDER_NOT_FOUND", "message": "Order with ID ord_abc123xyz not found", "suggestion": "Check the order ID or ensure it was created by this API key" }

401 Unauthorized

{ "ok": false, "error": "UNAUTHORIZED", "message": "Invalid or missing API key", "suggestion": "Check your X-API-Key header" }

Common Error Codes

HTTPError CodeReasonSolution
401UNAUTHORIZEDInvalid/missing API keyCheck X-API-Key header
404ORDER_NOT_FOUNDInvalid order IDVerify order ID is correct
429RATE_LIMIT_EXCEEDEDToo many requestsIncrease polling interval
500INTERNAL_SERVER_ERRORServer errorRetry with backoff

Integration Example

Complete Workflow

// 1. Submit order const order = await submitOrder(quote, signer); console.log(`Order submitted: ${order.order.orderId}`); // 2. Poll for status const finalStatus = await waitForConfirmation(order.order.orderId); // 3. Handle result if (finalStatus.status === "confirmed") { console.log("Swap successful!"); console.log( `View on Etherscan: https://etherscan.io/tx/${finalStatus.txHash}` ); // Update UI with success showSuccess({ txHash: finalStatus.txHash, blockNumber: finalStatus.blockNumber, }); } else { console.error("Swap failed"); showError(finalStatus.error); }

GET /api/v1/mev/orders/user/:userAddress

Retrieve order history for a specific user address.

Get a paginated list of all orders submitted by a specific wallet address. Useful for building transaction history interfaces and order management dashboards.


Endpoint Details

GET https://api.unikron.ch/api/v1/mev/orders/user/:userAddress

Authentication Required: Yes (API Key via X-API-Key header)


Request Parameters

Path Parameters

ParameterTypeRequiredDescription
userAddressstringYesUser’s wallet address (checksummed)

Query Parameters

ParameterTypeRequiredDescription
limitnumberNoMax orders to return (default: 50, max: 200)
offsetnumberNoNumber of orders to skip (default: 0)
statusstringNoFilter by status (e.g., confirmed, failed)

Headers

HeaderRequiredDescriptionExample
X-API-KeyYesYour UNIKRON API keyuk_live_abc123...

Code Examples

JavaScript / TypeScript

const API_KEY = process.env.UNIKRON_API_KEY; const API_URL = "https://api.unikron.ch"; async function getUserOrders( userAddress: string, limit: number = 50, offset: number = 0, status?: string ) { const params = new URLSearchParams({ limit: limit.toString(), offset: offset.toString(), }); if (status) { params.append("status", status); } const response = await fetch( `${API_URL}/api/v1/mev/orders/user/${userAddress}?${params}`, { headers: { "X-API-Key": API_KEY, }, } ); if (!response.ok) { throw new Error(`HTTP ${response.status}: ${await response.text()}`); } const { ok, data } = await response.json(); if (!ok) { throw new Error(`API Error: ${data.error}`); } return data; } // Example: Get recent orders const userAddress = "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb"; try { const orders = await getUserOrders(userAddress, 20); console.log(`Total orders: ${orders.total}`); console.log(`Showing: ${orders.orders.length}`); console.log(`Has more: ${orders.hasMore}`); orders.orders.forEach((order) => { console.log(`\nOrder ID: ${order.orderId}`); console.log(`Status: ${order.status}`); console.log(`Created: ${order.createdAt}`); console.log(`TX Hash: ${order.txHash || "pending"}`); }); } catch (error) { console.error("Failed to get orders:", error); }

Response Format

Success Response (200 OK)

{ "ok": true, "data": { "orders": [ { "orderId": "ord_abc123xyz", "status": "confirmed", "txHash": "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef", "blockNumber": 18500000, "createdAt": "2024-01-15T10:30:00Z", "confirmedAt": "2024-01-15T10:32:15Z", "summary": { "sellToken": "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2", "buyToken": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", "sellAmount": "1000000000000000000", "buyAmount": "3700000000" } }, { "orderId": "ord_def456uvw", "status": "pending", "txHash": null, "blockNumber": null, "createdAt": "2024-01-15T11:00:00Z", "confirmedAt": null, "summary": { "sellToken": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", "buyToken": "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2", "sellAmount": "5000000000", "buyAmount": "1350000000000000000" } } ], "total": 150, "hasMore": true, "pagination": { "limit": 20, "offset": 0, "nextOffset": 20 } } }

Response Fields Reference

Root Data Object

FieldTypeDescription
ordersarrayArray of order objects (see below)
totalnumberTotal number of orders for this user
hasMorebooleanWhether more orders are available
paginationobjectPagination metadata

Order Object

FieldTypeDescription
orderIdstringUnique order identifier
statusstringOrder status
txHashstringTransaction hash (null if not submitted)
blockNumbernumberBlock number (null if not confirmed)
createdAtstringISO 8601 order creation timestamp
confirmedAtstringISO 8601 confirmation time (if confirmed)
summaryobjectOrder summary with token details

Summary Object

FieldTypeDescription
sellTokenstringToken being sold (address)
buyTokenstringToken being bought (address)
sellAmountstringSell amount in smallest units
buyAmountstringBuy amount in smallest units

Pagination

Pagination Best Practices:

  • Use limit to control page size (max 200)
  • Use offset to skip to specific pages
  • Check hasMore to determine if more pages exist
  • Use pagination.nextOffset for the next page

Example: Paginated Fetching

async function getAllUserOrders(userAddress: string) { const allOrders = []; let offset = 0; const limit = 100; while (true) { const data = await getUserOrders(userAddress, limit, offset); allOrders.push(...data.orders); console.log( `Fetched ${data.orders.length} orders (total: ${allOrders.length}/${data.total})` ); if (!data.hasMore) { break; } offset = data.pagination.nextOffset; } return allOrders; }

Filtering by Status

Filter Options: Use the status query parameter to filter orders:

  • confirmed - Successfully completed orders
  • failed - Failed orders
  • pending - Orders waiting for submission
  • mining - Orders being mined
// Get only confirmed orders const confirmed = await getUserOrders(userAddress, 50, 0, "confirmed"); // Get only failed orders const failed = await getUserOrders(userAddress, 50, 0, "failed");

Error Responses

400 Bad Request - Invalid Address

{ "ok": false, "error": "INVALID_ADDRESS", "message": "User address is not a valid Ethereum address", "details": { "address": "invalid_address", "reason": "Invalid format" } }

400 Bad Request - Invalid Limit

{ "ok": false, "error": "INVALID_PARAMETER", "message": "Limit must be between 1 and 200", "details": { "parameter": "limit", "provided": 500, "max": 200 } }

Common Error Codes

HTTPError CodeReasonSolution
400INVALID_ADDRESSInvalid wallet addressUse valid checksummed address
400INVALID_PARAMETERInvalid limit/offsetUse valid pagination values
401UNAUTHORIZEDInvalid/missing API keyCheck X-API-Key header
429RATE_LIMIT_EXCEEDEDToo many requestsImplement rate limiting

Use Cases

Transaction History UI

// Build transaction history table async function buildHistoryTable(userAddress: string) { const orders = await getUserOrders(userAddress, 50); const tableData = orders.orders.map((order) => ({ date: new Date(order.createdAt).toLocaleString(), status: order.status, from: formatToken(order.summary.sellToken), to: formatToken(order.summary.buyToken), amount: formatAmount(order.summary.sellAmount), txHash: order.txHash ? ( <a href={`https://etherscan.io/tx/${order.txHash}`}> {order.txHash.slice(0, 10)}... </a> ) : ( "Pending" ), })); return tableData; }

Order Analytics

// Calculate user statistics async function getUserStats(userAddress: string) { const allOrders = await getAllUserOrders(userAddress); const stats = { total: allOrders.length, confirmed: allOrders.filter((o) => o.status === "confirmed").length, failed: allOrders.filter((o) => o.status === "failed").length, pending: allOrders.filter((o) => o.status === "pending").length, totalVolume: calculateTotalVolume(allOrders), }; return stats; }

Related Operations


Need Help?

Last updated on