REST API v1.0 • Enterprise Core

AsanShipping Developer Documentation

Seamlessly connect custom storefronts, ERPs, and mobile applications to AsanShipping catalog, authoritative inventory, canonical order ingestion, automated courier tracking, and real-time webhook events.

Architecture

Overview & Architecture

The AsanShipping Developer API is a high-throughput, multi-tenant RESTful API. It is designed to act as the single source of truth for your e-commerce operations across Pakistan.

Tenant Data Isolation

Every API key is bound cryptographically to a single merchant organization. Cross-tenant access is strictly prohibited at the database engine level.

Sub-100ms Latency

Optimized indexing on MongoDB clusters, Redis caching layers, and high-performance routing ensure instantaneous order creation and inventory syncing.

Idempotency Guarantee

Network dropouts and automated retries never cause duplicate orders or phantom inventory deductions thanks to 24-hour idempotent transaction caching.

Base URLs

EnvironmentBase URLPurpose
Live Productionhttps://merchant-api.asanshipping.com/api/v1Production store integrations & live order processing
Local / Sandboxhttp://localhost:5000/api/v1Local staging, CI/CD pipelines & test suites
Security

Authentication & Granular Scopes

All requests to the Developer API must be authenticated with an API key. You can pass the key in two ways:

Option 1: Bearer Token (Recommended)
Authorization: Bearer as_live_79a2f10b...
Option 2: Custom Header
X-API-Key: as_live_79a2f10b...

Supported Key Prefixes

as_live_...

Live production secret key for backend server integrations.

as_test_...

Sandbox test key for staging environments and mock suites.

store_live_...

Public storefront key restricted to read-only catalog queries.

Granular Permission Scopes

Scope IdentifierPermission & Capabilities
products:readView catalog products, variant details, pricing, and image URLs.
products:writeCreate, update, archive products, and upload WebP images to Backblaze B2.
inventory:readAccess real-time inventory ledger quantities and warehouse stock balances.
inventory:writeSubmit authoritative stock adjustments (restocks, write-offs) and warehouse transfers.
orders:readQuery canonical order records, customer details, consignments, and tracking.
orders:writeCreate canonical customer orders with automated destination validation and phone normalization.
orders:cancelCancel pending or unbooked orders and trigger automatic inventory restocks.
tracking:readFetch public and authenticated shipment tracking milestones and carrier progress.
locations:readAccess all available Pakistani delivery cities, provinces, tiers, and sub-areas.
tools:executeIntelligently parse unstructured single or bulk address strings to extract phone numbers, cities, and sub-areas.
webhooks:manageRegister, update, delete webhook subscriptions, dispatch tests, and inspect audit logs.
Reliability

Idempotency Protocol

The AsanShipping API supports idempotent mutations using the Idempotency-Key HTTP header on POST /orders, POST /inventory/adjustments, and POST /products.

How Idempotency Works:
  1. Generate a unique UUIDv4 string on your client (e.g. b84c8491-03fc-4b57-a384-93e1b00e3182) representing the transaction.
  2. Pass this string in the Idempotency-Key header of your request.
  3. If the request succeeds, AsanShipping stores the full status code and response payload for 24 hours.
  4. If network failure causes your client to retry the request with the identical key, AsanShipping returns the cached response with the header X-Cache-Lookup: IDEMPOTENT_HIT without executing any database mutations a second time.
Throttling & Errors

Rate Limits & Unified Error Protocol

Live Production Rate Limit

120 req / min

Burst tolerance of 30 concurrent calls. Monitored per merchant account.

Test Sandbox Rate Limit

60 req / min

Burst tolerance of 15 concurrent calls for staging environments.

Standardized Error Response Body

