# API Reference

Rentalot provides a REST API for programmatic access to your account. Use it to sync properties from your PMS, build custom integrations, connect CRM tools, or let AI bots manage your rental operations.

## Base URL

```
https://rentalot.ai/api/v1
```

## Authentication

All API requests require an API key passed in the `Authorization` header:

```
Authorization: Bearer your_api_key_here
```

Generate and manage API keys from **Settings** > **API Keys** in your dashboard. See [Authentication](/docs/api-reference/authentication) for details.

## Endpoints

### Properties

| Method | Endpoint | Description |
|--------|----------|-------------|
| `GET` | `/properties` | List all properties |
| `POST` | `/properties` | Create a property |
| `POST` | `/properties/bulk` | Bulk create properties (async, returns jobId) |
| `GET` | `/properties/bulk/:jobId` | Poll a bulk-create job |
| `GET` | `/properties/:id` | Get a property |
| `PATCH` | `/properties/:id` | Update a property |
| `DELETE` | `/properties/:id` | Delete a property (soft-delete) |

### Property Images

| Method | Endpoint | Description |
|--------|----------|-------------|
| `GET` | `/properties/:id/images` | List images for a property |
| `POST` | `/properties/:id/images/presign` | Get a presigned upload URL |
| `POST` | `/properties/:id/images/confirm` | Confirm an uploaded image |
| `POST` | `/properties/:id/images/presign-batch` | Get multiple presigned URLs |
| `POST` | `/properties/:id/images/confirm-batch` | Confirm multiple uploads |
| `POST` | `/properties/:id/images/import` | Import images from URLs (async) |
| `GET` | `/properties/:id/images/import/:jobId` | Poll an import job |
| `DELETE` | `/properties/:id/images` | Delete images by ID (batch body) |
| `PATCH` | `/properties/:id/images/reorder` | Reorder images |

### Contacts

| Method | Endpoint | Description |
|--------|----------|-------------|
| `GET` | `/contacts` | List all contacts |
| `POST` | `/contacts` | Create a contact |
| `GET` | `/contacts/:id` | Get a contact |
| `PATCH` | `/contacts/:id` | Update a contact |
| `DELETE` | `/contacts/:id` | Delete a contact (soft-delete) |

Contacts are also created automatically when prospects interact with your workflows.

### Showings

| Method | Endpoint | Description |
|--------|----------|-------------|
| `GET` | `/showings` | List all showings |
| `POST` | `/showings` | Schedule a showing |
| `GET` | `/showings/:id` | Get a showing |
| `PATCH` | `/showings/:id` | Update a showing |
| `DELETE` | `/showings/:id` | Cancel a showing |
| `GET` | `/showings/availability` | Check available time slots |

### Conversations

| Method | Endpoint | Description |
|--------|----------|-------------|
| `GET` | `/conversations` | List all conversations |
| `GET` | `/conversations/:id/messages` | Get messages in a conversation |
| `GET` | `/conversations/search` | Search across message content |

Read-only access for CRM sync and reporting.

### Events

| Method | Endpoint | Description |
|--------|----------|-------------|
| `GET` | `/events` | List all calendar events |

Read-only view of your full calendar (showings, synced Google Calendar events, Cal.com events).

### Workflows

| Method | Endpoint | Description |
|--------|----------|-------------|
| `GET` | `/workflows` | List workflow templates |
| `GET` | `/workflows/:id` | Get a template |
| `GET` | `/workflows/runs` | List workflow runs |
| `POST` | `/workflows/runs` | Trigger a workflow run |
| `GET` | `/workflows/runs/:id` | Get a run |

### Messages

| Method | Endpoint | Description |
|--------|----------|-------------|
| `POST` | `/messages` | Send a message to a contact |

### Drafts

| Method | Endpoint | Description |
|--------|----------|-------------|
| `GET` | `/drafts` | List draft messages |
| `POST` | `/drafts` | Create a draft |
| `GET` | `/drafts/:id` | Get a draft |
| `PATCH` | `/drafts/:id` | Update a draft |
| `DELETE` | `/drafts/:id` | Delete a draft |
| `POST` | `/drafts/:id/send` | Send a draft |

### Follow-ups

| Method | Endpoint | Description |
|--------|----------|-------------|
| `GET` | `/followups` | List scheduled follow-ups |
| `POST` | `/followups` | Schedule a follow-up |
| `GET` | `/followups/:id` | Get a follow-up |
| `DELETE` | `/followups/:id` | Cancel a follow-up |

### Sessions (Pre-Screening)

| Method | Endpoint | Description |
|--------|----------|-------------|
| `GET` | `/sessions` | List pre-screening sessions |
| `GET` | `/sessions/:id` | Get a session |
| `PATCH` | `/sessions/:id/review` | Approve or deny a session |

View and manage prospect submissions from public chat workflows.

### Webhooks

