API Documentation

Abstract commercial leases and extract structured data via REST API

🚀 Quick Start

Get your API key from the API keys page and start abstracting leases!

curl -X POST 'https://leasebossai.com/api/parse.php' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{ "file": "https://example.com/lease.pdf" }'

Base URL

https://leasebossai.com/api

For production: https://leasebossai.com/api

🔐 Authentication

All API requests require an API key in the Bearer authorization header:

Authorization: Bearer YOUR_API_KEY

Do not put an API key in a URL. Query-string keys are rejected because URLs are routinely saved in browser history, access logs, analytics and referrer headers.

The API supports cross-origin requests for integrations, including the Authorization header. A Bearer key grants its holder access without another login, so keep it in a server-side secret store. Do not embed it in public browser JavaScript, local storage, a mobile binary or a client-side repository.

📡 Endpoints

Abstract Lease

Abstract a lease document and extract structured data.

POST /api/parse.php

Cost: $20 per lease contract. An amendment to a lease already on your account is free, and a document that fails to abstract is not charged. The usage block in the response says which of those happened.

Method 1: File Upload (multipart/form-data)

curl -X POST https://leasebossai.com/api/parse.php \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -F "file=@/path/to/lease.pdf"

Method 2: File URL (JSON)

curl -X POST https://leasebossai.com/api/parse.php \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "file": "https://example.com/lease.pdf" }'

Supported File Types

  • PDF (.pdf)
  • Microsoft Word (.doc, .docx) and Rich Text (.rtf)
  • Excel (.xlsx) and PowerPoint (.pptx)
  • Plain Text (.txt) and CSV (.csv)
  • Images and scans (.png, .jpg, .jpeg, .tif, .tiff, .bmp, .webp, .heic)

Maximum File Size: 10 MB

Scans and photographs are read with OCR. Where the read is poor — blank pages, low confidence, pages that had to be rotated, or a footer claiming more pages than were uploaded — the abstraction carries ocr_* findings saying so, rather than quietly returning a short abstract.

A ZIP archive of leases can be uploaded on the batch page. It is expanded on the server and each document inside becomes its own job; folder structure is discarded and anything unreadable is reported rather than failing the batch.

Note: This API is designed to abstract one lease per request. If a file contains multiple leases, unexpected results may occur.

📚 Reading the portfolio (v1)

Everything above abstracts a document. Everything here reads what has already been abstracted — leases, abstracts, clauses, schedules, key dates, findings and search — under a versioned path, with the same API key.

curl https://leasebossai.com/api/v1/leases?per_page=10 \
  -H "Authorization: Bearer YOUR_API_KEY"
Rate limit
120 requests per key per minute
Pagination
page, per_page (max 100); follow next
Cost
Reads are free. Only /parse is charged.
Method Path Returns
GET /v1 This list of endpoints
GET /v1/leases The organization's leases, newest first
q
— Match filename, lease type, landlord, tenant or address.
GET /v1/leases/{id} One lease: consolidated fields and provenance
GET /v1/leases/{id}/abstract The lease abstract
GET /v1/leases/{id}/clauses Segmented and classified provisions
type
— Restrict to one clause type, e.g. insurance.
text
— false to omit clause bodies, which are most of the bytes.
GET /v1/leases/{id}/payments The payment schedule
GET /v1/leases/{id}/amendments Amendments attached to this lease
GET /v1/leases/{id}/validations Risk findings for this lease
status
— open, accepted, ignored or resolved. Default open.
GET /v1/leases/{id}/text The converted document text
GET /v1/events Key dates across the portfolio
within_days
— How far ahead to look. Default 365.
past_days
— How far back to include dates that have passed.
date_type
— Restrict to one kind of date, e.g. expiration.
GET /v1/payments Upcoming payments across the portfolio
GET /v1/validations Risk findings across the portfolio
status
— open, accepted, ignored or resolved. Default open.
level
— error, warning or note.
code
— One rule, e.g. expiration_before_commencement.
GET /v1/search Hybrid keyword, semantic and facet search
q
— Free text. Read for dates and amounts as well as keywords.
f
— Repeatable facet filter as name|op or name|op|value.
sort
— relevance, expiration, rent or recent.
GET /v1/portfolio Portfolio statistics
GET /v1/analytics WALT, expiration ladder and concentration, with coverage
years
— How many years of the expiration ladder. Default 10, max 25.
top
— How many to name in each concentration table. Default 10.
GET /v1/entities Properties, tenants and landlords
kind
— property, tenant or landlord. Default tenant.
q
— Match the name.
sort
— rent, sf, count or name. Default rent.
unused
— true to include ones no lease points at.
GET /v1/entities/{id} One property, tenant or landlord
GET /v1/entities/{id}/leases The leases filed under it
GET /v1/portfolios Named groupings of properties
GET /v1/batches Recent upload batches
GET /v1/batches/{id} One batch and its files
GET /v1/webhooks Configured webhook endpoints
GET /v1/webhooks/deliveries Recent webhook delivery attempts
status
— pending, delivered, failed or abandoned.
event
— One event name, e.g. lease.parsed.
webhook_id
— Restrict to one endpoint.
POST /v1/chat Ask a question, answered with citations
question
— Required. The question, in the JSON body.
lease_id
— Ask about one lease instead of the whole portfolio.
POST /v1/parse Abstract one lease document
file
— A publicly reachable URL, or a multipart upload.

