Viettel Post icon

Viettel Post data API: parcels, COD, lockers

Viettel Media Inc · Transport 4.4 ★

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

  • Viettel Post screenshot 1
  • Viettel Post screenshot 2
  • Viettel Post screenshot 3
  • Viettel Post screenshot 4
  • Viettel Post screenshot 5
  • Viettel Post screenshot 6

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/otp osint

    Sends 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/session osint

    Exchanges 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/me osint

    Returns the signed-in shipper profile used by the account screen.

    Auth: Bearer accessToken from POST /v1/viettelpost/session.

    • CUS_ID
    • fullName
    • phoneNumber
    • email
    • 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/parcels opendata

    Places 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/parcels opendata

    Pages 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}/void opendata

    Cancels 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/quote openfinance

    Quotes 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} opendata

    Hydrates 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/cod openfinance

    Returns 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/bills openfinance

    Pages 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/offices opendata

    Returns 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/places opendata

    Autocomplete 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/pay openbanking

    Starts 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/lockers opendata

    Returns 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

Get a quote