{
  "success": false,
  "error": {
    "code": "INSUFFICIENT_STOCK",
    "message": "Requested quantity (5) exceeds available stock (2) for SKU 'TS-BLK-M'",
    "details": { "sku": "TS-BLK-M", "requested": 5, "available": 2 },
    "timestamp": "2026-09-26T14:00:00.000Z"
  },
  "meta": {
    "requestId": "req_01J8EF89X...",
    "documentation": "https://asanshipping.com/developers#rate-limits"
  }
}

Error Code Catalog

StatusError CodeDescription
401UNAUTHORIZEDMissing, expired, or malformed API Key or Bearer token.
403FORBIDDEN_INSUFFICIENT_SCOPEThe provided API key does not have the required permission scope for this action.
400INVALID_IDEMPOTENCY_KEYMissing, malformed, or previously mismatched Idempotency-Key header.
409IDEMPOTENCY_PAYLOAD_MISMATCHA request with this Idempotency-Key was already executed with different parameters.
429RATE_LIMIT_EXCEEDEDExceeded the allowed requests per minute (120 req/min Live, 60 req/min Test). Check Retry-After header.
400VALIDATION_ERROROne or more request parameters failed schema validation (e.g. invalid phone or negative price).
422INSUFFICIENT_STOCKRequested item quantity exceeds authoritative available ledger balance.
400ORDER_ALREADY_DISPATCHEDCannot cancel or modify an order that has already been booked or dispatched with a courier.
404RESOURCE_NOT_FOUNDThe requested product, order, transfer, or webhook ID does not exist for this merchant.
401WEBHOOK_VERIFICATION_FAILEDThe HMAC-SHA256 signature mismatch on an inbound webhook payload.
Resource Domain

Store Profile

Endpoints to inspect the active merchant profile, operational currency, timezone, and configured warehouse fulfillment locations.

GET
store:read / any valid key

Get Store Profile

Retrieve store identity, default currency (PKR), timezone, operational environment, and configured warehouse facilities.

Request Specifications & Parameters

Request Headers

Header NameTypeDescription
Authorization *stringBearer <YOUR_API_KEY>
Code Snippets & Live Response Payloads
1curl -X GET "https://merchant-api.asanshipping.com/api/v1/store" \
2 -H "Authorization: Bearer as_live_YOUR_KEY" \
3 -H "Accept: application/json"
Resource Domain

Catalog & Products

Manage catalog items, multi-variant SKUs, pricing, barcode attributes, and upload WebP images backed by Backblaze B2 object storage.

GET
products:read

List Products

Retrieve a paginated, filterable list of catalog products with variant stock and media URLs.

Request Specifications & Parameters

Query Parameters

ParameterTypeDescription
page integerPage number (default: 1)
limit integerRecords per page (1-100, default: 25)
search stringSearch by title or SKU
sku stringFilter by exact SKU
status stringProduct status: active | draft | archived
stockStatus stringStock filter: IN_STOCK | OUT_OF_STOCK
updatedSince string (ISO)Fetch only products modified after timestamp
Code Snippets & Live Response Payloads
1curl -X GET "https://merchant-api.asanshipping.com/api/v1/products?limit=10&status=active" \
2 -H "Authorization: Bearer as_live_YOUR_KEY"
POST
products:writeIdempotent

Create Product

Add a new product with variant definitions, initial inventory allocation, and dimensional weight metrics.

Request Specifications & Parameters

Request Headers

Header NameTypeDescription
Idempotency-Key *string (UUIDv4)Unique key preventing duplicate creations
Content-Type *stringapplication/json

Request Body Schema

FieldTypeDescription
sku *stringUnique stock keeping unit
title *stringProduct display title
price *numberRetail selling price in PKR
compareAtPrice numberOriginal strike-through price
costPrice numberInternal unit cost for margin analytics
weightGrams *integerParcel weight in grams (used for freight calculations)
inventory *object{ warehouseId: string, quantity: number }
Code Snippets & Live Response Payloads
1curl -X POST "https://merchant-api.asanshipping.com/api/v1/products" \
2 -H "Authorization: Bearer as_live_YOUR_KEY" \
3 -H "Idempotency-Key: $(uuidgen)" \
4 -H "Content-Type: application/json" \
5 -d '{
6 "sku": "HD-EMR-XL",
7 "title": "Emerald Heavyweight Hoodie",
8 "price": 4999,
9 "weightGrams": 650,
10 "inventory": { "warehouseId": "wh-khi-01", "quantity": 40 }
11 }'
POST
products:write