Response shape

Three shapes and no others. Every response carries success and a request_id, which is also returned in the X-Request-Id header — quote it if you need to ask us about a request.

// one resource
{ "success": true, "request_id": "...", "data": { ... } }

// a page of a collection. count is the whole collection, not this page.
{ "success": true, "request_id": "...", "count": 41, "page": 1, "per_page": 25,
  "next": "https://leasebossai.com/api/v1/leases?page=2", "previous": null, "results": [ ... ] }

// an error. error_code is the stable value to branch on.
{ "success": false, "request_id": "...", "error": "No lease with id 41.",
  "error_code": "not_found" }

🏢 Tenants, buildings and portfolio figures

A lease carries its tenant, landlord and address as text, the way the document wrote them. That is enough to display and useless to count: the same tenant arrives as Coastal Robotics, Inc. on one lease and COASTAL ROBOTICS INC on the next, and two suites of one building look like two buildings. /v1/entities is the resolved version: one record per tenant, landlord and building, with the leases filed under it.

canonical_key

The identity two names have to share to be treated as one. Every entity publishes its own, so you can tell why two leases were grouped — or why they were not — without asking us, and reproduce the same grouping over your own data. Legal suffixes, punctuation and case are removed; for a building the suite is dropped and the street type abbreviated, so 400 Harbor Way, Suite 200, Boston, MA becomes 400 harbor way|boston|ma.

merged_into

Grouping is deliberately cautious: one word different is a different company until somebody says otherwise. When they do, the record they merged away is kept and points at the survivor, so an id you stored keeps working. Follow merged_into when it is not null rather than treating the record as current.

/v1/analytics returns the four figures a portfolio gets judged by, computed from those records: WALT (weighted average lease term, in years), the expiration ladder, concentration by tenant, landlord and building, and rent per building.

Read the coverage before the number

A weighted average over the two thirds of a portfolio that had a readable expiration date is not an approximate answer — it is an answer about a different portfolio. So every figure arrives with the count behind it and what it had to leave out: walt.counted, walt.excluded.no_expiration_date, walt.excluded.expired, and a coverage block for the whole payload. Concentration reports unattributed for leases whose party we could not identify, and it is in the denominator — so the shares are of the real portfolio rather than of the part we understood.

WALT comes back three ways: by_rent, by_rentable_sf and unweighted, because when the first two disagree that is the finding: a rent-weighted term well above the area-weighted one means the expensive space is what runs longest, and the near-term expiries are the cheap space.

Concentration includes an HHI — the Herfindahl–Hirschman index, the sum of each group's squared percentage share, from near 0 to 10,000. It is reported over every group, not just the ones named in results, so narrowing top does not change it. The accompanying hhi_label reads it against the usual thresholds (1,500 and 2,500) so you do not have to pick your own.

curl https://leasebossai.com/api/v1/analytics?years=10&top=5 \
  -H "Authorization: Bearer YOUR_API_KEY"

{
  "success": true,
  "data": {
    "walt": { "by_rent": 5.9, "by_rentable_sf": 5.6, "unweighted": 6.4,
              "unit": "years", "counted": 3,
              "excluded": { "no_expiration_date": 1, "expired": 1, ... } },
    "expiration_ladder": {
      "years": [ { "year": 2026, "lease_count": 0, "annual_rent": 0.0,
                   "share_of_rent": 0.0 }, ... ],
      "expired": { ... }, "undated": { ... }, "peak_year": 2029
    },
    "concentration": {
      "tenant": { "groups": 3, "hhi": 3841.2, "hhi_label": "Highly concentrated",
                  "top_share": 0.438, "results": [ ... ],
                  "unattributed": { "lease_count": 0, "annual_rent": null } },
      "landlord": { ... }, "property": { ... }
    },
    "coverage": { "live_lease_count": 3, "with_expiry": 3, "with_tenant": 3, ... }
  }
}

🔔 Webhooks

Rather than polling /leases to see whether an upload finished, subscribe an endpoint on the Webhooks page and we will post to it. Delivery is retried 6 times with a widening gap, so a deploy or a restart on your side does not lose an event.

Event Sent when
lease.parsed A document finished extraction and was saved, however it arrived: dashboard, API or batch.
lease.updated A person corrected a field, or an amendment was attached or detached, so the position in force is different from before.
batch.completed Every file in an upload batch reached a final state.
validation.opened A check began failing on a lease that was previously clean, or a new document raised one.
key_date.due A dated obligation crossed 90, 30 or 7 days out, or passed. Sent once per date per threshold, not daily.
ping Sent only when you ask for one, to prove the endpoint works before it matters.

