# SingaNow Full API, JSON Schema & LLM Tool Specification > Complete Machine-Readable API Reference, Formal JSON Response Schemas, Multi-Platform LLM Tool Calling Definitions, and Integration Manual for AI Agents & Developers. This document serves as the comprehensive, authoritative technical specification for the SingaNow real-time API suite. It provides: 1. **Domain Constants & Conventions** (Singapore geographic bounding box, transport codes, UEN formats, PSI/UV rating scales, EV connector standards, traffic camera network). 2. **Exhaustive API Reference** (All 13 endpoints with full query parameter dictionaries, default values, validation constraints, and error codes). 3. **Formal JSON Response Schemas** (RFC Draft 2020-12 / Draft-07 JSON Schema compliant definitions for every endpoint). 4. **Concrete Response Payloads** (Real-world JSON data samples matching the schemas). 5. **Universal LLM Tool Calling Definitions** (Ready-to-use schemas for OpenAI Function Calling, Anthropic Claude Tool Use, and Google Gemini Function Declarations). 6. **Code Snippets & Agent Validation** (Python + Pydantic, TypeScript + Zod, and cURL). - API Base URL: `https://singanow.com/api` - Concise LLM Index: `https://singanow.com/llms.txt` - Interactive Web Documentation: `https://singanow.com/docs` - Default Protocol: HTTPS GET - Authentication: None required for public endpoints - Default Response Format: JSON (`Content-Type: application/json; charset=UTF-8`) - CORS: Enabled globally (`Access-Control-Allow-Origin: *`) - Timezone: `Asia/Singapore` (SGT, UTC+8, ISO-8601 formatted with `+08:00`) --- ## 1. Domain Constants, Conventions & Enums ### 1.1 Geographic Boundary - Country: Singapore (SG) - WGS84 Latitude Range: `1.1500°N` to `1.4800°N` - WGS84 Longitude Range: `103.5800°E` to `104.0500°E` - Central Reference Coordinate (City Hall / Raffles Place): `Lat: 1.2968, Lng: 103.8525` - Out-of-Bounds Behavior: GPS endpoints (`/api/bus/nearby`, `/api/bus/plan`, `/api/carparks`, `/api/ev`) automatically detect requests originating outside Singapore and return a graceful fallback to Central Singapore with `"is_outside_singapore": true`. ### 1.2 Public Bus Transport Codes - **Bus Stop Code**: 5-digit zero-padded string (e.g. `"01012"`, `"09048"`, `"67009"`). Never parse as an integer. - **Bus Service Number**: Alphanumeric string, case-insensitive (e.g. `"10"`, `"65"`, `"190"`, `"960e"`, `"NR1"`). - **Public Transport Operators (PTOs)**: - `SBST`: SBS Transit - `SMRT`: SMRT Buses - `TTS`: Tower Transit Singapore - `GAS`: Go-Ahead Singapore - **Passenger Crowd Load Indicators**: - `SEA` (Seats Available): High availability / Low crowding. - `SDA` (Standing Available): Moderate crowding / Standing room only. - `LSD` (Limited Standing): Heavy crowding / Bus approaching maximum capacity. - **Vehicle Deck Types**: - `SD`: Single Deck Bus - `DD`: Double Deck Bus - `BD`: Bendy / Articulated Bus - **Accessibility**: - `is_wab: true` or `Feature: "WAB"` indicates Wheelchair Accessible Bus with boarding ramp. ### 1.3 ACRA Corporate Registry & UEN Formats - **Businesses registered with ACRA** (9 characters): e.g. `53123456B` (`NNNNNNNNX`) - **Local Companies registered with ACRA** (10 characters): e.g. `201812345A` (`YYYYNNNNNX`) - **Other Entities / LLPs / Societies / Healthcare / Foreign Branches** (10 characters): e.g. `T08LL0001B` (`TyyPQNNNNX`) - Issuing Agencies: `ACRA` (Accounting and Corporate Regulatory Authority), `ROS` (Registry of Societies), `MOH` (Ministry of Health), `MAS` (Monetary Authority of Singapore). - **SSIC Codes**: Singapore Standard Industrial Classification (5-digit numeric codes with official industry descriptions). ### 1.4 Environment & Air Quality Scales - **24-hour PSI (Pollutant Standards Index)**: - `0 - 50`: **Good** (Normal activities) - `51 - 100`: **Moderate** (Normal activities) - `101 - 200`: **Unhealthy** (Reduce prolonged strenuous outdoor activity) - `201 - 300`: **Very Unhealthy** (Avoid strenuous outdoor activity) - `> 300`: **Hazardous** (Stay indoors) - **1-hour PM2.5 Concentrations**: µg/m³ across North, South, East, West, Central. - **UV Index Levels**: - `0 - 2`: **Low** - `3 - 5`: **Moderate** - `6 - 7`: **High** - `8 - 10`: **Very High** - `11+`: **Extreme** ### 1.5 Carpark Agencies & Lot Types - **Agencies**: - `HDB`: Housing & Development Board (Public residential estates and town centres) - `LTA`: Land Transport Authority (Commercial shopping centres, offices, transit hubs) - `URA`: Urban Redevelopment Authority (City centre, commercial district surface lots) - **Lot Types**: - `C`: Cars / Light Vehicles - `Y`: Motorcycles - `H`: Heavy Vehicles / Buses ### 1.6 EV Charging Networks & Power Tiers - **Operators**: - `SP_MOBILITY`: SP Group Mobility (Largest public fast-charging network) - `CDG_ENGIE`: ComfortDelGro ENGIE (Extensive HDB MSCP & mall coverage) - `CHARGE_PLUS`: Charge+ (Commercial & high-density hubs) - `SHELL`: Shell Recharge (Petrol station ultra-rapid DC hubs) - `TESLA`: Tesla Superchargers (Proprietary V3/V4 DC fast charging) - `KEPPEL_VOLT`: Keppel Volt - `TOTALENERGIES`: TotalEnergies - `GO_CITY_ENERGY`: Go by City Energy - **Charging Power Categories**: - `ULTRA_FAST`: ≥ 120 kW DC (up to 250 kW Superchargers) - `FAST_DC`: 50 kW to 100 kW DC - `AC_NORMAL`: 7.4 kW to 43 kW AC (Type 2 standard) - **Connector Types**: - `CCS2`: Combined Charging System 2 (National standard for DC fast charging) - `TYPE2`: Mennekes Type 2 (National standard for AC charging) - `TESLA`: Tesla Proprietary / Supercharger plug ### 1.7 Expressways & Border Checkpoint Cameras - **Expressways**: `PIE`, `CTE`, `AYE`, `BKE`, `ECP`, `SLE`, `KJE`, `TPE`, `MCE`. - **Border Checkpoints**: - `Woodlands Checkpoint / Causeway`: Cameras `2701` (Causeway towards Johor), `2702` (Checkpoint Immigration), `2706` (Mandai Road entrance). - `Tuas Second Link / Checkpoint`: Cameras `4703` (Second Link towards Malaysia), `4713` (Tuas Checkpoint arrival/departure lanes). --- ## 2. API Endpoints: Specifications, Parameters & JSON Schemas ### 2.1 GET /api/bus/arrival Retrieves real-time bus arrival predictions, passenger capacity load levels, wheelchair accessibility, and vehicle deck types for the next 3 arriving buses at any specified Singapore bus stop. #### Query Parameters | Parameter | Type | Required | Default | Description | Example | |---|---|---|---|---|---| | `stop` or `bus_stop_code` | `string` | Yes | — | 5-digit Singapore Bus Stop Code | `"01012"` | | `service` | `string` | No | — | Filter by specific bus service number | `"190"` | | `refresh` | `boolean` | No | `false` | Force live cache invalidation from LTA DataMall feed (`1` or `true`) | `1` | #### Formal JSON Response Schema (Draft 2020-12) ```json { "$schema": "https://json-schema.org/draft/2020-12/schema", "title": "BusArrivalResponse", "type": "object", "required": ["ok", "bus_stop_code", "timestamp", "services", "total_services"], "properties": { "ok": { "type": "boolean" }, "bus_stop_code": { "type": "string", "pattern": "^[0-9]{5}$" }, "stop_info": { "type": ["object", "null"], "properties": { "description": { "type": "string" }, "road_name": { "type": "string" }, "latitude": { "type": "number" }, "longitude": { "type": "number" } }, "required": ["description", "road_name", "latitude", "longitude"] }, "timestamp": { "type": "string", "format": "date-time" }, "services": { "type": "array", "items": { "type": "object", "required": ["service_no", "operator", "has_arrivals", "status", "buses"], "properties": { "service_no": { "type": "string" }, "operator": { "type": "string", "enum": ["SBST", "SMRT", "TTS", "GAS", ""] }, "origin_code": { "type": "string" }, "origin_name": { "type": "string" }, "origin_road": { "type": "string" }, "destination_code": { "type": "string" }, "destination_name": { "type": "string" }, "destination_road": { "type": "string" }, "loop_desc": { "type": "string" }, "has_arrivals": { "type": "boolean" }, "status": { "type": "string" }, "operating_hours": { "type": "object", "properties": { "first_bus": { "type": "string" }, "last_bus": { "type": "string" }, "in_hours": { "type": "boolean" } } }, "buses": { "type": "array", "items": { "type": "object", "required": ["slot", "estimated_arrival", "diff_seconds", "minutes", "text", "load", "is_wab", "type", "type_label"], "properties": { "slot": { "type": "integer", "enum": [1, 2, 3] }, "estimated_arrival": { "type": "string", "format": "date-time" }, "diff_seconds": { "type": "integer" }, "minutes": { "type": "integer" }, "text": { "type": "string" }, "load": { "type": "object", "required": ["label", "level", "color", "icon"], "properties": { "label": { "type": "string" }, "level": { "type": "string", "enum": ["good", "moderate", "crowded", "unknown"] }, "color": { "type": "string" }, "icon": { "type": "string" } } }, "is_wab": { "type": "boolean" }, "wab_text": { "type": "string" }, "type": { "type": "string", "enum": ["SD", "DD", "BD"] }, "type_label": { "type": "string" }, "monitored": { "type": "integer", "enum": [0, 1] }, "estimate_type": { "type": "string" }, "origin_code": { "type": "string" }, "destination_code": { "type": "string" }, "latitude": { "type": ["number", "null"] }, "longitude": { "type": ["number", "null"] } } } } } } }, "total_services": { "type": "integer" } } } ``` #### Example JSON Response ```json { "ok": true, "bus_stop_code": "01012", "stop_info": { "description": "Hotel Grand Pacific", "road_name": "Victoria St", "latitude": 1.296848, "longitude": 103.852536 }, "timestamp": "2026-09-25T12:00:00+08:00", "services": [ { "service_no": "190", "operator": "SMRT", "origin_code": "44009", "origin_name": "Choa Chu Kang Int", "origin_road": "Choa Chu Kang Loop", "destination_code": "03239", "destination_name": "Kampong Bahru Ter", "destination_road": "Spooner Rd", "loop_desc": "", "has_arrivals": true, "status": "Operating", "buses": [ { "slot": 1, "estimated_arrival": "2026-09-25T12:03:30+08:00", "diff_seconds": 210, "minutes": 3, "text": "3 min", "load": { "label": "Seats Available", "level": "good", "color": "var(--clr-cap-green)", "icon": "🟢" }, "is_wab": true, "wab_text": "♿ Wheelchair Accessible", "type": "DD", "type_label": "Double Deck", "monitored": 1, "estimate_type": "Live estimate", "origin_code": "44009", "destination_code": "03239", "latitude": 1.3021, "longitude": 103.856 } ] } ], "total_services": 1 } ``` --- ### 2.2 GET /api/bus/plan Multi-modal public bus journey planner. Resolves origin and destination from 5-digit bus stop codes, GPS coordinates (`"lat,lng"`), or text names (e.g. `"Orchard"`, `"Bedok"`). Returns ordered itineraries (direct routes and 1-transfer routes) with walking distance, stop sequences, cumulative travel times, Google Maps transit deep links, and live arrival times for the first boarding bus. #### Query Parameters | Parameter | Type | Required | Default | Description | Example | |---|---|---|---|---|---| | `from` or `origin` or `start` | `string` | Yes | — | Origin 5-digit code, `"lat,lng"` coords, or landmark/stop search term | `"01012"` | | `to` or `dest` or `destination` or `end` | `string` | Yes | — | Destination 5-digit code, `"lat,lng"` coords, or landmark/stop search term | `"09048"` | #### Formal JSON Response Schema (Draft 2020-12) ```json { "$schema": "https://json-schema.org/draft/2020-12/schema", "title": "BusPlanResponse", "type": "object", "required": ["ok", "origin", "destination", "google_maps_url", "total_itineraries", "direct_count", "transfer_count", "itineraries"], "properties": { "ok": { "type": "boolean" }, "origin": { "type": "object", "required": ["bus_stop_code", "description", "road_name", "latitude", "longitude"], "properties": { "bus_stop_code": { "type": "string" }, "description": { "type": "string" }, "road_name": { "type": "string" }, "latitude": { "type": "number" }, "longitude": { "type": "number" } } }, "destination": { "type": "object", "required": ["bus_stop_code", "description", "road_name", "latitude", "longitude"], "properties": { "bus_stop_code": { "type": "string" }, "description": { "type": "string" }, "road_name": { "type": "string" }, "latitude": { "type": "number" }, "longitude": { "type": "number" } } }, "google_maps_url": { "type": "string", "format": "uri" }, "total_itineraries": { "type": "integer" }, "direct_count": { "type": "integer" }, "transfer_count": { "type": "integer" }, "itineraries": { "type": "array", "items": { "type": "object", "required": ["type", "transfers", "total_stops", "total_distance_km", "total_duration_mins", "legs"], "properties": { "type": { "type": "string", "enum": ["direct", "transfer"] }, "transfers": { "type": "integer", "enum": [0, 1] }, "total_stops": { "type": "integer" }, "total_distance_km": { "type": "number" }, "total_duration_mins": { "type": "integer" }, "walk_to_orig_m": { "type": "integer" }, "walk_from_dest_m": { "type": "integer" }, "transfer_stop": { "type": ["object", "null"], "properties": { "bus_stop_code": { "type": "string" }, "description": { "type": "string" }, "road_name": { "type": "string" } } }, "legs": { "type": "array", "items": { "type": "object", "required": ["service_no", "operator", "direction", "start_stop", "end_stop", "num_stops", "distance_km", "estimated_mins"], "properties": { "service_no": { "type": "string" }, "operator": { "type": "string" }, "direction": { "type": "integer" }, "start_stop": { "type": "object", "required": ["bus_stop_code", "description", "road_name"], "properties": { "bus_stop_code": { "type": "string" }, "description": { "type": "string" }, "road_name": { "type": "string" }, "latitude": { "type": "number" }, "longitude": { "type": "number" } } }, "end_stop": { "type": "object", "required": ["bus_stop_code", "description", "road_name"], "properties": { "bus_stop_code": { "type": "string" }, "description": { "type": "string" }, "road_name": { "type": "string" }, "latitude": { "type": "number" }, "longitude": { "type": "number" } } }, "num_stops": { "type": "integer" }, "distance_km": { "type": "number" }, "estimated_mins": { "type": "integer" }, "live_arrival": { "type": ["object", "null"], "properties": { "minutes": { "type": "integer" }, "estimated_arrival": { "type": "string", "format": "date-time" }, "load": { "type": "object" }, "type": { "type": "string" }, "type_label": { "type": "string" }, "is_wab": { "type": "boolean" } } } } } } } } } } } ``` #### Example JSON Response ```json { "ok": true, "origin": { "bus_stop_code": "01012", "description": "Hotel Grand Pacific", "road_name": "Victoria St", "latitude": 1.296848, "longitude": 103.852536 }, "destination": { "bus_stop_code": "09048", "description": "Orchard Stn/Tang Plaza", "road_name": "Orchard Rd", "latitude": 1.3045, "longitude": 103.8331 }, "google_maps_url": "https://www.google.com/maps/dir/?api=1&origin=1.296848%2C103.852536&destination=1.3045%2C103.8331&travelmode=transit", "total_itineraries": 3, "direct_count": 2, "transfer_count": 1, "itineraries": [ { "type": "direct", "transfers": 0, "total_stops": 6, "total_distance_km": 2.8, "total_duration_mins": 14, "legs": [ { "service_no": "190", "operator": "SMRT", "direction": 1, "start_stop": { "bus_stop_code": "01012", "description": "Hotel Grand Pacific", "road_name": "Victoria St", "latitude": 1.296848, "longitude": 103.852536 }, "end_stop": { "bus_stop_code": "09048", "description": "Orchard Stn/Tang Plaza", "road_name": "Orchard Rd", "latitude": 1.3045, "longitude": 103.8331 }, "num_stops": 6, "distance_km": 2.8, "estimated_mins": 14, "live_arrival": { "minutes": 3, "estimated_arrival": "2026-09-25T12:03:30+08:00", "load": { "label": "Seats Available", "level": "good" }, "type": "DD", "type_label": "Double Deck", "is_wab": true } } ] } ] } ``` --- ### 2.3 GET /api/bus/services List registered Singapore public bus routes or retrieve full route stop sequences for a single service. #### Query Parameters | Parameter | Type | Required | Default | Description | Example | |---|---|---|---|---|---| | `service` or `no` | `string` | No | — | Look up single bus service with direction 1 & 2 route stops | `"190"` | | `q` | `string` | No | — | Search service number, terminal, or destination keyword | `"Jurong"` | | `operator` | `string` | No | — | Filter by operator: `SBST`, `SMRT`, `TTS`, `GAS` | `"SBST"` | | `category` | `string` | No | — | Filter by category: `TRUNK`, `FEEDER`, `EXPRESS`, `INDUSTRIAL` | `"EXPRESS"` | #### Formal JSON Response Schema (Draft 2020-12) ```json { "$schema": "https://json-schema.org/draft/2020-12/schema", "title": "BusServicesResponse", "type": "object", "required": ["ok"], "properties": { "ok": { "type": "boolean" }, "total": { "type": "integer" }, "services": { "type": "array", "items": { "type": "object", "required": ["service_no", "operator", "category"], "properties": { "service_no": { "type": "string" }, "operator": { "type": "string" }, "category": { "type": "string" }, "origin_code": { "type": "string" }, "origin_name": { "type": "string" }, "destination_code": { "type": "string" }, "destination_name": { "type": "string" }, "loop_desc": { "type": "string" } } } }, "service": { "type": "object", "properties": { "service_no": { "type": "string" }, "operator": { "type": "string" }, "category": { "type": "string" }, "directions": { "type": "array", "items": { "type": "object", "required": ["direction", "origin_name", "destination_name", "routes"], "properties": { "direction": { "type": "integer", "enum": [1, 2] }, "origin_code": { "type": "string" }, "origin_name": { "type": "string" }, "destination_code": { "type": "string" }, "destination_name": { "type": "string" }, "routes": { "type": "array", "items": { "type": "object", "required": ["stop_sequence", "bus_stop_code", "distance", "stop_name", "road_name"], "properties": { "stop_sequence": { "type": "integer" }, "bus_stop_code": { "type": "string" }, "distance": { "type": "number" }, "stop_name": { "type": "string" }, "road_name": { "type": "string" }, "latitude": { "type": "number" }, "longitude": { "type": "number" }, "wd_first_bus": { "type": "string" }, "wd_last_bus": { "type": "string" } } } } } } } } } } } ``` --- ### 2.4 GET /api/bus/stops Search and inspect Singapore bus stops by 5-digit code, road name, or description. #### Query Parameters | Parameter | Type | Required | Default | Description | Example | |---|---|---|---|---|---| | `code` or `stop` | `string` | No | — | Direct 5-digit bus stop code lookup (returns stop with calling services) | `"01012"` | | `q` or `query` | `string` | No | — | Keyword query matching description or road name | `"Orchard"` | | `limit` | `integer` | No | `30` | Result limit (1 to 100) | `20` | #### Formal JSON Response Schema (Draft 2020-12) ```json { "$schema": "https://json-schema.org/draft/2020-12/schema", "title": "BusStopsResponse", "type": "object", "required": ["ok"], "properties": { "ok": { "type": "boolean" }, "query": { "type": "string" }, "total": { "type": "integer" }, "stops": { "type": "array", "items": { "type": "object", "required": ["bus_stop_code", "road_name", "description", "latitude", "longitude", "services"], "properties": { "bus_stop_code": { "type": "string" }, "road_name": { "type": "string" }, "description": { "type": "string" }, "latitude": { "type": "number" }, "longitude": { "type": "number" }, "services": { "type": "array", "items": { "type": "string" } } } } }, "stop": { "type": "object", "properties": { "bus_stop_code": { "type": "string" }, "road_name": { "type": "string" }, "description": { "type": "string" }, "latitude": { "type": "number" }, "longitude": { "type": "number" }, "services": { "type": "array", "items": { "type": "object" } } } } } } ``` --- ### 2.5 GET /api/bus/routes Retrieve sequential route stops, cumulative kilometer distances, and scheduled frequencies for a bus service. #### Query Parameters | Parameter | Type | Required | Default | Description | Example | |---|---|---|---|---|---| | `service` or `no` | `string` | Yes | — | Bus Service Number | `"65"` | | `dir` or `direction` | `integer` | No | `1` | Direction: `1` (Outbound) or `2` (Inbound) | `1` | #### Formal JSON Response Schema (Draft 2020-12) ```json { "$schema": "https://json-schema.org/draft/2020-12/schema", "title": "BusRoutesResponse", "type": "object", "required": ["ok", "service_no", "direction", "total_stops", "stops"], "properties": { "ok": { "type": "boolean" }, "service_no": { "type": "string" }, "direction": { "type": "integer", "enum": [1, 2] }, "total_stops": { "type": "integer" }, "service": { "type": "object" }, "stops": { "type": "array", "items": { "type": "object", "required": ["stop_sequence", "bus_stop_code", "road_name", "description", "distance_km", "wd_first_bus", "wd_last_bus"], "properties": { "stop_sequence": { "type": "integer" }, "bus_stop_code": { "type": "string" }, "road_name": { "type": "string" }, "description": { "type": "string" }, "distance_km": { "type": "number" }, "wd_first_bus": { "type": "string" }, "wd_last_bus": { "type": "string" }, "sat_first_bus": { "type": "string" }, "sat_last_bus": { "type": "string" }, "sun_first_bus": { "type": "string" }, "sun_last_bus": { "type": "string" } } } } } } ``` --- ### 2.6 GET /api/bus/nearby Search nearest bus stops from any GPS coordinate within a given radius. #### Query Parameters | Parameter | Type | Required | Default | Description | Example | |---|---|---|---|---|---| | `lat` | `float` | Yes | — | WGS84 Latitude (Singapore: `1.15` to `1.48`) | `1.2968` | | `lng` | `float` | Yes | — | WGS84 Longitude (Singapore: `103.58` to `104.05`) | `103.8525` | | `radius` | `float` | No | `1.2` | Search radius in kilometers (0.1 to 10.0) | `1.0` | | `limit` | `integer` | No | `20` | Maximum results to return (1 to 50) | `15` | #### Formal JSON Response Schema (Draft 2020-12) ```json { "$schema": "https://json-schema.org/draft/2020-12/schema", "title": "BusNearbyResponse", "type": "object", "required": ["ok", "is_outside_singapore", "is_fallback", "user_coords", "radius_km", "total", "stops"], "properties": { "ok": { "type": "boolean" }, "is_outside_singapore": { "type": "boolean" }, "is_fallback": { "type": "boolean" }, "user_coords": { "type": "object", "required": ["lat", "lng"], "properties": { "lat": { "type": "number" }, "lng": { "type": "number" } } }, "radius_km": { "type": "number" }, "total": { "type": "integer" }, "note": { "type": ["string", "null"] }, "stops": { "type": "array", "items": { "type": "object", "required": ["bus_stop_code", "road_name", "description", "latitude", "longitude", "distance_km", "distance_m", "services"], "properties": { "bus_stop_code": { "type": "string" }, "road_name": { "type": "string" }, "description": { "type": "string" }, "latitude": { "type": "number" }, "longitude": { "type": "number" }, "distance_km": { "type": "number" }, "distance_m": { "type": "integer" }, "services": { "type": "array", "items": { "type": "string" } } } } } } } ``` --- ### 2.7 GET /api/bus/planned Scheduled upcoming bus route diversions, road closures, and network service adjustments. #### Formal JSON Response Schema (Draft 2020-12) ```json { "$schema": "https://json-schema.org/draft/2020-12/schema", "title": "BusPlannedResponse", "type": "object", "required": ["ok", "total_changes", "changes"], "properties": { "ok": { "type": "boolean" }, "total_changes": { "type": "integer" }, "changes": { "type": "array", "items": { "type": "object", "required": ["service_no", "operator", "direction", "effective_date", "total_stops", "stops"], "properties": { "service_no": { "type": "string" }, "operator": { "type": "string" }, "direction": { "type": "integer" }, "effective_date": { "type": "string" }, "total_stops": { "type": "integer" }, "stops": { "type": "array", "items": { "type": "object", "properties": { "bus_stop_code": { "type": "string" }, "road_name": { "type": "string" }, "description": { "type": "string" } } } } } } } } } ``` --- ### 2.8 GET /api/weather Live 2-hour regional area weather forecast across 47 Singapore towns, 24-hour national forecast, 4-day outlook, and real-time station metrics (temperature, humidity, wind, rainfall). #### Formal JSON Response Schema (Draft 2020-12) ```json { "$schema": "https://json-schema.org/draft/2020-12/schema", "title": "WeatherResponse", "type": "object", "required": ["ok", "generated", "forecast_2h", "forecast_24h", "outlook_4d", "stations"], "properties": { "ok": { "type": "boolean" }, "generated": { "type": "string", "format": "date-time" }, "forecast_2h": { "type": "object", "required": ["validPeriod", "regions"], "properties": { "validPeriod": { "type": ["object", "null"], "properties": { "start": { "type": ["string", "null"] }, "end": { "type": ["string", "null"] } } }, "regions": { "type": "array", "items": { "type": "object", "required": ["area", "forecast", "icon"], "properties": { "area": { "type": "string" }, "forecast": { "type": "string" }, "icon": { "type": "string", "enum": ["sunny", "clear-night", "partly-cloudy", "cloudy", "showers", "drizzle", "rain", "heavy-rain", "thunderstorm", "windy"] } } } } } }, "forecast_24h": { "type": ["object", "null"], "required": ["forecast", "icon", "temp_low", "temp_high", "rh_low", "rh_high", "periods"], "properties": { "forecast": { "type": "string" }, "icon": { "type": "string" }, "temp_low": { "type": ["number", "null"] }, "temp_high": { "type": ["number", "null"] }, "rh_low": { "type": ["number", "null"] }, "rh_high": { "type": ["number", "null"] }, "wind_speed_low": { "type": ["number", "null"] }, "wind_speed_high": { "type": ["number", "null"] }, "wind_direction": { "type": "string" }, "periods": { "type": "array", "items": { "type": "object", "required": ["time", "regions"], "properties": { "time": { "type": "string" }, "regions": { "type": "object", "properties": { "west": { "type": "string" }, "east": { "type": "string" }, "central": { "type": "string" }, "south": { "type": "string" }, "north": { "type": "string" } } } } } } } }, "outlook_4d": { "type": "array", "items": { "type": "object", "required": ["date", "forecast", "icon", "temp_low", "temp_high"], "properties": { "date": { "type": "string" }, "forecast": { "type": "string" }, "icon": { "type": "string" }, "temp_low": { "type": ["number", "null"] }, "temp_high": { "type": ["number", "null"] }, "rh_low": { "type": ["number", "null"] }, "rh_high": { "type": ["number", "null"] }, "wind_speed": { "type": ["number", "null"] }, "wind_dir": { "type": "string" } } } }, "stations": { "type": "array", "items": { "type": "object", "required": ["info"], "properties": { "info": { "type": "object", "required": ["id", "name", "lat", "lon"], "properties": { "id": { "type": "string" }, "name": { "type": "string" }, "lat": { "type": ["number", "null"] }, "lon": { "type": ["number", "null"] } } }, "temp": { "type": ["number", "null"] }, "rh": { "type": ["number", "null"] }, "wind": { "type": ["number", "null"] }, "rain": { "type": ["number", "null"] } } } } } } ``` --- ### 2.9 GET /api/environment 24-hour National & Regional Pollutant Standards Index (PSI), 1-hour PM2.5 concentrations, and hourly UV index readings. #### Formal JSON Response Schema (Draft 2020-12) ```json { "$schema": "https://json-schema.org/draft/2020-12/schema", "title": "EnvironmentResponse", "type": "object", "required": ["ok", "generated", "psi", "pm25", "uv"], "properties": { "ok": { "type": "boolean" }, "generated": { "type": "string", "format": "date-time" }, "psi": { "type": "object", "required": ["timestamp", "regions"], "properties": { "timestamp": { "type": ["string", "null"] }, "regions": { "type": "object", "properties": { "national": { "$ref": "#/$defs/PsiRegion" }, "north": { "$ref": "#/$defs/PsiRegion" }, "south": { "$ref": "#/$defs/PsiRegion" }, "east": { "$ref": "#/$defs/PsiRegion" }, "west": { "$ref": "#/$defs/PsiRegion" }, "central": { "$ref": "#/$defs/PsiRegion" } } } } }, "pm25": { "type": "object", "required": ["timestamp", "regions"], "properties": { "timestamp": { "type": ["string", "null"] }, "regions": { "type": "object", "properties": { "north": { "type": ["number", "null"] }, "south": { "type": ["number", "null"] }, "east": { "type": ["number", "null"] }, "west": { "type": ["number", "null"] }, "central": { "type": ["number", "null"] } } } } }, "uv": { "type": "object", "required": ["timestamp", "index", "category", "trend"], "properties": { "timestamp": { "type": ["string", "null"] }, "index": { "type": ["integer", "null"] }, "category": { "type": ["string", "null"], "enum": ["Low", "Moderate", "High", "Very High", "Extreme", null] }, "trend": { "type": "array", "items": { "type": "object", "required": ["time", "value"], "properties": { "time": { "type": "string" }, "value": { "type": "integer" } } } } } } }, "$defs": { "PsiRegion": { "type": "object", "required": ["psi_24h", "category", "color"], "properties": { "psi_24h": { "type": ["integer", "null"] }, "category": { "type": "string", "enum": ["Good", "Moderate", "Unhealthy", "Very Unhealthy", "Hazardous"] }, "color": { "type": "string", "enum": ["good", "moderate", "unhealthy", "very-unhealthy", "hazardous"] } } } } } ``` --- ### 2.10 GET /api/traffic Live expressway and checkpoint traffic camera images updated continuously (87+ cameras across PIE, CTE, AYE, BKE, ECP, SLE, KJE, TPE, MCE, and border checkpoints). #### Formal JSON Response Schema (Draft 2020-12) ```json { "$schema": "https://json-schema.org/draft/2020-12/schema", "title": "TrafficCamerasResponse", "type": "object", "required": ["ok", "generated", "total", "categories"], "properties": { "ok": { "type": "boolean" }, "generated": { "type": "string", "format": "date-time" }, "total": { "type": "integer" }, "categories": { "type": "object", "additionalProperties": { "type": "array", "items": { "type": "object", "required": ["id", "imageUrl", "timestamp", "label", "description"], "properties": { "id": { "type": "string" }, "imageUrl": { "type": "string", "format": "uri" }, "timestamp": { "type": ["string", "null"] }, "lat": { "type": ["number", "null"] }, "lon": { "type": ["number", "null"] }, "label": { "type": "string" }, "description": { "type": "string" } } } } } } } ``` --- ### 2.11 GET /api/carparks Real-time parking lot vacancy, GPS nearby distance calculation, and available lot breakdowns across 2,600+ HDB, LTA (shopping malls & commercial hubs), and URA carparks nationwide. #### Query Parameters | Parameter | Type | Required | Default | Description | Example | |---|---|---|---|---|---| | `lat` | `float` | No | — | User latitude for nearby distance ranking | `1.2938` | | `lng` | `float` | No | — | User longitude for nearby distance ranking | `103.8532` | | `radius` | `float` | No | `1.5` | Search radius in km (0.1 to 15.0 km) | `1.5` | | `query` | `string` | No | — | Filter carpark ID, development/mall name, or area | `"Orchard"` | | `agency` | `string` | No | `ALL` | Filter agency: `ALL`, `HDB`, `LTA`, `URA` | `"LTA"` | | `lot_type` | `string` | No | `ALL` | Filter vehicle lot type: `ALL`, `C`, `Y`, `H` | `"C"` | | `sort` | `string` | No | `distance` | Sort order: `distance`, `available`, `pct` / `occupancy` | `"distance"` | | `page` | `integer` | No | `1` | Pagination page number | `1` | | `perPage` | `integer` | No | `50` | Results per page (10 to 200) | `30` | #### Formal JSON Response Schema (Draft 2020-12) ```json { "$schema": "https://json-schema.org/draft/2020-12/schema", "title": "CarparksResponse", "type": "object", "required": ["ok", "generated", "is_nearby", "is_outside_singapore", "page", "perPage", "total", "summary", "carparks"], "properties": { "ok": { "type": "boolean" }, "generated": { "type": "string", "format": "date-time" }, "is_nearby": { "type": "boolean" }, "is_outside_singapore": { "type": "boolean" }, "user_coords": { "type": ["object", "null"], "properties": { "lat": { "type": "number" }, "lng": { "type": "number" } } }, "radius_km": { "type": ["number", "null"] }, "query": { "type": "string" }, "agency": { "type": "string" }, "lot_type": { "type": "string" }, "page": { "type": "integer" }, "perPage": { "type": "integer" }, "total": { "type": "integer" }, "summary": { "type": "object", "required": ["totalCarparks", "totalLots", "totalAvailable", "overallPct"], "properties": { "totalCarparks": { "type": "integer" }, "totalLots": { "type": "integer" }, "totalAvailable": { "type": "integer" }, "overallPct": { "type": ["integer", "null"] } } }, "carparks": { "type": "array", "items": { "type": "object", "required": ["id", "name", "area", "agency", "available", "status", "color", "lot_types"], "properties": { "id": { "type": "string" }, "name": { "type": "string" }, "area": { "type": "string" }, "agency": { "type": "string", "enum": ["HDB", "LTA", "URA", ""] }, "lat": { "type": ["number", "null"] }, "lng": { "type": ["number", "null"] }, "distance_km": { "type": ["number", "null"] }, "distance_m": { "type": ["integer", "null"] }, "lots": { "type": ["integer", "null"] }, "available": { "type": "integer" }, "pct": { "type": ["integer", "null"] }, "status": { "type": "string", "enum": ["Available", "Limited", "Full"] }, "color": { "type": "string", "enum": ["green", "orange", "red"] }, "lot_types": { "type": "object", "additionalProperties": { "type": "object", "properties": { "total": { "type": "integer" }, "available": { "type": "integer" } } } } } } } } } ``` --- ### 2.12 GET /api/ev Real-time electric vehicle (EV) charging stations, live plug availability, fast DC & AC charging power, and tariffs across major Singapore operators. #### Query Parameters | Parameter | Type | Required | Default | Description | Example | |---|---|---|---|---|---| | `lat` | `float` | No | — | User latitude for nearby distance ranking | `1.3045` | | `lng` | `float` | No | — | User longitude for nearby distance ranking | `103.8335` | | `radius` | `float` | No | `2.5` | Search radius in km (0.1 to 25.0 km) | `2.5` | | `query` | `string` | No | — | Filter station name, mall, estate, or postal code | `"Orchard"` | | `operator` | `string` | No | `ALL` | Operator: `ALL`, `SP_MOBILITY`, `CDG_ENGIE`, `CHARGE_PLUS`, `SHELL`, `TESLA`, `KEPPEL_VOLT`, `TOTALENERGIES`, `GO_CITY_ENERGY` | `"SP_MOBILITY"` | | `speed` | `string` | No | `ALL` | Power speed: `ALL`, `ULTRA_FAST` (≥120kW), `FAST_DC` (50-100kW), `AC_NORMAL` (7.4-22kW) | `"ULTRA_FAST"` | | `connector` | `string` | No | `ALL` | Connector type: `ALL`, `CCS2`, `TYPE2`, `TESLA` | `"CCS2"` | | `region` | `string` | No | `ALL` | Singapore region: `ALL`, `Central`, `East`, `West`, `North`, `North-East`, `South` | `"Central"` | | `available_only` | `boolean` | No | `false` | Only return stations with at least 1 currently free plug | `1` | | `sort` | `string` | No | `distance` | Sort field: `distance`, `available`, `power` / `speed` | `"power"` | | `page` | `integer` | No | `1` | Page number | `1` | | `perPage` | `integer` | No | `40` | Results per page (1 to 100) | `30` | #### Formal JSON Response Schema (Draft 2020-12) ```json { "$schema": "https://json-schema.org/draft/2020-12/schema", "title": "EvStationsResponse", "type": "object", "required": ["ok", "generated", "is_nearby", "is_outside_singapore", "page", "perPage", "total", "summary", "stations"], "properties": { "ok": { "type": "boolean" }, "generated": { "type": "string", "format": "date-time" }, "is_nearby": { "type": "boolean" }, "is_outside_singapore": { "type": "boolean" }, "user_coords": { "type": ["object", "null"], "properties": { "lat": { "type": "number" }, "lng": { "type": "number" } } }, "radius_km": { "type": ["number", "null"] }, "query": { "type": "string" }, "operator": { "type": "string" }, "speed": { "type": "string" }, "connector": { "type": "string" }, "page": { "type": "integer" }, "perPage": { "type": "integer" }, "total": { "type": "integer" }, "summary": { "type": "object", "required": ["totalStations", "totalPlugs", "totalAvailable", "overallPct", "fastDcCount", "ultraFastCount"], "properties": { "totalStations": { "type": "integer" }, "totalPlugs": { "type": "integer" }, "totalAvailable": { "type": "integer" }, "overallPct": { "type": "integer" }, "fastDcCount": { "type": "integer" }, "ultraFastCount": { "type": "integer" }, "liveLtaCount": { "type": "integer" } } }, "stations": { "type": "array", "items": { "type": "object", "required": ["id", "name", "address", "area", "operator", "operator_name", "lat", "lng", "total_plugs", "available", "status", "color", "pct", "max_speed_kw", "has_ultra_fast", "has_fast_dc", "connector_types", "plugs"], "properties": { "id": { "type": "string" }, "name": { "type": "string" }, "address": { "type": "string" }, "area": { "type": "string" }, "operator": { "type": "string" }, "operator_name": { "type": "string" }, "lat": { "type": "number" }, "lng": { "type": "number" }, "total_plugs": { "type": "integer" }, "available": { "type": "integer" }, "status": { "type": "string", "enum": ["Available", "Limited", "Full / In Use", "Unknown"] }, "color": { "type": "string", "enum": ["green", "orange", "red"] }, "pct": { "type": "integer" }, "max_speed_kw": { "type": "number" }, "has_ultra_fast": { "type": "boolean" }, "has_fast_dc": { "type": "boolean" }, "connector_types": { "type": "array", "items": { "type": "string" } }, "pricing_ac": { "type": "string" }, "pricing_dc": { "type": "string" }, "parking_info": { "type": "string" }, "distance_km": { "type": ["number", "null"] }, "distance_m": { "type": ["integer", "null"] }, "plugs": { "type": "array", "items": { "type": "object", "required": ["id", "type", "speed_kw", "category", "is_available"], "properties": { "id": { "type": "string" }, "type": { "type": "string" }, "speed_kw": { "type": "number" }, "category": { "type": "string", "enum": ["ULTRA_FAST", "FAST_DC", "AC_NORMAL"] }, "is_available": { "type": "boolean" } } } } } } } } } ``` --- ### 2.13 GET /api/acra Search corporate entities, companies, businesses, LLPs, societies, and healthcare institutions across Singapore regulatory registries with intelligent relevance ranking. #### Query Parameters | Parameter | Type | Required | Default | Description | Example | |---|---|---|---|---|---| | `q` or `query` | `string` | Yes | — | Search term: Company Name or UEN | `"DBS Bank"` | | `page` | `integer` | No | `1` | Page number (24 entities per page) | `1` | #### Formal JSON Response Schema (Draft 2020-12) ```json { "$schema": "https://json-schema.org/draft/2020-12/schema", "title": "AcraSearchResponse", "type": "object", "required": ["ok", "query", "page", "limit", "total", "entities"], "properties": { "ok": { "type": "boolean" }, "query": { "type": "string" }, "page": { "type": "integer" }, "limit": { "type": "integer", "const": 24 }, "total": { "type": "integer" }, "total_primary": { "type": "integer" }, "total_supp": { "type": "integer" }, "dataset": { "type": "string" }, "entities": { "type": "array", "items": { "type": "object", "required": ["uen", "name", "type", "status", "agency", "full_address"], "properties": { "uen": { "type": "string" }, "name": { "type": "string" }, "type": { "type": "string" }, "status": { "type": "string" }, "agency": { "type": "string", "enum": ["ACRA", "ROS", "MOH", "MAS"] }, "issue_date": { "type": ["string", "null"] }, "street": { "type": ["string", "null"] }, "postal": { "type": ["string", "null"] }, "full_address": { "type": "string" }, "constitution": { "type": "object", "properties": { "business": { "type": ["string", "null"] }, "company": { "type": ["string", "null"] }, "paf": { "type": ["string", "null"] } } }, "filing": { "type": "object", "properties": { "annual_return": { "type": ["string", "null"] }, "account_due": { "type": ["string", "null"] } } }, "ssic_primary": { "type": ["object", "null"], "properties": { "code": { "type": "string" }, "description": { "type": "string" }, "user_desc": { "type": ["string", "null"] } } }, "ssic_secondary": { "type": ["object", "null"], "properties": { "code": { "type": "string" }, "description": { "type": "string" }, "user_desc": { "type": ["string", "null"] } } }, "no_of_officers": { "type": ["string", "null"] }, "former_names": { "type": "array", "items": { "type": "string" } }, "audit_firms": { "type": "array", "items": { "type": "object", "properties": { "name": { "type": "string" }, "uen": { "type": "string" } } } } } } } } } ``` --- ## 3. Production LLM Tool Definitions Below are complete, validated, production-grade tool definitions structured for each leading LLM orchestration standard. ### 3.1 Format A: OpenAI Function Calling Specification (`tools` array) ```json [ { "type": "function", "function": { "name": "get_singapore_bus_arrivals", "description": "Fetch live arrival times, crowding status (SEA: Seats Available, SDA: Standing Available, LSD: Limited Standing), vehicle deck type (SD/DD/BD), and wheelchair accessibility for the next 3 arriving buses at any 5-digit Singapore bus stop.", "parameters": { "type": "object", "properties": { "bus_stop_code": { "type": "string", "description": "5-digit zero-padded Singapore Bus Stop Code (e.g. '01012', '09048', '67009')." }, "service_no": { "type": "string", "description": "Optional specific bus service number to filter (e.g. '190', '65', '10')." } }, "required": ["bus_stop_code"] } } }, { "type": "function", "function": { "name": "plan_singapore_bus_journey", "description": "Plan a public bus journey in Singapore between any two locations. Resolves 5-digit stop codes, GPS lat/lng coordinates, or landmark/stop names. Returns direct and 1-transfer itineraries with duration, stop count, and live arrival times for the first boarding leg.", "parameters": { "type": "object", "properties": { "origin": { "type": "string", "description": "Starting location: 5-digit bus stop code (e.g. '01012'), coordinates ('1.2968,103.8525'), or landmark/road name ('Victoria St', 'City Hall')." }, "destination": { "type": "string", "description": "Destination location: 5-digit bus stop code (e.g. '09048'), coordinates ('1.3045,103.8331'), or landmark/road name ('Orchard Stn', 'Tang Plaza')." } }, "required": ["origin", "destination"] } } }, { "type": "function", "function": { "name": "find_nearby_singapore_bus_stops", "description": "Find closest public bus stops from GPS coordinates in Singapore, sorted by walking distance with calling bus services.", "parameters": { "type": "object", "properties": { "latitude": { "type": "number", "description": "WGS84 Latitude between 1.15 and 1.48 (e.g. 1.2968)." }, "longitude": { "type": "number", "description": "WGS84 Longitude between 103.58 and 104.05 (e.g. 103.8525)." }, "radius_km": { "type": "number", "description": "Search radius in km (default 1.2, max 10.0)." }, "limit": { "type": "integer", "description": "Maximum number of bus stops to return (default 20, max 50)." } }, "required": ["latitude", "longitude"] } } }, { "type": "function", "function": { "name": "search_singapore_bus_stops", "description": "Search Singapore bus stops by road name, landmark name, or 5-digit stop code.", "parameters": { "type": "object", "properties": { "query": { "type": "string", "description": "Search term (e.g. 'Orchard', 'Bedok Int', 'Victoria St', '01012')." }, "limit": { "type": "integer", "description": "Max results to return (default 30, max 100)." } }, "required": ["query"] } } }, { "type": "function", "function": { "name": "get_singapore_bus_service_details", "description": "Retrieve full route details, operating operators, directions, and ordered stop sequences for a specific Singapore bus service.", "parameters": { "type": "object", "properties": { "service_no": { "type": "string", "description": "Bus service number (e.g. '190', '65', '14', '960e')." } }, "required": ["service_no"] } } }, { "type": "function", "function": { "name": "get_singapore_bus_route_stops", "description": "Retrieve the sequential list of bus stops, cumulative kilometer distance, and weekday/weekend operating timetables for a bus line and direction.", "parameters": { "type": "object", "properties": { "service_no": { "type": "string", "description": "Bus service number (e.g. '65')." }, "direction": { "type": "integer", "enum": [1, 2], "description": "Direction 1 (outbound) or 2 (inbound). Default: 1." } }, "required": ["service_no"] } } }, { "type": "function", "function": { "name": "get_singapore_planned_bus_changes", "description": "Retrieve scheduled future bus route diversions, road closures, and route adjustments across Singapore.", "parameters": { "type": "object", "properties": {} } } }, { "type": "function", "function": { "name": "get_singapore_weather", "description": "Retrieve live Singapore weather: 2-hour regional nowcast across 47 towns, 24-hour national forecast with sub-day periods, 4-day outlook, and live station readings (temperature, humidity, wind, rainfall).", "parameters": { "type": "object", "properties": {} } } }, { "type": "function", "function": { "name": "get_singapore_environment_air_quality", "description": "Get real-time Singapore 24-hour PSI air quality ratings, 1-hour PM2.5 readings across 5 regions (North, South, East, West, Central), and current UV index with hourly trend.", "parameters": { "type": "object", "properties": {} } } }, { "type": "function", "function": { "name": "get_singapore_traffic_cameras", "description": "Retrieve live expressway traffic camera image snapshot URLs and coordinates across all major expressways (PIE, CTE, AYE, BKE, etc.) and Malaysia border checkpoints (Woodlands Causeway, Tuas Second Link).", "parameters": { "type": "object", "properties": {} } } }, { "type": "function", "function": { "name": "get_singapore_carpark_availability", "description": "Check live parking lot vacancy and distance across 2,600+ HDB, URA, and LTA shopping mall carparks in Singapore.", "parameters": { "type": "object", "properties": { "query": { "type": "string", "description": "Filter by carpark code (e.g. 'ACB'), mall/building name (e.g. 'Suntec', 'Orchard'), or estate." }, "lat": { "type": "number", "description": "User GPS latitude for nearby distance ranking." }, "lng": { "type": "number", "description": "User GPS longitude for nearby distance ranking." }, "radius": { "type": "number", "description": "Search radius in km (0.1 to 15.0 km, default 1.5)." }, "agency": { "type": "string", "enum": ["ALL", "HDB", "LTA", "URA"], "description": "Filter by agency. Default: 'ALL'." }, "lot_type": { "type": "string", "enum": ["ALL", "C", "Y", "H"], "description": "Vehicle type: 'C' (Cars), 'Y' (Motorcycles), 'H' (Heavy). Default: 'ALL'." } } } } }, { "type": "function", "function": { "name": "get_singapore_ev_charging_points", "description": "Search real-time EV charging stations and live plug availability across SP Mobility, CDG ENGIE, Charge+, Shell Recharge, Tesla Superchargers, and HDB hubs in Singapore.", "parameters": { "type": "object", "properties": { "query": { "type": "string", "description": "Station name, shopping mall, operator, or 6-digit postal code (e.g. 'Orchard', 'Tesla', '529510')." }, "operator": { "type": "string", "enum": ["ALL", "SP_MOBILITY", "CDG_ENGIE", "CHARGE_PLUS", "SHELL", "TESLA", "KEPPEL_VOLT", "TOTALENERGIES", "GO_CITY_ENERGY"], "description": "Filter operator network." }, "speed": { "type": "string", "enum": ["ALL", "ULTRA_FAST", "FAST_DC", "AC_NORMAL"], "description": "Filter charging speed tier: ULTRA_FAST (>=120kW), FAST_DC (50-100kW), AC_NORMAL (7.4-22kW)." }, "connector": { "type": "string", "enum": ["ALL", "CCS2", "TYPE2", "TESLA"], "description": "Filter plug connector type." }, "lat": { "type": "number", "description": "GPS latitude for nearby distance ranking." }, "lng": { "type": "number", "description": "GPS longitude for nearby distance ranking." }, "radius": { "type": "number", "description": "Search radius in km (0.1 to 25.0 km, default 2.5)." }, "available_only": { "type": "boolean", "description": "Set to true to only return stations with at least 1 currently available plug." } } } } }, { "type": "function", "function": { "name": "search_singapore_acra_entity", "description": "Search Singapore registered companies, businesses, LLPs, societies, and healthcare institutions across ACRA regulatory registries by entity name or UEN.", "parameters": { "type": "object", "properties": { "query": { "type": "string", "description": "Company name or UEN (e.g. 'DBS Bank', 'Grab', '201812345A')." }, "page": { "type": "integer", "description": "Page number (24 entities per page, default: 1)." } }, "required": ["query"] } } } ] ``` --- ### 3.2 Format B: Anthropic Claude Tool Use Specification Claude tools use `input_schema` instead of `parameters`. Below is the complete 13-tool schema array: ```json [ { "name": "get_singapore_bus_arrivals", "description": "Fetch live arrival times, crowding status (SEA: Seats Available, SDA: Standing Available, LSD: Limited Standing), vehicle deck type (SD/DD/BD), and wheelchair accessibility for the next 3 arriving buses at any 5-digit Singapore bus stop.", "input_schema": { "type": "object", "properties": { "bus_stop_code": { "type": "string", "description": "5-digit zero-padded Singapore Bus Stop Code (e.g. '01012', '09048', '67009')." }, "service_no": { "type": "string", "description": "Optional specific bus service number to filter (e.g. '190', '65', '10')." } }, "required": ["bus_stop_code"] } }, { "name": "plan_singapore_bus_journey", "description": "Plan a public bus journey in Singapore between any two locations. Resolves 5-digit stop codes, GPS lat/lng coordinates, or landmark/stop names. Returns direct and 1-transfer itineraries with duration, stop count, and live arrival times for the first boarding leg.", "input_schema": { "type": "object", "properties": { "origin": { "type": "string", "description": "Starting location: 5-digit bus stop code (e.g. '01012'), coordinates ('1.2968,103.8525'), or landmark/road name ('Victoria St', 'City Hall')." }, "destination": { "type": "string", "description": "Destination location: 5-digit bus stop code (e.g. '09048'), coordinates ('1.3045,103.8331'), or landmark/road name ('Orchard Stn', 'Tang Plaza')." } }, "required": ["origin", "destination"] } }, { "name": "find_nearby_singapore_bus_stops", "description": "Find closest public bus stops from GPS coordinates in Singapore, sorted by walking distance with calling bus services.", "input_schema": { "type": "object", "properties": { "latitude": { "type": "number", "description": "WGS84 Latitude between 1.15 and 1.48 (e.g. 1.2968)." }, "longitude": { "type": "number", "description": "WGS84 Longitude between 103.58 and 104.05 (e.g. 103.8525)." }, "radius_km": { "type": "number", "description": "Search radius in km (default 1.2, max 10.0)." }, "limit": { "type": "integer", "description": "Maximum number of bus stops to return (default 20, max 50)." } }, "required": ["latitude", "longitude"] } }, { "name": "search_singapore_bus_stops", "description": "Search Singapore bus stops by road name, landmark name, or 5-digit stop code.", "input_schema": { "type": "object", "properties": { "query": { "type": "string", "description": "Search term (e.g. 'Orchard', 'Bedok Int', 'Victoria St', '01012')." }, "limit": { "type": "integer", "description": "Max results to return (default 30, max 100)." } }, "required": ["query"] } }, { "name": "get_singapore_bus_service_details", "description": "Retrieve full route details, operating operators, directions, and ordered stop sequences for a specific Singapore bus service.", "input_schema": { "type": "object", "properties": { "service_no": { "type": "string", "description": "Bus service number (e.g. '190', '65', '14', '960e')." } }, "required": ["service_no"] } }, { "name": "get_singapore_bus_route_stops", "description": "Retrieve the sequential list of bus stops, cumulative kilometer distance, and weekday/weekend operating timetables for a bus line and direction.", "input_schema": { "type": "object", "properties": { "service_no": { "type": "string", "description": "Bus service number (e.g. '65')." }, "direction": { "type": "integer", "enum": [1, 2], "description": "Direction 1 (outbound) or 2 (inbound). Default: 1." } }, "required": ["service_no"] } }, { "name": "get_singapore_planned_bus_changes", "description": "Retrieve scheduled future bus route diversions, road closures, and route adjustments across Singapore.", "input_schema": { "type": "object", "properties": {} } }, { "name": "get_singapore_weather", "description": "Retrieve live Singapore weather: 2-hour regional nowcast across 47 towns, 24-hour national forecast with sub-day periods, 4-day outlook, and live station readings (temperature, humidity, wind, rainfall).", "input_schema": { "type": "object", "properties": {} } }, { "name": "get_singapore_environment_air_quality", "description": "Get real-time Singapore 24-hour PSI air quality ratings, 1-hour PM2.5 readings across 5 regions (North, South, East, West, Central), and current UV index with hourly trend.", "input_schema": { "type": "object", "properties": {} } }, { "name": "get_singapore_traffic_cameras", "description": "Retrieve live expressway traffic camera image snapshot URLs and coordinates across all major expressways (PIE, CTE, AYE, BKE, etc.) and Malaysia border checkpoints (Woodlands Causeway, Tuas Second Link).", "input_schema": { "type": "object", "properties": {} } }, { "name": "get_singapore_carpark_availability", "description": "Check live parking lot vacancy and distance across 2,600+ HDB, URA, and LTA shopping mall carparks in Singapore.", "input_schema": { "type": "object", "properties": { "query": { "type": "string", "description": "Filter by carpark code (e.g. 'ACB'), mall/building name (e.g. 'Suntec', 'Orchard'), or estate." }, "lat": { "type": "number", "description": "User GPS latitude for nearby distance ranking." }, "lng": { "type": "number", "description": "User GPS longitude for nearby distance ranking." }, "radius": { "type": "number", "description": "Search radius in km (0.1 to 15.0 km, default 1.5)." }, "agency": { "type": "string", "enum": ["ALL", "HDB", "LTA", "URA"], "description": "Filter by agency. Default: 'ALL'." }, "lot_type": { "type": "string", "enum": ["ALL", "C", "Y", "H"], "description": "Vehicle type: 'C' (Cars), 'Y' (Motorcycles), 'H' (Heavy). Default: 'ALL'." } } } }, { "name": "get_singapore_ev_charging_points", "description": "Search real-time EV charging stations and live plug availability across SP Mobility, CDG ENGIE, Charge+, Shell Recharge, Tesla Superchargers, and HDB hubs in Singapore.", "input_schema": { "type": "object", "properties": { "query": { "type": "string", "description": "Station name, shopping mall, operator, or 6-digit postal code (e.g. 'Orchard', 'Tesla', '529510')." }, "operator": { "type": "string", "enum": ["ALL", "SP_MOBILITY", "CDG_ENGIE", "CHARGE_PLUS", "SHELL", "TESLA", "KEPPEL_VOLT", "TOTALENERGIES", "GO_CITY_ENERGY"], "description": "Filter operator network." }, "speed": { "type": "string", "enum": ["ALL", "ULTRA_FAST", "FAST_DC", "AC_NORMAL"], "description": "Filter charging speed tier: ULTRA_FAST (>=120kW), FAST_DC (50-100kW), AC_NORMAL (7.4-22kW)." }, "connector": { "type": "string", "enum": ["ALL", "CCS2", "TYPE2", "TESLA"], "description": "Filter plug connector type." }, "lat": { "type": "number", "description": "GPS latitude for nearby distance ranking." }, "lng": { "type": "number", "description": "GPS longitude for nearby distance ranking." }, "radius": { "type": "number", "description": "Search radius in km (0.1 to 25.0 km, default 2.5)." }, "available_only": { "type": "boolean", "description": "Set to true to only return stations with at least 1 currently available plug." } } } }, { "name": "search_singapore_acra_entity", "description": "Search Singapore registered companies, businesses, LLPs, societies, and healthcare institutions across ACRA regulatory registries by entity name or UEN.", "input_schema": { "type": "object", "properties": { "query": { "type": "string", "description": "Company name or UEN (e.g. 'DBS Bank', 'Grab', '201812345A')." }, "page": { "type": "integer", "description": "Page number (24 entities per page, default: 1)." } }, "required": ["query"] } } ] ``` --- ### 3.3 Format C: Google Gemini Function Declarations In the Google Gemini SDK (Python `google-genai` or Node.js `@google/genai`), functions are declared inside `function_declarations`. Below is the complete 13-function declaration suite: ```python from google import genai from google.genai import types tools = [ types.Tool( function_declarations=[ types.FunctionDeclaration( name="get_singapore_bus_arrivals", description="Fetch live arrival times, crowding status (SEA: Seats Available, SDA: Standing Available, LSD: Limited Standing), vehicle deck type (SD/DD/BD), and wheelchair accessibility for the next 3 arriving buses at any 5-digit Singapore bus stop.", parameters=types.Schema( type=types.Type.OBJECT, properties={ "bus_stop_code": types.Schema(type=types.Type.STRING, description="5-digit zero-padded Singapore Bus Stop Code (e.g. '01012', '09048', '67009')"), "service_no": types.Schema(type=types.Type.STRING, description="Optional specific bus service number to filter (e.g. '190', '65', '10')") }, required=["bus_stop_code"] ) ), types.FunctionDeclaration( name="plan_singapore_bus_journey", description="Plan a public bus journey in Singapore between any two locations. Resolves 5-digit stop codes, GPS lat/lng coordinates, or landmark/stop names. Returns direct and 1-transfer itineraries with duration, stop count, and live arrival times for the first boarding leg.", parameters=types.Schema( type=types.Type.OBJECT, properties={ "origin": types.Schema(type=types.Type.STRING, description="Starting location: 5-digit bus stop code (e.g. '01012'), coordinates ('1.2968,103.8525'), or landmark/road name ('Victoria St', 'City Hall')"), "destination": types.Schema(type=types.Type.STRING, description="Destination location: 5-digit bus stop code (e.g. '09048'), coordinates ('1.3045,103.8331'), or landmark/road name ('Orchard Stn', 'Tang Plaza')") }, required=["origin", "destination"] ) ), types.FunctionDeclaration( name="find_nearby_singapore_bus_stops", description="Find closest public bus stops from GPS coordinates in Singapore, sorted by walking distance with calling bus services.", parameters=types.Schema( type=types.Type.OBJECT, properties={ "latitude": types.Schema(type=types.Type.NUMBER, description="WGS84 Latitude between 1.15 and 1.48 (e.g. 1.2968)"), "longitude": types.Schema(type=types.Type.NUMBER, description="WGS84 Longitude between 103.58 and 104.05 (e.g. 103.8525)"), "radius_km": types.Schema(type=types.Type.NUMBER, description="Search radius in km (default 1.2, max 10.0)"), "limit": types.Schema(type=types.Type.INTEGER, description="Maximum number of bus stops to return (default 20, max 50)") }, required=["latitude", "longitude"] ) ), types.FunctionDeclaration( name="search_singapore_bus_stops", description="Search Singapore bus stops by road name, landmark name, or 5-digit stop code.", parameters=types.Schema( type=types.Type.OBJECT, properties={ "query": types.Schema(type=types.Type.STRING, description="Search term (e.g. 'Orchard', 'Bedok Int', 'Victoria St', '01012')"), "limit": types.Schema(type=types.Type.INTEGER, description="Max results to return (default 30, max 100)") }, required=["query"] ) ), types.FunctionDeclaration( name="get_singapore_bus_service_details", description="Retrieve full route details, operating operators, directions, and ordered stop sequences for a specific Singapore bus service.", parameters=types.Schema( type=types.Type.OBJECT, properties={ "service_no": types.Schema(type=types.Type.STRING, description="Bus service number (e.g. '190', '65', '14', '960e')") }, required=["service_no"] ) ), types.FunctionDeclaration( name="get_singapore_bus_route_stops", description="Retrieve the sequential list of bus stops, cumulative kilometer distance, and weekday/weekend operating timetables for a bus line and direction.", parameters=types.Schema( type=types.Type.OBJECT, properties={ "service_no": types.Schema(type=types.Type.STRING, description="Bus service number (e.g. '65')"), "direction": types.Schema(type=types.Type.INTEGER, description="Direction 1 (outbound) or 2 (inbound). Default: 1") }, required=["service_no"] ) ), types.FunctionDeclaration( name="get_singapore_planned_bus_changes", description="Retrieve scheduled future bus route diversions, road closures, and route adjustments across Singapore.", parameters=types.Schema( type=types.Type.OBJECT, properties={} ) ), types.FunctionDeclaration( name="get_singapore_weather", description="Retrieve live Singapore weather: 2-hour regional nowcast across 47 towns, 24-hour national forecast with sub-day periods, 4-day outlook, and live station readings (temperature, humidity, wind, rainfall).", parameters=types.Schema( type=types.Type.OBJECT, properties={} ) ), types.FunctionDeclaration( name="get_singapore_environment_air_quality", description="Get real-time Singapore 24-hour PSI air quality ratings, 1-hour PM2.5 readings across 5 regions (North, South, East, West, Central), and current UV index with hourly trend.", parameters=types.Schema( type=types.Type.OBJECT, properties={} ) ), types.FunctionDeclaration( name="get_singapore_traffic_cameras", description="Retrieve live expressway traffic camera image snapshot URLs and coordinates across all major expressways (PIE, CTE, AYE, BKE, etc.) and Malaysia border checkpoints (Woodlands Causeway, Tuas Second Link).", parameters=types.Schema( type=types.Type.OBJECT, properties={} ) ), types.FunctionDeclaration( name="get_singapore_carpark_availability", description="Check live parking lot vacancy and distance across 2,600+ HDB, URA, and LTA shopping mall carparks in Singapore.", parameters=types.Schema( type=types.Type.OBJECT, properties={ "query": types.Schema(type=types.Type.STRING, description="Filter by carpark code, mall/building name, or estate"), "lat": types.Schema(type=types.Type.NUMBER, description="User GPS latitude for nearby distance ranking"), "lng": types.Schema(type=types.Type.NUMBER, description="User GPS longitude for nearby distance ranking"), "radius": types.Schema(type=types.Type.NUMBER, description="Search radius in km (0.1 to 15.0 km, default 1.5)"), "agency": types.Schema(type=types.Type.STRING, description="Filter by agency: 'ALL', 'HDB', 'LTA', 'URA'"), "lot_type": types.Schema(type=types.Type.STRING, description="Vehicle type: 'C' (Cars), 'Y' (Motorcycles), 'H' (Heavy)") } ) ), types.FunctionDeclaration( name="get_singapore_ev_charging_points", description="Search real-time EV charging stations and live plug availability across SP Mobility, CDG ENGIE, Charge+, Shell Recharge, Tesla Superchargers, and HDB hubs in Singapore.", parameters=types.Schema( type=types.Type.OBJECT, properties={ "query": types.Schema(type=types.Type.STRING, description="Station name, shopping mall, operator, or 6-digit postal code"), "operator": types.Schema(type=types.Type.STRING, description="Filter operator ('ALL', 'SP_MOBILITY', 'CDG_ENGIE', 'CHARGE_PLUS', 'SHELL', 'TESLA', etc.)"), "speed": types.Schema(type=types.Type.STRING, description="Filter charging speed: 'ALL', 'ULTRA_FAST', 'FAST_DC', 'AC_NORMAL'"), "connector": types.Schema(type=types.Type.STRING, description="Filter connector type: 'ALL', 'CCS2', 'TYPE2', 'TESLA'"), "lat": types.Schema(type=types.Type.NUMBER, description="GPS latitude for nearby distance ranking"), "lng": types.Schema(type=types.Type.NUMBER, description="GPS longitude for nearby distance ranking"), "radius": types.Schema(type=types.Type.NUMBER, description="Search radius in km (default 2.5)"), "available_only": types.Schema(type=types.Type.BOOLEAN, description="Only return stations with at least 1 currently available plug") } ) ), types.FunctionDeclaration( name="search_singapore_acra_entity", description="Search Singapore registered companies, businesses, LLPs, societies, and healthcare institutions across ACRA regulatory registries by entity name or UEN.", parameters=types.Schema( type=types.Type.OBJECT, properties={ "query": types.Schema(type=types.Type.STRING, description="Company name or UEN (e.g. 'DBS Bank', 'Grab', '201812345A')"), "page": types.Schema(type=types.Type.INTEGER, description="Page number (24 entities per page, default: 1)") }, required=["query"] ) ) ] ) ] ``` --- ## 4. Production Code Implementations ### 4.1 Python 3 + Pydantic Schema Validation ```python """ SingaNow API Client with Pydantic v2 Type Safety & Schema Validation. """ from typing import Optional, List, Dict, Any from pydantic import BaseModel, Field import requests BASE_URL = "https://singanow.com/api" class BusLoad(BaseModel): label: str level: str color: str icon: str class BusArrivalSlot(BaseModel): slot: int text: str minutes: int estimated_arrival: str load: BusLoad is_wab: bool type_label: str class ServiceArrival(BaseModel): service_no: str operator: str destination_name: str has_arrivals: bool buses: List[BusArrivalSlot] class BusArrivalResponse(BaseModel): ok: bool bus_stop_code: str services: List[ServiceArrival] def fetch_bus_arrivals(stop_code: str, service: Optional[str] = None) -> BusArrivalResponse: params = {"stop": stop_code} if service: params["service"] = service resp = requests.get(f"{BASE_URL}/bus/arrival", params=params, timeout=8) resp.raise_for_status() return BusArrivalResponse.model_validate(resp.json()) def plan_journey(origin: str, destination: str) -> Dict[str, Any]: params = {"from": origin, "to": destination} resp = requests.get(f"{BASE_URL}/bus/plan", params=params, timeout=10) resp.raise_for_status() return resp.json() def search_acra(query: str) -> Dict[str, Any]: resp = requests.get(f"{BASE_URL}/acra", params={"q": query}, timeout=10) resp.raise_for_status() return resp.json() if __name__ == "__main__": arrival = fetch_bus_arrivals("01012", service="190") print(f"Stop: {arrival.bus_stop_code}") for svc in arrival.services: if svc.has_arrivals: first = svc.buses[0] print(f"Service {svc.service_no} -> {svc.destination_name}: {first.text} [{first.load.label}]") ``` --- ### 4.2 TypeScript + Zod Response Validation ```typescript import { z } from "zod"; const BusArrivalSlotSchema = z.object({ slot: z.number(), minutes: z.number(), text: z.string(), estimated_arrival: z.string(), load: z.object({ label: z.string(), level: z.string(), }), is_wab: z.boolean(), type_label: z.string(), }); const ServiceArrivalSchema = z.object({ service_no: z.string(), operator: z.string(), has_arrivals: z.boolean(), buses: z.array(BusArrivalSlotSchema), }); const BusArrivalResponseSchema = z.object({ ok: z.boolean(), bus_stop_code: z.string(), timestamp: z.string(), services: z.array(ServiceArrivalSchema), }); export type BusArrivalResponse = z.infer; export async function getBusArrivals(stopCode: string, serviceNo?: string): Promise { const url = new URL("https://singanow.com/api/bus/arrival"); url.searchParams.set("stop", stopCode); if (serviceNo) url.searchParams.set("service", serviceNo); const res = await fetch(url.toString(), { headers: { Accept: "application/json" } }); if (!res.ok) throw new Error(`HTTP ${res.status}: ${res.statusText}`); const json = await res.json(); return BusArrivalResponseSchema.parse(json); } ``` --- ### 4.3 Command Line cURL Recipes ```bash # 1. Bus Arrivals at Hotel Grand Pacific (01012) curl -s "https://singanow.com/api/bus/arrival?stop=01012" | jq . # 2. Plan Bus Journey between Hotel Grand Pacific and Orchard Station curl -s "https://singanow.com/api/bus/plan?from=01012&to=09048" | jq . # 3. Find Bus Stops within 800m of Raffles Place MRT curl -s "https://singanow.com/api/bus/nearby?lat=1.2839&lng=103.8515&radius=0.8" | jq . # 4. Live 2-Hour & 24-Hour Singapore Weather curl -s "https://singanow.com/api/weather" | jq . # 5. Air Quality (PSI, PM2.5, UV Index) curl -s "https://singanow.com/api/environment" | jq . # 6. Live Traffic Cameras for Woodlands Checkpoint & Tuas curl -s "https://singanow.com/api/traffic" | jq '.categories["Woodlands Checkpoint"]' # 7. Nearby Carpark Vacancy around Marina Bay Sands curl -s "https://singanow.com/api/carparks?lat=1.2838&lng=103.8591&radius=1.0" | jq . # 8. Available Fast DC & Ultra-Fast EV Chargers in Orchard curl -s "https://singanow.com/api/ev?query=Orchard&speed=FAST_DC" | jq . # 9. Search ACRA Corporate Registry for DBS Bank curl -s "https://singanow.com/api/acra?q=DBS+Bank" | jq . ``` --- ## 5. Reliability, Caching & Error Handling Guidelines 1. **HTTP Status Codes**: - `200 OK`: Request succeeded. Response body contains valid data with `"ok": true`. - `400 Bad Request`: Missing mandatory parameters (e.g. `stop` for arrival or `from`/`to` for plan). - `404 Not Found`: Entity, bus stop code, or bus route not found. - `503 Service Unavailable`: Upstream government data source temporarily unreachable (e.g. during DataMall maintenance windows). 2. **Cache Headers & Freshness**: - Real-time endpoints (`/api/bus/arrival`, `/api/traffic`, `/api/carparks`) employ short internal memory/file caching (20s to 90s) to guard against upstream throttling while ensuring fresh live updates. - Client requests can pass `?refresh=1` to force live upstream invalidation when immediate freshness is required. 3. **Graceful Degeneracy**: - If an LTA live prediction is momentarily unavailable, arrival APIs automatically fall back to scheduled first/last bus operating hours and display `"has_arrivals": false` with `"status": "Not In Operation"` or `"No Est. Available"`.