| Method | Endpoint | Description |
|--------|----------|-------------|
| `GET` | `/webhooks` | List webhook subscriptions |
| `POST` | `/webhooks` | Create a webhook |
| `GET` | `/webhooks/:id` | Get a webhook |
| `PATCH` | `/webhooks/:id` | Update a webhook |
| `DELETE` | `/webhooks/:id` | Delete a webhook |
| `POST` | `/webhooks/:id/test` | Send a test ping |
| `POST` | `/webhooks/:id/rotate-secret` | Rotate the signing secret |

### Settings

| Method | Endpoint | Description |
|--------|----------|-------------|
| `GET` | `/settings` | Get all agent settings |
| `PATCH` | `/settings` | Update agent settings |
| `GET` | `/settings/followups` | Get follow-up settings |
| `PATCH` | `/settings/followups` | Update follow-up settings |

## Idempotency

All `POST` endpoints support an optional `Idempotency-Key` header. If you send the same key with the same request body within 24 hours, you'll get the cached response back with an `X-Idempotent-Replayed: true` header. Use this to safely retry requests without creating duplicates.

```
Idempotency-Key: your-unique-key-here
```

## Access by Plan

| Plan | API Access | Details |
|------|-----------|---------|
| **Free Trial** | None | No API access |
| **Starter** | Read-only | `GET` on all resources. No writes. |
| **Pro** | Full CRUD | Read + write on all resources. Webhooks. |
| **Scale** | Full + priority | Higher rate limits, more API keys. |

## Rate Limits

Rate limits are per API key and vary by plan:

| Plan | Global RPM | Daily Requests |
|------|-----------|----------------|
| Starter | 30/min | 5,000/day |
| Pro | 120/min | 50,000/day |
| Scale | 600/min | 500,000/day |

Write operations have additional per-resource daily and monthly caps. See your plan details for specifics.

Rate limit headers are included in every response:

```
X-RateLimit-Limit: 120
X-RateLimit-Remaining: 87
X-RateLimit-Reset: 1707667200
X-RateLimit-Resource: properties
Retry-After: 3                    (429 responses only)
```

## Pagination

All list endpoints return paginated results:

```json
{
  "data": [...],
  "pagination": {
    "page": 1,
    "limit": 20,
    "total": 142,
    "totalPages": 8
  }
}
```

Page size is capped by your plan tier (Starter: 50, Pro: 100, Scale: 200).

## Errors

Errors follow [RFC 9457 Problem Details](https://www.rfc-editor.org/rfc/rfc9457). Responses use `Content-Type: application/problem+json`:

```json
{
  "type": "https://rentalot.ai/problems/not-found",
  "title": "Not Found",
  "status": 404,
  "detail": "Property not found"
}
```

Validation errors include a per-field `errors` array:

```json
{
  "type": "https://rentalot.ai/problems/validation-error",
  "title": "Validation Error",
  "status": 422,
  "detail": "Request validation failed",
  "errors": [
    { "field": "monthlyRent", "message": "Expected number, received string" }
  ]
}
```

| Status | `type` (suffix of `https://rentalot.ai/problems/`) | Meaning |
|--------|----------------------------------------------------|---------|
| 401 | `unauthorized` | Missing or invalid API key |
| 403 | `forbidden` | Plan doesn't allow this operation |
| 404 | `not-found` | Resource not found |
| 409 | `conflict` | Resource already exists |
| 410 | `gone` | Resource has expired |
| 422 | `validation-error` / `unprocessable-entity` | Invalid request body, parameters, or business-rule violation |
| 429 | `rate-limited` | Rate limit exceeded — check `Retry-After` header |
| 500 | `internal-error` | Server error — safe to retry with backoff |

## Developer Tools

### MCP Server

Connect any AI assistant (Claude Code, Claude Desktop, Cursor, Codex, Gemini CLI) to your Rentalot account with our [MCP server](https://github.com/Rentalot-ai/rentalot-mcp). 65 tools covering all API resources.

```bash
# Claude Code
claude mcp add rentalot -e RENTALOT_API_KEY=ra_your_key -- npx -y @rentalot/mcp-server

# Codex
codex mcp add --env RENTALOT_API_KEY=ra_your_key -- npx -y @rentalot/mcp-server

# Gemini CLI
gemini mcp add --transport stdio rentalot -- npx -y @rentalot/mcp-server
```

For Claude Desktop, Cursor, and Windsurf, add to your config JSON:

```json
{
  "mcpServers": {
    "rentalot": {
      "command": "npx",
      "args": ["-y", "@rentalot/mcp-server"],
      "env": { "RENTALOT_API_KEY": "ra_your_key" }
    }
  }
}
```

See the [full setup guide](https://github.com/Rentalot-ai/rentalot-mcp#setup) for all supported clients and config file authentication.

### CLI

Manage properties, contacts, showings, and workflows from the terminal with the [Rentalot CLI](https://github.com/Rentalot-ai/rentalot-cli).

```bash
go install github.com/Rentalot-ai/rentalot-cli/cmd/rentalot@latest
rentalot --help
```

Also usable as a Go library:

```go
import "github.com/Rentalot-ai/rentalot-cli/pkg/rentalotcli"
```

## OpenAPI Spec

A machine-readable OpenAPI 3.0 spec is available at:

```
GET /api/v1/openapi.json
```

Use it to auto-generate client libraries in any language.
