HVMExpress Gateway API v1
Use the Gateway API to register products, create packages, list and track deliveries, and calculate delivery fees. All endpoints require merchant authentication via HTTP headers.
https://<base-url>/api/v1/gatewayContent-Type:
application/json (request and response)Getting access: Base URL, API keys, and merchant IDs are provided upon request. Contact the IT team and support to obtain access.
1. Authentication
All gateway endpoints require merchant authentication via HTTP headers.
Required headers
| Header | Type | Required | Description |
|---|---|---|---|
HVMX-MERCHANT-ID | string | Yes | Your merchant identifier (provided when API access is enabled). |
HVMX-API-KEY | string | Yes | Your API key (secret). |
Content-Type | string | Yes for POST | application/json for request bodies. |
Unauthorized response (401)
When authentication fails, the response body includes a machine-readable error code:
| HTTP Status | Body field | Type | Description |
|---|---|---|---|
| 401 | status | number | 0 |
| 401 | error | string | One of: missing_merchant_id, missing_api_key, invalid_credentials, environment_not_allowed, environment_mismatch |
| 401 | message | string | Human-readable message (e.g. "Unauthorized") |
Example (missing API key):
{
"status": 0,
"error": "missing_api_key",
"message": "Unauthorized"
}
2. Common response format
Success
- status:
number—1for success - message:
string— Short description - data:
objectorarray— Response payload (structure depends on endpoint)
Error (business logic / validation)
- status:
number—0for failure - message:
string— Error description - log_id:
string— (Present only on error responses) Unique log ID (e.g.HVM+ 10 hex characters) for support/debugging. Use this in the Developer Dashboard “Search Logs” to find the request.
3. Error responses & log ID
All gateway requests are logged. When the API returns an error (status: 0), the response body includes log_id so you can trace the request in the HVMExpress Developer Dashboard (Search Logs by Log ID).
Example error response with log_id:
{
"status": 0,
"message": "custom_package_id already exists for this vendor",
"log_id": "HVM1A2B3C4D5E"
}
4. Products API
Base path: /api/v1/gateway/products
4.1 Create product
POST /api/v1/gateway/products/create
Register a new product for your vendor. The product is created with status pending (requires admin approval before it can be used in packages).
Request
Headers: HVMX-MERCHANT-ID, HVMX-API-KEY, Content-Type: application/json
Body:
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Product name. Must be unique per vendor. |
weight | number | Yes | Weight in kg. Can be 0. |
price | number | Yes | Unit price. Must be >= 0. |
description | string | No | Product description. |
product_type_id | number | Yes | ID of an active product type (from Get Product Types). |
dimension_width | number | No | Width. Default 0. |
dimension_height | number | No | Height. Default 0. |
dimension_length | number | No | Length. Default 0. |
Example request body:
{
"name": "Cotton Crew Neck T-Shirt",
"weight": 0.3,
"price": 2499,
"description": "Soft cotton, regular fit. Available in multiple sizes.",
"product_type_id": 1,
"dimension_width": 25,
"dimension_height": 2,
"dimension_length": 35
}
Success (201 Created): status: 1, message, data with created product (id, name, weight, price, description, product_type_id, dimensions, flag: 2 = pending, created_at).
Error (400): status: 0, message describes the issue. Response may include log_id.
4.2 Get product types
GET /api/v1/gateway/products/types
Returns the list of active product types (for dropdowns and when creating products).
Headers: HVMX-MERCHANT-ID, HVMX-API-KEY. Body: None.
Success (200): status: 1, data = array of { "id": number, "name": string }.
{
"status": 1,
"message": "OK",
"data": [
{ "id": 1, "name": "Apparel" },
{ "id": 2, "name": "Accessories" }
]
}
5. Packages API
Base path: /api/v1/gateway/packages
Packages are delivery consignments. Only packages with create_type = ecommerce_api are returned by list and details. Status in responses is normalized to: pending | completed | cancelled | returned | moving.
5.1 Create package
POST /api/v1/gateway/packages/create
Create a new package. The package is created in status ready for pickup and a first journey step is recorded. Delivery route is resolved from the receiver address.
Request body
| Field | Type | Required | Description |
|---|---|---|---|
weight | number | Yes | Package weight in kg. Must be > 0. |
price | number | Yes | Package value/price. Must be >= 0. |
receiver_name | string | Yes | Recipient name. |
receiver_phone | string | Yes | Recipient phone. |
receiver_address | string | Yes | Full delivery address (used for route lookup). Must be in a serviced area. |
collection_type | string | Yes | Who pays what at delivery. See options below. |
custom_package_id | string | Yes | Your unique reference per vendor. Must be unique for the vendor. |
products | array | No | Line items: { "product_id": number, "quantity": number }. Only approved (flag=1) products allowed. |
collection_type — what is collected at delivery
Choose how much the customer pays when the package is delivered:
| Value | Meaning |
|---|---|
delivery_fee_with_package_price | Collecting both the package price and the delivery fee from the customer at delivery. |
delivery_fee_only | Collecting only the delivery fee from the customer at delivery (package price is already paid). |
delivery_only | Collecting nothing from the customer at delivery (both package price and delivery fee are already paid). |
Example request body:
{
"weight": 1.2,
"price": 8500,
"receiver_name": "Nadeera Fernando",
"receiver_phone": "+94112345678",
"receiver_address": "45 Galle Road, Colombo 03",
"collection_type": "delivery_fee_with_package_price",
"custom_package_id": "SHOP-2024-1847",
"products": [
{ "product_id": 10, "quantity": 2 },
{ "product_id": 11, "quantity": 1 }
]
}
Success (201): data = package object (same shape as Package Details). Error (400): e.g. duplicate custom_package_id, invalid address; may include log_id.
5.2 List packages
GET /api/v1/gateway/packages/list/:page
List packages for the authenticated vendor (ecommerce_api only). Paginated, 100 per page.
URL parameters: page — Page number (1-based). Example: GET /api/v1/gateway/packages/list/1
Success (200): data.packages = array of Package objects; data.pagination = { page, per_page, total, total_pages }.
{
"status": 1,
"message": "OK",
"data": {
"packages": [
{
"id": 1,
"package_id": "D1C2ABC123",
"custom_package_id": "SHOP-2024-1847",
"package_status": "pending",
"weight": 1.2,
"price": 8500,
"delivery_fee": 250,
"total_price": 8750,
"collection_type": "delivery_fee_with_package_price",
"receiver_name": "Nadeera Fernando",
"receiver_phone": "+94112345678",
"receiver_address": "45 Galle Road, Colombo 03",
"delivery_date": "",
"created_at": "2024-02-28T10:30:00.000Z",
"products": [
{ "product_id": 10, "product_name": "Cotton T-Shirt (Blue)", "total_price": 5000 },
{ "product_id": 11, "product_name": "Denim Jacket", "total_price": 3500 }
]
}
],
"pagination": {
"page": 1,
"per_page": 100,
"total": 1,
"total_pages": 1
}
}
}
5.3 Get package details
POST /api/v1/gateway/packages/details
Get a single package by its package_id (system-generated, e.g. D1C2ABC123). Only packages belonging to the vendor and with create_type = ecommerce_api are returned.
Body: { "package_id": "D1C2ABC123" }
Success (200): data = Package object. Not found (404): status: 0, message: "Package not found".
5.4 Get delivery fee
POST /api/v1/gateway/packages/delivery-fee
Calculate delivery fee by city name and weight. Uses the same pricing slab logic as package creation. If city is not found, Colombo rates are applied and city_status reflects that.
Body: city (optional, string), weight (required, number > 0). Example: { "city": "Colombo", "weight": 1.2 }
Success (200): data = { delivery_fee, recognized_city, city_status, weight }.
{
"status": 1,
"message": "City recognized successfully.",
"data": {
"delivery_fee": 250,
"recognized_city": "Colombo",
"city_status": "City recognized successfully.",
"weight": 1.2
}
}
Package object
Used in Create Package response, List Packages (data.packages[]), and Get Package Details (data).
| Field | Type | Description |
|---|---|---|
id | number | Internal package ID. |
package_id | string | System-generated ID (e.g. D1C2ABC123). Use for Get Package Details. |
custom_package_id | string | Your reference (unique per vendor). |
package_status | string | pending | completed | cancelled | returned | moving. |
weight | number | Weight (kg). |
price | number | Package value. |
delivery_fee | number | Delivery fee. |
total_price | number | Total (depends on collection_type). |
collection_type | string | What is collected at delivery: delivery_fee_with_package_price (both), delivery_fee_only (fee only), or delivery_only (nothing). |
receiver_name | string | Recipient name. |
receiver_phone | string | Recipient phone. |
receiver_address | string | Delivery address. |
delivery_date | string | Delivery date when set; empty until delivered/scheduled. |
created_at | string | ISO 8601 UTC. |
products | array | Line items: product_id, product_name, total_price. |
Summary
| Method | Endpoint | Description |
|---|---|---|
| POST | /api/v1/gateway/products/create | Create product (pending approval). |
| GET | /api/v1/gateway/products/types | List product types. |
| POST | /api/v1/gateway/packages/create | Create package. |
| GET | /api/v1/gateway/packages/list/:page | List packages (paginated). |
| POST | /api/v1/gateway/packages/details | Get package by package_id. |
| POST | /api/v1/gateway/packages/delivery-fee | Get delivery fee by city and weight. |
All requests require headers HVMX-MERCHANT-ID and HVMX-API-KEY. POST bodies must be application/json. Error responses use status: 0 and include message; error responses also include log_id for tracing in the Developer Dashboard.