Home Property Setup Property Documents

5 Property Documents

Attach contracts, technical docs, floor plans, and other files to your properties with role-based access control.

Why Attach Documents?

Property documents keep all important files organized and accessible in one place — contracts, technical documentation, floor plans, passwords, and more.

Benefits

  • All property files in one organized place
  • Role-based visibility — control who can see each document
  • Categorized by type: contracts, technical docs, plans, passwords
  • Secure cloud storage with access via signed URLs

How to Add Documents

You can upload documents via the web interface or through the API. Each document is assigned a type and can optionally be restricted to specific roles.

In the web interface: open the property page, then click "Documents" in the property menu.

See the full documentation in the Library: Property Documents.

Document Types

Each document belongs to one of five categories. Choose the right type for proper organization.

OFFICIAL_DOCUMENT Contracts, agreements, acts (PDF, DOC, max 20 MB)
TECHNICAL_DOCUMENT Tech specs, blueprints (PDF, DWG, XLS, max 50 MB)
INFORMATIONAL_DOCUMENT Instructions, notes, memos (PDF, TXT, max 10 MB)
SCHEMA_IMAGE Floor plans, layouts (JPG, PNG, PDF, max 20 MB)
PASSWORD_FILE Access codes, WiFi passwords (TXT, PDF, max 1 MB)

Access Control

By default, documents are visible to all property participants. You can restrict visibility to specific roles. The owner and agent always see all documents.

PROPERTY_TENANT PROPERTY_TENANT_AGENT PROPERTY_MAINTENANCE
Empty visible_to or null means the document is visible to everyone. Set specific roles to restrict access.

For Developers: REST API

You can manage property documents via the REST API. Files are uploaded as base64-encoded content.

POST Upload Document

Upload a document by sending the file content as a base64-encoded string. Specify the document type to categorize it.

POST /api/v1/properties/{id}/documents

Headers:

Authorization: Bearer {token} Content-Type: application/json

Required Fields:

document_type_id Document type ID (1-5)
file_content Base64-encoded file content
file_name Original file name with extension
mime_type MIME type (application/pdf, image/png...)

Optional Fields:

comment Description or comment for the document

Request Body:

{ "document_type_id": 1, "file_content": "base64-encoded-file-content...", "file_name": "rental-agreement.pdf", "mime_type": "application/pdf", "comment": "Rental agreement 2026" }
Document type IDs: 1 = OFFICIAL_DOCUMENT, 2 = TECHNICAL_DOCUMENT, 3 = INFORMATIONAL_DOCUMENT, 4 = SCHEMA_IMAGE, 5 = PASSWORD_FILE. Use GET /api/document-types for the full list.

Response (201 Created):

{ "message": "Document uploaded successfully", "data": { "id": 50, "property_id": 2, "document_type": { "id": 1, "code": "OFFICIAL_DOCUMENT", "name_key": "document_type.official.name" }, "file_url": "https://landlordkeeper.com/file/cG1mOjUwOjA6...", "original_name": "rental-agreement.pdf", "file_size": 45678, "file_size_formatted": "44.61 KB", "mime_type": "application/pdf", "extension": "pdf", "is_image": false, "is_video": false, "is_pdf": true, "comment": "Rental agreement 2026", "visible_to_roles": null, "created_at": "2026-02-20T12:00:00+00:00" } }

GET List Documents

Get all documents for a property. Use type_id filter to show only specific document types.

GET /api/v1/properties/{id}/documents

Query Parameters:

type_id Filter by document type ID (e.g. 1 for official documents)

Response (200 OK):

{ "data": [ { "id": 50, "property_id": 2, "document_type": {"id": 1, "code": "OFFICIAL_DOCUMENT"}, "file_url": "https://landlordkeeper.com/file/cG1mOjUwOjA6...", "original_name": "rental-agreement.pdf", "file_size": 45678, "file_size_formatted": "44.61 KB", "is_pdf": true, "comment": "Rental agreement 2026", "visible_to_roles": null, "created_at": "2026-02-20T12:00:00+00:00" } ], "total": 3, "stats": { "total_count": 3, "total_size": 137034, "total_size_formatted": "133.82 KB" } }

PUT Update Document

Update a document's comment and/or visibility. You cannot replace the file itself — delete and re-upload instead.

PUT /api/v1/documents/{documentId}

Use the document ID from the list (GET) or upload (POST) response.

Request Body:

{ "comment": "Updated rental agreement", "visible_to": ["PROPERTY_TENANT", "PROPERTY_MAINTENANCE"] }

Available roles for visible_to:

PROPERTY_TENANT PROPERTY_TENANT_AGENT PROPERTY_MAINTENANCE
Owner and agent always see all documents regardless of visible_to settings.

Response (200 OK):

{ "message": "Document updated successfully", "data": { "id": 50, "comment": "Updated rental agreement", "visible_to_roles": ["PROPERTY_TENANT", "PROPERTY_MAINTENANCE"] } }

DELETE Delete Document

Permanently delete a document by its ID.

DELETE /api/v1/documents/{documentId}

Response (200 OK):

{"message": "Document deleted successfully"}

cURL Examples

1. Upload Document

curl -X POST https://landlordkeeper.com/api/v1/properties/2/documents \ -H "Content-Type: application/json" \ -H "Authorization: Bearer YOUR_TOKEN_HERE" \ -d '{ "document_type_id": 1, "file_content": "'$(base64 -w 0 contract.pdf)'", "file_name": "contract.pdf", "mime_type": "application/pdf", "comment": "Rental agreement 2026" }'

2. List Documents

curl https://landlordkeeper.com/api/v1/properties/2/documents?type_id=1 \ -H "Authorization: Bearer YOUR_TOKEN_HERE"

3. Update Document

curl -X PUT https://landlordkeeper.com/api/v1/documents/50 \ -H "Content-Type: application/json" \ -H "Authorization: Bearer YOUR_TOKEN_HERE" \ -d '{ "visible_to": ["PROPERTY_TENANT"], "comment": "Visible to tenant" }'

4. Delete Document

curl -X DELETE https://landlordkeeper.com/api/v1/documents/50 \ -H "Authorization: Bearer YOUR_TOKEN_HERE"
Replace YOUR_TOKEN_HERE with the JWT token from the authentication step.