Planning method
API use: choosing the right Asmaliana tool and reading its result
Asmaliana exposes six read-only domain capabilities through REST and Remote MCP. They share schemas, domain services, evidence rules, quota accounting, and capability descriptions. Operational health/status endpoints are not additional travel tools.
The current environment is demo-only unless /api/v1/meta explicitly reports an approved verified revision. Demo results are synthetic and unsuitable for real travel decisions.
Start with metadata
Before calling a travel operation, inspect:
GET /api/v1/meta
The response should identify data mode, coverage, data/schema versions, enabled capabilities, provider state, and material limitations. A client should not assume production coverage from a 200 response or from the domain name.
Use /api/v1/health for minimal service health and /api/v1/status for safe public service/provider state. Neither endpoint proves that a particular place is open.
Local examples use:
BASE_URL=http://localhost:4321
Use actual IDs from the current demo fixture/search response. Do not copy an illustrative placeholder as though it were a real place.
Choose one of the six capabilities
1. search_melaka_places
REST: GET /api/v1/places
Use it to find covered stable IDs from a query, category, locale, and bounded filters. Do not use it to infer that an unreturned real-world place does not exist.
The response should explain matching and distinguish satisfied conditions from unknown conditions. Stable cursors are bound to filters and a data version; a changed version should produce a recoverable conflict rather than silently changing pagination.
2. get_melaka_place_facts
REST: GET /api/v1/places/{place_id}
Use it when you already have the stable ID and need facts, evidence, applicable times, sources, restrictions, or sub-service state. Request only allowlisted fields. Necessary status/source/version context remains even with projection.
An uncovered field is unknown; it is not fabricated. A nonexistent ID is a 404.
3. check_melaka_visit_window
REST: POST /api/v1/visit-window/check
Use it for one place/service, arrival instant, duration, party, and relevant constraints. It evaluates published schedules, last entry, exceptions, and sub-service state. It does not confirm live operation, inventory, admission, or booking.
4. get_melaka_weather_advisory
REST: GET /api/v1/weather/advisory
Use it for a registered location and date within configured coverage. Read spatial granularity, issue/valid times, freshness, and provider state. no_location_data, out_of_forecast_range, stale, and unavailable are meaningful outcomes. No alert is not a guarantee of safety.
Live weather is not currently qualified; demo or unavailable output must identify itself.
5. plan_melaka_day
REST: POST /api/v1/itineraries/plan
Use it to generate a bounded one-day candidate plan from structured time, party, budget, hard constraints, preferences, candidate IDs, and at most eight requested stops. The planner uses deterministic filtering/ranking and complete validation. It does not promise a global optimum.
Missing route or required cost evidence remains a blocking unknown. Exact starting coordinates are transient and must not be logged.
6. validate_melaka_itinerary
REST: POST /api/v1/itineraries/validate
Use it when you already have up to eight structured stops and want conflicts, blocking unknowns, suggested fixes, checked/unchecked dimensions, and evidence. Free-form prose is not silently accepted as trusted structured data.
A minimal request pattern
This illustrative request intentionally uses a placeholder ID:
curl -sS \
-H "Content-Type: application/json" \
-X POST \
"http://localhost:4321/api/v1/visit-window/check" \
--data '{
"place_id": "<demo_place_id_from_search>",
"arrival_at": "2030-01-15T10:30:00+08:00",
"duration_minutes": 60
}'
The date and ID are illustrative, not a live fact. Consult generated OpenAPI for the exact current schema and bounds; do not infer optional fields from this shortened example.
Read the envelope before the result
A normal business response includes fields equivalent to:
{
"success": true,
"request_id": "generated-per-request",
"schema_version": "...",
"data_version": "...",
"data_mode": "demo",
"result": {},
"sources": [],
"timestamp": "generated-at-runtime",
"cache": {},
"warnings": [],
"next_actions": []
}
Literal placeholder strings shown above are documentation, never valid runtime values. success=true means the operation completed. Inspect result.assessment, evaluation_scope, assumptions, blocking unknowns, and unchecked dimensions before deciding whether the travel question was resolved.
Assessment semantics
feasible: all declared hard constraints in the evaluated scope passed; read assumptions and unchecked dimensions.infeasible: at least one supported hard contradiction exists.needs_verification: the operation ran, but material evidence is missing, stale, conflicting, restricted, or unavailable.
A valid request with insufficient evidence normally returns 200 plus needs_verification; that is not a server error.
Errors and retries
Expected error categories include:
400malformed syntax;401missing/invalid authentication where required;403valid identity without scope;404missing entity/route;409cursor/version or idempotency-style conflict;413request too large;422semantically unsupported range/input;429quota exceeded, withRetry-After;500safe internal error;503required provider unavailable with no usable cache.
Use the structured error code, retryable, and details. Do not retry every failure. Validation, authentication, permission, and unsupported-range errors need a changed request or authority. Bound retries and honour Retry-After.
Authentication and quotas
Public facts/docs/meta may be anonymous. Planning and validation can have a conservative anonymous quota; a scoped API key can raise limits for an integration.
An API key is not an end-user login or permission to submit private data unnecessarily. Keep it server-side, never place it in browser bundles or URLs, and never log the Authorization header. The server derives tenant identity from the credential and ignores a client-supplied tenant ID.
REST and MCP meter the same domain operation once. MCP initialisation and tool listing are not completed travel tasks.
Field projection and small outputs
Use fields only from the documented allowlist and request details when needed. A projection cannot remove evidence state, source linkage, or version fields necessary to interpret a returned value. The default response is a compact summary, not a mirror of source pages.
Input and output have configured size limits. Split a workflow semantically; do not try to upload an unrestricted itinerary or ask for every source body.
Cache and privacy
Public rights-cleared facts can be cached by revision. Private POST/calculation responses and credential-specific data should be private, no-store. Never cache an envelope with one tenant’s quota or request ID for another client.
Do not send names, emails, phone numbers, dietary preferences, or other unnecessary personal fields. Exact coordinates and complete itineraries are transient sensitive inputs even when a calculation is anonymous.
MCP clients
Remote MCP exposes the same six capability names and meanings. A compatible client should initialise, list tools, select one tool, validate its schema, and call it. Do not infer authentication or enduring authority from the initial session handshake. Compare data_version, evidence, and assessment semantics with REST during integration testing.
A safe client workflow
- Read meta and capability availability.
- Search once to obtain stable IDs when needed.
- Fetch facts only for the selected IDs/fields.
- Call a window, weather, plan, or validation tool that matches the decision.
- Inspect assessment, sources, evidence states, assumptions, and unchecked dimensions.
- Follow a next action only if it exists, is necessary, and the client is authorised.
- Stop rather than looping the same call without changed input or new evidence.
Final checklist
- Confirmed
data_mode; demo was not used for a real decision. - Selected the narrowest correct tool.
- Used stable IDs and structured inputs with bounds/time offsets.
- Kept keys and private trip data out of logs and URLs.
- Treated technical success separately from feasibility.
- Read evidence, freshness, resolution, sources, and versions.
- Preserved unknown/restricted values rather than inventing defaults.
- Honoured status codes, retryability, quotas, and
Retry-After. - Did not infer booking, live availability, contact, or payment capability.
The API is designed to make uncertainty machine-readable. A careful client keeps it that way.