Developers

API Documentation

Integrate Rentari.ai's property intelligence engine directly into your enterprise software, custom dashboards, or automated workflows.

AI proposes the best matching section. You decide if it answers your question.

Getting Started

Every Rentari.ai API request talks to https://Rentari.ai/api/v1/external over HTTPS, sends and receives JSON, and is scoped to a single landlord portfolio. Three steps to make your first call:

  1. 1

    Generate an API key

    Open the Developer dashboard, submit a short access request, and once approved click "Create key". Test keys start with sk_test_, live keys with sk_live_. Store the key in your secret manager. We never show it again.

  2. 2

    Send the bearer header

    Add Authorization: Bearer <your_key> to every request. Missing or malformed headers return HTTP 401.

  3. 3

    Make a test call

    Hit GET /api/v1/external/properties with a test key. It returns the demo portfolio, so you can integrate before any real data exists.

Authentication

The Rentari.ai API uses API keys to authenticate requests. You can view and manage your API keys in the Landlord Settings Dashboard. Your API keys carry many privileges, so be sure to keep them secure!

curl https://Rentari.ai/api/v1/external/properties \
  -H "Authorization: Bearer sk_live_your_api_key_here"

List Properties

Returns a paginated list of all properties within your portfolio. The properties are returned sorted by creation date, with the most recently created properties appearing first.

GET /api/v1/external/properties
curl https://Rentari.ai/api/v1/external/properties?limit=20 \
  -H "Authorization: Bearer sk_live_your_api_key_here"
Example Response
{
  "object": "list",
  "data": [
    {
      "id": "prop_8x9a2",
      "street_address": "123 Smart Way",
      "city": "Creve Coeur",
      "state": "MO",
      "unit_count": 4
    }
  ]
}

Generate Lease

Dynamically generate a state-specific lease agreement using our AI Legal Engine. Accepts the property ID and tenant details to return a customized, ESIGN-ready PDF document URL.

POST /api/v1/external/leases/generate
curl -X POST https://Rentari.ai/api/v1/external/leases/generate \
  -H "Authorization: Bearer sk_live_your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "property_id": "prop_8x9a2",
    "tenant_id": "tnt_12fa7",
    "start_date": "2026-06-01",
    "monthly_rent": 1850
  }'
Example Response
{
  "id": "lease_4q1z8",
  "status": "draft",
  "document_url": "https://cdn.Rentari.ai/leases/lease_4q1z8.pdf",
  "esign_url": "https://Rentari.ai/sign/lease_4q1z8",
  "expires_at": "2026-06-08T00:00:00Z"
}

Webhooks

Subscribe to real-time events to keep your internal CRM or accounting software perfectly synced with Rentari.ai. Endpoints must be HTTPS and return a 200 status code quickly.

lease.signed

Fired when all parties have securely e-signed an agreement.

payment.succeeded

Fired when a rent ACH or Credit Card payment successfully clears.

maintenance.created

Fired when a tenant submits a new AI-triaged repair ticket.

Webhook Signing

Every webhook delivery includes an X-Rentari.ai-Signature header. Verify it before trusting the payload. The signature is the hex HMAC-SHA256 of timestamp.body using your endpoint signing secret (shown once when you create the endpoint). Reject requests older than 5 minutes to defeat replay attacks.

import hmac, hashlib, time

def verify(secret, raw_body, header):
    ts, sig = header.split(",")
    ts = ts.split("=")[1]
    sig = sig.split("=")[1]
    if abs(time.time() - int(ts)) > 300:
        raise ValueError("stale webhook")
    expected = hmac.new(
        secret.encode(), f"{ts}.{raw_body}".encode(), hashlib.sha256
    ).hexdigest()
    if not hmac.compare_digest(expected, sig):
        raise ValueError("bad signature")

Rentari.ai retries failed deliveries with exponential backoff for 24 hours. Return any 2xx to acknowledge.

Errors

Rentari.ai uses standard HTTP status codes. All error responses share the same envelope so you can write one handler:

Error Envelope
{
  "error": {
    "type": "validation_error",
    "code": "invalid_field",
    "message": "monthly_rent must be a positive number.",
    "param": "monthly_rent",
    "request_id": "req_8x9a2b1c"
  }
}
StatusTypeWhen you'll see it
400validation_errorBody or query failed schema validation. Check param.
401authentication_errorMissing, malformed, or revoked API key.
403permission_errorKey is valid but lacks the required scope or plan tier.
404not_foundResource id does not exist in your portfolio.
409conflictIdempotency replay with a different body, or stale write.
429rate_limit_exceededBack off, then retry after the Retry-After header.
5xxapi_errorOur problem. Safe to retry with exponential backoff.

Always log request_id. Our support team can find any request by id within 90 days.

Rate Limits

Limits are per API key, measured over a rolling 60-second window. Every response includes the headers below so you can implement adaptive backoff:

Starter

60 req/min

Burst up to 120, then throttled.

Pro

600 req/min

Burst up to 1,200.

Prime

3,000 req/min

Custom ceilings on request.

Response Headers
X-RateLimit-Limit: 600
X-RateLimit-Remaining: 412
X-RateLimit-Reset: 1717689600
Retry-After: 14

Endpoint Reference

The full surface available today. Every list endpoint follows the pagination contract above; every mutation respects idempotency keys via the Idempotency-Key header.

MethodPathWhat it does
GET/api/v1/external/propertiesList properties in the portfolio.
GET/api/v1/external/properties/{id}Retrieve a single property with units.
GET/api/v1/external/tenantsList tenants in the portfolio.
GET/api/v1/external/leasesList leases with status, dates, and rent.
GET/api/v1/external/maintenance/ticketsList repair tickets, including AI triage category.
GET/api/v1/external/paymentsList rent payments with status and method.
POST/api/v1/external/webhooks/endpointsRegister a webhook endpoint and receive its signing secret.
GET/api/v1/external/webhooks/endpointsList your registered webhook endpoints.
DELETE/api/v1/external/webhooks/endpoints/{id}Disable a webhook endpoint. Existing history preserved.

Need an endpoint that isn't here yet? Email api@rentari.ai with the use case.