# Leases API

Create and manage rental agreements with full French regulatory compliance. The Leases API handles the entire lease lifecycle: creation, tenant assignment, PDF generation, electronic signatures, rent revisions, amendments, and termination.

## Quick Example

```bash
curl -X POST https://api.faireplace.com/api/leases \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "estate_id": "<estate_uuid>",
    "lease_type_id": "<lease_type_uuid>",
    "start_date": "2026-04-01",
    "end_date": "2029-03-31",
    "rent_amount": 950.00,
    "rent_frequency": "MONTHLY",
    "deposit_amount": 950.00,
    "usage_type": "RESIDENTIAL_ONLY",
    "payment_terms": "TERME_A_ECHOIR",
    "payment_method": "VIREMENT_BANCAIRE"
  }'
```

## Common Workflows

### Create and sign a lease
1. `POST /api/leases` — Create the lease
2. `POST /api/leases/{lease_id}/lessees` — Add tenants
3. `POST /api/leases/{lease_id}/pdf` — Generate the document
4. `POST /api/leases/{lease_id}/signature/initiate` — Start e-signature
5. See the [full tutorial](/signatures/lease-workflow)

### Annual rent revision (IRL)
1. `GET /api/leases/{lease_id}` — Get current rent
2. `POST /api/leases/{lease_id}/amendments` — Create revision amendment
3. `PUT /api/leases/{lease_id}/rent` — Apply new rent amount

### Terminate a lease
1. `PUT /api/leases/{lease_id}/lessees/{lessee_id}/end` — End tenant's term
2. `PUT /api/leases/{lease_id}/status` — Set status to `TERMINATED`
3. `POST /api/leases/{lease_id}/pdf` — Generate final documents

---

## Overview

The Leases API provides complete lease management with support for:
- **Lease Lifecycle**: Creation, updates, status management, and termination
- **Tenant Management**: Associate multiple tenants with leases
- **Document Management**: Upload and manage lease-related documents  
- **Amendment System**: Track lease modifications and changes
- **PDF Generation**: Create formatted lease documents
- **Compliance Checking**: French rental law compliance validation
- **Rent Management**: Complex rent calculations and revisions

## Authentication

All endpoints require authentication with the following permissions:
- **LeasesRead**: For GET operations
- **LeasesWrite**: For POST and PUT operations  
- **LeasesDelete**: For DELETE operations

## Base URL

All lease endpoints are prefixed with `/api/leases`

---

## Core Lease Operations

### List Leases
**GET** `/api/leases`

Retrieve all leases for the tenant with optional filtering.

**Response:**
```json
[
  {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "estate_id": "550e8400-e29b-41d4-a716-446655440010",
    "lease_type_id": "550e8400-e29b-41d4-a716-446655440020",
    "template_id": "550e8400-e29b-41d4-a716-446655440030",
    "agent_id": "550e8400-e29b-41d4-a716-446655440040",
    "reference_number": "LEASE-2024-001",
    "start_date": "2024-03-01",
    "end_date": "2027-02-28",
    "rent_amount": 1200.00,
    "rent_frequency": "MONTHLY",
    "deposit_amount": 2400.00,
    "status": "ACTIVE",
    "revision_index_type": "IRL",
    "next_revision_date": "2025-03-01",
    "usage_type": "RESIDENTIAL_ONLY",
    "notes": "Tenant preferred March start date",
    "payment_day": 5,
    "payment_terms": "TERME_A_ECHOIR",
    "payment_method": "VIREMENT_BANCAIRE",
    "charge_settlement_mode": "PROVISION",
    "is_subject_to_rent_evolution_decree": true,
    "is_subject_to_reference_rent_cap": true,
    "reference_rent_per_m2": 25.50,
    "reference_rent_increased_per_m2": 28.00,
    "base_rent_amount": 1100.00,
    "rent_complement_amount": 100.00,
    "rent_complement_justification": "Recent renovation and premium location",
    "created_at": "2024-01-15T10:30:00Z",
    "updated_at": "2024-01-15T10:30:00Z"
  }
]
```

### Create Lease
**POST** `/api/leases`

Create a new lease agreement.

