> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://developer.fortresstech.io/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://developer.fortresstech.io/_mcp/server.

# Conventions

> Fortress API Conventions used throughout the documentation

## API Design Principles

The Fortress API follows consistent conventions to ensure predictability and ease of use:

* **RESTful design** - Standard HTTP methods (GET, POST, PUT, PATCH, DELETE)
* **Resource-oriented** - Clear URL structure around business entities
* **Minimal nesting** - Paths are nested only for truly hierarchical relationships
* **Consistent naming** - Predictable patterns across all endpoints
* **Idempotent operations** - Safe to retry requests using `idempotencyId` for most of our endpoints

## Resource Naming

### URL Structure

* **Plural resources**: Collection endpoints use plural names (e.g., `/properties`, `/units`, `/workOrders`)
* **Singular identifiers**: Individual resources accessed via ID (e.g., `/properties/{propertyId}`, `/units/{unitId}`)
* **Nested resources**: Sub-resources nested when they represent true parent-child relationships:
  * `/applications/{applicationId}/customers` - Customers belong to applications
  * `/applications/{applicationId}/pets` - Pets belong to applications
  * `/workOrders/{workOrderId}/timeEntries` - Time entries belong to work orders

### Identifiers

* All resource IDs use **UUIDv4** format
* Path parameters follow pattern: `{resourceName}Id` (e.g., `{propertyId}`, `{customerId}`)
* Foreign key properties suffixed with `Id` (e.g., `propertyId`, `householdId`)

## HTTP Methods and Status Codes

### Standard Operations

* **GET** - Retrieve resource(s) → Returns `200 OK`
* **POST** - Create new resource → Returns `201 Created` (or `200 OK` for some operations)
* **PUT** - Update entire resource → Returns `200 OK`
* **PATCH** - Partial update or state change → Returns `200 OK` or `204 No Content`
* **DELETE** - Remove resource → Returns `200 OK` with message

### Status Code Patterns

* `200 OK` - Successful operation with response body
* `201 Created` - Resource created successfully (POST operations)
* `204 No Content` - Successful operation, already in desired state (idempotent state transitions)
* `400 Bad Request` - Invalid request parameters or body
* `401 Unauthorized` - Missing or invalid API key
* `404 Not Found` - Resource does not exist
* `500 Internal Server Error` - Server error (safe to retry with same `idempotencyId`)

## Query Parameters

All list endpoints support the following query parameters:

### Pagination

* `page` - Page number (starts at 1, defaults to 1)
* `limit` - Items per page (defaults to 100)

Example:

```
GET /properties?page=2&limit=25
```

### Filtering

* `filter` - FQL (Fortress Query Language) expressions for filtering results

Example:

```
GET /workOrders?filter=status=OPEN&propertyId=123e4567-e89b-12d3-a456-426614174000
```

See the [Filtering with FQL](fql) page for detailed filtering syntax.

### Sorting

* `sort` - Order results by field(s), prefix with `-` for descending

Examples:

```
GET /transactions?sort=date
GET /transactions?sort=-createdAt
```

### Field Selection and Relations

* `fields` - Select specific fields or include related entities

Examples:

```
GET /households?fields=id,name,property.*
GET /units?fields=*,floorPlan.name,property.name
```

## Response Formats

### List Responses

List endpoints return arrays directly with pagination metadata in headers:

```json
// Response Headers
x-total-count: 157

// Response Body
[
  {
    "id": "123e4567-e89b-12d3-a456-426614174000",
    "name": "Sunset Apartments",
    "status": "ACTIVE",
    "createdAt": "2024-01-15T10:30:00Z"
  }
]
```

### Single Resource Responses

Individual resource endpoints return the entity object:

```json
{
  "id": "123e4567-e89b-12d3-a456-426614174000",
  "name": "Sunset Apartments",
  "status": "ACTIVE",
  "createdAt": "2024-01-15T10:30:00Z",
  "updatedAt": "2024-01-15T10:30:00Z"
}
```

### Create/Update Responses

Most POST operations return `201 Created` with the created resource or a wrapper object:

```json
{
  "message": "Application created successfully",
  "data": {
    "id": "123e4567-e89b-12d3-a456-426614174000",
    "propertyId": "987e4567-e89b-12d3-a456-426614174999"
  }
}
```

### Delete Responses

DELETE operations return `200 OK` with a message:

```json
{
  "message": "Customer deleted successfully"
}
```

## Property Conventions

### Standard Fields

All entities include these common properties:

* `id` (UUID) - Unique identifier
* `createdAt` (ISO-8601 datetime) - When the record was created
* `updatedAt` (ISO-8601 datetime) - When the record was last modified
* `deletedAt` (ISO-8601 datetime, nullable) - Soft delete timestamp

Additional common fields:

* `readableId` (string, nullable) - Human-readable identifier
* `idempotencyId` (UUID, nullable) - For idempotent operations

### Property Naming

* **camelCase** - All property names use camelCase (e.g., `firstName`, `phoneNumber`)
* **Foreign keys** - Suffixed with `Id` (e.g., `propertyId`, `customerId`, `householdId`)
* **Booleans** - Prefixed with `is`, `has`, or similar (e.g., `isActive`, `hasBalcony`, `isServiceAnimal`)
* **Dates** - Suffixed with `At` or `Date`:
  * `*At` for timestamps (e.g., `createdAt`, `deletedAt`, `offboardedAt`)
  * `*Date` for dates only (e.g., `moveInDate`, `birthDate`, `scheduledDate`)

### Data Types

* **Dates and Times** - ISO-8601 format strings, UTC timezone by default
* **UUIDs** - Standard UUIDv4 format strings
* **Enums** - ALL_CAPS with underscores (e.g., `VACANT_READY`, `OCCUPIED_NO_NOTICE`)
* **Phone Numbers** - String format, country codes allowed (e.g., `"+1234567890"`)
* **Amounts** - Numeric with decimal precision for currency values

## Authentication

All API requests require authentication via the `x-api-key` header:

```bash
curl https://api.fortresstech.io/v1/properties \
  -H "x-api-key: YOUR_API_KEY"
```

The API key automatically maps requests to your organization, ensuring data isolation.

See the [Authentication](authentication) page for more details.

## Error Handling

Errors follow RFC 7807 Problem Details format with standard HTTP status codes:

```json
{
  "type": "https://api.fortresstech.io/errors/validation-error",
  "title": "Validation Error",
  "status": 400,
  "detail": "Invalid property ID format"
}
```

Operations are safe to retry on 5xx errors when using the same `idempotencyId`.

## Idempotency

To ensure safe retries, include an `idempotencyId` in your request body for create operations:

```json
{
  "idempotencyId": "unique-uuid-per-operation",
  "propertyId": "123e4567-e89b-12d3-a456-426614174000",
  "name": "New Work Order"
}
```

The same `idempotencyId` will always produce the same result, preventing duplicate operations.