logistics.send_intracity_parcel — Full Intent Specification
INTENT NAMESPACE: logistics
INTENT NAME: send_intracity_parcel
FULL ID: logistics.send_intracity_parcel
VERSION: v1.0.0
STATUS: live
TTBS WEIGHTS: time 0.40 · taste 0.10 · budget 0.30 · safety 0.20
LAST UPDATED: 2026-05-14
Same-city point-A-to-point-B parcel pickup on a bike/auto/mini-truck rider. Distinct from mobility.book_intracity_ride because: (a) the user is not in the vehicle; (b) the cargo identity matters (size/weight/fragility/declared value); (c) the recipient identity matters (OTP-on-handover + ID match); (d) chain-of-custody must be logged at pickup and delivery; (e) certain items are HARD-blocked (cash, gold, narcotics, weapons, hazardous chemicals, livestock).
1. NATURAL LANGUAGE COVERAGE
Classifies IN
- "send documents to office"
- "pickup parcel from home, drop at courier hub"
- "send laptop to repair shop and back"
- "deliver cake to friend's address by 7 pm"
- "Porter for an AC unit move across town"
- "Dunzo a wallet I forgot at home"
- "send these clothes to mom's place"
- "courier intra-city, sensitive document"
- "bike delivery, gift box, fragile"
- "mini-truck same-city, 2 cartons"
Classifies OUT — borderline NO
- "ship parcel to Delhi" →
logistics.send_intercity_parcel - "send to USA" →
logistics.send_international_parcel - "shift my house" →
logistics.book_full_house_move - "move a sofa across town" →
logistics.book_furniture_move - "deliver food from this restaurant" →
food.order_delivery - "I need a cab" →
mobility.book_intracity_ride
MULTI-INTENT TRIGGERS
- "send my forgotten laptop home and book a cab back" →
logistics.send_intracity_parcel+mobility.book_intracity_ride - "Pickup birthday cake and send to friend with a note" →
food.order_cake_or_special+logistics.send_intracity_parcel
2. INPUT — TOMO → PROVIDER
{
"intent": "logistics.send_intracity_parcel",
"intent_version": "v1.0.0",
"request_id": "req_lp_5q2m_2026-05-14T13:20:00Z",
"user_session_id": "anon_user_token_or_uid",
"pickup": {
"address_id": "addr_home_v1",
"lat": 17.4239,
"lng": 78.4738,
"pin": "500032",
"contact_phone_e164": "+91XXXXXXXXXX",
"ready_at_iso": "2026-05-14T13:45:00+05:30"
},
"drop": {
"address_id": "addr_office_v1",
"lat": 17.4435,
"lng": 78.3772,
"pin": "500081",
"contact_phone_e164": "+91XXXXXXXXXX",
"recipient_name": "Anu Rao",
"deliver_by_iso": "2026-05-14T15:00:00+05:30"
},
"cargo": {
"category": "documents",
"size_band": "envelope",
"weight_kg": 0.2,
"declared_value_inr": 5000,
"fragile": false,
"needs_signature": true,
"needs_otp": true
},
"vehicle_preference": "bike",
"vehicle_allowed": ["bike", "auto", "mini_truck"],
"user_constants": {
"preferred_partners": ["Porter", "Dunzo", "Loadshare"],
"saved_pickup": "addr_home_v1"
}
}
Field rules
cargo.categorySTRICT ENUM; banned categories rejected at intake.weight_kgnumeric float;size_bandis a coarser bucket used for vehicle eligibility.declared_value_inrdrives insurance band (and TOMO surfaces if uninsured).deliver_by_isomust be ≥ready_at_iso+ 20 min (minimum routing buffer); elseERR_DEADLINE_TOO_TIGHT.
3. PROVIDER TOOLS
parcel.quote
Returns price + ETA + vehicle assignment estimate.
parcel.create_order
Books the parcel. Returns order_id + tracking URL + rider assignment timeline.
parcel.attach_recipient_otp
Generates a one-time 4-digit OTP, bound to order_id. Rider can't mark delivered without it.
parcel.handover_capture
Rider clicks pickup photo + records cargo intake. TOMO retains photo hash; partner retains photo.
parcel.live_track
Returns last rider GPS + ETA refresh.
parcel.dispute_damage
Opens damage claim against partner insurance. Requires unboxing photo from recipient ≤ 30 min of delivery.
parcel.cancel
Allowed pre-pickup. Post-pickup cancel → return-to-sender flow + ₹X penalty per partner.
4. RESPONSE SHAPE — PROVIDER → TOMO
{
"intent": "logistics.send_intracity_parcel",
"request_id": "req_lp_5q2m_2026-05-14T13:20:00Z",
"options": [
{
"tier": "OK",
"provider": "Dunzo Bike",
"vehicle": "bike",
"price_inr": 89,
"eta_min_pickup": 12,
"eta_min_deliver": 38,
"insurance_included": true,
"insurance_cover_inr": 10000,
"rider_rating_avg": 4.6,
"ttbs_score": 0.74,
"tier_reason": "cheapest, fastest"
},
{
"tier": "GOOD",
"provider": "Porter Bike",
"vehicle": "bike",
"price_inr": 119,
"eta_min_pickup": 10,
"eta_min_deliver": 35,
"insurance_included": true,
"insurance_cover_inr": 25000,
"rider_rating_avg": 4.7,
"background_check_band": "verified",
"ttbs_score": 0.82,
"tier_reason": "verified rider + higher insurance"
},
{
"tier": "GREAT",
"provider": "Porter Auto",
"vehicle": "auto",
"price_inr": 219,
"eta_min_pickup": 8,
"eta_min_deliver": 30,
"insurance_included": true,
"insurance_cover_inr": 50000,
"rider_rating_avg": 4.8,
"background_check_band": "verified_plus_aadhaar",
"cargo_locker_flag": true,
"ttbs_score": 0.88,
"tier_reason": "locker, aadhaar-verified rider, climate-safe"
}
],
"deadline_check": {
"deliver_by_iso": "2026-05-14T15:00:00+05:30",
"best_eta_meets_deadline": true
},
"banned_check": {
"passed": true
}
}
Field rules
insurance_cover_inrMUST be ≥declared_value_inrfor tier to qualify; else surface mismatch warning.background_check_band∈ {unverified,verified,verified_plus_aadhaar}; required ≥verifiedifdeclared_value_inr> ₹25,000.rider_rating_avgis recent-90-day weighted average (not lifetime).
5. CONTROLLED VOCABULARIES
cargo.category
documents · electronics · apparel · food_perishable · food_non_perishable · pharmacy_otc · gift_box · home_goods · other_lawful
cargo.category (BANNED — rejected at intake)
cash · gold_jewellery · narcotics · weapons · flammable_liquid · compressed_gas · radioactive · livestock · human_remains · pharmacy_prescription_controlled
vehicle
bike · auto · mini_truck
size_band
envelope · shoebox · carton_small · carton_medium · carton_large · oversize
background_check_band
unverified · verified · verified_plus_aadhaar
All STRICT ENUM.
6. TTBS DIMENSIONS
TIME (weight 0.40 — dominant)
eta_min_pickup+eta_min_deliver- Buffer against
deliver_by_iso - Rider availability in pickup PIN at request time
- TIME score = 1 − (total_min / deadline_min)
TASTE (weight 0.10)
- Rider rating + repeat-customer band
- App tracking UX
- TASTE score = rating_norm × tracking_quality
BUDGET (weight 0.30)
price_inrratio against best-in-set- Hidden surcharges (rain/peak)
- Cancellation fee transparency
- BUDGET score = 1 − (this_price − best) / best
SAFETY (weight 0.20)
insurance_cover_inr ≥ declared_value_inrbackground_check_bandband- OTP-on-delivery flag honored
- Cargo locker for valuable/fragile
- Chain-of-custody photo capture
- SAFETY score = insurance_fit × bg_band × otp_flag × locker_flag × photo_flag
HARD FILTERS
- Cargo category not in banned list.
- Vehicle capacity ≥ cargo size_band.
insurance_cover_inr ≥ declared_value_inr(or warn + user override).background_check_band ≥ verifiedifdeclared_value_inr > ₹25k.- Best ETA must meet
deliver_by_iso.
7. COMPLETION CONTRACT
Success criteria
- Rider assigned + ETA shared.
- Pickup photo captured + cargo intake confirmed.
- Live tracking active.
- OTP entered by recipient → delivered state.
- Delivery photo captured.
- CPC webhook fires.
CPC webhook (HMAC-SHA256)
{
"event": "logistics.send_intracity_parcel.completed",
"intent_id": "logistics.send_intracity_parcel",
"request_id": "req_lp_5q2m_2026-05-14T13:20:00Z",
"order_id": "LP9KQ72",
"provider": "Porter",
"vehicle": "bike",
"price_inr": 119,
"tomo_commission_base_inr": 24,
"tomo_commission_inr": 2.4,
"pass_through_inr": 95,
"rider_otp_verified": true,
"delivery_photo_hash": "sha256-…",
"completed_at_iso": "2026-05-14T14:51:00+05:30",
"signature_hmac_sha256": "…"
}
tomo_commission_base_inr = Porter's commission slice (net), NOT the ride fare. pass_through_inr = rider payout. Aligns with COMMISSION BASE = NET.
Failure cases
pickup_no_show_user→ cancel fee per partner; surfaced plainly.rider_no_show→ auto-reassign or refund.damage_at_delivery→ recipient files viaparcel.dispute_damage; insurance pays per declared_value.banned_item_detected_at_pickup→ rider refuses, full refund.
8. WIDGET
{
"widget": "ParcelOrderWidget",
"header": {
"route_strip": "Home → Office · 13.4 km",
"deadline_strip": "Deliver by 3:00 PM · 95 min buffer"
},
"regions": {
"region_1_intelligence": ["envelope, 200 g, documents", "₹5,000 declared value", "OTP-on-delivery on"],
"region_2_summary": "Bike pickup at 1:45 PM, delivered by ~2:23 PM",
"region_3_visual": "rider_photo_url (post-assignment, partner-supplied)",
"region_4_now_pin": "Book now — rider 12 min away",
"region_5_tomo_choices": [
{"tier": "OK", "label": "Dunzo · ₹89 · 38 min", "reason": "cheapest"},
{"tier": "GOOD", "label": "Porter · ₹119 · verified rider + ₹25k cover", "reason": "balanced"},
{"tier": "GREAT", "label": "Porter Auto · ₹219 · locker + Aadhaar-verified", "reason": "highest safety"}
]
},
"footer_disclosures": [
"Banned items (cash, gold, narcotics, weapons) will be refused at pickup.",
"Insurance pays up to declared value — keep the unboxing photo if damaged.",
"OTP is mandatory on delivery — recipient won't get the parcel without it."
]
}
9. CACHING POLICY
- Quote: 60s TTL on-device.
- Rider rating + bg band: provider-fresh per quote.
- Past parcels (read-only ledger): 90 days on-device, encrypted.
- Pickup photo / delivery photo: hash only on TOMO; full image at partner.
- Banned-list ENUM: shipped client-side, refreshed on app update.
10. ERROR CODES
| Code | Meaning | UI surface |
|---|---|---|
ERR_BANNED_CATEGORY |
category in banned list | Plain blocker + alternatives |
ERR_DEADLINE_TOO_TIGHT |
ETA cannot meet deliver_by_iso |
Suggest extension |
ERR_INSURANCE_GAP |
cover < declared_value | Warn + ask user to accept or upgrade |
ERR_BG_BAND_TOO_LOW |
bg band insufficient for value | Upgrade tier suggested |
ERR_VEHICLE_CAPACITY |
size_band > vehicle | Re-route to larger vehicle |
ERR_RIDER_NO_SHOW |
rider didn't arrive | Auto-reassign + apology + refund partial |
ERR_DELIVERY_OTP_FAILED |
recipient OTP wrong 3 times | Partner support takeover |
ERR_PICKUP_ADDRESS_UNRESOLVED |
pickup not geocoded | Re-prompt |
ERR_BANNED_AT_PICKUP |
rider visually flagged banned item | Refuse + refund |
ERR_PARTNER_OFFLINE |
partner API down | Try next partner |
11. SANDBOX → PRODUCTION CHECKLIST
- Sandbox banned-category list rejects every banned ENUM.
- Sandbox
parcel.quoteETAs vary by time-of-day realistically. - Sandbox OTP-on-delivery cycle tested.
- Sandbox damage-dispute flow generates insurance claim ID.
- Sandbox rider no-show triggers auto-reassign within 5 min.
- Sandbox CPC webhook HMAC-SHA256 verified.
- Production rider background-check band sourced from partner — no TOMO inference.
- Production insurance contract per partner attested in legal.
- Production rate-limit: 20 parcels/user/day.
- Production cargo-photo retention policy at partner ≥ 30 days for dispute window.
- Production multi-partner rotation tested for high-demand PINs.
12. ANTI-FABRICATION RULES
- NO
paid_placementon partner ranking — TTBS-deterministic. - NO synthetic rider photos — partner-supplied only after assignment.
- NO fake insurance claims ("up to ₹50,000 cover") unless
insurance_cover_inris explicit per option. - NO "fastest in the city" marketing — only ETAs from partner quotes.
- NO bundling promo with parcel price.
- NO concealing surge — surge displayed explicitly.
- NO claiming OTP delivery when partner doesn't enforce it.
- NO holding cargo state in TOMO — partner is custodian.
- NO TOMO-issued "safe delivery guaranteed" — TOMO is router; partner + insurance carry liability.
- NO marketing language like "smart logistics".
13. REGULATORY FRAMING
- Carriage by Road Act 2007 + Rules 2011 govern intra-city goods carriage operators.
- MoRTH / state RTO registers vehicle as goods carrier (auto/mini-truck/bike with goods permit).
- Consumer Protection Act 2019 — partner is "service provider"; TOMO is "service intermediary" with disclosed routing role.
- IT Act 2000 + DPDPA 2023 — addresses, phone, recipient name are personal data; TOMO holds pointer + cache; partner is processor.
- Insurance Act 1938 / IRDAI — partner insurance is between partner's insurer and user; TOMO surfaces cover.
- TOMO does NOT hold custody, does NOT operate vehicles, does NOT issue insurance — pure routing surface.