**Request Body:**
```json
{
  "estate_id": "550e8400-e29b-41d4-a716-446655440010",
  "lease_type_id": "550e8400-e29b-41d4-a716-446655440020",
  "template_id": "550e8400-e29b-41d4-a716-446655440030",
  "agent_id": "550e8400-e29b-41d4-a716-446655440040",
  "reference_number": "LEASE-2024-002",
  "start_date": "2024-04-01",
  "end_date": "2027-03-31",
  "rent_amount": 1350.00,
  "rent_frequency": "MONTHLY",
  "deposit_amount": 2700.00,
  "revision_index_type": "IRL",
  "next_revision_date": "2025-04-01",
  "usage_type": "RESIDENTIAL_ONLY",
  "payment_day": 1,
  "payment_terms": "TERME_A_ECHOIR",
  "payment_method": "VIREMENT_BANCAIRE",
  "charge_settlement_mode": "PROVISION",
  "is_subject_to_rent_evolution_decree": true,
  "is_subject_to_reference_rent_cap": true,
  "reference_rent_per_m2": 26.00,
  "base_rent_amount": 1250.00,
  "rent_complement_amount": 100.00,
  "rent_complement_justification": "Premium location near metro"
}
```

**Response:** `201 Created`
Returns the created lease object.

### Get Lease
**GET** `/api/leases/{lease_id}`

Retrieve a specific lease by ID.

**Path Parameters:**
- `lease_id` (UUID): The lease ID

**Response:** `200 OK`
Returns the lease object.

### Update Lease
**PUT** `/api/leases/{lease_id}`

Update an existing lease. All fields are optional.

**Path Parameters:**
- `lease_id` (UUID): The lease ID

**Request Body:**
```json
{
  "rent_amount": 1400.00,
  "next_revision_date": "2025-04-01",
  "notes": "Rent increase due to market adjustment"
}
```

**Response:** `200 OK`
Returns the updated lease object.

### Delete Lease
**DELETE** `/api/leases/{lease_id}`

Delete a lease (typically only allowed for draft leases).

**Path Parameters:**
- `lease_id` (UUID): The lease ID

**Response:** `204 No Content`

### Change Lease Status
**PUT** `/api/leases/{lease_id}/status`

Change the status of a lease (Active, Terminated, etc.).

**Path Parameters:**
- `lease_id` (UUID): The lease ID

**Request Body:**
```json
{
  "status": "TERMINATED"
}
```

**Response:** `200 OK`
Returns the updated lease object.

### Update Lease Rent
**PUT** `/api/leases/{lease_id}/rent`

Update lease rent amount with revision tracking.

**Path Parameters:**
- `lease_id` (UUID): The lease ID

**Request Body:**
```json
{
  "new_rent_amount": 1250.00,
  "revision_date": "2025-01-01",
  "irl_reference_quarter": "T3-2024",
  "irl_reference_value": 142.74
}
```

**Response:** `200 OK`
Returns the updated lease object.

### List Leases by Estate
**GET** `/api/leases/estate/{estate_id}`

Retrieve all leases for a specific estate.

**Path Parameters:**
- `estate_id` (UUID): The estate ID

**Response:** `200 OK`
Returns array of lease objects.

---

## Lease Documents Management

### Create Document
**POST** `/api/leases/{lease_id}/documents`

Upload a document to a lease.

**Path Parameters:**
- `lease_id` (UUID): The lease ID

This endpoint uses `multipart/form-data` to upload the file directly.

**Form Fields:**
- `document_type` (required, string): The type of document (e.g., `LeaseAgreement`)
- `description` (optional, string): A description of the document
- `file` (required, binary): The file to upload

**Example:**
```bash
curl -X POST /api/leases/{lease_id}/documents \
  -H "Authorization: Bearer $API_KEY" \
  -F "document_type=LeaseAgreement" \
  -F "description=Signed lease agreement" \
  -F "file=@/path/to/lease-agreement.pdf"
```

**Response:** `201 Created`
Returns the created document object.

### List Documents
**GET** `/api/leases/{lease_id}/documents`

Retrieve all documents for a lease.

**Path Parameters:**
- `lease_id` (UUID): The lease ID

**Response:** `200 OK`
```json
[
  {
    "id": "doc-550e8400-e29b-41d4-a716-446655440000",
    "lease_id": "550e8400-e29b-41d4-a716-446655440000",
    "document_type": "LeaseAgreement",
    "file_path": "/documents/lease-agreement-001.pdf",
    "description": "Signed lease agreement",
    "created_at": "2024-01-15T10:30:00Z",
    "updated_at": "2024-01-15T10:30:00Z"
  }
]
```

### Get Document
**GET** `/api/leases/{lease_id}/documents/{document_id}`

Retrieve a specific document.

**Path Parameters:**
- `lease_id` (UUID): The lease ID
- `document_id` (UUID): The document ID

