# Webhooks and delivery health

Subscribe to current events, verify notifications and monitor delivery.

## REST operations and key permissions

| Task | Key permissions | Start here |
| --- | --- | --- |
| Register webhooks and monitor deliveries | `write:webhooks`, `read:webhooks` | `POST /api/v1/landlord/webhooks` |

## Subscribe to current events

Register only events from the current catalog: `application.submitted`, `application.intake_finalized`, `listing.changed`, `listing.unpublished`, `portfolio_import.completed`, `property.created`, `screening.started`, `unit.created`, `rent_roll_import.completed`, `fault_report.created`, `work_order.updated`, `commercial_inspection.created`, `commercial_inspection.updated`, `commercial_inspection.submitted`, `commercial_inspection.reviewed`.

## Verify and acknowledge notifications

Store the signing secret when the webhook is created. `X-Homito-Signature` has the format `sha256=<64 lowercase hexadecimal digits>`. Verify HMAC-SHA256 over the **raw request body bytes**, using that secret and a constant-time comparison. Durably store and deduplicate `X-Homito-Event-Id` before returning 2xx. `X-Homito-Delivery` identifies a delivery; it is not the event deduplication key. Delivery is at least once; duplicates and different arrival order are possible. A notification does not prove that a later domain operation or a rental decision completed.

## Read delivery health separately

Read delivery health at `GET /api/v1/landlord/webhooks/{webhookId}/deliveries` with `read:webhooks`. Use application receipt/progress and authorized application reads for their separate status checks.

## Preserve application capabilities

Versioned application submission has a different contract: preserve its UUID `X-Application-Submission-Key`, receipt and upload keys. Follow the published receipt/progress operations before retrying. The landlord `Idempotency-Key` does not replace those capabilities.

## Keep private data out of public caches

Keep personal data, receipts and upload capabilities out of public listing caches. Tenant and application reads intentionally return minimized operational projections; do not infer missing private fields or screening conclusions. Keep nullable/unknown values distinct from zero or a completed result.
