Webhooks
HomeDash POSTs JSON to URLs you register, signed with HMAC-SHA256 so you can trust the body. There are 43 event types, and one endpoint can subscribe to up to 32 of them. Subscriptions are managed in the Developer Dashboard, not via the API.
The envelope
Every webhook delivery has the same outer shape:
{
"id": "evt_<uuid>",
"event": "rent.overdue",
"created_at": "2026-01-15T10:30:00.000Z",
"landlord_id": "<uuid>",
"data": { ... event-specific fields ... }
}id— stable per event, prefixedevt_. Use it as your idempotency key — HomeDash may retry the same id up to 3 times.event— one of the 9 types listed below._test: trueat the top level (and insidedata) marks a test delivery from the Developer Dashboard. Real deliveries omit this.
Request headers
POST /your-endpoint HTTP/1.1
Content-Type: application/json
X-HomeDash-Signature-256: sha256=<64-char-hex>
X-HomeDash-Event: rent.overdue
X-HomeDash-Delivery: <uuid>X-HomeDash-Signature-256— HMAC-SHA256 of the raw request body, hex-encoded, prefixed withsha256=. Always verify before trusting.X-HomeDash-Event— same aseventin the body, useful for routing without parsing JSON.X-HomeDash-Delivery— the same UUID embedded inid(without theevt_prefix).
Verifying the signature
Always compute the HMAC over the raw request body — before any framework reparses or reformats it. Use a timing-safe comparison.
// Node.js
import crypto from 'node:crypto';
function verify(rawBody, headerValue, secret) {
const sig = (headerValue || '').replace(/^sha256=/i, '');
if (!/^[a-f0-9]{64}$/i.test(sig)) return false;
const expected = crypto
.createHmac('sha256', secret)
.update(rawBody, 'utf8')
.digest('hex');
const a = Buffer.from(sig.toLowerCase(), 'hex');
const b = Buffer.from(expected, 'hex');
return a.length === b.length && crypto.timingSafeEqual(a, b);
}# Python
import hmac, hashlib
def verify(raw_body: bytes, header_value: str, secret: str) -> bool:
sig = (header_value or '').replace('sha256=', '', 1).lower()
if len(sig) != 64:
return False
expected = hmac.new(
secret.encode('utf-8'),
raw_body,
hashlib.sha256,
).hexdigest()
return hmac.compare_digest(sig, expected)<?php
// PHP
function verify(string $rawBody, string $headerValue, string $secret): bool {
$sig = strtolower(preg_replace('/^sha256=/i', '', $headerValue ?? ''));
if (!preg_match('/^[a-f0-9]{64}$/', $sig)) return false;
$expected = hash_hmac('sha256', $rawBody, $secret);
return hash_equals($expected, $sig);
}Delivery, retries, and timeouts
- HomeDash calls your URL with a 10-second timeout.
- Any 2xx response counts as success.
- On failure (non-2xx, timeout, network error) HomeDash retries up to 2 more times: once after ~15 minutes, once after ~60 minutes (with jitter to avoid thundering herds). After the third attempt the delivery is marked permanently failed.
- Each retry carries the same
id, so de-duplicate onid. - Multiple subscriptions for the same event each receive an independent delivery with the same
id. - Delivery history is visible in the Developer Dashboard, including response code, latency, and the option to manually retry failed deliveries.
Event catalog
The payloads below are real fixtures from the HomeDash test-delivery system, with a stable id and timestamp so you can copy-paste reliably.
Rent overdue
rent.overdueFired when scheduled rent is past its due date and still unpaid.
{
"id": "evt_00000000-0000-4000-8000-000000000000",
"event": "rent.overdue",
"created_at": "2026-01-15T10:30:00.000Z",
"landlord_id": "11111111-1111-4111-8111-111111111111",
"_test": true,
"data": {
"_test": true,
"rent_payment_id": "rent_test_1",
"contract_id": "contract_test_1",
"property_id": "property_test_1",
"property_name": "12 Test Street",
"amount": 1200,
"due_date": "2026-01-01",
"days_overdue": 7
}
}Contract expiring
contract.expiringFired ahead of a contract end date so you can prompt for renewal.
{
"id": "evt_00000000-0000-4000-8000-000000000000",
"event": "contract.expiring",
"created_at": "2026-01-15T10:30:00.000Z",
"landlord_id": "11111111-1111-4111-8111-111111111111",
"_test": true,
"data": {
"_test": true,
"contract_id": "contract_test_1",
"property_id": "property_test_1",
"property_name": "12 Test Street",
"end_date": "2026-03-01",
"days_until_expiry": 30
}
}Contract created
contract.createdFired when a new contract is added to a property.
{
"id": "evt_00000000-0000-4000-8000-000000000000",
"event": "contract.created",
"created_at": "2026-01-15T10:30:00.000Z",
"landlord_id": "11111111-1111-4111-8111-111111111111",
"_test": true,
"data": {
"_test": true,
"contract_id": "contract_test_1",
"property_id": "property_test_1",
"property_name": "12 Test Street",
"tenancy_id": "tenancy_test_1",
"main_tenant_id": "tenant_test_1",
"status": "Active",
"start_date": "2026-01-01",
"end_date": null,
"rent_amount": 1500
}
}Contract updated
contract.updatedFired when an existing contract is updated.
{
"id": "evt_00000000-0000-4000-8000-000000000000",
"event": "contract.updated",
"created_at": "2026-01-15T10:30:00.000Z",
"landlord_id": "11111111-1111-4111-8111-111111111111",
"_test": true,
"data": {
"_test": true,
"contract_id": "contract_test_1",
"property_id": "property_test_1",
"property_name": "12 Test Street",
"tenancy_id": "tenancy_test_1",
"main_tenant_id": "tenant_test_1",
"status": "Active",
"start_date": "2026-01-01",
"end_date": "2027-01-01",
"rent_amount": 1575
}
}Contract deleted
contract.deletedFired when a contract is deleted.
{
"id": "evt_00000000-0000-4000-8000-000000000000",
"event": "contract.deleted",
"created_at": "2026-01-15T10:30:00.000Z",
"landlord_id": "11111111-1111-4111-8111-111111111111",
"_test": true,
"data": {
"_test": true,
"contract_id": "contract_test_1",
"property_id": "property_test_1",
"property_name": "12 Test Street",
"tenancy_id": "tenancy_test_1",
"main_tenant_id": "tenant_test_1",
"status": "Deleted",
"start_date": "2026-01-01",
"end_date": "2027-01-01",
"deleted_at": "2026-02-01T10:00:00.000Z"
}
}Contract ended
contract.endedFired when a contract transitions to the Ended state.
{
"id": "evt_00000000-0000-4000-8000-000000000000",
"event": "contract.ended",
"created_at": "2026-01-15T10:30:00.000Z",
"landlord_id": "11111111-1111-4111-8111-111111111111",
"_test": true,
"data": {
"_test": true,
"contract_id": "contract_test_1",
"property_id": "property_test_1",
"property_name": "12 Test Street",
"status": "Ended",
"start_date": "2025-01-01",
"end_date": "2026-01-01"
}
}Maintenance issue created
maintenance.createdFired when a tenant or staff member opens a new maintenance issue.
{
"id": "evt_00000000-0000-4000-8000-000000000000",
"event": "maintenance.created",
"created_at": "2026-01-15T10:30:00.000Z",
"landlord_id": "11111111-1111-4111-8111-111111111111",
"_test": true,
"data": {
"_test": true,
"issue_id": "issue_test_1",
"property_id": "property_test_1",
"property_name": "12 Test Street",
"title": "Leaking tap",
"description": "Tap is leaking under the sink",
"priority": "Medium",
"status": "Open"
}
}Maintenance issue updated
maintenance.updatedFired when a maintenance issue changes state or details.
{
"id": "evt_00000000-0000-4000-8000-000000000000",
"event": "maintenance.updated",
"created_at": "2026-01-15T10:30:00.000Z",
"landlord_id": "11111111-1111-4111-8111-111111111111",
"_test": true,
"data": {
"_test": true,
"issue_id": "issue_test_1",
"property_id": "property_test_1",
"property_name": "12 Test Street",
"title": "Leaking tap",
"description": "Plumber scheduled for next week",
"priority": "High",
"status": "In_Progress"
}
}Maintenance issue deleted
maintenance.deletedFired when a maintenance issue is deleted.
{
"id": "evt_00000000-0000-4000-8000-000000000000",
"event": "maintenance.deleted",
"created_at": "2026-01-15T10:30:00.000Z",
"landlord_id": "11111111-1111-4111-8111-111111111111",
"_test": true,
"data": {
"_test": true,
"issue_id": "issue_test_1",
"property_id": "property_test_1",
"property_name": "12 Test Street",
"title": "Leaking tap",
"priority": "High",
"status": "Deleted",
"deleted_at": "2026-02-01T10:00:00.000Z"
}
}Inspection scheduled
inspection.scheduledFired when an inspection is booked into the calendar.
{
"id": "evt_00000000-0000-4000-8000-000000000000",
"event": "inspection.scheduled",
"created_at": "2026-01-15T10:30:00.000Z",
"landlord_id": "11111111-1111-4111-8111-111111111111",
"_test": true,
"data": {
"_test": true,
"inspection_id": "insp_test_1",
"property_id": "property_test_1",
"property_name": "12 Test Street",
"inspection_date": "2026-02-01",
"inspection_type": "routine",
"status": "in_progress"
}
}Inspection updated
inspection.updatedFired when an inspection is updated.
{
"id": "evt_00000000-0000-4000-8000-000000000000",
"event": "inspection.updated",
"created_at": "2026-01-15T10:30:00.000Z",
"landlord_id": "11111111-1111-4111-8111-111111111111",
"_test": true,
"data": {
"_test": true,
"inspection_id": "insp_test_1",
"property_id": "property_test_1",
"property_name": "12 Test Street",
"inspection_date": "2026-02-01",
"inspection_type": "routine",
"status": "in_progress",
"landlord_actions": "Arrange follow-up visit"
}
}Inspection deleted
inspection.deletedFired when an inspection is deleted.
{
"id": "evt_00000000-0000-4000-8000-000000000000",
"event": "inspection.deleted",
"created_at": "2026-01-15T10:30:00.000Z",
"landlord_id": "11111111-1111-4111-8111-111111111111",
"_test": true,
"data": {
"_test": true,
"inspection_id": "insp_test_1",
"property_id": "property_test_1",
"property_name": "12 Test Street",
"inspection_date": "2026-02-01",
"inspection_type": "routine",
"status": "deleted",
"deleted_at": "2026-02-01T10:00:00.000Z"
}
}Inspection completed
inspection.completedFired when an inspection is marked complete and the report is available.
{
"id": "evt_00000000-0000-4000-8000-000000000000",
"event": "inspection.completed",
"created_at": "2026-01-15T10:30:00.000Z",
"landlord_id": "11111111-1111-4111-8111-111111111111",
"_test": true,
"data": {
"_test": true,
"inspection_id": "insp_test_1",
"property_id": "property_test_1",
"property_name": "12 Test Street",
"inspection_date": "2026-02-01",
"inspection_type": "routine",
"status": "completed"
}
}Property created
property.createdFired when a property record is created.
{
"id": "evt_00000000-0000-4000-8000-000000000000",
"event": "property.created",
"created_at": "2026-01-15T10:30:00.000Z",
"landlord_id": "11111111-1111-4111-8111-111111111111",
"_test": true,
"data": {
"_test": true,
"property_id": "property_test_1",
"address": "12 Test Street",
"short_name": "Test House",
"status": "Vacant",
"rent_amount": 1500,
"city": "London",
"postcode": "SW1A 1AA"
}
}Property updated
property.updatedFired when a property record is updated.
{
"id": "evt_00000000-0000-4000-8000-000000000000",
"event": "property.updated",
"created_at": "2026-01-15T10:30:00.000Z",
"landlord_id": "11111111-1111-4111-8111-111111111111",
"_test": true,
"data": {
"_test": true,
"property_id": "property_test_1",
"address": "12 Test Street",
"short_name": "Test House",
"status": "Occupied",
"rent_amount": 1575,
"city": "London",
"postcode": "SW1A 1AA"
}
}Property deleted
property.deletedFired when a property record is deleted.
{
"id": "evt_00000000-0000-4000-8000-000000000000",
"event": "property.deleted",
"created_at": "2026-01-15T10:30:00.000Z",
"landlord_id": "11111111-1111-4111-8111-111111111111",
"_test": true,
"data": {
"_test": true,
"property_id": "property_test_1",
"address": "12 Test Street",
"short_name": "Test House",
"status": "Deleted",
"deleted_at": "2026-02-01T10:00:00.000Z"
}
}Tenant created
tenant.createdFired when a tenant record is created.
{
"id": "evt_00000000-0000-4000-8000-000000000000",
"event": "tenant.created",
"created_at": "2026-01-15T10:30:00.000Z",
"landlord_id": "11111111-1111-4111-8111-111111111111",
"_test": true,
"data": {
"_test": true,
"tenant_id": "tenant_test_1",
"property_id": "property_test_1",
"first_name": "Alex",
"last_name": "Tenant",
"email": "alex.tenant@example.com",
"phone": "+447700900000",
"status": "INVITED"
}
}Tenant updated
tenant.updatedFired when a tenant record is updated.
{
"id": "evt_00000000-0000-4000-8000-000000000000",
"event": "tenant.updated",
"created_at": "2026-01-15T10:30:00.000Z",
"landlord_id": "11111111-1111-4111-8111-111111111111",
"_test": true,
"data": {
"_test": true,
"tenant_id": "tenant_test_1",
"property_id": "property_test_1",
"first_name": "Alex",
"last_name": "Tenant",
"email": "alex.tenant@example.com",
"phone": "+447700900001",
"status": "ACTIVE"
}
}Tenant deleted
tenant.deletedFired when a tenant record is deleted.
{
"id": "evt_00000000-0000-4000-8000-000000000000",
"event": "tenant.deleted",
"created_at": "2026-01-15T10:30:00.000Z",
"landlord_id": "11111111-1111-4111-8111-111111111111",
"_test": true,
"data": {
"_test": true,
"tenant_id": "tenant_test_1",
"property_id": "property_test_1",
"first_name": "Alex",
"last_name": "Tenant",
"email": "alex.tenant@example.com",
"status": "DELETED",
"deleted_at": "2026-02-01T10:00:00.000Z"
}
}Contact created
contact.createdFired when a contact is created.
{
"id": "evt_00000000-0000-4000-8000-000000000000",
"event": "contact.created",
"created_at": "2026-01-15T10:30:00.000Z",
"landlord_id": "11111111-1111-4111-8111-111111111111",
"_test": true,
"data": {
"_test": true,
"contact_id": "contact_test_1",
"name": "Ace Plumbing",
"company": "Ace Ltd",
"email": "ace@example.com",
"mobile": "+447700900100",
"categories": [
"Plumbing"
]
}
}Contact updated
contact.updatedFired when a contact is updated.
{
"id": "evt_00000000-0000-4000-8000-000000000000",
"event": "contact.updated",
"created_at": "2026-01-15T10:30:00.000Z",
"landlord_id": "11111111-1111-4111-8111-111111111111",
"_test": true,
"data": {
"_test": true,
"contact_id": "contact_test_1",
"name": "Ace Plumbing",
"company": "Ace Services Ltd",
"email": "ace@example.com",
"mobile": "+447700900100",
"categories": [
"Plumbing",
"Emergency"
]
}
}Contact deleted
contact.deletedFired when a contact is deleted.
{
"id": "evt_00000000-0000-4000-8000-000000000000",
"event": "contact.deleted",
"created_at": "2026-01-15T10:30:00.000Z",
"landlord_id": "11111111-1111-4111-8111-111111111111",
"_test": true,
"data": {
"_test": true,
"contact_id": "contact_test_1",
"name": "Ace Plumbing",
"company": "Ace Services Ltd",
"deleted_at": "2026-02-01T10:00:00.000Z"
}
}Chat message sent
chat.message_sentFired when a landlord sends a chat message.
{
"id": "evt_00000000-0000-4000-8000-000000000000",
"event": "chat.message_sent",
"created_at": "2026-01-15T10:30:00.000Z",
"landlord_id": "11111111-1111-4111-8111-111111111111",
"_test": true,
"data": {
"_test": true,
"message_id": "message_test_1",
"chat_id": "chat_test_1",
"property_id": "property_test_1",
"tenant_id": "tenant_test_1",
"text": "Hello, the contractor will visit tomorrow.",
"attachment_type": null,
"attachment_name": null,
"sent_at": "2026-02-01T10:00:00.000Z"
}
}Mortgage created
mortgage.createdFired when a mortgage is created.
{
"id": "evt_00000000-0000-4000-8000-000000000000",
"event": "mortgage.created",
"created_at": "2026-01-15T10:30:00.000Z",
"landlord_id": "11111111-1111-4111-8111-111111111111",
"_test": true,
"data": {
"_test": true,
"mortgage_id": "mortgage_test_1",
"lender": "Test Bank",
"reference": "M-001",
"balance": 250000,
"interest_rate": 4.25,
"monthly_payment": 1200,
"property_ids": [
"property_test_1"
],
"status": "Active"
}
}Mortgage updated
mortgage.updatedFired when a mortgage is updated.
{
"id": "evt_00000000-0000-4000-8000-000000000000",
"event": "mortgage.updated",
"created_at": "2026-01-15T10:30:00.000Z",
"landlord_id": "11111111-1111-4111-8111-111111111111",
"_test": true,
"data": {
"_test": true,
"mortgage_id": "mortgage_test_1",
"lender": "Test Bank",
"reference": "M-001",
"balance": 245000,
"interest_rate": 4.1,
"monthly_payment": 1185,
"property_ids": [
"property_test_1"
],
"status": "Active"
}
}Mortgage deleted
mortgage.deletedFired when a mortgage is deleted.
{
"id": "evt_00000000-0000-4000-8000-000000000000",
"event": "mortgage.deleted",
"created_at": "2026-01-15T10:30:00.000Z",
"landlord_id": "11111111-1111-4111-8111-111111111111",
"_test": true,
"data": {
"_test": true,
"mortgage_id": "mortgage_test_1",
"lender": "Test Bank",
"reference": "M-001",
"balance": 245000,
"property_ids": [
"property_test_1"
],
"status": "Deleted",
"deleted_at": "2026-02-01T10:00:00.000Z"
}
}Rent created
rent.createdFired when a rent payment is created.
{
"id": "evt_00000000-0000-4000-8000-000000000000",
"event": "rent.created",
"created_at": "2026-01-15T10:30:00.000Z",
"landlord_id": "11111111-1111-4111-8111-111111111111",
"_test": true,
"data": {
"_test": true,
"rent_payment_id": "rent_test_1",
"contract_id": "contract_test_1",
"property_id": "property_test_1",
"tenant_id": "tenant_test_1",
"amount": 1500,
"due_date": "2026-02-05",
"status": "Pending",
"period": "monthly"
}
}Rent updated
rent.updatedFired when a rent payment is updated.
{
"id": "evt_00000000-0000-4000-8000-000000000000",
"event": "rent.updated",
"created_at": "2026-01-15T10:30:00.000Z",
"landlord_id": "11111111-1111-4111-8111-111111111111",
"_test": true,
"data": {
"_test": true,
"rent_payment_id": "rent_test_1",
"contract_id": "contract_test_1",
"property_id": "property_test_1",
"tenant_id": "tenant_test_1",
"amount": 1500,
"due_date": "2026-02-05",
"status": "Paid",
"date_paid": "2026-02-06",
"amount_received": 1500,
"period": "monthly"
}
}Rent invoice sent
rent.invoice_sentFired when an invoice or receipt email is sent to a tenant via the public API. Delivery is asynchronous via the webhook outbox.
{
"id": "evt_00000000-0000-4000-8000-000000000000",
"event": "rent.invoice_sent",
"created_at": "2026-01-15T10:30:00.000Z",
"landlord_id": "11111111-1111-4111-8111-111111111111",
"_test": true,
"data": {
"_test": true,
"rent_payment_id": "rent_test_1",
"contract_id": "contract_test_1",
"property_id": "property_test_1",
"tenant_id": "tenant_test_1",
"tenant_email": "tenant@example.com",
"document_type": "invoice",
"period": "February 2026",
"amount": 1500,
"due_date": "2026-02-05",
"sent_via": "public_api"
}
}Rent due soon
rent.due_soonFired a few days ahead of a pending rent payment due date.
{
"id": "evt_00000000-0000-4000-8000-000000000000",
"event": "rent.due_soon",
"created_at": "2026-01-15T10:30:00.000Z",
"landlord_id": "11111111-1111-4111-8111-111111111111",
"_test": true,
"data": {
"_test": true,
"rent_payment_id": "rent_test_1",
"contract_id": "contract_test_1",
"property_id": "property_test_1",
"property_name": "12 Test Street",
"amount": 1200,
"due_date": "2026-01-08",
"days_until_due": 3
}
}Property document created
property_document.createdFired when a property document is uploaded.
{
"id": "evt_00000000-0000-4000-8000-000000000000",
"event": "property_document.created",
"created_at": "2026-01-15T10:30:00.000Z",
"landlord_id": "11111111-1111-4111-8111-111111111111",
"_test": true,
"data": {
"_test": true,
"document_id": "prop_doc_test_1",
"property_id": "property_test_1",
"name": "EPC Certificate",
"type": "EPC_Certificate",
"expiry_date": "2029-01-01",
"uploaded_at": "2026-02-01T10:00:00.000Z",
"size_bytes": 204800
}
}Property document deleted
property_document.deletedFired when a property document is deleted.
{
"id": "evt_00000000-0000-4000-8000-000000000000",
"event": "property_document.deleted",
"created_at": "2026-01-15T10:30:00.000Z",
"landlord_id": "11111111-1111-4111-8111-111111111111",
"_test": true,
"data": {
"_test": true,
"document_id": "prop_doc_test_1",
"property_id": "property_test_1",
"name": "EPC Certificate",
"type": "EPC_Certificate",
"deleted_at": "2026-02-01T10:00:00.000Z"
}
}Contract document created
contract_document.createdFired when a contract document is uploaded.
{
"id": "evt_00000000-0000-4000-8000-000000000000",
"event": "contract_document.created",
"created_at": "2026-01-15T10:30:00.000Z",
"landlord_id": "11111111-1111-4111-8111-111111111111",
"_test": true,
"data": {
"_test": true,
"document_id": "contract_doc_test_1",
"contract_id": "contract_test_1",
"property_id": "property_test_1",
"name": "Tenancy Agreement",
"type": "Contract",
"uploaded_at": "2026-02-01T10:00:00.000Z",
"size_bytes": 307200
}
}Contract document deleted
contract_document.deletedFired when a contract document is deleted.
{
"id": "evt_00000000-0000-4000-8000-000000000000",
"event": "contract_document.deleted",
"created_at": "2026-01-15T10:30:00.000Z",
"landlord_id": "11111111-1111-4111-8111-111111111111",
"_test": true,
"data": {
"_test": true,
"document_id": "contract_doc_test_1",
"contract_id": "contract_test_1",
"property_id": "property_test_1",
"name": "Tenancy Agreement",
"type": "Contract",
"deleted_at": "2026-02-01T10:00:00.000Z"
}
}Note created
note.createdFired when a note is added to a maintenance issue.
{
"id": "evt_00000000-0000-4000-8000-000000000000",
"event": "note.created",
"created_at": "2026-01-15T10:30:00.000Z",
"landlord_id": "11111111-1111-4111-8111-111111111111",
"_test": true,
"data": {
"_test": true,
"note_id": "note_test_1",
"issue_id": "issue_test_1",
"property_id": "property_test_1",
"text": "Tenant confirmed access for tomorrow.",
"created_at": "2026-02-01T10:00:00.000Z"
}
}Document signed
document.signedFired when an e-signature request is fully signed.
{
"id": "evt_00000000-0000-4000-8000-000000000000",
"event": "document.signed",
"created_at": "2026-01-15T10:30:00.000Z",
"landlord_id": "11111111-1111-4111-8111-111111111111",
"_test": true,
"data": {
"_test": true,
"signature_request_id": "sigreq_test_1",
"document_name": "Tenancy Agreement.pdf",
"signer_email": "tenant@example.com",
"document_type": "tenancy_agreement",
"status": "signed",
"signed_document_url": "https://example.com/signed.pdf"
}
}Document declined / unsigned
document.unsignedFired when an e-signature request is declined or expires unsigned.
{
"id": "evt_00000000-0000-4000-8000-000000000000",
"event": "document.unsigned",
"created_at": "2026-01-15T10:30:00.000Z",
"landlord_id": "11111111-1111-4111-8111-111111111111",
"_test": true,
"data": {
"_test": true,
"signature_request_id": "sigreq_test_1",
"document_name": "Tenancy Agreement.pdf",
"signer_email": "tenant@example.com",
"document_type": "tenancy_agreement",
"status": "declined"
}
}Deposit updated
deposit.updatedFired when a deposit reaches an outcome — returned, partially returned after deductions, retained, or disputed.
{
"id": "evt_00000000-0000-4000-8000-000000000000",
"event": "deposit.updated",
"created_at": "2026-01-15T10:30:00.000Z",
"landlord_id": "11111111-1111-4111-8111-111111111111",
"_test": true,
"data": {
"_test": true,
"deposit_id": "deposit_test_1",
"contract_id": "contract_test_1",
"tenant_id": "tenant_test_1",
"property_id": "property_test_1",
"property_name": "12 Test Street",
"amount": 1500,
"status": "partial_return",
"deduction_amount": 250,
"deduction_reason": "Cleaning £150 (End of tenancy clean); Damage £100 (Broken door handle)",
"days_to_return": 10
}
}Payment plan created
payment_plan.createdFired when a landlord agrees a schedule for a tenant to clear rent arrears.
{
"id": "evt_00000000-0000-4000-8000-000000000000",
"event": "payment_plan.created",
"created_at": "2026-01-15T10:30:00.000Z",
"landlord_id": "11111111-1111-4111-8111-111111111111",
"_test": true,
"data": {
"_test": true,
"plan_id": "plan_test_1",
"tenant_id": "tenant_test_1",
"property_id": "property_test_1",
"property_name": "12 Test Street",
"outstanding_amount": 1200,
"plan_description": "6 instalments of £200.00, from 2026-09-01 to 2027-02-01",
"agreed_date": "2026-08-21"
}
}Meter registered
meter.registeredFired when a utility meter is recorded at a property.
{
"id": "evt_00000000-0000-4000-8000-000000000000",
"event": "meter.registered",
"created_at": "2026-01-15T10:30:00.000Z",
"landlord_id": "11111111-1111-4111-8111-111111111111",
"_test": true,
"data": {
"_test": true,
"meter_id": "meter_test_1",
"property_id": "property_test_1",
"utility_type": "electricity",
"unit": "kWh",
"tariff_structure": "economy_7",
"payment_mode": "credit",
"mpan": "1200023305408",
"location_description": "Cupboard under the stairs",
"removed_date": null
}
}Meter updated
meter.updatedFired when a meter’s details change — supply number, unit, location.
{
"id": "evt_00000000-0000-4000-8000-000000000000",
"event": "meter.updated",
"created_at": "2026-01-15T10:30:00.000Z",
"landlord_id": "11111111-1111-4111-8111-111111111111",
"_test": true,
"data": {
"_test": true,
"meter_id": "meter_test_1",
"property_id": "property_test_1",
"utility_type": "electricity",
"unit": "kWh",
"tariff_structure": "economy_7",
"payment_mode": "credit",
"mpan": "1200023305408",
"location_description": "Cupboard under the stairs",
"removed_date": null
}
}Meter removed
meter.removedFired when a meter is taken off the wall. Its readings stay attached to it, so historic consumption is still attributed to the hardware that produced it.
{
"id": "evt_00000000-0000-4000-8000-000000000000",
"event": "meter.removed",
"created_at": "2026-01-15T10:30:00.000Z",
"landlord_id": "11111111-1111-4111-8111-111111111111",
"_test": true,
"data": {
"_test": true,
"meter_id": "meter_test_1",
"property_id": "property_test_1",
"utility_type": "electricity",
"unit": "kWh",
"tariff_structure": "economy_7",
"payment_mode": "credit",
"mpan": "1200023305408",
"location_description": "Cupboard under the stairs",
"removed_date": "2026-09-05"
}
}Meter reading recorded
meter_reading.recordedFired when a reading is taken. A reading on a changeover date carries two tenancy links — one check-out and one check-in — because it is one physical visit serving both.
{
"id": "evt_00000000-0000-4000-8000-000000000000",
"event": "meter_reading.recorded",
"created_at": "2026-01-15T10:30:00.000Z",
"landlord_id": "11111111-1111-4111-8111-111111111111",
"_test": true,
"data": {
"_test": true,
"reading_id": "reading_test_1",
"meter_id": "meter_test_1",
"property_id": "property_test_1",
"utility_type": "electricity",
"reading_date": "2026-09-05",
"reason": "changeover",
"status": "actual",
"payment_mode": "credit",
"registers": [
{
"register": "day",
"value": 12345.5,
"unit": "kWh"
},
{
"register": "night",
"value": 9876.25,
"unit": "kWh"
}
],
"contracts": [
{
"contract_id": "contract_test_1",
"role": "check_out"
},
{
"contract_id": "contract_test_2",
"role": "check_in"
}
],
"warnings": []
}
}Tips for writing a robust receiver
- Reply 2xx fast. Acknowledge in under a second by enqueuing the payload for asynchronous processing.
- Verify the signature first. Reject anything you cannot verify with
401— do not even parse the body. - Idempotency: store seen
idvalues for at least 24 hours and skip duplicates. - Test deliveries: branch on
_test === trueif your handler has external side effects (e.g. don't actually send an email on test events).