**Response:** `200 OK`
Returns the document object.

### Update Document
**PUT** `/api/leases/{lease_id}/documents/{document_id}`

Update document metadata.

**Path Parameters:**
- `lease_id` (UUID): The lease ID
- `document_id` (UUID): The document ID

**Request Body:**
```json
{
  "description": "Updated signed lease agreement with amendments"
}
```

**Response:** `200 OK`
Returns the updated document object.

### Delete Document
**DELETE** `/api/leases/{lease_id}/documents/{document_id}`

Delete a document from a lease.

**Path Parameters:**
- `lease_id` (UUID): The lease ID
- `document_id` (UUID): The document ID

**Response:** `204 No Content`

---

## Lease Amendments Management

### Create Amendment
**POST** `/api/leases/{lease_id}/amendments`

Create an amendment to modify lease terms.

**Path Parameters:**
- `lease_id` (UUID): The lease ID

**Request Body:**
```json
{
  "amendment_number": "AVE-001",
  "amendment_type": "RENT_INCREASE",
  "effective_date": "2024-06-01",
  "description": "Rent increase due to property improvements",
  "created_by": "<user_uuid>"
}
```

**Response:** `201 Created`
Returns the created amendment object.

### List Amendments
**GET** `/api/leases/{lease_id}/amendments`

Retrieve all amendments for a lease.

**Path Parameters:**
- `lease_id` (UUID): The lease ID

**Response:** `200 OK`
Returns array of amendment objects.

### Get Amendment
**GET** `/api/leases/{lease_id}/amendments/{amendment_id}`

Retrieve a specific amendment.

**Path Parameters:**
- `lease_id` (UUID): The lease ID
- `amendment_id` (UUID): The amendment ID

**Response:** `200 OK`
Returns the amendment object.

### Update Amendment
**PUT** `/api/leases/{lease_id}/amendments/{amendment_id}`

Update an amendment (only for draft amendments).

**Path Parameters:**
- `lease_id` (UUID): The lease ID
- `amendment_id` (UUID): The amendment ID

**Request Body:**
```json
{
  "effective_date": "2024-07-01",
  "description": "Updated based on final renovation costs"
}
```

**Response:** `200 OK`
Returns the updated amendment object.

### Delete Amendment
**DELETE** `/api/leases/{lease_id}/amendments/{amendment_id}`

Delete an amendment (only for draft amendments).

**Path Parameters:**
- `lease_id` (UUID): The lease ID
- `amendment_id` (UUID): The amendment ID

**Response:** `204 No Content`

### Change Amendment Status
**PUT** `/api/leases/{lease_id}/amendments/{amendment_id}/status`

Change the status of an amendment.

**Path Parameters:**
- `lease_id` (UUID): The lease ID
- `amendment_id` (UUID): The amendment ID

**Request Body:**
```json
{
  "status": "APPROVED"
}
```

**Response:** `200 OK`
Returns the updated amendment object.

---

## Lease Tenants (Lessees) Management

### Add Tenant to Lease
**POST** `/api/leases/{lease_id}/lessees`

Add a tenant to a lease.

**Path Parameters:**
- `lease_id` (UUID): The lease ID

**Request Body:**
```json
{
  "lessee_id": "550e8400-e29b-41d4-a716-446655440050",
  "role_type": "PRIMARY",
  "start_date": "2024-03-01"
}
```

**Response:** `201 Created`
Returns the created lease-tenant association.

### List Lease Tenants
**GET** `/api/leases/{lease_id}/lessees`

Retrieve all tenants for a lease.

**Path Parameters:**
- `lease_id` (UUID): The lease ID

**Response:** `200 OK`
Returns array of lease-tenant associations.

### Get Active Tenants
**GET** `/api/leases/{lease_id}/lessees/active`

Retrieve only active tenants for a lease.

**Path Parameters:**
- `lease_id` (UUID): The lease ID

**Response:** `200 OK`
Returns array of active lease-tenant associations.

### Get Lease Tenant
**GET** `/api/leases/{lease_id}/lessees/{lessee_id}`

Retrieve specific tenant details for a lease.

**Path Parameters:**
- `lease_id` (UUID): The lease ID
- `lessee_id` (UUID): The tenant ID

**Response:** `200 OK`
Returns the lease-tenant association object.

### Update Lease Tenant
**PUT** `/api/leases/{lease_id}/lessees/{lessee_id}`

Update tenant information in a lease.

