---
title: "Legal opinion on your documents"
method: POST
path: "/api/v1/tools/legal_opinion_project"
---

# Legal opinion on your documents

`POST /api/v1/tools/legal_opinion_project`

## Request

- Base URL: `https://verified.realestate`
- URL: `https://verified.realestate/api/v1/tools/legal_opinion_project`
- Auth: HTTP bearer

The full document-based legal opinion, the one the LandLens workspace produces: upload the buyer's documents (sale deeds, patta, EC, approvals, tax receipts), name the parcel, and every document is read, classified and cross-checked against the land, registration, planning and court registers before the AI opinion (verdict, risk score, title chain, red flags, recommendations) generates. Actions: "upload" stores one file (file_name plus file_base64; pdf/jpg/png/doc/docx, up to 25 MB; kept 24 hours). One call carries at most 700 KB of file, so send a bigger file in parts: part 1 of N with file_name, then parts 2..N with the upload_id the first part returned, each part the base64 of the next slice of the file; "uploads" lists what is waiting; "remove" drops one; "create" returns a PROPOSAL with the itemised quote (survey_numbers, lat, lng and the revenue codes the free parcel lookup returns, plus an optional questionnaire); once the user approves it, the project is created, billed and started; "status" polls a project (progress, and anything the pipeline is waiting on); "answer" records replies to its questions and attaches documents (upload first, then document_actions for a requested one or attach_upload_ids for any other), submit_all true to continue. The finished report is read with the legal opinion report reader. Every action here is free; the approved run costs 10 credits for up to 100 pages, 4 per further 50 pages and 2 per survey number beyond 3, billed when approved.

## Request body

- object
  - `action` 'upload' | 'uploads' | 'remove' | 'create' | 'status' | 'answer', required
  - `file_name` string: upload: the file name with its extension, e.g. sale-deed-2019.pdf
  - `file_base64` string: upload: the file contents, base64 encoded (at most 950,000 characters per call; bigger files in parts)
  - `part` integer: upload: this part number, 1-based, when a file is sent in parts
  - `parts` integer: upload: how many parts the file is sent in (omit for a single-call upload)
  - `is_merged_upload` boolean: upload: true when one file holds several documents scanned together
  - `upload_id` string: remove: the upload_id to drop; upload parts 2..N: the upload_id part 1 returned
  - `name` string: create: a name for the project (optional)
  - `survey_numbers` string[]: create: survey numbers with sub-division, e.g. ["163/2A", "164"]; the first is the primary
  - `lat` number
  - `lng` number
  - `district_code` string: create: revenue codes from the free parcel lookup; they let the register checks run without guessing
  - `district_name` string
  - `taluk_code` string
  - `taluk_name` string
  - `village_code` string
  - `village_name` string
  - `rural_urban` 'rural' | 'urban'
  - `firka_ward_number` string
  - `urban_block_number` string
  - `sro_code` string: create: the sub-registrar office code from the free SRO lookup or the EC in hand; used when the revenue codes do not map to an office, common in Chennai
  - `sro_name` string
  - `upload_ids` string[]: create: which pending uploads to include; all of them when omitted
  - `questionnaire` object: create: what the workspace asks: dealer_name, dealer_relationship, property_type, cersai_property_type, area_value, area_unit, is_vacant, concerns
    - `dealer_name` string
    - `dealer_relationship` string
    - `property_type` string
    - `cersai_property_type` string
    - `area_value` number
    - `area_unit` string
    - `is_vacant` string
    - `concerns` string
  - `survey_numbers_uncertain` boolean
  - `taluk_details_uncertain` boolean
  - `project_id` integer: status/answer: the project
  - `document_actions` object: answer: keyed by the missing document id from status; each {action: uploaded|not_available|explained|identifier_provided, upload_id?, value?}
  - `question_answers` object: answer: keyed by the question id from status; the answer text
  - `attach_upload_ids` string[]: answer: pending uploads to add to the project as further documents when they answer no particular request
  - `submit_all` boolean: answer: true to hand the answers to the pipeline and continue

## Response `200`

The envelope: ok, status, data, credits_charged, balance_after, request_id

## Other responses

- `401`: No valid credential
- `402`: Not enough credits
- `429`: Rate limit

---

[API](https://skmtc.dev/verified/apis/landlens-tool-api.md) · [All operations](https://skmtc.dev/verified/apis/landlens-tool-api/llms.txt) · [OpenAPI document](https://skmtc.dev/verified/apis/landlens-tool-api/revisions/7923c1c24431?raw)
