API endpoints

The storefront talks to everything through its own hostname; CloudFront maps path prefixes onto API Gateways. Always call the relative path so the request stays inside its environment.

Pricing and coupons on dev

PathOrigin APIService
/api/calculatePrice/calculateCost2vn0mqj906dcalculatecost2 dev
/api/calculatePrice/getCostvn0mqj906dsame
/api/calculatePrice/suggestCoupon410u70d13mlegacy — auto-apply suggestions
/api/calculatePrice/getShipping410u70d13mlegacy
/api/coupon2/couponCheckerqe1hv09c68villacoupon3 dev
/api/polygon/getPolygonCost4x2xz1tybjPolygonCost — Regular vs Nationwide

/api/calculatePrice/* is a catch-all pointing at the 2021 calculator. Any new endpoint under that prefix silently lands there until a more specific CloudFront behavior is added.

Auth

Authorization: Bearer <apikey> on /api/*. An apikey: header is rejected. Keys come from get-apikey-master and last five hours — see run-coupon-test-matrix.

Response shapes worth knowing

PolygonCost (4x2xz1tybj) — what the checkout code expects:

{"success": true, "top5": [{"br_code": 1046, "store_name": "Sukhumvit 11", "cost": 90.0,
                            "dist": 0.292, "eligible_to_shop_at_33": true}]}

shipping-cost (km797c84si) — a newer service with an incompatible shape. Nothing consumes it correctly today; pointing the frontend at it caused 2026-07-29-shipping-forced-nationwide:

{"eligible_branches": [{"code": "1046", "distance_km": 0.76, "delivery_cost": 11.43}],
 "ineligible_count": 0}

calculatecost2 — see discount-fields for the discount fields and the balance identity.

Calling the Lambda directly

Bypasses CloudFront auth, useful when isolating whether a problem is routing or logic. It expects an API Gateway proxy event, so a raw payload fails to parse:

event = {'body': json.dumps(payload), 'headers': {'Content-Type': 'application/json'},
         'requestContext': {}, 'httpMethod': 'POST', 'path': '/Prod/calculatecost3'}
boto3.client('lambda', region_name='ap-southeast-1') \
     .invoke(FunctionName='calculate-cost-3-dev', Payload=json.dumps(event).encode())