What arrives

A thin payload and a link, not the whole extraction. The lease object is the same one GET /v1/leases returns, so nothing you learn here can disagree with what you fetch next.

POST /your/endpoint
Content-Type: application/json
X-LeaseBoss-Event: lease.parsed
X-LeaseBoss-Delivery: evt_9f86d081884c7d65
X-LeaseBoss-Signature: t=1767225600,v1=5257a869e7ecdb4d...
X-LeaseBoss-Attempt: 1

{
  "id": "evt_9f86d081884c7d65",
  "event": "lease.parsed",
  "created_at": "2026-01-01T09:20:00+00:00",
  "data": {
    "lease": { "id": 41, "tenant_name": "Coastal Robotics Inc",
               "property_address": "400 Harbor Way", "monthly_rent": 12500.00,
               "expiration_date": "2029-06-30",
               "links": { "self": "https://leasebossai.com/api/v1/leases/41" } },
    "source": "api",
    "counts": { "clauses": 42, "open_risks": 3, "fields_to_review": 7, "pages": 31 },
    "amendment": null
  }
}

Verify the signature

Anyone who learns your URL can post to it, so check the signature before you trust the body. The HMAC is taken over <t>.<raw body> with SHA-256 and your signing secret. Check t too — without a freshness window, a delivery captured once can be replayed forever.

# Python
import hashlib, hmac, time

def verify(header, body, secret, tolerance=300):
    parts = dict(p.split("=", 1) for p in header.split(","))
    t = int(parts["t"])
    if abs(time.time() - t) > tolerance:
        return False
    expected = hmac.new(secret.encode(), f"{t}.".encode() + body,
                        hashlib.sha256).hexdigest()
    return hmac.compare_digest(expected, parts["v1"])

Answer quickly

Reply 2xx as soon as you have the payload and do the work behind your own queue. We wait 10 seconds, and anything else is treated as a failure and retried.

Expect a repeat

A retry carries the same X-LeaseBoss-Delivery id. Treat it as the idempotency key: a network failure after your 200 means we will send it again.

https, publicly reachable

Private and internal addresses are refused. The signature proves who sent a payload, not that nobody else read it.

Failures are visible

Every attempt and what your endpoint said is on the Webhooks page, and at GET /v1/webhooks/deliveries. After 20 consecutive failures we stop calling and tell you.

✅ Success Response (200 OK)

Every response carries four blocks under data: document (what kind of document this is), parsed (the extracted terms, always the full schema whether or not a value was found), provenance (the quote behind each value, keyed by dotted field path), and meta (file and run details).

Absent values are present as fields. A term the lease does not address comes back as null, "" or [] rather than being omitted, so you can tell “the lease is silent” from “we did not look”. Fields with no provenance entry were not found in the document.