**Path Parameters:**
- `lease_id` (UUID): The lease ID
- `lessee_id` (UUID): The tenant ID

**Request Body:**
```json
{
  "role_type": "CO_TENANT"
}
```

**Response:** `200 OK`
Returns the updated lease-tenant association.

### Remove Tenant from Lease
**DELETE** `/api/leases/{lease_id}/lessees/{lessee_id}`

Remove a tenant from a lease.

**Path Parameters:**
- `lease_id` (UUID): The lease ID
- `lessee_id` (UUID): The tenant ID

**Response:** `204 No Content`

### End Tenant Term
**PUT** `/api/leases/{lease_id}/lessees/{lessee_id}/end`

End a tenant's term in a lease.

**Path Parameters:**
- `lease_id` (UUID): The lease ID
- `lessee_id` (UUID): The tenant ID

**Request Body:**
```json
{
  "end_date": "2024-12-31"
}
```

**Response:** `200 OK`
Returns the updated lease-tenant association.

---

## PDF Generation and Management

### Generate PDF
**POST** `/api/leases/{lease_id}/pdf`

Generate a PDF document for a lease.

**Path Parameters:**
- `lease_id` (UUID): The lease ID

**Request Body:**
```json
{
  "template_id": "<template_uuid>",
  "template_type": "LeaseContract",
  "data": {}
}
```

**Response:** `201 Created`
```json
{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "lease_id": "550e8400-e29b-41d4-a716-446655440010",
  "template_id": "<template_uuid>",
  "template_type": "LeaseContract",
  "file_path": "/generated/lease-contract-2024.pdf",
  "file_size": 245000,
  "creation_timestamp": "2024-01-15T10:30:00Z"
}
```

### List Lease PDFs
**GET** `/api/leases/{lease_id}/pdfs`

Retrieve all generated PDFs for a lease.

**Path Parameters:**
- `lease_id` (UUID): The lease ID

**Response:** `200 OK`
Returns array of PDF objects.

### Download PDF
**GET** `/api/leases/pdf/{pdf_id}`

Download a generated PDF file.

**Path Parameters:**
- `pdf_id` (UUID): The PDF ID

**Response:** `200 OK`
Returns PDF file with appropriate headers.

### Delete PDF
**DELETE** `/api/leases/pdf/{pdf_id}`

Delete a generated PDF file.

**Path Parameters:**
- `pdf_id` (UUID): The PDF ID

**Response:** `204 No Content`

---

## Compliance Management

### Check Lease Compliance
**GET** `/api/leases/{lease_id}/compliance`

Check lease compliance with French rental regulations (rent control, high-demand zones). Read-only — does not modify the lease.

**Path Parameters:**
- `lease_id` (UUID): The lease ID

**Response:** `200 OK`
```json
{
  "lease_id": "550e8400-e29b-41d4-a716-446655440000",
  "country_code": "FR",
  "country_name": "Île-de-France",
  "postal_code": "75001",
  "compliance_checks": [
    {
      "check_type": "RentControl",
      "status": "Compliant",
      "details": "The rent complies with rent control regulations",
      "recommendations": []
    },
    {
      "check_type": "RentRegulation",
      "status": "Warning",
      "details": "High-demand zone detected for Paris. Special regulations apply.",
      "recommendations": [
        "Comply with rent control rules",
        "Notice period reduced to 1 month in case of termination"
      ]
    }
  ],
  "overall_status": "Warning",
  "rent_revision_date": "2025-01-01",
  "irl_reference_quarter": "T3-2024",
  "irl_reference_value": 142.74
}
```

### Check and Update Lease Compliance
**POST** `/api/leases/{lease_id}/compliance/update`

Check compliance AND automatically update the lease with compliance information (e.g., `rent_regulation_compliance_status`).

**Path Parameters:**
- `lease_id` (UUID): The lease ID

**Response:** `200 OK`
Returns the same compliance check response as above, with the lease updated in place.

---

## Cache Management

### Get PDF Cache Statistics
**GET** `/api/leases/cache/stats`

Retrieve PDF generation cache statistics.

**Response:** `200 OK`
```json
{
  "hit_count": 42,
  "miss_count": 8,
  "size": 15
}
```

### Clear PDF Cache
**POST** `/api/leases/cache/clear`

Clear the PDF generation cache.

**Response:** `200 OK`
```json
{
  "message": "PDF cache cleared successfully",
  "cleared_entries": 15
}
```

---

## Data Types and Enums