Upload Product Image

Upload a JPG/PNG/WebP image (up to 10MB). The server automatically compresses and optimizes the file to high-density WebP and stores it on Backblaze B2.

Request Specifications & Parameters

Request Headers

Header NameTypeDescription
Content-Type *stringmultipart/form-data

Path Parameters

ParameterTypeDescription
id *stringProduct MongoDB ID or SKU
Code Snippets & Live Response Payloads
1curl -X POST "https://merchant-api.asanshipping.com/api/v1/products/prod_01J8B1/images" \
2 -H "Authorization: Bearer as_live_YOUR_KEY" \
3 -F "image=@/path/to/hoodie-front.jpg"
Resource Domain

Authoritative Inventory Ledger

Multi-node warehouse stock synchronization. Perform atomic adjustments (restocks, cycle counts, damage writes) and cross-warehouse transfers with full audit logging.

GET
inventory:read

Query Inventory Ledger

Retrieve real-time available, reserved, and incoming stock balances grouped by warehouse and SKU.

Request Specifications & Parameters

Query Parameters

ParameterTypeDescription
sku stringFilter by exact SKU
warehouseId stringFilter by warehouse node
lowStockOnly booleanFilter items below reorder threshold
Code Snippets & Live Response Payloads
1curl -X GET "https://merchant-api.asanshipping.com/api/v1/inventory?warehouseId=wh-khi-01" \
2 -H "Authorization: Bearer as_live_YOUR_KEY"
POST
inventory:writeIdempotent

Adjust Stock Ledger

Submit an atomic delta change to a SKU stock ledger (e.g. +50 for inbound supplier restock, -2 for transit damage).

Request Specifications & Parameters

Request Body Schema

FieldTypeDescription
sku *stringProduct SKU
warehouseId *stringTarget warehouse node
quantityDelta *integerPositive or negative integer delta
reason *stringRESTOCK | CYCLE_COUNT | DAMAGE | RETURN | AUDIT
referenceId stringSupplier PO or Inspection Ticket ID
Code Snippets & Live Response Payloads
1curl -X POST "https://merchant-api.asanshipping.com/api/v1/inventory/adjustments" \
2 -H "Authorization: Bearer as_live_YOUR_KEY" \
3 -H "Idempotency-Key: $(uuidgen)" \
4 -H "Content-Type: application/json" \
5 -d '{
6 "sku": "TS-BLK-M",
7 "warehouseId": "wh-khi-01",
8 "quantityDelta": 25,
9 "reason": "RESTOCK"
10 }'
Resource Domain

Canonical Orders & Idempotency

Ingest e-commerce orders, validate recipient delivery addresses, reserve stock atomically, and execute order cancellations with automatic stock restoration.

POST
orders:writeIdempotent

Create Canonical Order

Submit a new customer order. Automatically validates destination city & subarea against AsanShipping directory, normalizes Pakistani mobile numbers to E.164 (+92), calculates order totals, reserves inventory, and logs an idempotent transaction.

Request Specifications & Parameters

Request Headers

Header NameTypeDescription
Idempotency-Key *string (UUIDv4)Unique idempotency key (e.g. checkout session or cart ID)
Content-Type *stringapplication/json

Request Body Schema

