Get Trade Intent by External ID
Retrieve a Trade Intent using your intent_id
API: GET https://api.sniperoute.io/api/v1/intents/by-external-id/{intent_id}
Request
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
intent_id | string | Yes | Your external intent identifier |
Headers
| Header | Value | Required |
|---|---|---|
Authorization | Bearer your_api_key | Yes |
Response
Success (200 OK)
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"intent_id": "trade_001",
"symbol": "AAPL",
"side": "buy",
"quantity": 10,
"order_type": "market",
"status": "filled",
"broker_id": "alpaca_abc123",
"orders": [
{
"id": "660e8400-e29b-41d4-a716-446655440000",
"broker_order_id": "order_123",
"status": "filled",
"fills": [
{
"quantity": 10,
"price": 175.50,
"filled_at": "2025-11-30T10:30:00Z"
}
],
"created_at": "2025-11-30T10:29:59Z",
"updated_at": "2025-11-30T10:30:00Z"
}
],
"created_at": "2025-11-30T10:29:59Z",
"updated_at": "2025-11-30T10:30:00Z"
}Error (4xx/5xx)
{
"detail": "Trade Intent not found",
"error_code": "not_found",
"request_id": "req_abc123"
}Examples
curl https://api.sniperoute.io/api/v1/intents/by-external-id/trade_001 \
-H "Authorization: Bearer sk_live_abc123..."Response Fields
| Field | Type | Description |
|---|---|---|
id | string (UUID) | Internal Trade Intent UUID |
intent_id | string | Your external intent identifier |
symbol | string | Trading symbol |
side | string | "buy" or "sell" |
quantity | number | Number of shares/units |
order_type | string | "market", "limit", "stop", or "stop_limit" |
limit_price | number | null | Limit price (if applicable) |
stop_price | number | null | Stop price (if applicable) |
time_in_force | string | "day", "gtc", "ioc", or "fok" |
extended_hours | boolean | Extended hours trading enabled |
status | string | See Status Values |
broker_id | string | Connected broker account ID |
orders | array | List of broker orders |
created_at | string (ISO 8601) | Creation timestamp |
updated_at | string (ISO 8601) | Last update timestamp |
Status Values
| Status | Description |
|---|---|
pending | Order submitted to broker, awaiting execution |
filled | Order fully executed |
partially_filled | Order partially executed |
canceled | Order canceled before full execution |
rejected | Broker rejected the order |
failed | Routing or validation failed |
Error Codes
| Status Code | Error Code | Description |
|---|---|---|
401 | unauthorized | Invalid or missing API key |
404 | not_found | Trade Intent with this intent_id not found |
500 | internal_server_error | Server error |
Why Use This Endpoint?
This endpoint is more convenient than /intents/{id} because:
- You don't need to track the internal UUID
- You can use your own
intent_iddirectly - It's the same identifier you used when creating the intent
Best Practice: Use this endpoint (/by-external-id/{intent_id}) for querying Trade Intents in your application.
Use Cases
Check Order Immediately After Creation
import asyncio
from sniperoute import SnipeRouteClient
from sniperoute.models import TradeIntentRequest, OrderSide, OrderType
from decimal import Decimal
async def create_and_check():
client = SnipeRouteClient()
# Create intent
intent = TradeIntentRequest(
intent_id="trade_001",
symbol="AAPL",
side=OrderSide.BUY,
quantity=Decimal("10"),
order_type=OrderType.MARKET,
broker_id="alpaca_abc123"
)
response = await client.create_intent(intent)
print(f"Created: {response.intent_id}")
# Check status using same intent_id
status = await client.get_intent_by_external_id("trade_001")
print(f"Status: {status.status}")
asyncio.run(create_and_check())Wait for Fill
import asyncio
async def wait_for_fill(client, intent_id, timeout=60):
"""Poll until order fills or times out."""
start_time = asyncio.get_event_loop().time()
while True:
intent = await client.get_intent_by_external_id(intent_id)
if intent.status == "filled":
print("Order filled!")
return intent
elif intent.status == "rejected":
print("Order rejected")
return intent
elif asyncio.get_event_loop().time() - start_time > timeout:
raise TimeoutError("Order did not fill within timeout")
await asyncio.sleep(1) # Poll every second
# Usage
filled_intent = await wait_for_fill(client, "trade_001")⚠️
Polling vs Webhooks: While polling works, webhooks are more efficient for real-time updates.
Track Multiple Intents
async def track_intents(client, intent_ids):
"""Check status of multiple intents."""
results = {}
for intent_id in intent_ids:
try:
intent = await client.get_intent_by_external_id(intent_id)
results[intent_id] = intent.status
except Exception as e:
results[intent_id] = f"Error: {e}"
return results
# Usage
status_map = await track_intents(
client,
["trade_001", "trade_002", "trade_003"]
)
for intent_id, status in status_map.items():
print(f"{intent_id}: {status}")Get Fill Details
async def get_fill_details(client, intent_id):
"""Get detailed fill information."""
intent = await client.get_intent_by_external_id(intent_id)
if intent.status != "filled":
print(f"Order not filled yet. Status: {intent.status}")
return
total_quantity = 0
total_value = 0.0
for order in intent.orders:
for fill in order.fills:
total_quantity += fill.quantity
total_value += fill.quantity * fill.price
print(f"Fill: {fill.quantity} @ ${fill.price} at {fill.filled_at}")
avg_price = total_value / total_quantity if total_quantity > 0 else 0
print(f"\nTotal: {total_quantity} shares at avg price ${avg_price:.2f}")
# Usage
await get_fill_details(client, "trade_001")