Skip to main content

Unit Management

Manage property units in the Sakneen system using the Units API.

Overview

The Units API allows you to create or update property units in the Sakneen system. This is essential for property developers, real estate companies, and property management systems that need to maintain up-to-date unit inventory.

Endpoint

POST /external/apis/v1.0/units

Authentication

All requests require a valid API key in the header:

api-key: YOUR_API_KEY

Request Body Schema

Required Fields

FieldTypeDescription
recordSystemIdstringUnique system identifier for the record
unitIdstringUnique identifier for the unit

Optional Fields

FieldTypeDescriptionValidation
pricenumberBase price of the unit≥ 0
buanumberBuilt-up area in square meters≥ 0
propertyTypestringType of propertyAny string
statusstringCurrent status of the unitAny string
bedroomsnumberNumber of bedrooms≥ 0
bathroomsnumberNumber of bathrooms≥ 0
landAreanumberLand area in square meters≥ 0
gardenAreanumberGarden area in square meters≥ 0
finishingTypestringType of finishingAny string
floorstringFloor levelAny string
amenitiesstring[]Array of amenity namesArray of strings
featuresstring[]Array of feature namesArray of strings
saleTypestringType of saleprimary or resale (default: primary)
priceByYearobjectPrice variations by yearKey-value pairs (year: price)
priceByPaymentPlanarrayArray of payment plan pricingSee Payment Plan Schema below

Payment Plan Schema

Each item in priceByPaymentPlan array should contain:

FieldTypeRequiredDescriptionValidation
pricenumber✅ YesPrice for this payment plan≥ 0
paymentPlanIdstring✅ YesMongoDB ObjectId of payment planValid MongoDB ObjectId
finishingTypeIdstring✅ YesMongoDB ObjectId of finishing typeValid MongoDB ObjectId
numberOfYearsnumber❌ OptionalPayment plan duration in years≥ 0

Complete Example Request

{
"recordSystemId": "00163EAB688B1EECA9C3E1F963E029CC",
"unitId": "VH-12",
"price": 1200000,
"bua": 120,
"propertyType": "apartment",
"status": "available",
"bedrooms": 2,
"bathrooms": 2,
"landArea": 150,
"gardenArea": 30,
"finishingType": "Fully finished",
"floor": "2nd",
"amenities": ["wifi", "parking", "gym", "pool"],
"features": ["balcony", "parking", "city_view"],
"saleType": "primary",
"priceByYear": {
"2024": 1200000,
"2025": 1250000,
"2026": 1300000
},
"priceByPaymentPlan": [
{
"price": 1200000,
"paymentPlanId": "64a1b2c3d4e5f6789012345",
"finishingTypeId": "64a1b2c3d4e5f6789012346",
"numberOfYears": 5
},
{
"price": 1150000,
"paymentPlanId": "64a1b2c3d4e5f6789012347",
"finishingTypeId": "64a1b2c3d4e5f6789012348",
"numberOfYears": 3
}
]
}

Headers

HeaderRequiredDescription
api-key✅ YesYour organization's API key
Content-Type✅ YesMust be application/json
language❌ OptionalLanguage preference (e.g., en-us, ar-eg)

Response

Success Response (201 Created)

{
"success": true,
"message": "Unit created/updated successfully",
"data": {
"unitId": "VH-12",
"recordSystemId": "00163EAB688B1EECA9C3E1F963E029CC"
}
}

Error Responses

400 Bad Request - Validation Error

{
"statusCode": 400,
"message": [
"recordSystemId should not be empty",
"unitId should not be empty",
"price must be a number conforming to the specified constraints"
],
"error": "Bad Request"
}

401 Unauthorized - Invalid API Key

{
"statusCode": 401,
"message": "Access Denied, API key not provided",
"error": "Unauthorized"
}

Code Examples

cURL

curl -X POST "https://your-domain/external/apis/v1.0/units" \
-H "api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-H "language: en-us" \
-d '{
"recordSystemId": "00163EAB688B1EECA9C3E1F963E029CC",
"unitId": "VH-12",
"price": 1200000,
"bua": 120,
"propertyType": "apartment",
"status": "available",
"bedrooms": 2,
"bathrooms": 2,
"landArea": 150,
"finishingType": "Fully finished",
"floor": "2nd",
"amenities": ["wifi", "parking", "gym"],
"features": ["balcony", "parking"],
"saleType": "primary"
}'

JavaScript/Node.js

const apiKey = process.env.SAKNEEN_API_KEY;
const baseDomain = process.env.SAKNEEN_DOMAIN;

async function createUnit(unitData) {
try {
const response = await fetch(`https://${baseDomain}/external/apis/v1.0/units`, {
method: 'POST',
headers: {
'api-key': apiKey,
'Content-Type': 'application/json',
'language': 'en-us'
},
body: JSON.stringify(unitData)
});

if (!response.ok) {
const errorData = await response.json().catch(() => ({}));
throw new Error(`HTTP ${response.status}: ${errorData.message || response.statusText}`);
}

const result = await response.json();
console.log('Unit created:', result);
return result;
} catch (error) {
console.error('Error creating unit:', error);
throw error;
}
}