FieldTypeDescription
orderNumber *stringStorefront unique order identifier
customer *object{ name, phone (03xx / +92), email }
shippingAddress *object{ address1, city, subarea, postalCode }
items *arrayArray of [{ sku, quantity, unitPrice }]
paymentMethod *stringCOD | PREPAID
shippingFee numberFreight charged to customer
Code Snippets & Live Response Payloads
1curl -X POST "https://merchant-api.asanshipping.com/api/v1/orders" \
2 -H "Authorization: Bearer as_live_YOUR_KEY" \
3 -H "Idempotency-Key: ord-idem-773a-44e" \
4 -H "Content-Type: application/json" \
5 -d '{
6 "orderNumber": "WEB-2026-9041",
7 "customer": {
8 "name": "Bilal Ahmed",
9 "phone": "03001234567"
10 },
11 "shippingAddress": {
12 "address1": "House 42, Street 5, DHA Phase 6",
13 "city": "Lahore"
14 },
15 "items": [
16 { "sku": "TS-BLK-M", "quantity": 2, "unitPrice": 2499 }
17 ],
18 "paymentMethod": "COD",
19 "totalAmount": 5248
20 }'
POST
orders:cancel

Cancel Order

Cancel an unbooked order and immediately return reserved line item stock back to the warehouse ledger balance.

Request Specifications & Parameters

Path Parameters

ParameterTypeDescription
id *stringOrder ID or orderNumber

Request Body Schema

FieldTypeDescription
reason *stringCUSTOMER_REQUEST | FRAUD_SUSPECT | OUT_OF_STOCK | DUPLICATE
restockInventory booleanWhether to return reserved items to available inventory (default: true)
Code Snippets & Live Response Payloads
1curl -X POST "https://merchant-api.asanshipping.com/api/v1/orders/ord_01J8C8/cancel" \
2 -H "Authorization: Bearer as_live_YOUR_KEY" \
3 -H "Content-Type: application/json" \
4 -d '{ "reason": "CUSTOMER_REQUEST", "restockInventory": true }'
Resource Domain

Public Tracking

Public and customer-facing shipment status lookup. Provides courier journey milestones, delivery timestamps, and real-time COD collection state.

GET
tracking:read / Public

Get Tracking Milestones

Fetch the chronological courier milestone timeline, courier dispatch info, and current delivery state for a tracking number.

Request Specifications & Parameters

Path Parameters

ParameterTypeDescription
trackingNumber *stringAsanTracking number or courier CN
Code Snippets & Live Response Payloads
1curl -X GET "https://merchant-api.asanshipping.com/api/v1/tracking/ASN-PK-8921849" \
2 -H "Authorization: Bearer as_live_YOUR_KEY"
Resource Domain

Delivery Locations & Cities

Access verified delivery cities, provinces, logistics tiers, and sub-area coverage zones across Pakistan. Ideal for populating checkout city dropdowns, calculating transit times, and validating delivery availability.

GET
locations:read / Storefront

Get All Delivery Cities & Areas

Retrieve a complete list of delivery cities with optional search queries, province filtering, and sub-area sector listings.

Request Specifications & Parameters

Query Parameters

ParameterTypeDescription
search stringFilter cities by name or partial string (case-insensitive)
province stringFilter cities by province (e.g. Punjab, Sindh, KPK, Balochistan, ICT)
includeAreas booleanWhether to include detailed sub-areas and sectors (default: true)
page numberPage number for paginated results (default: 1)
limit numberMaximum cities to return per page (default: 1000, max: 2000)
Code Snippets & Live Response Payloads
1curl -X GET "https://merchant-api.asanshipping.com/api/v1/locations/cities?province=Punjab&search=lahore" \
2 -H "Authorization: Bearer as_live_YOUR_KEY"
Resource Domain

Address & Phone Reader Tool

Intelligent AI & rule-based parser that ingests raw, messy, or unstructured customer text (e.g. from WhatsApp, Instagram DMs, checkout textareas, or CSV spreadsheets) and automatically extracts normalized Pakistani phone numbers (+923...), standardized delivery cities, sub-areas, and clean street addresses with confidence scoring. Supports single strings and high-speed bulk arrays (up to 100 items per request).

POST
tools:execute / orders:write

