CleanRoll API
The CleanRoll API allows you to programmatically parse rent roll files and extract standardized data.
Features
- Parse Excel (.xlsx, .xls), CSV, and PDF rent rolls
- Automatic PM system format detection (Yardi, AppFolio, RealPage, etc.)
- AI-powered column mapping suggestions
- Batch processing for multiple files
Authentication
All API requests require authentication via an API key. Include your API key in the Authorization header:
Authorization: Bearer cr_live_your_api_keyAPI keys can be created and managed from the Developer Dashboard.
Scopes
API keys can optionally be restricted to specific scopes:
Keys without scopes have full access. Keys with scopes are limited to those specific operations.
Parse File
Upload and parse a single rent roll file.
/api/v1/parseRequest
Content-Type: multipart/form-data
Example Request
curl -X POST https://cleanroll.ai/api/v1/parse \
-H "Authorization: Bearer cr_live_your_api_key" \
-F "[email protected]"Response
{
"success": true,
"data": {
"headers": ["Unit", "Tenant", "SF", "Monthly Rent", "Lease End"],
"rows": [
{"Unit": "101", "Tenant": "Acme Corp", "SF": "2500", "Monthly Rent": "$5,000", "Lease End": "12/31/2025"},
...
],
"sampleRows": [...],
"totalRows": 24,
"filename": "rent-roll.xlsx",
"formatDetection": {
"detectedSystem": "yardi",
"confidence": 0.85,
"displayName": "Yardi",
"suggestedMappings": [
{"source": "Unit", "target": "unit_id", "confidence": 0.95},
{"source": "Tenant", "target": "tenant_name", "confidence": 0.98},
...
],
"notes": "Detected Yardi format based on column headers"
}
},
"usage": {
"documentsUsed": 15,
"documentsLimit": null,
"documentsRemaining": null,
"isUnlimited": true,
"tier": "pro"
}
}Batch Parse
Upload and parse multiple rent roll files in a single request.
/api/v1/parse-batchRequest
Content-Type: multipart/form-data
Batch Limits by Plan
Example Request
curl -X POST https://cleanroll.ai/api/v1/parse-batch \
-H "Authorization: Bearer cr_live_your_api_key" \
-F "[email protected]" \
-F "[email protected]" \
-F "[email protected]"Response
{
"success": true,
"batchId": "550e8400-e29b-41d4-a716-446655440000",
"files": [
{
"filename": "property1.xlsx",
"headers": [...],
"rows": [...],
"sampleRows": [...],
"totalRows": 24,
"formatDetection": {...}
},
{
"filename": "property2.xlsx",
"headers": [...],
"rows": [...],
"sampleRows": [...],
"totalRows": 18,
"formatDetection": {...}
},
{
"filename": "property3.csv",
"error": "Could not identify tabular data"
}
],
"totalFiles": 3,
"successfulFiles": 2,
"failedFiles": 1,
"usage": {...}
}Templates
List and use your saved column mapping templates via the API.
List Templates
/api/v1/templatescurl https://cleanroll.ai/api/v1/templates \
-H "Authorization: Bearer cr_live_your_api_key"Response
{
"success": true,
"templates": [
{
"id": "tmpl_abc123",
"name": "Yardi Format",
"description": "Standard Yardi export mapping",
"mappings": [
{ "sourceColumn": "Unit", "targetField": "unit_id" },
{ "sourceColumn": "Tenant Name", "targetField": "tenant_name" },
{ "sourceColumn": "RSF", "targetField": "sqft" }
],
"createdAt": "2025-01-15T10:30:00.000Z"
}
]
}Use Template with Parse
Pass a templateId when parsing to apply saved mappings:
curl -X POST https://cleanroll.ai/api/v1/parse \
-H "Authorization: Bearer cr_live_your_api_key" \
-F "[email protected]" \
-F "templateId=tmpl_abc123"Usage
Get your current API usage and subscription details.
/api/v1/usageExample Request
curl https://cleanroll.ai/api/v1/usage \
-H "Authorization: Bearer cr_live_your_api_key"Response
{
"success": true,
"usage": {
"documentsUsed": 45,
"documentsLimit": null,
"documentsRemaining": null,
"periodStart": "2025-01-01T00:00:00.000Z",
"periodEnd": "2025-01-31T23:59:59.999Z",
"tier": "pro",
"isUnlimited": true,
"canUpload": true
},
"limits": {
"batchUploadLimit": 10,
"canSaveTemplates": true,
"canBatchUpload": true
},
"plan": {
"name": "Pro",
"tier": "pro"
}
}Errors
The API uses standard HTTP status codes to indicate success or failure.
Error Response Format
{
"statusCode": 401,
"message": "Invalid or missing API key. Provide a valid key via Authorization header."
}Rate Limits
API usage is limited by your subscription plan's monthly document quota, not by request rate.
Usage is counted per successfully parsed document. Failed parses are not counted against your quota.
SDKs & Libraries
Official and community SDKs make it easy to integrate CleanRoll into your applications.
Python SDK
Official Python client for the CleanRoll API
pip install cleanrollJavaScript/Node.js
Official npm package for Node.js and browsers
npm install @cleanroll/sdkPython Quick Start
from cleanroll import CleanRoll
client = CleanRoll(api_key="cr_live_your_api_key")
# Parse a rent roll
result = client.parse("rent-roll.xlsx")
print(f"Parsed {result.total_rows} rows")
print(f"Detected format: {result.format_detection.system}")
# List your templates
templates = client.templates.list()
for t in templates:
print(f"Template: {t.name}")
# Parse with a template
result = client.parse("rent-roll.xlsx", template_id="tmpl_abc123")JavaScript Quick Start
import { CleanRoll } from '@cleanroll/sdk';
const client = new CleanRoll({ apiKey: 'cr_live_your_api_key' });
// Parse a rent roll
const result = await client.parse('./rent-roll.xlsx');
console.log(`Parsed ${result.totalRows} rows`);
console.log(`Detected format: ${result.formatDetection.system}`);
// List your templates
const templates = await client.templates.list();
templates.forEach(t => console.log(`Template: ${t.name}`));
// Parse with a template
const result2 = await client.parse('./rent-roll.xlsx', {
templateId: 'tmpl_abc123'
});