// Usage
const unitData = {
recordSystemId: "00163EAB688B1EECA9C3E1F963E029CC",
unitId: "VH-12",
price: 1200000,
bua: 120,
propertyType: "apartment",
status: "available",
bedrooms: 2,
bathrooms: 2,
landArea: 150,
gardenArea: 30,
finishingType: "Fully finished",
floor: "2nd",
amenities: ["wifi", "parking", "gym", "pool"],
features: ["balcony", "parking", "city_view"],
saleType: "primary",
priceByYear: {
"2024": 1200000,
"2025": 1250000
},
priceByPaymentPlan: [
{
price: 1200000,
paymentPlanId: "64a1b2c3d4e5f6789012345",
finishingTypeId: "64a1b2c3d4e5f6789012346",
numberOfYears: 5
}
]
};

createUnit(unitData)
.then(result => console.log('Success:', result))
.catch(error => console.error('Error:', error));

Python

import requests
import os
import json

def create_unit(unit_data):
api_key = os.getenv('SAKNEEN_API_KEY')
base_domain = os.getenv('SAKNEEN_DOMAIN')

url = f'https://{base_domain}/external/apis/v1.0/units'
headers = {
'api-key': api_key,
'Content-Type': 'application/json',
'language': 'en-us'
}

try:
response = requests.post(url, headers=headers, json=unit_data)
response.raise_for_status()

result = response.json()
print(f'Unit created: {result}')
return result
except requests.exceptions.RequestException as e:
print(f'Error creating unit: {e}')
raise

# Usage
unit_data = {
"recordSystemId": "00163EAB688B1EECA9C3E1F963E029CC",
"unitId": "VH-12",
"price": 1200000,
"bua": 120,
"propertyType": "apartment",
"status": "available",
"bedrooms": 2,
"bathrooms": 2,
"landArea": 150,
"gardenArea": 30,
"finishingType": "Fully finished",
"floor": "2nd",
"amenities": ["wifi", "parking", "gym", "pool"],
"features": ["balcony", "parking", "city_view"],
"saleType": "primary",
"priceByYear": {
"2024": 1200000,
"2025": 1250000
},
"priceByPaymentPlan": [
{
"price": 1200000,
"paymentPlanId": "64a1b2c3d4e5f6789012345",
"finishingTypeId": "64a1b2c3d4e5f6789012346",
"numberOfYears": 5
}
]
}

try:
result = create_unit(unit_data)
print(f'Success: {result}')
except Exception as e:
print(f'Error: {e}')

PHP

<?php
function createUnit($unitData) {
$domain = $_ENV['SAKNEEN_DOMAIN']; // your assigned domain
$apiKey = $_ENV['SAKNEEN_API_KEY'];

$headers = [
'api-key: ' . $apiKey,
'Content-Type: application/json'
];

$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://{$domain}/external/apis/v1.0/units",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => json_encode($unitData),
CURLOPT_HTTPHEADER => $headers,
]);

$response = curl_exec($curl);
$httpCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
curl_close($curl);

if ($httpCode !== 201) {
throw new Exception("HTTP Error: $httpCode");
}

return $response;
}

// Usage
$unitData = [
'recordSystemId' => '00163EAB688B1EECA9C3E1F963E029CC',
'unitId' => 'VH-12',
'price' => 12000,
'bua' => 120,
'propertyType' => 'apartment',
'status' => 'available',
'bedrooms' => 2,
'bathrooms' => 2,
'landAres' => 120,
'finishingType' => 'Fully finished',
'deliveryDateType' => 'months',
'deliveryDate' => '01-12-2026',
'deliveryDateMonths' => 25,
'floor' => 'ground',
'amenities' => ['wifi', 'parking'],
'features' => ['parking'],
'saleType' => 'primary'
];

try {
$result = createUnit($unitData);
echo "Unit created: $result\n";
} catch (Exception $e) {
echo "Error: " . $e->getMessage() . "\n";
}
?>

Validation Rules

Required Field Validation

  • All required fields must be present and not empty
  • price must be a positive number
  • propertyType must be one of the allowed values
  • status must be one of the allowed values

Data Type Validation

  • bedrooms and bathrooms must be integers if provided
  • bua and landAres must be numbers if provided
  • amenities and features must be arrays if provided
  • deliveryDate must follow DD-MM-YYYY format if provided

Business Logic Validation

  • If deliveryDateType is "months", deliveryDateMonths should be provided
  • If deliveryDateType is "date", deliveryDate should be provided
  • unitId should be unique within the system

Error Handling

Common Error Scenarios

  1. Missing API Key (401)

    • Ensure API key is included in headers
    • Verify API key is valid
  2. Invalid Data (400)

    • Check all required fields are present
    • Verify data types match the specification
    • Ensure enum values are from allowed lists
  3. Missing Request Body (403)

    • Include request body with unit data
    • Ensure Content-Type header is set to application/json
  4. Network Issues

    • Implement retry logic for transient failures
    • Set appropriate timeouts

Best Practices

  1. Data Validation: Always validate data before sending to API
  2. Error Handling: Implement comprehensive error handling
  3. Retry Logic: Add retry mechanisms for network failures
  4. Logging: Log all API interactions for debugging
  5. Rate Limiting: Respect API rate limits
  6. Data Consistency: Ensure unit data is consistent across systems

Use Cases

Property Management Systems

  • Sync property units with Sakneen
  • Update unit availability and pricing
  • Manage unit specifications and features

Real Estate Portals

  • Import property inventory
  • Update unit status after sales
  • Maintain synchronized property data

CRM Integration

  • Create units when new developments are added
  • Update unit information for sales teams
  • Track unit availability for lead management