Intelligent Address & Phone Parser (Single / Bulk)

Parse a single raw address string or a batch array of address strings into structured delivery parameters.

Request Specifications & Parameters

Request Body Schema

FieldTypeDescription
text string | string[]Raw address string (for single mode) or array of raw address strings (for batch mode)
addresses string[]Alternative array of raw address strings for batch parsing (max 100 per request)
Code Snippets & Live Response Payloads
1curl -X POST "https://merchant-api.asanshipping.com/api/v1/tools/parse-address" \
2 -H "Authorization: Bearer as_live_YOUR_KEY" \
3 -H "Content-Type: application/json" \
4 -d '{
5 "addresses": [
6 "Ali Khan, 0300-1234567, Flat 4B, Johar Town, lhr",
7 "Fatima Tariq, +923219876543, House 12, Gulshan-e-Iqbal, Karachi"
8 ]
9 }'
Resource Domain

Webhooks & Real-time Events

Receive instant HTTP POST callbacks on your server when orders change state, tracking milestones update, or inventory falls below safety thresholds. Every webhook includes an HMAC-SHA256 signature header for payload verification.

POST
webhooks:manage

Create Webhook Endpoint

Register an HTTPS webhook URL with subscribed topics and custom HMAC secret.

Request Specifications & Parameters

Request Body Schema

FieldTypeDescription
url *string (HTTPS)Your server webhook listener URL
events *arrayList of event names to subscribe to
secret stringCustom HMAC signing secret (auto-generated if omitted)
description stringInternal label for this endpoint
Code Snippets & Live Response Payloads
1curl -X POST "https://merchant-api.asanshipping.com/api/v1/webhooks" \
2 -H "Authorization: Bearer as_live_YOUR_KEY" \
3 -H "Content-Type: application/json" \
4 -d '{
5 "url": "https://myshop.com/api/webhooks/asan",
6 "events": ["order.created", "tracking.milestone_updated"]
7 }'
Event Subscriptions

Webhooks & Signature Verification

AsanShipping delivers real-time notifications via HTTPS POST to your registered webhook URL. Every webhook request contains an X-Asan-Signature header generated using HMAC-SHA256.

Supported Webhook Event Topics

Event TopicTrigger Condition
order.createdFired immediately after an order is accepted into the system.
order.updatedFired when customer details, delivery address, or consignments are updated.
order.cancelledFired when an order is cancelled and items are returned to inventory.
tracking.milestone_updatedFired when courier pushes a new tracking scan (Booked, Transit, Out for Delivery, Delivered, RTO).
inventory.low_stockFired when stock on hand for any SKU drops below its configured reorder safety threshold.

Verifying Webhook Signatures in Node.js

import crypto from 'crypto';

export function verifyAsanWebhook(rawBodyBuffer, signatureHeader, webhookSecret) {
  // signatureHeader format: 'sha256=1727357400.99a818e7f10b2c3d4e5f6a...'
  const parts = signatureHeader.split('.');
  const timestamp = parts[0].replace('sha256=', '');
  const signature = parts[1];

  // Prevent replay attacks (reject payloads older than 5 minutes)
  const fiveMinutesAgo = Math.floor(Date.now() / 1000) - 300;
  if (parseInt(timestamp) < fiveMinutesAgo) {
    throw new Error('Webhook timestamp too old');
  }

  // Compute expected HMAC-SHA256 signature
  const expected = crypto
    .createHmac('sha256', webhookSecret)
    .update(`${timestamp}.${rawBodyBuffer.toString('utf8')}`)
    .digest('hex');

  // Constant-time comparison to prevent timing attacks
  const isValid = crypto.timingSafeEqual(Buffer.from(signature, 'hex'), Buffer.from(expected, 'hex'));
  return isValid;
}

Interactive HMAC-SHA256 Signature Calculator

AsanShipping signs every outbound webhook with X-Asan-Signature: sha256=t.signature

Calculated X-Asan-Signature Header