{
    "success": true,
    "abstraction_id": 1842,
    "data": {
        "document": {
            "document_type": "lease",
            "amendment_number": null,
            "amendment_type": "",
            "effective_date": "",
            "amends_lease_dated": "",
            "amends_property": "",
            "amends_tenant": ""
        },
        "parsed": {
            "basic_info": {
                "lease_type": "Triple Net (NNN)",
                "execution_date": "2024-01-15",
                "governing_state": "WA"
            },
            "parties": {
                "landlord_name": "Harbor Point Owner LLC",
                "landlord_address": "1200 Harbor Point Drive, Suite 900, Seattle, WA 98101",
                "tenant_name": "Northwind Analytics Inc.",
                "tenant_address": "1200 Harbor Point Drive, Suite 400, Seattle, WA 98101",
                "guarantor_name": "Northwind Holdings Inc.",
                "guarantor_address": "",
                "property_manager_name": "Cascade Commercial Management",
                "property_manager_contact": "jrivera@cascadecm.example (206) 555-0142"
            },
            "premises": {
                "property_name": "Harbor Point Tower",
                "property_address": "1200 Harbor Point Drive, Seattle, WA 98101",
                "premises_description": "Suite 400 on the fourth floor, as shown on Exhibit A",
                "suite_unit": "400",
                "floor": "4",
                "county": "King",
                "property_type": "Office",
                "rentable_sf": 12000,
                "usable_sf": 10800,
                "parking_spaces": 24
            },
            "lease_term": {
                "commencement_date": "2024-03-01",
                "rent_commencement_date": "2024-06-01",
                "possession_date": "2024-02-15",
                "expiration_date": "2029-02-28",
                "initial_term_months": 60,
                "free_rent_months": 3,
                "holdover_rate": 150
            },
            "term_certainty": {
                "commencement_status": "",
                "expiration_status": "",
                "area_status": "",
                "basis": "",
                "trigger_event": "",
                "outside_date": "",
                "confirming_document": ""
            },
            "base_rent": {
                "initial_monthly_rent": 30000,
                "initial_annual_rent": 360000,
                "rent_per_sf": 30,
                "amount_kind": "",
                "amount_text": "",
                "currency": "USD",
                "payment_frequency": "monthly",
                "escalation_type": "fixed_percent",
                "annual_escalation_percent": 3,
                "cpi_index_name": "",
                "cpi_floor_percent": null,
                "cpi_ceiling_percent": null,
                "percentage_rent_rate": null,
                "breakpoint_sales_amount": null,
                "rent_review_date": "",
                "review_assumptions": "",
                "rent_schedule": [
                    {
                        "year": 1,
                        "monthly_rent": 30000,
                        "annual_rent": 360000,
                        "rent_psf": 30
                    },
                    {
                        "year": 2,
                        "monthly_rent": 30900,
                        "annual_rent": 370800,
                        "rent_psf": 30.9
                    }
                ]
            },
            "operating_expenses": {
                "expense_type": "Triple Net (NNN)",
                "base_year": "2024",
                "pro_rata_share": 12.5,
                "expense_stop_psf": null,
                "estimated_opex_psf": 11.5,
                "estimated_annual_opex": 138000,
                "cam_cap_percent": 5,
                "cam_cap_basis": "non_cumulative",
                "cam_exclusions": [
                    "Capital improvements except as amortized",
                    "Leasing commissions and marketing costs"
                ],
                "admin_fee_percent": 3,
                "property_tax_responsibility": "tenant",
                "insurance_responsibility": "tenant",
                "audit_right_days": 90
            },
            "security": {
                "security_deposit": 60000,
                "security_deposit_form": "cash",
                "loc_amount": null
            },
            "renewal_options": {
                "renewal_option_count": 2,
                "renewal_term_months": 60,
                "renewal_notice_days": 270,
                "renewal_rent_basis": "Fair market rent, not less than the then-current rent"
            },
            "termination": {
                "early_termination_allowed": true,
                "termination_effective_date": "",
                "termination_notice_days": 270,
                "termination_fee": 180000
            },
            "tenant_improvements": {
                "ti_allowance_total": 600000,
                "ti_allowance_psf": 50,
                "restoration_required": false,
                "return_conditions": "Broom clean, ordinary wear and tear excepted",
                "end_of_term_obligations": ""
            },
            "use_and_operations": {
                "permitted_use": "General office and software development",
                "exclusive_use": "None"
            },
            "assignment_subletting": {
                "assignment_allowed": "With Landlord's prior written consent, not to be unreasonably withheld",
                "subletting_allowed": "With Landlord's prior written consent for up to 40% of the Premises"
            },
            "construction_completion": {
                "tenant_improvement_work": "",
                "landlord_work": "",
                "completion_deadline": "",
                "permits_responsibility": "",
                "construction_insurance_required": false
            },
            "utilities": {
                "tenant_responsible_for": [
                    "Electricity",
                    "Telecommunications",
                    "Janitorial"
                ],
                "landlord_responsible_for": [
                    "Water",
                    "Sewer",
                    "Common area electricity"
                ],
                "utility_notes": ""
            },
            "maintenance_repairs": {
                "landlord_responsible": [],
                "tenant_responsible": [],
                "hvac_responsibility": "",
                "roof_structure_responsibility": "",
                "common_area_maintenance": ""
            },
            "maintenance_matrix": {
                "roof": "landlord",
                "hvac": "tenant",
                "parking_lot": "landlord",
                "foundation_structure": "landlord",
                "plumbing": "tenant",
                "electrical": "tenant",
                "windows_glass": "tenant",
                "exterior": "landlord",
                "interior": "tenant",
                "landscaping": "landlord",
                "pest_control": "",
                "janitorial": "tenant",
                "elevator": "landlord",
                "fire_life_safety": "shared",
                "snow_removal": "landlord"
            },
            "insurance_requirements": {
                "general_liability_limit": 2000000,
                "property_insurance_required": true,
                "workers_comp_required": true,
                "landlord_as_additional_insured": true,
                "insurance_notes": ""
            },
            "default_remedies": {
                "monetary_default_cure_days": 5,
                "non_monetary_default_cure_days": 30,
                "late_fee_percent": 5,
                "late_fee_fixed_amount": null,
                "interest_rate_on_late_payments": 12,
                "landlord_remedies": "",
                "tenant_remedies": ""
            },
            "warranties": {
                "landlord_warranties": "",
                "tenant_warranties": "",
                "warranty_notes": ""
            },
            "legal_provisions": {
                "estoppel_required": "yes",
                "estoppel_response_days": 10,
                "snda_required": "yes",
                "subordination_automatic": "yes",
                "force_majeure_present": "yes",
                "force_majeure_summary": "",
                "holdover_consent_required": "yes",
                "holdover_summary": "",
                "guaranty_present": "yes",
                "guaranty_type": "Limited corporate guaranty",
                "guaranty_capped_amount": 720000,
                "guaranty_summary": "",
                "attorneys_fees_prevailing_party": "yes",
                "jury_trial_waiver": "yes",
                "relocation_right": "no",
                "right_of_first_refusal": "no",
                "right_of_first_offer": "yes",
                "purchase_option": "no",
                "purchase_option_summary": "",
                "co_tenancy_clause": "no",
                "casualty_restoration_days": 180,
                "casualty_summary": "",
                "condemnation_summary": "",
                "environmental_provisions": "",
                "dispute_resolution": "Binding arbitration in King County, Washington",
                "notice_method": "Certified mail or nationally recognised overnight courier"
            },
            "additional_provisions": [
                "Tenant holds a right of first offer on the 5th floor.",
                "Landlord to deliver the Premises with a new roof membrane."
            ]
        },
        "provenance": {
            "base_rent.initial_monthly_rent": {
                "snippet": "Base Rent shall be Thirty Thousand Dollars ($30,000.00) per month",
                "page": 4,
                "basis": "verbatim",
                "confidence": 0.96
            },
            "base_rent.initial_annual_rent": {
                "snippet": "Base Rent shall be Thirty Thousand Dollars ($30,000.00) per month",
                "page": 4,
                "basis": "derived",
                "confidence": 0.96
            },
            "lease_term.expiration_date": {
                "snippet": "the Term shall expire on February 28, 2029",
                "page": 3,
                "basis": "verbatim",
                "confidence": 0.94
            },
            "maintenance_matrix.roof": {
                "snippet": "Landlord shall maintain, repair and replace the roof",
                "page": 11,
                "basis": "verbatim",
                "confidence": 0.91
            },
            "premises.rentable_sf": {
                "snippet": "containing approximately 12,000 rentable square feet",
                "page": 2,
                "basis": "verbatim",
                "confidence": 0.93
            }
        },
        "meta": {
            "filename": "harbor_point_suite_400.pdf",
            "file_type": "pdf",
            "file_size": 482913,
            "file_hash": "d41d8cd98f00b204e9800998ecf8427e",
            "status": "success",
            "processing_time": 8.41,
            "error_message": null,
            "cost": 20,
            "balance_before": 0,
            "balance_after": 0,
            "source": "api",
            "has_provenance": true,
            "page_count": 42
        }
    },
    "usage": {
        "cost": 20,
        "billed": true,
        "billing_reason": "lease_contract",
        "credit_applied": 0,
        "balance_remaining": 0,
        "calls_made": 137
    },
    "validation": {
        "open": 2,
        "by_level": {
            "error": 0,
            "warning": 2,
            "info": 0
        },
        "findings": [
            {
                "code": "critical_fields_unverified",
                "level": "warning",
                "title": "Critical values are unverified",
                "field_path": null,
                "message": "6 critical values have not been verified: Commencement Date, Annual Escalation Percent, Tenant Name and 3 others."
            },
            {
                "code": "missing_exhibit",
                "level": "warning",
                "title": "Referenced exhibits are not in the document",
                "field_path": null,
                "message": "The lease refers to Exhibit A, which does not appear in the document."
            }
        ]
    }
}

