# URL guide > DEMONSTRATION ONLY. This site shows what technology can do. The data here is NOT current. It may be wrong or out of date. TCGI does not promise it is accurate. Do not use it to buy, claim or decide anything. For current product information, contact TCGI. Products shown are fictional. > expires_at: 2026-11-13T02:07:00+07:00 Every URL of this site as a template with one working example, so a client can build the final URL of any page without driving a form. This file is generated from the routes and the param definitions of the running service. **FETCH**: an agent may request the URL. **HAND TO THE PERSON**: an agent builds the link and gives it to the person, and must not request it, because robots.txt closes it to automated clients. ## Basics - Base URL: https://sandbox.itgives.link - Languages: `en`, `vi`. A page carries its language in the path (`/en/...`, `/vi/...`). The home page and `/find` have no language in the path and take `?lang=`. `en` is used when it is left out. A path such as `/vi/find` does not exist (404). - Currency: VND. Every price is for one person for one year. - Data as of: 2026-11-04. expires_at: 2026-11-13T02:07:00+07:00. After that time every URL answers 410, except `/healthz`. - A page works with no JavaScript. Every answer a form gives is in the URL, so the URL alone gives the full page. | Product | slug | id | |---|---|---| | Personal Accident Cover (Demo) | `accident` | `demo-accident` | | Comprehensive Health Cover (Demo) | `comprehensive` | `demo-comprehensive` | | Hospital Cover (Demo) | `hospital` | `demo-hospital` | A fact id is the product id, a dot, and the fact key: `{product id}.{fact_key}`. It is the anchor of the fact on its product page and the `fact` of a match reason. Fact keys by product: - `accident`: `overview`, `age_entry`, `card_required`, `child_alone`, `not_accepted`, `wait_accident`, `benefit_death_disability`, `benefit_allowance`, `benefit_medical`, `cover_period`, `preexisting`, `excl_fighting`, `excl_sport`, `excl_alcohol`, `excl_war`, `price_basis`, `where_sold`, `how_to_buy`, `how_to_claim`, `renewal`, `cancellation`, `payment`, `contact` - `comprehensive`: `overview`, `age_entry`, `card_required`, `child_alone`, `child_copay`, `wait_illness`, `wait_chronic`, `wait_maternity`, `wait_accident`, `benefit_hospital`, `benefit_outpatient`, `benefit_dental`, `benefit_maternity`, `preexisting`, `excl_cosmetic`, `excl_experimental`, `excl_self_harm`, `excl_war`, `sum_insured_levels`, `chronic_list`, `price_basis`, `where_sold`, `cover_period`, `how_to_buy`, `how_to_claim`, `renewal`, `cancellation`, `payment`, `contact` - `hospital`: `overview`, `age_entry`, `age_basis`, `card_required`, `child_with_parent`, `wait_illness`, `wait_serious_illness`, `wait_accident`, `benefit_hospital`, `benefit_serious_illness`, `preexisting`, `excl_cosmetic`, `excl_war`, `sum_insured_levels`, `serious_illness_list`, `price_basis`, `where_sold`, `cover_period`, `how_to_buy`, `how_to_claim`, `renewal`, `cancellation`, `payment`, `contact` - Needs (`need`): `hospital` (Hospital stay), `serious_illness` (Serious illness), `accident` (Accident), `outpatient` (Outpatient), `dental` (Dental), `maternity` (Maternity). - Depths (`depth`): `newcomer` (I am new to insurance), `comparer` (I am comparing products), `advisor` (I advise customers), `servicing` (I help existing customers), `tech` (I want to see how this works). ## FETCH. Pages | Page | Template | Example | |---|---|---| | Home | `/?lang={lang}` | https://sandbox.itgives.link/?lang=vi | | Product list | `/{lang}/products` | https://sandbox.itgives.link/en/products | | Product | `/{lang}/products/{slug}` | https://sandbox.itgives.link/en/products/accident | | Product at a depth | `/{lang}/products/{slug}?depth={depth}` | https://sandbox.itgives.link/en/products/accident?depth=advisor | | One fact on its product page | `/{lang}/products/{slug}#{fact id}` | https://sandbox.itgives.link/en/products/hospital#demo-hospital.age_basis | | Product as markdown (English only) | `/en/products/{slug}.md` | https://sandbox.itgives.link/en/products/accident.md | | Product for agents: who it is not for, what it covers, every line with its fact id (English only) | `/llms/products/{slug}.txt` | https://sandbox.itgives.link/llms/products/accident.txt | | A worked price on the page (`accident` only) | `/{lang}/products/{slug}?sum_insured={n}&add_daily=1&daily_vnd={n}&add_medical=1&medical_vnd={n}#price` | https://sandbox.itgives.link/en/products/accident?sum_insured=200000000&add_daily=1&daily_vnd=150000&add_medical=1&medical_vnd=40000000#price | | Compare two products | `/{lang}/compare/{a}-vs-{b}` | https://sandbox.itgives.link/en/compare/accident-vs-comprehensive | | Guide | `/{lang}/guides/{guide}` | https://sandbox.itgives.link/en/guides/newcomer-choosing-cover | | Glossary | `/{lang}/glossary` | https://sandbox.itgives.link/vi/glossary | | One word in the glossary | `/{lang}/glossary#{word}` | https://sandbox.itgives.link/en/glossary#sum-insured | | How this was built | `/{lang}/how-this-was-built` | https://sandbox.itgives.link/en/how-this-was-built | | A common situation, by age | `/{lang}/scenarios/{situation}` | https://sandbox.itgives.link/en/scenarios/no-bhyt-card | - `depth` changes a product page only: the six facts at a glance, and plain wording at `newcomer` and `tech` against standard wording at the others. `newcomer` is used when it is left out. The product list carries it into its product links. A guide page ignores it. - An anchor (`#...`) is read by the browser, not by the server. A client that fetches the URL gets the whole page and finds the fact at the element whose `id` is the fact id. - Compare: `{a}` comes before `{b}` in slug order, which is alphabetical. The other order answers 308 with the right address. A product compared with itself is 404. The valid pairs: - https://sandbox.itgives.link/en/compare/accident-vs-comprehensive - https://sandbox.itgives.link/en/compare/accident-vs-hospital - https://sandbox.itgives.link/en/compare/comprehensive-vs-hospital - Guides: - https://sandbox.itgives.link/en/guides/newcomer-choosing-cover - https://sandbox.itgives.link/en/guides/advisor-product-rules - https://sandbox.itgives.link/en/guides/after-you-choose - Common situations. Which ones exist is read from the products' rules: - https://sandbox.itgives.link/en/scenarios/no-bhyt-card - https://sandbox.itgives.link/en/scenarios/child-under-6 - https://sandbox.itgives.link/en/scenarios/age-60-and-over - Glossary words (`{word}`): `sum-insured`, `waiting-period`, `pre-existing`, `lump-sum`, `co-payment`, `bhyt`, `premium`, `claim`, `exclusion`, `listed-serious-illness`, `listed-chronic-condition`, `age-at-last-birthday`, `sum-insured-per-year`. ## FETCH. Data | Data | Template | Example | |---|---|---| | All products | `/api/v1/products` | https://sandbox.itgives.link/api/v1/products | | One product | `/api/v1/products/{slug}` | https://sandbox.itgives.link/api/v1/products/accident | | Match | `/api/v1/match?age={n}&has_card={has_card}&need={need}&who={who}` | https://sandbox.itgives.link/api/v1/match?age=34&has_card=false&need=hospital&need=dental&who=self | | Match, params in the path | `/api/v1/match/age/{n}/card/{card}/need/{need}/who/{who}` | https://sandbox.itgives.link/api/v1/match/age/34/card/no/need/hospital/need/dental/who/self | | Quote | `/api/v1/quote?sum_insured={n}&daily_vnd={n}&medical_vnd={n}` | https://sandbox.itgives.link/api/v1/quote?sum_insured=200000000&daily_vnd=150000&medical_vnd=40000000 | | Quote, params in the path | `/api/v1/quote/sum/{n}/daily/{n}/medical/{n}` | https://sandbox.itgives.link/api/v1/quote/sum/200000000/daily/150000/medical/40000000 | | Glossary as JSON | `/api/v1/glossary` | https://sandbox.itgives.link/api/v1/glossary | | What a customer may say, and the call for it | `/llms-intents.txt` | https://sandbox.itgives.link/llms-intents.txt | | The same as JSON | `/api/v1/intents` | https://sandbox.itgives.link/api/v1/intents | | API description | `/openapi.json` | https://sandbox.itgives.link/openapi.json | | Site summary for agents | `/llms.txt` | https://sandbox.itgives.link/llms.txt | | Every product as markdown | `/llms-full.txt` | https://sandbox.itgives.link/llms-full.txt | | Every price, worked out | `/llms-prices.txt` | https://sandbox.itgives.link/llms-prices.txt | | This guide | `/llms-urls.txt` | https://sandbox.itgives.link/llms-urls.txt | | Sitemap | `/sitemap.xml` | https://sandbox.itgives.link/sitemap.xml | | Rules for automated clients | `/robots.txt` | https://sandbox.itgives.link/robots.txt | | Health check | `/healthz` | https://sandbox.itgives.link/healthz | - MCP: `POST https://sandbox.itgives.link/mcp` with a JSON-RPC body. It answers POST only, so a GET is 405. The tools give what the API gives. - The path form returns the same JSON as the query form. Params come as `/name/value` pairs in any order, and `need` can repeat. Short names: `sum` for `sum_insured`, `daily` for `daily_vnd`, `medical` for `medical_vnd`, `card` for `has_card`. The full names work in the path too. `card` takes `yes` or `no`. - An API call with a param it does not know, or a value outside the list, answers 400 with the reason. A param left out is a skipped answer. Match params: | Param | Allowed values | Can repeat | Must be given | Meaning | |---|---|---|---|---| | `age` | a whole number from 0 to 120 | no | no | Age of the person to be insured, in completed years. One call is one person, so a child gets a call of their own with the child's age. Leave out to skip. | | `age_days` | a whole number from 0 to 364 | no | no | For a baby under one year: the age in days. Some entry ages are counted in days. Send it in place of age. Leave out for anyone aged 1 or older. | | `has_card` | `true`, `false` | no | no | Holds a Vietnamese state health insurance (BHYT) card. Leave out to skip. | | `need` | `hospital`, `serious_illness`, `accident`, `outpatient`, `dental`, `maternity` | yes | no | What the cover is for. Repeat the param for more than one need: need=hospital&need=dental. A product that covers only some of them, or pays only part of one, is partly. Leave out to skip. | | `who` | `self`, `child`, `family` | no | no | Who the cover is for. It changes no result. family adds a note that results are per person, so send one call for each family member with that person's age. Leave out to skip. | Quote params: | Param | Allowed values | Can repeat | Must be given | Meaning | |---|---|---|---|---| | `sum_insured` | a whole number | no | yes | Sum insured in VND. | | `daily_vnd` | a whole number | no | no | Daily allowance in VND for each day in hospital. Its rate is charged on this amount times the days it can be paid, not on the sum insured. Leave out for no allowance. | | `medical_vnd` | a whole number | no | no | Medical cost limit in VND. Its rate is charged on this limit. Leave out for no medical cover. | Quote amounts for `accident`: `sum_insured` from 20,000,000 to 1,000,000,000. `daily_vnd` is one of 100,000, 150,000, 200,000. `medical_vnd` from 1 to 80,000,000. Write each number in the URL with no separators. ## HAND TO THE PERSON. The guided finder `/find?depth={depth}&who={who}&age={n}&need={need}&card={card}&step=results` The page shows the full result with no JavaScript. Add `&lang=vi` for Vietnamese. Give the link to the person. For the same answer as data, an agent calls the Match API above. | Param | Allowed values | Can repeat | If left out | |---|---|---|---| | `depth` | `newcomer`, `comparer`, `advisor`, `servicing`, `tech` | no | Skipped. Product links on the result then open at `newcomer` | | `who` | `self`, `child`, `family` | no | Skipped. It changes no result. `family` adds a note that results are per person | | `age` | a whole number from 0 to 120 | yes, once per person, up to 8. One value with commas also works: `age=34,36,4` | Skipped. Age then excludes no product | | `need` | `hospital`, `serious_illness`, `accident`, `outpatient`, `dental`, `maternity` | yes | Skipped. Need then excludes no product | | `card` | `yes`, `no`, `not_sure` | no | Skipped, which gives the same result as `not_sure`. The card rule then excludes no product | | `step` | `0`, `1`, `2`, `3`, `4`, `results` | no | `results` when any answer is given, the first question when none is. A number opens that question with the answers so far kept | | `lang` | `en`, `vi` | no | `en` | - Skipped answers never exclude a product. - The answer "Not sure" to the card question puts `card=not_sure` in the URL. - A value outside the list is read as skipped. It is never an error. The one exception is `age`: a value that is not a whole number in range opens the age question again. - `card` is read only when it can change a result. With needs given, and none of them covered by a product that needs a card, it is dropped. - With more than one `age`, the page shows one block per person, each the same as that person's own link. Worked example. Linh is 34, wants cover for her family, wants hospital stay and dental, and has no BHYT card: - https://sandbox.itgives.link/find?depth=newcomer&who=family&age=34&need=hospital&need=dental&card=no&step=results Results: fits: Comprehensive Health Cover (Demo). partly: Personal Accident Cover (Demo). no: Hospital Cover (Demo). The same with her partner aged 36 and her child aged 4, one block per person: - https://sandbox.itgives.link/find?depth=newcomer&who=family&age=34&age=36&age=4&need=hospital&need=dental&card=no&step=results For the same answers as data, one call per person: - `https://sandbox.itgives.link/api/v1/match?age=34&has_card=false&need=hospital&need=dental&who=family` - `https://sandbox.itgives.link/api/v1/match/age/34/card/no/need/hospital/need/dental/who/family` ## HAND TO THE PERSON. Filtered pages `/{lang}/products?need={need}&age={n}&card={card}&price={price}&wait={wait}&preexisting={preexisting}` | Param | Allowed values | Can repeat | What it keeps | |---|---|---|---| | `need` | `hospital`, `serious_illness`, `accident`, `outpatient`, `dental`, `maternity` | no | Products that cover the need | | `age` | a whole number from 0 to 120 | no | Products that take a person of that age | | `card` | `required`, `not_required` | no | By the product's rule, not the person's answer: products that need a BHYT card, or do not | | `price` | `under_1m`, `1m_5m`, `over_5m` | no | Products with a price in the band: `under_1m` is Under VND 1 million a year, `1m_5m` is VND 1 to 5 million a year, `over_5m` is VND 5 million a year or more | | `wait` | `0`, `90`, `270` | no | Products whose longest waiting period is that many days or fewer | | `preexisting` | `yes`, `no` | no | Products that cover pre-existing conditions (`yes`) or do not (`no`) | - A filter left out, or a value outside its list, excludes nothing. `depth` can be added and is carried into the product links. - This `card` is not the finder's `card`: here it filters on what the product asks for. - https://sandbox.itgives.link/en/products?need=maternity Lists: Comprehensive Health Cover (Demo). - https://sandbox.itgives.link/vi/products?age=34&card=not_required Lists: Personal Accident Cover (Demo), Comprehensive Health Cover (Demo). A product page also takes `age`, which marks that person's row in a price table by age: `/{lang}/products/{slug}?age={n}` - https://sandbox.itgives.link/en/products/hospital?age=34 ## The same answer on each surface The finder is for people and the API is for agents. They ask the same questions and run the same rules, with these names: | Answer | Finder `/find` | Product list filter | Match API, query | Match API, path | MCP `match_products` | |---|---|---|---|---|---| | Age | `age=34`, once per person | `age=34`, once only | `age=34`, one call per person | `/age/34` | `age: 34` | | Card | `card=yes` `card=no` `card=not_sure` | `card=required` or `card=not_required`, a filter on the product's rule | `has_card=true`, `has_card=false`, or left out for `not_sure` | `/card/yes`, `/card/no`, or left out | `has_card: true`, `has_card: false`, or left out | | Need | `need=` once per need | `need=` once only | `need=` once per need | `/need/` once per need | `need: [...]` | | Who | `who=` | not taken | `who=` | `/who/` | `who: "..."` | | Depth | `depth=` | `depth=`, carried into links | not taken. A fact holds both wordings: `text.standard` and `text.plain` | not taken | not taken | | Language | `lang=` | in the path: `/en/`, `/vi/` | not taken. Every text comes in `en` and `vi` | not taken | not taken | | Step | `step=results` | not taken | not taken | not taken | not taken | | Amount | Product page form | Quote API, query | Quote API, path | MCP `price_quote` | |---|---|---|---|---| | Sum insured | `sum_insured=` | `sum_insured=` | `/sum/` | `sum_insured: ...` | | Daily allowance | `add_daily=1&daily_vnd=` | `daily_vnd=` | `/daily/` | `daily_vnd: ...` | | Medical limit | `add_medical=1&medical_vnd=` | `medical_vnd=` | `/medical/` | `medical_vnd: ...` | ## Checked against the running code - `/find?...&step=results` renders the full result on the server. No JavaScript is needed. - "Not sure" on the card question is `card=not_sure`. A value such as `card=unsure` is not in the list and is read as skipped, which gives the same result. - Compare pairs are in alphabetical slug order. The other order redirects with 308. It is never a 404, unless a slug does not exist or both are the same. - `?lang=vi` works on `/find` and on the home page. Every other page carries the language in the path. - `/find` and the filtered pages are closed in robots.txt to every automated client. Every URL under FETCH in this file is open in robots.txt.