### LeaseStatus
- `DRAFT` - Lease being prepared
- `PENDING_SIGNATURE` - Awaiting electronic signature
- `ACTIVE` - Currently active lease
- `NOTICE` - Notice period (préavis) in progress
- `FINALISATION` - Lease being finalized (état des lieux de sortie)
- `TERMINATED` - Lease ended
- `EXPIRED` - Lease term expired

### LeaseRentFrequency
- `MONTHLY` - Monthly rent payments
- `QUARTERLY` - Quarterly payments
- `ANNUALLY` - Annual payments

### LeaseRevisionIndexType
- `IRL` - Indice de Référence des Loyers
- `ICC` - Indice du Coût de la Construction
- `ILAT` - Indice des Loyers des Activités Tertiaires
- `ILC` - Indice des Loyers Commerciaux
- `NONE` - No revision index

### LeaseUsageType
- `RESIDENTIAL_ONLY` - Residential use only
- `MIXED_PROFESSIONAL` - Mixed residential and professional use

### ChargeSettlementMode
- `PROVISION` - Provisional with annual regularization
- `PERIODIC` - Periodic payment of actual costs
- `FLAT_RATE` - Fixed charge amount

### LeasePaymentTerms
- `TERME_A_ECHOIR` - Payment in advance (terme à échoir)
- `TERME_ECHU` - Payment after period (terme échu)

### LeasePaymentMethod
- `VIREMENT_BANCAIRE` - Bank transfer
- `PRELEVEMENT_AUTOMATIQUE` - Direct debit
- `CHEQUE` - Check payment
- `ESPECES` - Cash payment
- `CARTE_BANCAIRE` - Bank card
- `MANDAT_CASH` - Cash money order
- `AUTRE` - Other payment method

---

## Error Responses

### Validation Errors
**400 Bad Request**
```json
{
  "error": "ValidationError",
  "message": "Invalid lease data",
  "details": [
    {
      "field": "rent_amount",
      "message": "Rent amount must be greater than 0"
    },
    {
      "field": "start_date",
      "message": "Start date cannot be in the past"
    }
  ]
}
```

### Compliance Errors
**422 Unprocessable Entity**
```json
{
  "error": "ComplianceError",
  "message": "Lease does not comply with regulations",
  "violations": [
    {
      "rule": "RentCap",
      "message": "Rent exceeds legal maximum for this area",
      "current_value": 28.00,
      "maximum_allowed": 25.50
    }
  ]
}
```

### Not Found
**404 Not Found**
```json
{
  "error": "NotFound",
  "message": "Lease not found"
}
```

---

## Common Use Cases

### Creating a Standard Residential Lease
1. Create lease with `POST /api/leases`
2. Add tenant with `POST /api/leases/{lease_id}/lessees`
3. Upload signed agreement with `POST /api/leases/{lease_id}/documents`
4. Check compliance with `GET /api/leases/{lease_id}/compliance`

### Annual Rent Revision
1. Check current rent with `GET /api/leases/{lease_id}`
2. Calculate new rent based on IRL index
3. Create amendment with `POST /api/leases/{lease_id}/amendments`
4. Update rent with `PUT /api/leases/{lease_id}/rent`

### Lease Termination Process
1. End tenant term with `PUT /api/leases/{lease_id}/lessees/{lessee_id}/end`
2. Change lease status with `PUT /api/leases/{lease_id}/status`
3. Generate final documents with `POST /api/leases/{lease_id}/pdf`

### Document Management Workflow
1. Generate lease PDF with `POST /api/leases/{lease_id}/pdf`
2. Download for signing with `GET /api/leases/pdf/{pdf_id}`
3. Upload signed version with `POST /api/leases/{lease_id}/documents`
4. Track document versions through amendments

---

## Business Rules

- **Rent Compliance**: All leases subject to French rent control laws
- **Deposit Limits**: Security deposits cannot exceed legal maximums
- **Revision Dates**: Rent revisions follow legal timing requirements
- **Amendment Tracking**: All lease changes must be documented
- **Tenant Associations**: Primary tenant required for all leases
- **Status Transitions**: Lease status changes follow defined workflows
- **Document Retention**: Legal document retention requirements

---

## Integration Notes

- **Estate Management**: Leases are tied to specific estates
- **Contact System**: Tenants and agents from contact management
- **Financial System**: Rent calculations and payment tracking
- **Compliance Engine**: French rental law validation
- **Template System**: PDF generation from lease templates
- **Notification System**: Automated reminders and alerts