Generated from the live extraction schema, so this example always matches the current response shape. Two blocks are conditional and not shown above: duplicate_of, an abstraction ID present when the same file is already in your portfolio, and amendment, present when the document amends an existing lease rather than being one.

Provenance and confidence

Every value the model fills in is returned with the text that supports it, keyed by the same dotted path used in parsed. An abstraction you cannot trace back to the lease is a guess, so provenance is how you decide what to accept automatically and what to route to a person.

Key Meaning
snippet The passage the value came from, quoted from the document.
page Page the passage was found on, or null when the document carries no page markers.
basis verbatim — the value appears in the text as written. derived — calculated from other values, such as annual rent from monthly. inferred — read from context rather than stated. human — corrected or confirmed by a reviewer, which outranks everything above.
confidence 0–1. Below 0.6 the value is queued for review in the app, as is any value that cited nothing at all; a human basis is always treated as verified.

Field reference

Every field in parsed, with its dotted path. Priority is how much a wrong or missing value matters: critical fields drive the review queue and the risk checks. Enum fields accept only the listed values — an empty string means the lease does not address the point, which is deliberately distinct from a value of “landlord” or “no”.

155 fields across 22 sections.

Overview basic_info

Path Type Priority Allowed values
basic_info.lease_type text important
basic_info.execution_date date
basic_info.governing_state text

Parties parties

Path Type Priority Allowed values
parties.landlord_name text important
parties.landlord_address text
parties.tenant_name text critical
parties.tenant_address text
parties.guarantor_name text
parties.guarantor_address text
parties.property_manager_name text
parties.property_manager_contact text

Premises premises

Path Type Priority Allowed values
premises.property_name text
premises.property_address text important
premises.premises_description text
premises.suite_unit text
premises.floor text
premises.county text
premises.property_type text
premises.rentable_sf area critical
premises.usable_sf area
premises.parking_spaces count

Lease Term lease_term

Path Type Priority Allowed values
lease_term.commencement_date date critical
lease_term.rent_commencement_date date important
lease_term.possession_date date
lease_term.expiration_date date critical
lease_term.initial_term_months count important
lease_term.free_rent_months count important
lease_term.holdover_rate percent

