Viettel Post data API: parcels, COD, lockers
Viettel Post is the official Android client of Viettel Post, the postal and logistics arm of the Viettel Group, published by Viettel Media Inc for Vietnamese households and shop sellers who ship parcels nationwide. After a phone OTP (and optional password or MFA), a sender quotes postage, creates a waybill with cash-on-delivery, tracks the bag, looks up nearby post offices, pays with VTPay, and can rent a smart locker. Viettel Media Inc sits on Floor 4 of The Light Building, Trung Van Ward, Hanoi; the Play listing is rated 4.4 from about 122,000 reviews with 5 million-plus downloads. It is the carrier's own customer app rather than a multi-carrier tracker, sitting next to UPS and Почта России as a national-post client and next to private last-mile apps such as Porter.
Waybill rows carry ORDER_NUMBER, ORDER_STATUS and postage in MONEY_TOTALFEE. The receiver block is RECEIVER_FULLNAME, RECEIVER_PHONE and RECEIVER_ADDRESS; the bag itself has PRODUCT_WEIGHT, PRODUCT_PRICE and PRODUCT_HEIGHT. Cash-on-delivery sits as MONEY_COLLECTION on the COD dashboard, while TRACKINGS rows expose TRANG_THAI. Nearby counters key on postOfficeCode and fullName; a locker rental starts from boxSize.
Marketplace checkouts quote postage then store the returned waybill; 3PL desks watch ORDER_STATUS and TRANG_THAI; shop accountants reconcile MONEY_COLLECTION against VTPay receipts — openData Studio turns that postal loop into callable open data.
Screenshots
API surface
The endpoints and request/response examples below are reconstructed from the app's interface — illustrative, not a live capture.
Send login OTP
POST
/v1/viettelpost/otposintSends the SMS OTP used on the Viettel Post login screen.
Auth: Unauthenticated. Body is phoneNumber. The SMS OTP is later posted to POST /v1/viettelpost/session.
- phoneNumber
- status
- message
POST /v1/viettelpost/otp HTTP/1.1 Content-Type: application/json { "phoneNumber": "0987654321" }{ "status": true, "message": "OTP sent" }Verify OTP for access token
POST
/v1/viettelpost/sessionosintExchanges the SMS OTP for the accessToken that gates later waybill, COD and quote calls.
Auth: Unauthenticated. Body is phoneNumber plus the SMS OTP from POST /v1/viettelpost/otp. The returned accessToken is sent as Authorization: Bearer on later calls; refreshToken renews the session.
- phoneNumber
- OTP
- accessToken
- refreshToken
- CUS_ID
- fullName
POST /v1/viettelpost/session HTTP/1.1 Content-Type: application/json { "phoneNumber": "0987654321", "OTP": "482193" }{ "accessToken": "eyJhbGciOi...", "refreshToken": "rt-9f3a", "CUS_ID": "441021", "fullName": "Nguyen Van A" }Signed-in account profile
GET
/v1/viettelpost/meosintReturns the signed-in shipper profile used by the account screen.
Auth: Bearer accessToken from POST /v1/viettelpost/session.
- CUS_ID
- fullName
- phoneNumber
- GROUPADDRESS_ID
GET /v1/viettelpost/me HTTP/1.1 Authorization: Bearer eyJhbGciOi... Accept: application/json{ "CUS_ID": "441021", "fullName": "Nguyen Van A", "phoneNumber": "0987654321", "email": "[email protected]", "GROUPADDRESS_ID": "ga-12" }Create parcel waybill
POST
/v1/viettelpost/parcelsopendataPlaces a domestic waybill and returns ORDER_NUMBER, ORDER_STATUS, DELIVERY_CODE and MONEY_TOTALFEE.
Auth: Bearer accessToken from POST /v1/viettelpost/session.
- CUS_ID
- GROUPADDRESS_ID
- SENDER_FULLNAME
- SENDER_PHONE
- SENDER_ADDRESS
- RECEIVER_FULLNAME
- RECEIVER_PHONE
- RECEIVER_ADDRESS
- PRODUCT_NAME
- PRODUCT_WEIGHT
- PRODUCT_LENGTH
- PRODUCT_WIDTH
- PRODUCT_HEIGHT
- PRODUCT_PRICE
- MONEY_COLLECTION
- ORDER_NOTE
- ORDER_NUMBER
- ORDER_STATUS
- DELIVERY_CODE
- MONEY_TOTALFEE
POST /v1/viettelpost/parcels HTTP/1.1 Authorization: Bearer eyJhbGciOi... Content-Type: application/json { "CUS_ID": "441021", "GROUPADDRESS_ID": "ga-12", "SENDER_FULLNAME": "Nguyen Van A", "SENDER_PHONE": "0987654321", "SENDER_ADDRESS": "12 Nguyen Trai, Ha Noi", "RECEIVER_FULLNAME": "Tran Thi B", "RECEIVER_PHONE": "0912345678", "RECEIVER_ADDRESS": "88 Le Loi, Da Nang", "PRODUCT_NAME": "Documents", "PRODUCT_WEIGHT": 500, "PRODUCT_LENGTH": 20, "PRODUCT_WIDTH": 15, "PRODUCT_HEIGHT": 10, "PRODUCT_PRICE": 150000, "MONEY_COLLECTION": 250000, "ORDER_NOTE": "Call before delivery" }{ "ORDER_NUMBER": "VTP2401000123", "ORDER_STATUS": "CREATED", "DELIVERY_CODE": "DC-7781", "MONEY_TOTALFEE": 32000, "MONEY_COLLECTION": 250000 }List my waybills
GET
/v1/viettelpost/parcelsopendataPages the signed-in shipper's waybills filtered by ORDER_STATUS.
Auth: Bearer accessToken from POST /v1/viettelpost/session.
- ORDER_STATUS
- items
- ORDER_NUMBER
- RECEIVER_FULLNAME
- RECEIVER_PHONE
- MONEY_COLLECTION
- MONEY_TOTALFEE
GET /v1/viettelpost/parcels?ORDER_STATUS=CREATED HTTP/1.1 Authorization: Bearer eyJhbGciOi... Accept: application/json{ "items": [{ "ORDER_NUMBER": "VTP2401000123", "ORDER_STATUS": "CREATED", "RECEIVER_FULLNAME": "Tran Thi B", "RECEIVER_PHONE": "0912345678", "MONEY_COLLECTION": 250000, "MONEY_TOTALFEE": 32000 }] }Void a waybill
POST
/v1/viettelpost/parcels/{orderNumber}/voidopendataCancels a created waybill and returns the updated ORDER_STATUS.
Auth: Bearer accessToken from POST /v1/viettelpost/session.
- ORDER_NUMBER
- CUS_ID
- ORDER_STATUS
POST /v1/viettelpost/parcels/VTP2401000123/void HTTP/1.1 Authorization: Bearer eyJhbGciOi... Content-Type: application/json { "ORDER_NUMBER": "VTP2401000123", "CUS_ID": "441021" }{ "ORDER_NUMBER": "VTP2401000123", "ORDER_STATUS": "CANCELLED" }Quote postage
POST
/v1/viettelpost/quoteopenfinanceQuotes MONEY_TOTALFEE for a weight, dimensions and COD amount between two provinces.
Auth: Bearer accessToken from POST /v1/viettelpost/session.
- PRODUCT_WEIGHT
- PRODUCT_LENGTH
- PRODUCT_WIDTH
- PRODUCT_HEIGHT
- MONEY_COLLECTION
- sender_provinceId
- receiver_provinceId
- serviceCode
- MONEY_TOTALFEE
POST /v1/viettelpost/quote HTTP/1.1 Authorization: Bearer eyJhbGciOi... Content-Type: application/json { "PRODUCT_WEIGHT": 500, "PRODUCT_LENGTH": 20, "PRODUCT_WIDTH": 15, "PRODUCT_HEIGHT": 10, "MONEY_COLLECTION": 250000, "sender_provinceId": 1, "receiver_provinceId": 48 }{ "serviceCode": "VCN", "MONEY_TOTALFEE": 32000, "MONEY_COLLECTION": 250000 }Track a waybill
GET
/v1/viettelpost/track/{orderNumber}opendataHydrates the tracking timeline: ORDER_STATUS plus TRACKINGS rows with TRANG_THAI.
Auth: Bearer accessToken from POST /v1/viettelpost/session. Guest track-by-number still works with ORDER_NUMBER alone.
- ORDER_NUMBER
- ORDER_STATUS
- TRACKINGS
- TRANG_THAI
- THOI_GIAN
GET /v1/viettelpost/track/VTP2401000123 HTTP/1.1 Authorization: Bearer eyJhbGciOi... Accept: application/json{ "ORDER_NUMBER": "VTP2401000123", "ORDER_STATUS": "TRANSIT", "TRACKINGS": [{ "TRANG_THAI": "Da lay hang", "THOI_GIAN": "2026-10-02T09:14:00" }] }COD dashboard
GET
/v1/viettelpost/codopenfinanceReturns the shipper COD cartouche: MONEY_COLLECTION collected versus MONEY_TOTALFEE charged.
Auth: Bearer accessToken from POST /v1/viettelpost/session.
- CUS_ID
- MONEY_COLLECTION
- MONEY_TOTALFEE
- unpaidBalance
GET /v1/viettelpost/cod HTTP/1.1 Authorization: Bearer eyJhbGciOi... Accept: application/json{ "CUS_ID": "441021", "MONEY_COLLECTION": 1850000, "MONEY_TOTALFEE": 128000, "unpaidBalance": 420000 }COD bill list
GET
/v1/viettelpost/cod/billsopenfinancePages COD settlement bills keyed by billCode and ORDER_NUMBER.
Auth: Bearer accessToken from POST /v1/viettelpost/session.
- items
- ORDER_NUMBER
- billCode
- MONEY_COLLECTION
- ORDER_STATUS
GET /v1/viettelpost/cod/bills HTTP/1.1 Authorization: Bearer eyJhbGciOi... Accept: application/json{ "items": [{ "ORDER_NUMBER": "VTP2401000123", "billCode": "BILL-9001", "MONEY_COLLECTION": 250000, "ORDER_STATUS": "DELIVERED" }] }List post offices
GET
/v1/viettelpost/officesopendataReturns post-office rows (postOfficeCode, fullName, coordinates) filtered by provinceId.
Auth: Bearer accessToken from POST /v1/viettelpost/session.
- provinceId
- items
- postOfficeCode
- fullName
- latitude
- longitude
GET /v1/viettelpost/offices?provinceId=1 HTTP/1.1 Authorization: Bearer eyJhbGciOi... Accept: application/json{ "items": [{ "postOfficeCode": "HN-01", "fullName": "Buu dien Ha Noi 1", "provinceId": 1, "latitude": 21.0285, "longitude": 105.8542 }] }Search addresses
GET
/v1/viettelpost/placesopendataAutocomplete for sender/receiver address: provinceId, districtId, wardId and coordinates.
Auth: Bearer accessToken from POST /v1/viettelpost/session.
- q
- items
- address
- provinceId
- districtId
- wardId
- latitude
- longitude
GET /v1/viettelpost/places?q=12%20Nguyen%20Trai HTTP/1.1 Authorization: Bearer eyJhbGciOi... Accept: application/json{ "items": [{ "address": "12 Nguyen Trai, Thanh Xuan, Ha Noi", "provinceId": 1, "districtId": 6, "wardId": 42, "latitude": 21.0012, "longitude": 105.8198 }] }Start VTPay charge
POST
/v1/viettelpost/payopenbankingStarts a VTPay charge for MONEY_TOTALFEE and returns qrCode plus paymentStatus.
Auth: Bearer accessToken from POST /v1/viettelpost/session.
- ORDER_NUMBER
- MONEY_TOTALFEE
- CUS_ID
- qrCode
- paymentStatus
POST /v1/viettelpost/pay HTTP/1.1 Authorization: Bearer eyJhbGciOi... Content-Type: application/json { "ORDER_NUMBER": "VTP2401000123", "MONEY_TOTALFEE": 32000, "CUS_ID": "441021" }{ "ORDER_NUMBER": "VTP2401000123", "qrCode": "000201010212...", "paymentStatus": "PENDING" }List locker sizes
GET
/v1/viettelpost/lockersopendataReturns smart-locker boxSize rows with dimensions and rental MONEY_TOTALFEE.
Auth: Bearer accessToken from POST /v1/viettelpost/session.
- items
- boxSize
- PRODUCT_LENGTH
- PRODUCT_WIDTH
- PRODUCT_HEIGHT
- MONEY_TOTALFEE
GET /v1/viettelpost/lockers HTTP/1.1 Authorization: Bearer eyJhbGciOi... Accept: application/json{ "items": [{ "boxSize": "M", "PRODUCT_LENGTH": 40, "PRODUCT_WIDTH": 30, "PRODUCT_HEIGHT": 20, "MONEY_TOTALFEE": 15000 }] }
Data categories
- parcel waybills
- COD
- postage quotes
- tracking
- post offices
- addresses
- VTPay
- smart lockers
- auth-sessions
Where teams use this data
Marketplace checkout onto a national carrier
A shop checkout posts POST /v1/viettelpost/quote (PRODUCT_WEIGHT, MONEY_COLLECTION) then POST /v1/viettelpost/parcels and stores the returned ORDER_NUMBER and MONEY_TOTALFEE.
Last-mile exception desk
A 3PL bot pages GET /v1/viettelpost/parcels and GET /v1/viettelpost/track/{orderNumber} so TRANG_THAI and ORDER_STATUS drive pickup / return tickets.
COD settlement into an ERP
A shop accountant reads GET /v1/viettelpost/cod (MONEY_COLLECTION) and GET /v1/viettelpost/cod/bills (billCode) before matching VTPay receipts from POST /v1/viettelpost/pay.
Locker and counter overlay
A map overlay joins GET /v1/viettelpost/offices (postOfficeCode, fullName) with GET /v1/viettelpost/lockers (boxSize) so a seller can pick a drop counter or a rented locker.
Frequently asked questions
How does Viettel Post authenticate API calls?
POST /v1/viettelpost/otp texts an OTP to phoneNumber. POST /v1/viettelpost/session exchanges phoneNumber plus that OTP for accessToken, refreshToken and CUS_ID. Later calls send Authorization: Bearer with that accessToken.
Which endpoints expose waybills, quotes and tracking?
POST /v1/viettelpost/parcels creates a waybill and returns ORDER_NUMBER, ORDER_STATUS, DELIVERY_CODE and MONEY_TOTALFEE. GET /v1/viettelpost/parcels pages those rows. POST /v1/viettelpost/quote returns MONEY_TOTALFEE for a weight and COD amount. GET /v1/viettelpost/track/{orderNumber} hydrates TRACKINGS with TRANG_THAI.
What COD and payment fields are returned?
GET /v1/viettelpost/cod returns MONEY_COLLECTION and MONEY_TOTALFEE. GET /v1/viettelpost/cod/bills lists billCode rows. POST /v1/viettelpost/pay starts a VTPay charge and returns qrCode plus paymentStatus.
Does the API cover post offices and smart lockers?
Yes. GET /v1/viettelpost/offices returns postOfficeCode, fullName, latitude and longitude. GET /v1/viettelpost/places autocompletes provinceId, districtId and wardId. GET /v1/viettelpost/lockers lists boxSize rows with rental MONEY_TOTALFEE.
Apps similar to Viettel Post
- UPS — UPS is an international carrier whose mobile app tracks packages, quotes rates and locates drop-off points — the cross-border analogue of Viettel Post's domestic waybill client.
- Почта России — Pochta Rossii is Russia's national-post customer app: barcode tracking, office maps and postage orders, the same role Viettel Post plays for Vietnam.
- Porter - Logistics Service App — Porter is an intra-city logistics app for businesses that need a van on demand, overlapping Viettel Post's shop-seller shipping audience on a private-fleet model.
- Giao Hàng Nhanh (GHN) — GHN is a major Vietnamese private courier that shop sellers use alongside Viettel Post for domestic parcels and COD.
- J&T Express — J&T Express is a regional parcel network with a large Vietnam footprint, a private-carrier alternative to Viettel Post's national post.
- Vietnam Post (VNPost) — VNPost is Vietnam's state postal operator — the other nationwide counter network next to Viettel Post.
- Ahamove — Ahamove is an on-demand bike and van delivery app in Hanoi and Ho Chi Minh City, covering the same last-mile shop-to-door leg Viettel Post sells as a scheduled parcel.
Topics
- viettel post api
- vietnam parcel api
- ORDER_NUMBER MONEY_COLLECTION
- viettel post COD
- vietnam postage quote
- viettel post tracking
- vietnam post office locator
- VTPay locker api
Need this app's data API integrated?
We deliver scoped integrations for any named app — from USD 500 with source-code handoff, or hosted access billed per call. Tell us the data you need.
- NDA + SOW on every engagement
- Delivery in 3–7 days
- Payment only after acceptance
- Work scoped to authorized use