Survey Number to Location API for Tamil Nadu
Yes. The LandLens survey to location API takes a survey number and the revenue codes of its village or town and returns where the parcel is: its boundary as GeoJSON, a point inside it, the extent, the ULPIN, the patta number and the land type where the register records them. Up to 30 surveys go in one call. A survey that has been divided comes back with its sub-divisions listed instead of a guess. It costs nothing.
https://verified.realestate/api/v1/tools/survey_to_location- Price
- Free
- Source
- State cadastral boundary map
- Coverage
- All of Tamil Nadu, village and town land
- Answers in
- Usually under 2 seconds
Example
curl -X POST https://verified.realestate/api/v1/tools/survey_to_location \
-H "Authorization: Bearer $LANDLENS_KEY" \
-H "Content-Type: application/json" \
-d '{"district_code":"03","taluk_code":"14","village_code":"196","survey_number":"65","sub_division":"4B"}'
{
"ok": true,
"status": "ok",
"data": {
"found": true,
"parcel": {
"district_code": "03",
"district_name": "Kancheepuram",
"taluk_code": "14/Y",
"taluk_name": "Kundrathur",
"village_code": "196",
"village_name": "Kavanoor",
"survey_number": "65",
"sub_division": "4B",
"rural_urban": "rural",
"firka_ward_number": null,
"urban_block_number": null,
"ulpin": "74QA3LDD0UTRH0",
"latitude": 12.842117,
"longitude": 80.030955,
"patta_no": "2883",
"land_type": "Wet",
"extent_ares": "5",
"extent_hectares": "0.05",
"patta_district_code": "03",
"patta_taluk_code": "14/Y",
"patta_village_code": "196",
"boundary_geojson": "{\"type\": \"Polygon\", \"coordinates\": [[[80.03092567312981, 12.842313841409181], [80.03106501327065, 12.842301679079027], …]]}"
}
},
"credits_charged": 0
}
A real answer from the API (22 Oct 2026). The boundary coordinates are shortened.
What it returns
One survey returns parcel. Several (surveys) return parcels[] for the ones found and missing[] with a reason for the rest. found is false (status not_found) when nothing was placed.
| Field | What it holds |
|---|---|
parcel.latitude, parcel.longitude | A point inside the parcel, ready for any point-based call (zone checks, guideline value, neighbours). |
parcel.boundary_geojson | The parcel outline as a GeoJSON polygon, in longitude and latitude. |
parcel.survey_number, parcel.sub_division | The survey placed. |
parcel.district_code, taluk_code, village_code and their names | The codes and names of the village or town that holds it. Use these returned codes for the next call: for a multi-part town they name the part. |
parcel.rural_urban, firka_ward_number, urban_block_number | Village or town land, and for town land the ward and block. |
parcel.ulpin | The Unique Land Parcel Identification Number, where the map carries one. |
parcel.patta_no, land_type, extent_hectares, extent_ares | The patta number, land type (Wet, Dry, Poramboke) and extent where the register records them. |
needs_subdivision, subdivisions[], subdivision_count | A bare parent survey that is divided: the sub-divisions the register holds, so you can pick one. |
needs_block, block_choices | A town survey number that repeats across blocks: the blocks to choose from. |
parcels[], missing[], requested, count | Several surveys at once. Each missing entry has a reason: needs_subdivision, needs_block, on_register_unmapped (on the register but with no map outline), not_found or no_codes. |
found_in_other_villages | On a miss: other villages of the same taluk that hold that survey number. |
Ways to call it
One survey, or up to 30 in a single call.
One survey
The codes come free from resolve_revenue_codes (names) or resolve_parcel (a map point).
{"district_code": "03","taluk_code": "14","village_code": "196","survey_number": "65","sub_division": "4B"}
Several surveys
Each entry may carry the sub-division in the number and its own codes; the codes at the top are the default.
{"district_code": "03","taluk_code": "14","village_code": "196","surveys": [{"survey_number": "65/4B"},{"survey_number": "65/1"}]}
Inputs
The JSON body of the POST is the arguments. The three codes are required. resolve_revenue_codes turns names into codes at no charge.
| Argument | Type | What to send |
|---|---|---|
district_coderequired |
string | Revenue district code |
taluk_coderequired |
string | Revenue taluk code |
village_coderequired |
string | Revenue village / town code |
survey_number |
string | The survey number, e.g. 65, or with the sub-division, e.g. 65/4B. |
sub_division |
string | Sub-division, if separate from the survey number |
rural_urban |
string: rural, urban | "rural" or "urban": which register the codes belong to. A taluk numbers its villages and its towns separately, and the codes overlap. |
ward_code |
string | Urban ward number. A TOWN survey number repeats across blocks, so pass ward and block whenever the user has named them or an earlier result carried them. |
block_code |
string | Urban block number, e.g. 0025. Use with ward_code. Without it a town survey recorded in several blocks comes back needs_block with the blocks listed. |
surveys |
array | Several surveys in one call (up to 30). Each entry: survey_number (may carry the subdivision, "637/2B1"), optional sub_division, and optional district_code/taluk_code/village_code which default to the top-level codes, so surveys in different villages can be mixed. |
Code
Set LANDLENS_KEY to your key. In an AI app, connect https://verified.realestate/mcp once and ask in plain words instead. In Postman, download this API's collection, import it (File, Import) and set apiKey.
curl -X POST https://verified.realestate/api/v1/tools/survey_to_location \
-H "Authorization: Bearer $LANDLENS_KEY" \
-H "Content-Type: application/json" \
-d '{"district_code":"03","taluk_code":"14","village_code":"196","survey_number":"65","sub_division":"4B"}'
import os, requests
r = requests.post(
"https://verified.realestate/api/v1/tools/survey_to_location",
headers={"Authorization": f"Bearer {os.environ['LANDLENS_KEY']}"},
json={
"district_code": "03",
"taluk_code": "14",
"village_code": "196",
"survey_number": "65",
"sub_division": "4B"
},
timeout=60,
)
body = r.json()
print(body["status"], body["credits_charged"], body["data"])
const res = await fetch("https://verified.realestate/api/v1/tools/survey_to_location", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.LANDLENS_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
"district_code": "03",
"taluk_code": "14",
"village_code": "196",
"survey_number": "65",
"sub_division": "4B"
}),
});
const body = await res.json();
console.log(body.status, body.credits_charged, body.data);
Show me survey 65/4B of Kavanoor village, Kundrathur taluk, on the map.
Your AI looks up the village codes, places the survey and draws its boundary.
Responses
Every answer has the same envelope. What status can say for this call:
| status | What it means |
|---|---|
ok | The survey was placed. For several surveys, at least one was; read missing[] for the rest. |
not_found | Nothing was placed: the survey is divided (needs_subdivision), repeats across town blocks (needs_block), or the register holds no such survey there. |
invalid_args | A revenue code is missing. |
free_limit_reached | The account has used its free calls for the hour or the day. retry_after says how many seconds to wait; paid calls keep working. |
Where the data comes from
The Tamil Nadu cadastral boundary layer (the FMB parcel map published by the state GIS), joined to the revenue A-register and the town survey land register.
Village survey land and town survey land in every district. Towns split into parts (Mylapore Part 1 and Part 2, for example) are searched across every part, and the answer names the part that holds the survey.
Read from our copy of the state parcel map and the registers, refreshed from the state sources. Boundaries change only when the survey department redraws them.
The survey is matched by its revenue codes. When it is missing from the village named, the same code is tried as a town of that taluk, and other villages of the taluk that hold the number are named, rather than answering a bare miss.
Who uses it
Property platforms
Draw the plot on a listing map from the survey number in the deed, without asking the seller for a pin.
Lenders
Place every survey in a loan file on the map in one call, and see at once which ones are divided or missing.
Advocates
Check that a deed's survey numbers lie together where the schedule says, before reading the title.
Limits and good practice
- A bare parent survey that is divided is not drawn. Pick a sub-division from subdivisions[] and call again.
- A town survey number repeats across blocks. Send ward_code and block_code when you have them.
- Some surveys are on the register but have no outline on the state map (on_register_unmapped). Their land record can still be fetched.
- A batch stops looking after about 40 seconds; anything left is listed in missing[] with reason time.
Pricing
The survey to location lookup costs nothing, one survey or thirty. Free calls have their own allowance per hour and per day. Credits come from the same LandLens wallet as the chat and the minis. How billing works.
Free calls have an hourly and daily allowance. For more than that, or a platform built on these registers, we set up limits and a plan to match.
Questions
Is there an API to get the location of a survey number in Tamil Nadu?
Yes, this one. Send the survey number with its district, taluk and village codes and you get the boundary as GeoJSON and a point inside the parcel.
Can I look up several survey numbers at once?
Yes. Pass up to 30 in surveys and they are looked up in one call, with parcels[] for the found and missing[] with a reason for the rest.
Why did my survey number come back not found?
Usually because it is divided: the answer then lists its sub-divisions. Otherwise the survey may be a town survey (send rural_urban urban), may repeat across town blocks, or may sit in a neighbouring village, which found_in_other_villages names.
Where do I get the revenue codes?
resolve_revenue_codes turns district, taluk and village names into codes, and revenue_directory lists them. Both are free.
Updated 22 Oct 2026 · OpenAPI description