Term Certainty term_certainty

Path Type Priority Allowed values
term_certainty.commencement_status enum "" | confirmed | estimated | contingent
term_certainty.expiration_status enum "" | confirmed | estimated | contingent
term_certainty.area_status enum "" | confirmed | estimated | contingent
term_certainty.basis text
term_certainty.trigger_event text
term_certainty.outside_date date
term_certainty.confirming_document text

Base Rent base_rent

Path Type Priority Allowed values
base_rent.initial_monthly_rent money critical
base_rent.initial_annual_rent money critical
base_rent.rent_per_sf money important
base_rent.amount_kind enum "" | fixed | token | rent_free | referenced | variable | unknown
base_rent.amount_text text
base_rent.currency text
base_rent.payment_frequency text important
base_rent.escalation_type text important
base_rent.annual_escalation_percent percent critical
base_rent.cpi_index_name text
base_rent.cpi_floor_percent percent
base_rent.cpi_ceiling_percent percent
base_rent.percentage_rent_rate percent
base_rent.breakpoint_sales_amount money
base_rent.rent_review_date date
base_rent.review_assumptions text
base_rent.rent_schedule list array

Operating Expenses operating_expenses

Path Type Priority Allowed values
operating_expenses.expense_type text important
operating_expenses.base_year text
operating_expenses.pro_rata_share percent important
operating_expenses.expense_stop_psf money
operating_expenses.estimated_opex_psf money
operating_expenses.estimated_annual_opex money important
operating_expenses.cam_cap_percent percent important
operating_expenses.cam_cap_basis enum "" | cumulative | non_cumulative | compounding
operating_expenses.cam_exclusions list array
operating_expenses.admin_fee_percent percent
operating_expenses.property_tax_responsibility enum important "" | landlord | tenant | shared
operating_expenses.insurance_responsibility enum important "" | landlord | tenant | shared
operating_expenses.audit_right_days count

Security security

Path Type Priority Allowed values
security.security_deposit money critical
security.security_deposit_form text
security.loc_amount money important

Renewal Options renewal_options

Path Type Priority Allowed values
renewal_options.renewal_option_count count important
renewal_options.renewal_term_months count important
renewal_options.renewal_notice_days count critical
renewal_options.renewal_rent_basis text

Termination termination

Path Type Priority Allowed values
termination.early_termination_allowed bool important
termination.termination_effective_date date important
termination.termination_notice_days count critical
termination.termination_fee money

Tenant Improvements tenant_improvements

Path Type Priority Allowed values
tenant_improvements.ti_allowance_total money important
tenant_improvements.ti_allowance_psf money
tenant_improvements.restoration_required bool
tenant_improvements.return_conditions text
tenant_improvements.end_of_term_obligations text

Use & Operations use_and_operations

Path Type Priority Allowed values
use_and_operations.permitted_use text
use_and_operations.exclusive_use text

Assignment & Subletting assignment_subletting

Path Type Priority Allowed values
assignment_subletting.assignment_allowed text important
assignment_subletting.subletting_allowed text important

Construction & Completion construction_completion

Path Type Priority Allowed values
construction_completion.tenant_improvement_work text
construction_completion.landlord_work text
construction_completion.completion_deadline date
construction_completion.permits_responsibility text
construction_completion.construction_insurance_required bool

Utilities utilities

Path Type Priority Allowed values
utilities.tenant_responsible_for list array
utilities.landlord_responsible_for list array
utilities.utility_notes text

Maintenance & Repairs maintenance_repairs

Path Type Priority Allowed values
maintenance_repairs.landlord_responsible list array
maintenance_repairs.tenant_responsible list array
maintenance_repairs.hvac_responsibility enum "" | landlord | tenant | shared
maintenance_repairs.roof_structure_responsibility enum "" | landlord | tenant | shared
maintenance_repairs.common_area_maintenance text

Responsibility Matrix maintenance_matrix

Path Type Priority Allowed values
maintenance_matrix.roof enum important "" | landlord | tenant | shared
maintenance_matrix.hvac enum important "" | landlord | tenant | shared
maintenance_matrix.parking_lot enum important "" | landlord | tenant | shared
maintenance_matrix.foundation_structure enum important "" | landlord | tenant | shared
maintenance_matrix.plumbing enum "" | landlord | tenant | shared
maintenance_matrix.electrical enum "" | landlord | tenant | shared
maintenance_matrix.windows_glass enum "" | landlord | tenant | shared
maintenance_matrix.exterior enum "" | landlord | tenant | shared
maintenance_matrix.interior enum "" | landlord | tenant | shared
maintenance_matrix.landscaping enum "" | landlord | tenant | shared
maintenance_matrix.pest_control enum "" | landlord | tenant | shared
maintenance_matrix.janitorial enum "" | landlord | tenant | shared
maintenance_matrix.elevator enum "" | landlord | tenant | shared
maintenance_matrix.fire_life_safety enum "" | landlord | tenant | shared
maintenance_matrix.snow_removal enum "" | landlord | tenant | shared

