Lease Amendments (Avenants)
Lease amendments allow you to formally modify the terms of an active lease. Every modification to a lease — rent changes, duration extensions, tenant replacements, early terminations — must go through an amendment to maintain a complete legal audit trail.
Legal Framework
The amendment system is built to comply with French real estate law:
| Law | Article | Requirement |
|---|---|---|
| Loi 89-462 | Art. 12 | Owner approval required for tenant/guarantor modifications |
| Loi 89-462 | Art. 15 | Minimum 90-day notice for early termination |
| Loi 89-462 | Art. 17-1 | Rent revision rules (index-based) |
| Loi 89-462 | Art. 17-2 | Rent cap in zone tendue (reference rent) |
| ALUR | Decret 2015-587 | Reference rent enforcement |
| Code Civil | Art. 1367 | Electronic signature validity |
Amendment Types
| Type | Description | Sub-resource |
|---|---|---|
RENT_MODIFICATION | Change the monthly rent amount | Rent Detail (1:1) |
DURATION_MODIFICATION | Extend or reduce the lease duration | Duration Detail (1:1) |
RENEWAL | Renew the lease for a new term | Duration Detail (1:1) |
TENANT_MODIFICATION | Replace or add a tenant | Lease Lessee API |
GUARANTOR_MODIFICATION | Replace or add a guarantor | Lease Lessee API |
CHARGE_MODIFICATION | Modify service charges | Charge module |
CONDITION_MODIFICATION | Update lease special conditions | — |
EARLY_TERMINATION | Terminate the lease before end date | — |
OTHER | Generic amendment | — |
Status Lifecycle
Code
Allowed transitions
| From | To | Trigger |
|---|---|---|
DRAFT | PENDING_SIGNATURE | Initiate signature |
DRAFT | REJECTED | Reject amendment |
DRAFT | CANCELLED | Cancel amendment |
PENDING_SIGNATURE | SIGNED | All parties signed |
PENDING_SIGNATURE | REJECTED | Reject during signature |
PENDING_SIGNATURE | CANCELLED | Cancel during signature |
SIGNED | ACTIVE | Activate (applies changes to lease) |
Activation requirements
When transitioning from SIGNED to ACTIVE, the system:
- Checks all mandatory validations are
APPROVED(blocks ifPENDINGorREJECTED) - Verifies the lease is in
ACTIVEstatus - Applies the amendment changes to the lease (type-specific logic)
- Validates business rules (e.g., rent cap in zone tendue)
- Transitions the amendment status
- Fires notifications to relevant parties
Conflict detection
Only one amendment of the same type can be in a non-terminal status (DRAFT, PENDING_SIGNATURE, or SIGNED) per lease at any time. Creating a second amendment of the same type while one is in progress returns a 400 error.
Core CRUD Operations
Create an amendment
Code
Request body:
Required fields: amendment_type, effective_date, created_by. All other fields are optional.
Code
Auto-created validations: For TENANT_MODIFICATION, GUARANTOR_MODIFICATION, and EARLY_TERMINATION, a mandatory OWNER validation is automatically created (Art. 12 & 15 Loi 89-462).
List amendments
Code
Returns all amendments for the lease, ordered by creation date.
Get a specific amendment
Code
Update an amendment
Code
Only allowed while the amendment is in DRAFT status.
Delete an amendment
Code
Change status
Code
Code
Sub-Resources
Rent Detail
One-to-one with RENT_MODIFICATION amendments. Stores the previous and new rent amounts, calculation method, and optional index references.
| Endpoint | Method | Description |
|---|---|---|
/{amendment_id}/rent-detail | POST | Create rent detail |
/{amendment_id}/rent-detail | GET | Get rent detail |
/{amendment_id}/rent-detail | PUT | Update rent detail |
/{amendment_id}/rent-detail | DELETE | Delete rent detail |
Rent cap validation (zone tendue): At activation, if the lease has is_subject_to_reference_rent_cap = true, the system validates:
Code
If exceeded, activation is blocked with a detailed error citing Art. 17-2.
Example:
Code
Duration Detail
One-to-one with DURATION_MODIFICATION and RENEWAL amendments. Stores the previous and new end dates with the extension type.
| Endpoint | Method | Description |
|---|---|---|
/{amendment_id}/duration-detail | POST | Create duration detail |
/{amendment_id}/duration-detail | GET | Get duration detail |
/{amendment_id}/duration-detail | PUT | Update duration detail |
/{amendment_id}/duration-detail | DELETE | Delete duration detail |
Validation: For RENEWAL and EXTENSION types, new_end_date must be after previous_end_date. For REDUCTION and EARLY_TERMINATION, an earlier date is allowed.
Example:
Code
Validations
Multi-role validation workflow. Each amendment can have multiple validation entries (one per role). Mandatory validations must all be APPROVED before the amendment can be activated.
| Endpoint | Method | Description |
|---|---|---|
/{amendment_id}/validations | POST | Create validation entry |
/{amendment_id}/validations | GET | List all validations |
/{amendment_id}/validations/status | GET | Compute aggregate status |
/{amendment_id}/validations/{id} | GET | Get validation entry |
/{amendment_id}/validations/{id} | PUT | Approve/reject |
/{amendment_id}/validations/{id} | DELETE | Delete validation entry |
Aggregate status computation:
| Condition | Result |
|---|---|
| No mandatory validations | FULLY_VALIDATED |
Any mandatory = REJECTED | REJECTED |
All mandatory = APPROVED | FULLY_VALIDATED |
| Otherwise | PENDING |
Validator roles: LEGAL, FINANCIAL, PROPERTY_MANAGER, OWNER, TENANT
Approve a validation:
Code
Documents
Documents attached to an amendment (unsigned drafts, signed copies, supporting documents).
| Endpoint | Method | Description |
|---|---|---|
/{amendment_id}/documents | POST | Attach a document |
/{amendment_id}/documents | GET | List documents |
/{amendment_id}/documents/{id} | GET | Get document |
/{amendment_id}/documents/{id} | PUT | Update a document |
/{amendment_id}/documents/{id} | DELETE | Delete document |
/{amendment_id}/documents/{id}/validate | PUT | Validate a document |
Document types: DRAFT, SIGNED_COPY, SUPPORTING_DOCUMENT, NOTICE, CALCULATION_DETAILS, LEGAL_NOTICE
History
Read-only audit trail. Entries are automatically created by the system when changes occur.
| Endpoint | Method | Description |
|---|---|---|
/{amendment_id}/history | GET | List all history entries |
/{amendment_id}/history/{id} | GET | Get a specific entry |
Change types: STATUS_CHANGE, CONTENT_MODIFICATION, VALIDATION_CHANGE, SIGNATURE_UPDATE, DOCUMENT_ADDITION
Notifications
Notifications are auto-created on status transitions and published as events for email delivery.
| Endpoint | Method | Description |
|---|---|---|
/{amendment_id}/notifications | GET | List notifications |
/{amendment_id}/notifications/{id} | GET | Get notification |
/{amendment_id}/notifications/{id} | PUT | Update status (mark read/actioned) |
/{amendment_id}/notifications/{id} | DELETE | Delete notification |
Auto-generated notifications:
| Transition | Notification Type | Recipients |
|---|---|---|
Any -> PENDING_SIGNATURE | SIGNATURE_REQUIRED | All lessees + owner |
Any -> REJECTED | AMENDMENT_REJECTED | Creator (owner) |
Any -> ACTIVE | AMENDMENT_ACTIVATED | All lessees |
Any -> EXPIRED | AMENDMENT_EXPIRING | Creator (owner) |
Notification statuses: DRAFT -> SENT -> READ -> ACTIONED (or EXPIRED)
Recipient types: OWNER, LESSEE, VALIDATOR, CREATOR
PDF Generation
Code
Generates a legal PDF document using Typst templates. The template is auto-selected based on amendment_type:
| Amendment Type | Template |
|---|---|
RENT_MODIFICATION | Rent revision template (Art. 17-1) |
DURATION_MODIFICATION | Duration modification template |
TENANT_MODIFICATION | Tenant modification template (3 signature zones) |
| Other types | Generic amendment template |
Returns application/pdf binary content.
Electronic Signature
Two-step process using the shared signature infrastructure (Scaleway Topics + DO Global).
Step 1 — Initiate
Code
Code
What happens:
- Generates the amendment PDF (Typst)
- Uploads to encrypted storage (SSE-C)
- Creates
DocumentSignaturewithdocument_type: AMENDMENT - Creates
SignatureRequestper signer (owner + all lessees) - Publishes signature events to external queue
- Transitions amendment to
PENDING_SIGNATURE - Creates
DRAFTdocument record
Step 2 — Finalize
Code
Code
What happens:
- Updates
DocumentSignaturetoCOMPLETED - Stores signed PDF URL
- Transitions amendment to
SIGNED - Creates
SIGNED_COPYdocument record
Complete Workflow Example
Here's the full lifecycle for a rent modification amendment:
Code
Endpoints Summary
All endpoints are prefixed with /leases/{lease_id}.
| Method | Path | Description |
|---|---|---|
POST | /amendments | Create amendment |
GET | /amendments | List amendments |
GET | /amendments/{id} | Get amendment |
PUT | /amendments/{id} | Update amendment |
DELETE | /amendments/{id} | Delete amendment |
PUT | /amendments/{id}/status | Change status |
POST | /amendments/{id}/generate-pdf | Generate PDF |
POST | /amendments/{id}/initiate-signature | Start signature |
POST | /amendments/{id}/finalize-signature | Complete signature |
POST | /amendments/{id}/rent-detail | Create rent detail |
GET | /amendments/{id}/rent-detail | Get rent detail |
PUT | /amendments/{id}/rent-detail | Update rent detail |
DELETE | /amendments/{id}/rent-detail | Delete rent detail |
POST | /amendments/{id}/duration-detail | Create duration detail |
GET | /amendments/{id}/duration-detail | Get duration detail |
PUT | /amendments/{id}/duration-detail | Update duration detail |
DELETE | /amendments/{id}/duration-detail | Delete duration detail |
POST | /amendments/{id}/validations | Create validation |
GET | /amendments/{id}/validations | List validations |
GET | /amendments/{id}/validations/status | Aggregate status |
GET | /amendments/{id}/validations/{vid} | Get validation |
PUT | /amendments/{id}/validations/{vid} | Approve/reject |
DELETE | /amendments/{id}/validations/{vid} | Delete validation |
POST | /amendments/{id}/documents | Attach document |
GET | /amendments/{id}/documents | List documents |
GET | /amendments/{id}/documents/{did} | Get document |
PUT | /amendments/{id}/documents/{did} | Update document |
DELETE | /amendments/{id}/documents/{did} | Delete document |
PUT | /amendments/{id}/documents/{did}/validate | Validate document |
GET | /amendments/{id}/history | List history |
GET | /amendments/{id}/history/{eid} | Get history entry |
GET | /amendments/{id}/notifications | List notifications |
GET | /amendments/{id}/notifications/{nid} | Get notification |
PUT | /amendments/{id}/notifications/{nid} | Update notification |
DELETE | /amendments/{id}/notifications/{nid} | Delete notification |
Total: 36 endpoints