One endpoint does the work: upload a rent roll, get structured data back with a deterministic verification report. No async jobs, no polling — a single HTTP call.
Pass your API key in the X-Api-Key header (or as a bearer token). Get a key from the pricing page; manage it at your account.
X-Api-Key: rr_live_your_key_here
# or
Authorization: Bearer rr_live_your_key_here
No key? The web app allows 3 free extractions/day per IP for evaluation.
Extracts structured data from one document. Send multipart/form-data with a file field.
.xlsx, .xlsm| Parameter | Values | Default | Description |
|---|---|---|---|
format | json · csv · xlsx | json | Response format. csv/xlsx return a downloadable file. |
curl -X POST "https://rentrollapi.com/v1/extract?format=json" \ -H "X-Api-Key: rr_live_your_key_here" \ -F "file=@rent-roll.pdf"
Official client on NuGet: RentRollAPI.Client (netstandard2.0 / net8.0).
dotnet add package RentRollAPI.Client
using RentRollApi.Client;
using var client = new RentRollClient("rr_live_your_key_here");
var result = await client.ExtractAsync("rent-roll.pdf");
Console.WriteLine($"{result.Units.Count} units, confidence {result.Verification.DocumentConfidence:P0}");
foreach (var check in result.Verification.Checks)
Console.WriteLine($"[{check.Result}] {check.Name}: {check.Detail}");
// Or get Excel / CSV directly:
byte[] xlsx = await client.ExtractToXlsxAsync(stream, "rent-roll.pdf");
Every field carries a value, status (Extracted / Missing / Flagged), and confidence. The verification block is computed deterministically — totals are re-added and reconciled against what the document states, so you know when to trust the output.
{
"propertyName": { "value": "Maplewood Commerce Center", "status": "Extracted", "confidence": 0.9 },
"asOfDate": { "value": "2026-06-30", "status": "Extracted", "confidence": 0.9 },
"units": [
{
"unitNumber": { "value": "101", "status": "Extracted", "confidence": 0.9 },
"tenantName": { "value": "Cedar Point Dental", "status": "Extracted", "confidence": 0.9 },
"squareFeet": { "value": 1850, "status": "Extracted", "confidence": 0.9 },
"monthlyRent": { "value": 4625.0, "status": "Extracted", "confidence": 0.9 },
"leaseStart": { "status": "Missing" },
"leaseEnd": { "value": "2028-03-31", "status": "Extracted", "confidence": 0.9 },
"occupancy": { "value": "Occupied", "status": "Extracted", "confidence": 0.9 }
}
],
"totals": { "unitCount": 8, "monthlyRent": 28155.0, "squareFeet": 13750 },
"verification": {
"documentConfidence": 0.9,
"flaggedFieldCount": 0,
"allChecksPassed": true,
"checks": [
{ "name": "UnitCountReconciliation", "result": "Pass", "detail": "Extracted 8 units; document states 8." },
{ "name": "TotalMonthlyRentReconciliation", "result": "Pass", "detail": "Computed 28,155.00 vs stated 28,155.00 (within tolerance)." },
{ "name": "TotalSquareFeetReconciliation", "result": "Pass", "detail": "Computed 13,750.00 vs stated 13,750.00 (within tolerance)." },
{ "name": "DuplicateUnits", "result": "Pass", "detail": "No duplicate unit numbers." },
{ "name": "LeaseDateOrder", "result": "Pass", "detail": "All lease end dates follow start dates." },
{ "name": "NonNegativeRents", "result": "Pass", "detail": "No negative rents." }
]
}
}
| Status | Meaning |
|---|---|
400 | Missing/empty file field, file over 25 MB, or unknown format |
401 | Invalid or revoked API key |
422 | Unsupported or unreadable document |
429 | Monthly quota exceeded and no prepaid credits remain (or demo limit reached) |
All errors return {"error": "human-readable message"}.
All authenticated with the same X-Api-Key header.
| Endpoint | Description |
|---|---|
GET/api/account | Plan, monthly usage, remaining quota, prepaid credits |
POST/api/account/rotate | Issues a new key, immediately revokes the current one (credits carry over) |
POST/api/portal | Returns a Stripe Customer Portal URL — upgrade, downgrade, cancel, invoices |
POST/api/credits/checkout | Returns a Stripe Checkout URL for a 25-credit top-up applied to this key |
Documents are processed in memory and never stored after your extraction completes. See the privacy policy.