Insurance Requirements insurance_requirements

Path Type Priority Allowed values
insurance_requirements.general_liability_limit money
insurance_requirements.property_insurance_required bool
insurance_requirements.workers_comp_required bool
insurance_requirements.landlord_as_additional_insured bool
insurance_requirements.insurance_notes text

Default & Remedies default_remedies

Path Type Priority Allowed values
default_remedies.monetary_default_cure_days count
default_remedies.non_monetary_default_cure_days count
default_remedies.late_fee_percent percent
default_remedies.late_fee_fixed_amount money
default_remedies.interest_rate_on_late_payments percent
default_remedies.landlord_remedies text
default_remedies.tenant_remedies text

Warranties warranties

Path Type Priority Allowed values
warranties.landlord_warranties text
warranties.tenant_warranties text
warranties.warranty_notes text

Legal Provisions legal_provisions

Path Type Priority Allowed values
legal_provisions.estoppel_required enum important "" | yes | no
legal_provisions.estoppel_response_days count
legal_provisions.snda_required enum important "" | yes | no
legal_provisions.subordination_automatic enum "" | yes | no
legal_provisions.force_majeure_present enum "" | yes | no
legal_provisions.force_majeure_summary text
legal_provisions.holdover_consent_required enum "" | yes | no
legal_provisions.holdover_summary text
legal_provisions.guaranty_present enum important "" | yes | no
legal_provisions.guaranty_type text
legal_provisions.guaranty_capped_amount money
legal_provisions.guaranty_summary text
legal_provisions.attorneys_fees_prevailing_party enum "" | yes | no
legal_provisions.jury_trial_waiver enum "" | yes | no
legal_provisions.relocation_right enum "" | yes | no
legal_provisions.right_of_first_refusal enum important "" | yes | no
legal_provisions.right_of_first_offer enum "" | yes | no
legal_provisions.purchase_option enum important "" | yes | no
legal_provisions.purchase_option_summary text
legal_provisions.co_tenancy_clause enum "" | yes | no
legal_provisions.casualty_restoration_days count
legal_provisions.casualty_summary text
legal_provisions.condemnation_summary text
legal_provisions.environmental_provisions text
legal_provisions.dispute_resolution text
legal_provisions.notice_method text

Additional Provisions additional_provisions

Path Type Priority Allowed values
additional_provisions list array

Validation findings

Every parse is checked for contradictions, gaps and document-integrity problems, and the findings are returned on the response. Branch on code, not on the message: the codes below are stable, the wording is not.

A useful pattern is to hold anything with an error for human review and ingest the rest, since an error means the lease as recorded contradicts itself and one of the two values is wrong.

