VerticalRent API
Programmatic access to your properties, listings, leases, screening, and rental applications. Build integrations, automate workflows, or power custom internal tools.
Available on Growth ($29/mo) and Portfolio ($79/mo) plans.
Free and Starter accounts can read the docs but can't create API keys. See pricing →
Authentication
Every API request must include an Authorization header with a Bearer token. Create a key in Settings → API Keys. Keys start with vr_pk_ followed by 48 hex chars.
One-time display: Keys are shown to you exactly once when created. Store them securely — we can't recover lost keys.
curl https://www.verticalrent.com/api/v1/listings \
-H "Authorization: Bearer vr_pk_a1b2c3d4e5f6..."Rotating keys
- Create a new key in Settings → API Keys
- Update your integration to use the new key
- Verify everything still works, then revoke the old key
Security best practices
- Never commit keys to source control — use environment variables
- Use a separate key for each integration so one revocation doesn't break others
- Rotate keys at least quarterly
- Revoke immediately if you suspect a leak
Response Format
Success
{
"ok": true,
"data": { /* ... */ }
}Paginated
{
"ok": true,
"data": [ /* ... */ ],
"pagination": {
"page": 1,
"perPage": 25,
"total": 142,
"hasMore": true
}
}Error
{
"error": "Invalid API key",
"code": "INVALID_API_KEY"
}Error codes
| Code | HTTP | Meaning |
|---|---|---|
| INVALID_API_KEY | 401 | Missing, malformed, revoked, or expired API key |
| PLAN_UPGRADE_REQUIRED | 403 | Account is not on a Growth or Portfolio plan |
| FORBIDDEN | 403 | Authenticated but not authorized for this resource |
| VALIDATION_ERROR | 400 | Request body or query params failed validation |
| NOT_FOUND | 404 | Resource doesn't exist or isn't owned by this key |
| CONFLICT | 409 | Operation conflicts with current state (e.g. duplicate) |
| RATE_LIMITED | 429 | 100 req/min exceeded. See Retry-After header. |
| INTERNAL_ERROR | 500 | Unexpected server-side failure |
Endpoint Reference
All endpoints under /api/v1 require API-key authentication.
/api/v1/listingsSearch active listings owned by the API key holder. Paginated.
| Name | Type | Required | Description |
|---|---|---|---|
| page | integer | no | Page number, default 1 |
| perPage | integer | no | Results per page, default 25, max 100 |
| city | string | no | Case-insensitive partial match |
| state | string | no | Two-letter US state code (PA, CA, etc.) |
| minRent | number | no | Minimum monthly rent in dollars |
| maxRent | number | no | Maximum monthly rent in dollars |
| bedrooms | integer | no | Exact bedroom count match |
| pets | boolean | no | true = only pet-friendly listings |
curl "https://www.verticalrent.com/api/v1/listings?state=PA&minRent=1000" \
-H "Authorization: Bearer vr_pk_xxx"{
"ok": true,
"data": [
{
"id": "abc-123",
"title": "3BR / 2BA in Erie, PA",
"description": "...",
"photos": ["https://..."],
"availableDate": "2026-06-01T00:00:00.000Z",
"petPolicy": "cats_ok",
"unit": { "bedrooms": 3, "bathrooms": 2, "rent": 1600 },
"property": { "city": "Erie", "state": "PA", "address": "..." },
"publicUrl": "https://www.verticalrent.com/listings/abc-123"
}
],
"pagination": { "page": 1, "perPage": 25, "total": 4, "hasMore": false }
}/api/v1/listings/{id}Fetch a single listing by ID.
curl https://www.verticalrent.com/api/v1/listings/abc-123 \
-H "Authorization: Bearer vr_pk_xxx"{ "ok": true, "data": { "id": "abc-123", ... } }/api/v1/listingsCreate a new listing on a unit you own.
| Name | Type | Required | Description |
|---|---|---|---|
| unitId | uuid | yes | Must be a unit you own |
| title | string | yes | Up to 150 chars |
| description | string | yes | Free text |
| availableDate | ISO date | yes | When the unit becomes available |
| petPolicy | string | no | One of: cats_ok, dogs_small, dogs_any, all_pets, negotiable, not_allowed |
| parkingSpots | integer | no | 0–10 |
| utilitiesIncluded | string[] | no | e.g. ['water','trash'] |
| leaseTerm | string | no | e.g. '12_months' |
| photos | string[] | no | Up to 20 HTTPS image URLs |
| videoUrl | string | no | YouTube or Vimeo URL |
curl -X POST https://www.verticalrent.com/api/v1/listings \
-H "Authorization: Bearer vr_pk_xxx" \
-H "Content-Type: application/json" \
-d '{
"unitId": "...",
"title": "3BR / 2BA in Erie, PA",
"description": "Spacious...",
"availableDate": "2026-06-01"
}'{ "ok": true, "data": { "id": "...", ... } }/api/v1/listings/{id}Full update — requires title, description, availableDate.
curl -X PUT https://www.verticalrent.com/api/v1/listings/abc-123 \
-H "Authorization: Bearer vr_pk_xxx" \
-H "Content-Type: application/json" \
-d '{ "title": "...", "description": "...", "availableDate": "2026-07-01" }'{ "ok": true, "data": { "id": "abc-123", ... } }/api/v1/listings/{id}Partial update — provide only the fields to change.
curl -X PATCH https://www.verticalrent.com/api/v1/listings/abc-123 \
-H "Authorization: Bearer vr_pk_xxx" \
-H "Content-Type: application/json" \
-d '{ "isActive": false }'{ "ok": true, "data": { ..., "isActive": false } }/api/v1/listings/{id}Permanently delete a listing.
curl -X DELETE https://www.verticalrent.com/api/v1/listings/abc-123 \
-H "Authorization: Bearer vr_pk_xxx"{ "ok": true, "data": { "deleted": true } }/api/v1/applicationsCreate a rental application invite. Renter completes via the returned inviteUrl.
| Name | Type | Required | Description |
|---|---|---|---|
| applicantEmail | string | yes | Where to send the invite |
| applicantName | string | no | Pre-fills the form |
| applicantPhone | string | no | For SMS invites |
| unitId | uuid | no | Pre-select a unit (must be yours) |
| message | string | no | Personal note to the applicant |
curl -X POST https://www.verticalrent.com/api/v1/applications \
-H "Authorization: Bearer vr_pk_xxx" \
-H "Content-Type: application/json" \
-d '{
"applicantEmail": "jane@example.com",
"applicantName": "Jane Smith",
"unitId": "..."
}'{
"ok": true,
"data": {
"id": "...",
"token": "...",
"inviteUrl": "https://www.verticalrent.com/apply/...",
"expiresAt": "2026-06-17T..."
}
}/api/v1/screening-reports/{id}Retrieve a screening report. FCRA-audited: every access logs an entry attributed to your API key. Only accessible if you have permissible purpose (e.g. an open application from the renter).
curl https://www.verticalrent.com/api/v1/screening-reports/abc-123 \
-H "Authorization: Bearer vr_pk_xxx"{
"ok": true,
"data": {
"id": "abc-123",
"reportType": "criminal",
"status": "complete",
"completedAt": "2026-05-15T...",
"renter": { "id": "...", "email": "...", "fullName": "..." },
"data": { /* report payload — treat as FCRA-regulated PII */ }
}
}Webhooks
Subscribe to real-time event notifications. We POST a JSON payload to your URL whenever a subscribed event fires, signed with HMAC-SHA256 so you can verify authenticity.
Create + manage subscriptions in Settings → Webhooks.
Verifying the signature
Each delivery includes an X-VerticalRent-Signature header. Verify it by computing the same HMAC-SHA256 over the raw request body using your subscription's secret.
import crypto from "node:crypto";
export default function handler(req, res) {
const sig = req.headers["x-verticalrent-signature"]; // "sha256=..."
const body = req.rawBody; // raw request body string
const expected = "sha256=" + crypto
.createHmac("sha256", process.env.VR_WEBHOOK_SECRET)
.update(body)
.digest("hex");
if (sig !== expected) return res.status(401).end();
const event = JSON.parse(body);
console.log("Received:", event.event, event.data);
res.status(200).end();
}Event types
| Event | Fires when |
|---|---|
| application.submitted | An applicant submits a rental application |
| application.approved | Landlord approves an application |
| application.denied | Landlord denies an application |
| screening.completed | A screening report finishes |
| lease.generated | AI lease generation completes |
| lease.signed | Tenant signs a lease |
| rent.received | A rent payment succeeds |
| rent.late | Rent payment becomes overdue |
| maintenance.submitted | Tenant submits a maintenance request |
| maintenance.completed | Vendor marks a job complete |
| tenant.move_out_notice | Tenant submits a move-out notice |
Retry policy
Deliveries that fail (non-2xx response or network error) are retried automatically on this schedule: 1 min, 5 min, 30 min, 2 hours, 12 hours. After 5 attempts, the delivery is marked failed permanently. You can manually replay any delivery from Settings → Webhooks.
Quick-start Tutorials
Common integration patterns to get you started fast.
Build a Zapier integration that creates a Slack message when a tenant pays rent▼
1. In Settings → Webhooks, click Add Endpoint.
2. In Zapier, create a Webhook by Zapier trigger with Catch Hook. Copy the URL Zapier gives you.
3. Paste that URL into VerticalRent, check the rent.received event, and save.
4. Save the signing secret — you'll need it later to verify signatures.
5. In Zapier, add a Slack → Send Channel Message action. Use the webhook payload fields (e.g. data.amount, data.tenant.name) in the message template.
Sync new listings to your own CRM via webhooks▼
1. Build a webhook receiver at e.g. https://your-crm.com/webhooks/vr.
2. Subscribe to application.submitted from VerticalRent.
3. On each delivery: verify the signature, then create a Contact + Deal in your CRM from data.applicantEmail and data.applicantName.
4. Return HTTP 200 within 10 seconds, or VerticalRent will retry.
Bulk-import properties using the REST API▼
The bulk-import endpoints land in Phase 8 of our roadmap. For now, you can loop over your data and call POST /api/v1/listings per unit. Mind the 100 req/min rate limit — add a 600ms delay between calls if importing in volume.
Ready to build?
Create your first API key and ship in minutes.