SMSA Express APIsmsaexpress.com ↗
Track SMSA Express shipments by AWB number. Returns status, delivery details, and tracking events for one or multiple shipments in a single request.
What is the SMSA Express API?
The SMSA Express API provides 1 endpoint — track_shipment — that returns real-time shipment status and tracking details for one or more AWB numbers in a single call. Submit a comma- or space-separated list of SMSA Express tracking numbers and receive a structured array of shipment results alongside a total_found count, making it straightforward to monitor multiple packages at once without issuing repeated requests.
curl -X POST 'https://api.parse.bot/scraper/bbefb5fe-6810-4dba-9726-6bea4f024e8f/track_shipment' \
-H 'X-API-Key: $PARSE_API_KEY' \
-H 'Content-Type: application/json' \
-d '{}'Typed, relational, agent-ready
A generated client with real types, enums, and the links between objects — the structure a flat JSON response can't carry. Autocompletes in your editor and reads cleanly to coding agents.
- Fully typed · autocompletes
- Objects link to objects
- Typed errors & pagination
Typed Python client. Set up the SDK in your uv project, then pull this API’s typed client:
uv add parse-sdk uv run parse init uv run parse add --marketplace smsaexpress-com-api
uv run parse add --marketplace pulls a pinned snapshot of this canonical API — it won’t change underneath you. To customize it, subscribe and swap to your own copy.
"""
SMSA Express Shipment Tracking API Client
Track shipments on SMSA Express by entering tracking numbers (AWB numbers).
Supports multiple tracking numbers in a single request.
Get your API key from: https://parse.bot/settings
"""
import os
import requests
from typing import Optional, List, Dict, Any
class ParseClient:
"""Client for interacting with the Parse API for SMSA Express shipment tracking."""
def __init__(self, api_key: Optional[str] = None):
"""
Initialize the Parse API client.
Args:
api_key: Your Parse API key. If not provided, reads from PARSE_API_KEY env var.
"""
self.base_url = "https://api.parse.bot"
self.scraper_id = "bbefb5fe-6810-4dba-9726-6bea4f024e8f"
self.api_key = api_key or os.getenv("PARSE_API_KEY")
if not self.api_key:
raise ValueError(
"API key not provided. Set PARSE_API_KEY environment variable or pass api_key parameter."
)
def _call(
self, endpoint: str, method: str = "POST", **params
) -> Dict[str, Any]:
"""
Make a request to the Parse API.
Args:
endpoint: The endpoint name to call.
method: HTTP method (GET or POST).
**params: Query/body parameters to send.
Returns:
JSON response as dictionary.
Raises:
requests.exceptions.RequestException: If the request fails.
"""
url = f"{self.base_url}/scraper/{self.scraper_id}/{endpoint}"
headers = {
"X-API-Key": self.api_key,
"Content-Type": "application/json",
}
try:
if method.upper() == "GET":
response = requests.get(url, headers=headers, params=params)
elif method.upper() == "POST":
response = requests.post(url, headers=headers, json=params)
else:
raise ValueError(f"Unsupported HTTP method: {method}")
response.raise_for_status()
return response.json()
except requests.exceptions.RequestException as e:
print(f"API request failed: {e}")
raise
def track_shipment(
self,
tracking_numbers: str,
language: str = "EN",
) -> Dict[str, Any]:
"""
Track one or more shipments by their SMSA Express tracking numbers (AWB numbers).
Args:
tracking_numbers: One or more SMSA Express tracking numbers (AWB numbers),
separated by commas or spaces (e.g. '290019498498' or
'290019498498,290019934499').
language: Language for tracking response. Accepts: EN, AR, FR. Defaults to EN.
Returns:
Dictionary containing tracking_numbers, shipments array, and total_found count.
Example:
>>> client = ParseClient()
>>> result = client.track_shipment("290019498498")
>>> print(f"Found {result['total_found']} shipment(s)")
"""
return self._call(
"track_shipment",
method="POST",
tracking_numbers=tracking_numbers,
language=language,
)
def display_shipment_info(shipment: Dict[str, Any]) -> None:
"""
Pretty print shipment tracking information.
Args:
shipment: Shipment data dictionary.
"""
print("\n" + "=" * 60)
for key, value in shipment.items():
if isinstance(value, dict):
print(f" {key}:")
for sub_key, sub_value in value.items():
print(f" {sub_key}: {sub_value}")
elif isinstance(value, list):
print(f" {key}: {len(value)} items")
for item in value[:3]:
print(f" - {item}")
if len(value) > 3:
print(f" ... and {len(value) - 3} more")
else:
print(f" {key}: {value}")
print("=" * 60)
if __name__ == "__main__":
# Initialize the client
client = ParseClient()
# Practical use case: Track multiple shipments and display results
print("SMSA Express Shipment Tracking Example")
print("-" * 60)
# Example 1: Track a single shipment
print("\n1. Tracking a single shipment...")
single_tracking = "290019498498"
result = client.track_shipment(single_tracking)
print(f"Queried tracking numbers: {result['tracking_numbers']}")
print(f"Total shipments found: {result['total_found']}")
if result["total_found"] > 0:
print(f"\nShipment details:")
for shipment in result["shipments"]:
display_shipment_info(shipment)
else:
print("No shipments found for this tracking number.")
# Example 2: Track multiple shipments in one request
print("\n\n2. Tracking multiple shipments...")
multiple_tracking = "290019498498,290019934499"
result = client.track_shipment(multiple_tracking)
print(f"Queried tracking numbers: {result['tracking_numbers']}")
print(f"Total shipments found: {result['total_found']}")
if result["total_found"] > 0:
print(f"\nProcessing {result['total_found']} shipment(s):\n")
for idx, shipment in enumerate(result["shipments"], 1):
print(f"Shipment #{idx}:")
display_shipment_info(shipment)
else:
print("No shipments found for the provided tracking numbers.")
# Example 3: Track with different language
print("\n\n3. Tracking with Arabic language preference...")
result = client.track_shipment("290019498498", language="AR")
print(f"Language: AR (Arabic)")
print(f"Total shipments found: {result['total_found']}")
if result["total_found"] > 0:
for shipment in result["shipments"]:
display_shipment_info(shipment)
# Example 4: Batch processing workflow
print("\n\n4. Batch processing multiple tracking numbers...")
tracking_list = [
"290019498498",
"290019934499",
"290019111222",
]
batch_results = {}
for tracking_num in tracking_list:
print(f"Processing tracking number: {tracking_num}...")
try:
result = client.track_shipment(tracking_num)
batch_results[tracking_num] = result
except Exception as e:
print(f"Failed to track {tracking_num}: {e}")
batch_results[tracking_num] = {"error": str(e)}
# Summary report
print("\n\nBatch Processing Summary:")
print("-" * 60)
successful = sum(1 for r in batch_results.values() if "total_found" in r)
failed = len(batch_results) - successful
print(f"Total requests: {len(batch_results)}")
print(f"Successful: {successful}")
print(f"Failed: {failed}")
for tracking_num, result in batch_results.items():
if "total_found" in result:
print(f" {tracking_num}: {result['total_found']} shipment(s) found")
else:
print(f" {tracking_num}: Error - {result.get('error', 'Unknown error')}")Track one or more shipments by their SMSA Express tracking numbers (AWB numbers). Returns shipment status and tracking details for each valid tracking number found. Multiple tracking numbers can be provided separated by commas or spaces.
| Param | Type | Description |
|---|---|---|
| language | string | Language for tracking response. Accepts: EN, AR, FR. |
| tracking_numbersrequired | string | One or more SMSA Express tracking numbers (AWB numbers), separated by commas or spaces (e.g. '290019498498' or '290019498498,290019934499'). |
{
"type": "object",
"fields": {
"shipments": "array of shipment tracking results (empty if no shipments found)",
"total_found": "integer count of shipments found",
"tracking_numbers": "array of tracking numbers that were queried"
},
"sample": {
"shipments": [],
"total_found": 0,
"tracking_numbers": [
"290019498498"
]
}
}About the SMSA Express API
Endpoint: track_shipment
The track_shipment endpoint accepts one or more SMSA Express AWB numbers via the tracking_numbers parameter. Numbers can be separated by commas or spaces, so a single request like 290019498498, 290019498499 is valid. The response returns a shipments array containing tracking results for each valid number found, a total_found integer reflecting how many shipments were matched, and a tracking_numbers array echoing back the queried values for easy reconciliation on your end.
Language Support
The optional language parameter accepts EN, AR, or FR, controlling the language of status descriptions and any human-readable fields in the response. This is useful for applications serving Arabic-speaking markets in Saudi Arabia and the Gulf region, where SMSA Express primarily operates.
Response Shape and Coverage
When tracking numbers are valid and found, each entry in the shipments array carries shipment status and tracking details for that AWB. If no shipments are located — for example, if a tracking number is invalid or not yet in the system — the shipments array returns empty and total_found is 0. There is no partial-failure envelope; all matched results appear together in a single response.
The SMSA Express API is a managed, monitored endpoint for smsaexpress.com — not a raw scraper you maintain. Every endpoint is automatically health-checked on a schedule, and when smsaexpress.com changes and a check fails, the API is automatically queued for repair and re-verified. It is built to keep working as the site underneath it changes.
This isn't an official smsaexpress.com API — it's an independent, maintained REST wrapper over public data. Where the source has no official API (or only a limited one), Parse gives you a stable contract over a source that never promised one, and keeps it current. Need a new endpoint or field? You can revise it yourself in plain English and the agent rebuilds it against the live site in minutes — contributing the change back to the shared API is free.
Will this API break when the source site changes?+
Is this an official API from the source site?+
Can I fix or extend this API myself if I need a new endpoint or field?+
What happens if I call an endpoint that has an issue?+
- Automate post-purchase delivery notifications by polling
track_shipmentwith customer AWB numbers - Build a multi-shipment dashboard that batches AWBs into a single request and maps
total_foundto order fulfillment status - Flag delayed or undelivered shipments by comparing current status fields against expected delivery windows
- Support Arabic-speaking customers by setting
language=ARto return status descriptions in Arabic - Reconcile third-party logistics records against SMSA tracking data using the echoed
tracking_numbersarray in each response - Integrate SMSA Express tracking into an e-commerce order management system to surface shipment status without manual portal lookups
| Tier | Price | Credits/month | Rate limit |
|---|---|---|---|
| Free | $0/mo | 100 | 5 req/min |
| Hobby | $30/mo | 1,000 | 20 req/min |
| Developer | $100/mo | 5,000 | 100 req/min |
One credit = one API call regardless of which marketplace API you call. Exceeding the rate limit returns a 429 response. Authenticate with the X-API-Key header.
Does SMSA Express have an official developer API?+
What does the track_shipment endpoint return when a tracking number is not found?+
shipments array is empty and total_found returns 0. The tracking_numbers field still echoes back whatever values were submitted, so you can identify which numbers failed to resolve.Can I retrieve shipment history or event timelines through this API?+
track_shipment response. Detailed event-by-event movement history (individual scan timestamps and location logs) is not currently a discrete field in the response. You can fork this API on Parse and revise it to surface granular transit event data if your use case requires it.Does the API support tracking numbers from other carriers or only SMSA Express AWBs?+
shipments array. You can fork the API on Parse and revise it to add endpoints for additional carriers if needed.Is there a limit to how many tracking numbers can be submitted in one request?+
tracking_numbers parameter accepts multiple AWBs separated by commas or spaces in a single request. No explicit upper bound on the number of AWBs per call is documented in the endpoint spec; in practice, very large batches may affect response time and completeness.