Code Level Meaning
expiration_before_commencement error Expiration is on or before commencement — A term cannot end before it begins. Check both dates against the lease.
date_before_start error Rent starts before the term does — Rent commencement is earlier than lease commencement. Usually the two were read from different clauses.
missing_critical_field error A critical value is missing — Every derived figure that depends on this value is unavailable until it is filled in.
ocr_short_upload error Fewer pages than the document says it has — The footer states a page count higher than what was uploaded. The end of a lease is where the signatures and exhibits live.
amendment_conflict error Amendments conflict — Two amendments change the same value with no way to tell which governs. A person has to decide.
possession_after_commencement warning Possession is after commencement — The tenant takes possession after the term has started, which is unusual and often a misread date.
term_length_mismatch warning Stated term does not match the dates — The stated number of months disagrees with the gap between commencement and expiration.
rent_arithmetic_conflict warning Monthly and annual rent disagree — Twelve times the monthly rent is not the annual rent. One figure was misread.
rent_psf_conflict warning Rent per square foot disagrees with the annual rent — The stated rate per square foot does not reconcile with the annual rent and the area.
escalation_implausible warning Escalation rate looks implausible — An annual increase outside roughly 0-25% is usually a percentage read as a fraction, or the wrong number entirely.
pro_rata_implausible warning Pro-rata share looks implausible — A share above 100% cannot be right. Check whether a fraction was read as a percentage.
percent_unit_unclear warning A percentage may have been read as a fraction — The value is below 1%, and the lease does not print it as a percentage anywhere, so it may be a fraction: 0.05 meaning five percent. Where the document settles it we correct it automatically; here it does not, and a half-percent fee is just as plausible as the alternative.
area_may_be_building_area warning The premises area may be the building's — The only place this figure appears in the lease is a sentence describing the building rather than the premises, and the building holds other tenants. Extraction quotes the document accurately here -- the question is whose square footage it is. Check the premises clause: where it defers the area to a schedule or exhibit, the right answer is usually that this lease does not state one.
rent_unpriced warning Rent is owed but the amount is not stated here — The lease imposes rent without giving a figure -- set by an exhibit, an index, or a market review. Nothing is missing from the extraction; every rent total for this lease is a floor rather than the whole obligation, and the schedule leaves those periods unpriced instead of projecting a number the lease never agreed to.
term_trigger_overdue warning A contingent term is past its outside date — The lease set an outside date for the event that settles this term, and it has passed while the term is still recorded as unsettled. Either the event happened and nobody recorded it, or a right to terminate has arisen.
critical_fields_unverified warning Critical values are unverified — The extraction was not confident and nobody has confirmed these yet. The review queue lists them field by field.
insurance_gap warning No liability insurance requirement found — A commercial lease almost always sets a general liability limit. Its absence is usually a missed clause, not a missing obligation.
missing_signature warning No signature block found — The document may be an unexecuted draft, or the signature pages may not have been included.
missing_exhibit warning Referenced exhibits are not in the document — The lease refers to exhibits that were not uploaded. Exhibits routinely carry the rent schedule and the site plan.
ocr_low_text_density warning Very little text per page — The scan quality may have defeated OCR, which means clauses are missing rather than absent.
ocr_page_gap warning Page numbers skip — The document's own page numbering jumps, so pages are missing from what was uploaded.
ocr_blank_pages warning Some pages produced no text — Those pages were in the file but nothing could be read off them, so any clause they carried is missing rather than absent.
ocr_low_confidence warning The scan was read with low confidence — The OCR engine reported it was guessing. Figures and dates are the first things it gets wrong.
ocr_garbled_text warning The extracted text looks garbled — Failed OCR returns plausible-looking nonsense rather than nothing, which reads as text to everything downstream.
amendment_unattached warning Amendment is not attached to a lease — Its terms are recorded but are not affecting any lease, so the portfolio shows superseded values.
deadline_imminent warning A deadline falls inside 90 days — A notice window that closes unnoticed is the most expensive thing a lease administrator can miss.
term_provisional info The term is not fixed yet — A date here is anticipated or depends on an event that has not happened, so every deadline derived from it — expiration, renewal notice, termination notice — moves when it settles. Confirm it from the commencement memorandum once one exists.
security_undocumented info No security recorded — Neither a deposit nor a letter of credit was found. Often correct, occasionally a missed clause.
insurance_limit_low info Liability limit is below the market norm — Commercial leases typically require at least $1,000,000 per occurrence.
responsibility_unallocated info Major building systems are unallocated — Nobody is recorded as responsible for these systems, which is the most expensive kind of ambiguity in a lease.
cam_uncapped info Operating expenses are uncapped — The tenant reimburses operating expenses with no cap recorded, so the exposure is open-ended.
holdover_undefined info No holdover rate recorded — Without a holdover rate there is no agreed penalty for staying past expiration.
no_assignment_clause info No assignment or subletting terms found — Whether the tenant may assign or sublet affects what the lease is worth on a sale.
ocr_rotated_pages info Pages had to be rotated — Sideways pages still read, but table and heading detection degrades on them.
deadline_passed info A recorded deadline has passed — Confirm whether the option was exercised or allowed to lapse.
lease_expired info The term has ended — This lease has expired. If the tenant is still in place, a renewal or an amendment is missing.

❌ Error Responses

400

Bad Request

Invalid request format or unsupported file type.

{ "success": false, "error": "Invalid file type..." }
401

Unauthorized

Invalid or missing API key.

{ "success": false, "error": "Invalid or inactive API key." }
402

Payment Required

The account cannot be charged for this request — either it has no active licence (no_licence) or it has reached its monthly cap (capped). Branch on code rather than the message. Nothing is extracted or charged, so the request is safe to retry once the cause is resolved.

{ "success": false, "error": "...", "code": "capped", "usage": { "contracts_this_month": 40, "monthly_limit": 40 }, "cost": 20.00 }
405

Method Not Allowed

Invalid HTTP method (use POST for abstraction).

{ "success": false, "error": "Method not allowed." }
500

Internal Server Error

Abstraction failed due to server error.

{ "success": false, "error": "Failed to abstract lease" }

💻 Code Examples

cURL Command Line

# POST a remote file URL
curl -X POST 'https://leasebossai.com/api/parse.php' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{ "file": "https://example.com/lease.pdf" }'
# POST with file upload
curl -X POST 'https://leasebossai.com/api/parse.php' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -F 'file=@lease.pdf'

🎯 Getting Your API Key

  1. Log in to your dashboard
  2. Scroll to the "API keys" section
  3. Enter an optional note for the key
  4. Click "Create a new key"
  5. Copy and save the API key (you won't be able to see it again!)

⚡ Rate Limits & Pricing

Every authenticated endpoint, including both abstraction paths, shares a limit of 120 requests per API key per minute. Responses include X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset; a 429 response also includes Retry-After. Each lease contract abstracted costs $20, invoiced monthly alongside your platform licence. Amendments to leases already on your account are free, and failed abstractions are not charged.

If your account has a monthly cap set, requests past it return 402 with code: "capped" rather than being charged. Caps and licences are managed in billing settings.