Unit Events
Unit lifecycle events publish the stored Unit after a direct change in Sakneen's Unit administration.
Event types
| Event | Emitted when |
|---|---|
unit.created | A Unit is successfully created through Unit administration |
unit.updated | A directly targeted Unit's published fields change through Unit administration |
unit.deleted | A directly targeted Unit is soft-deleted through Unit administration |
All three events use eventVersion: 1, resource.type: "unit", and the Unit's
integration version as resource.version.
Version one covers direct create, update, media, price, status, and delete changes completed in Sakneen's Unit administration. It does not represent every write to a Unit.
External API, CRM, and provider synchronization do not emit these events. Indirect changes caused by reservations, payment plans, Unit designs, availability processing, reviews, approvals, issue reporting, launch tags, or code generation also do not emit Unit lifecycle events in version one.
For bulk administration operations, Sakneen emits one event for each directly
targeted Unit whose published state changed. Related events can share a
correlationId, while every Unit keeps its own resource.id and
resource.version.
Envelope values
Unit events use the standard event envelope with these values:
| Field | Unit event value |
|---|---|
eventType | unit.created, unit.updated, or unit.deleted |
eventVersion | 1 |
occurredAt | The Unit snapshot's updatedAt timestamp |
source | sakneen |
organizationId | Organization that owns the Unit |
resource.type | unit |
resource.id | Same identifier as data._id |
resource.version | Positive, monotonically increasing Unit integration version |
data | The stored Unit, described below |
eventVersion identifies the external contract described on this page.
resource.version identifies the revision of one Unit. A future Unit event can
have a higher, non-consecutive resource version, so compare versions rather than
assuming that they are contiguous.
Snapshot behavior
The data object is the complete stored Unit document at the moment of the
change, not a field-level patch. When processing unit.updated, replace the
stored snapshot only when the incoming resource.version is newer than the
version already processed.
Unit data
Version one delivers the Unit exactly as Sakneen stores it. data therefore
reflects your organization's own Unit configuration: which fields are present
depends on how your organization uses Sakneen, and on the individual Unit.
These fields are always present:
| Field | Type | Description |
|---|---|---|
_id | string | Canonical Sakneen Unit identifier; matches resource.id |
organizationId | string | Organization that owns the Unit; matches the envelope organization |
isDeleted | boolean | Whether the Unit has been soft-deleted |
createdAt | ISO 8601 string | UTC time when the Unit was created |
updatedAt | ISO 8601 string | UTC time of this Unit snapshot; matches occurredAt |
Every other stored Unit field is delivered as stored. Common examples include
unitId, code, title, status, price, priceCurrency, bua, beds,
bathrooms, saleType, locationId, media, translations, and the Unit's
plan and amenity identifier lists.
Value conventions:
- Identifiers are strings, and timestamps are ISO 8601 strings.
- Fields with no stored value are omitted. An omitted field is not an empty
string, zero,
false, or an empty array. - Numbers, booleans, arrays, and nested objects appear as stored.
The following are never included in data:
integrationVersion, which is published asresource.versioninstead;- Sakneen's internal document version key and identifier alias;
- computed values and related records loaded from other collections.
Because version one sends the Unit as stored, data can contain internal
operational fields — for example ownership, provider or CRM identifiers,
review state, and listing details. Send Unit events only to destinations that
are entitled to your organization's full Unit data, and do not forward the
payload unchanged to less-trusted systems.
A later event version will add organization-level field selection.
Sakneen can add fields to event version 1 at any time. Ignore unknown fields, and do not assume a fixed set of keys. Read the fields your integration understands, and validate them on your side rather than assuming a Sakneen-side shape guarantee.
Representative event
{
"eventId": "9035ed12-0c78-5dc4-8742-3d791aab6eb6",
"eventType": "unit.updated",
"eventVersion": 1,
"occurredAt": "2026-08-04T10:15:30.000Z",
"source": "sakneen",
"organizationId": "64f1a0d6d5d0a14a5c0e8a10",
"correlationId": "019c0eb1-8038-77d2-b91f-b27761d7387c",
"resource": {
"type": "unit",
"id": "66b1a0d6d5d0a14a5c0e8a20",
"version": 4
},
"data": {
"_id": "66b1a0d6d5d0a14a5c0e8a20",
"amenitiesIds": ["66b1a0d6d5d0a14a5c0e8a31"],
"bathrooms": 2,
"beds": 3,
"bua": 145,
"buildingId": "building-id",
"buildingTitle": "Building A",
"code": "ARK-A2345",
"createdAt": "2026-07-01T08:00:00.000Z",
"deliveryDetails": {
"date": "2027-02-01T00:00:00.000Z",
"type": "date"
},
"floor": {
"name": "First",
"value": 1
},
"isDeleted": false,
"locationId": "66b1a0d6d5d0a14a5c0e8a32",
"ownerId": "66b1a0d6d5d0a14a5c0e8a44",
"mainImageUrl": "https://example.com/main.png",
"media": [
{
"image": "https://example.com/unit.png",
"imageType": "exterior",
"isGenerated": false,
"type": "image",
"year": 2026
}
],
"organizationId": "64f1a0d6d5d0a14a5c0e8a10",
"price": 12000000,
"priceCurrency": "EGP",
"saleType": "primary",
"recordSystemId": "a0B5g000004abcDEA2",
"status": "Available",
"title": "Apartment A-101",
"translations": {
"ar-eg": {
"name": "شقة",
"slug": "apartment-ar"
},
"en-us": {
"name": "Apartment",
"slug": "apartment"
}
},
"unitId": "A-101",
"updatedAt": "2026-08-04T10:15:30.000Z"
}
}
Deletion snapshots
unit.deleted represents a soft deletion. Its data object is the full final
stored Unit with isDeleted: true; it is not a tombstone containing only an
identifier. Repeating a delete for an already deleted Unit does not produce a
new lifecycle event.
Processing recommendations
- Verify the webhook signature against the raw request body.
- Deduplicate every event by
eventId; delivery is at least once. - Partition processing by
resource.typeandresource.id. - Apply a snapshot only when
resource.versionis newer than the version you have already processed. - Replace your stored snapshot instead of treating
dataas a field-level patch. - Do not require resource versions to be consecutive.
- Configure the webhook endpoint to accept JSON request bodies up to 1 MiB.
- Return
2xxonly after durable acceptance. See Delivery and retries for automatic and manual retry behavior.
Events begin after an active destination subscribes to the event type. Historical Unit changes are not backfilled.