Skip to main content

Integration Examples

Practical examples of how to integrate with the Sakneen API.

Creating a Lead

The most common operation is creating a new lead in the system.

Basic Lead Creation

const createLead = async (leadData) => {
try {
const baseDomain = process.env.SAKNEEN_DOMAIN; // your assigned domain
const response = await fetch(`https://${baseDomain}/external/apis/v1.0/leads`, {
method: 'POST',
headers: {
'api-key': process.env.SAKNEEN_API_KEY,
'Content-Type': 'application/json'
},
body: JSON.stringify(leadData)
});

if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}

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

// Usage
const leadData = {
name: 'Jane Smith',
phoneNumber: '+1987654321',
project: 'Riverside Apartments',
email: '[email protected]'
};

createLead(leadData);

Lead Creation with Validation

const validateLead = (leadData) => {
const errors = [];

if (!leadData.name || leadData.name.trim().length === 0) {
errors.push('Name is required');
}

if (!leadData.phoneNumber || !/^\+\d{10,15}$/.test(leadData.phoneNumber)) {
errors.push('Valid phone number is required');
}

if (leadData.email && !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(leadData.email)) {
errors.push('Invalid email format');
}

return errors;
};

const createLeadSafely = async (leadData) => {
// Validate input
const validationErrors = validateLead(leadData);
if (validationErrors.length > 0) {
throw new Error(`Validation failed: ${validationErrors.join(', ')}`);
}

// Create lead
return await createLead(leadData);
};

Listing Units

Retrieve a paginated list of units with optional filtering and sorting.

Basic Unit Listing

const listUnits = async ({ page = 1, limit = 10, statuses, sortBy, order } = {}) => {
const baseDomain = process.env.SAKNEEN_DOMAIN;
const params = new URLSearchParams({ page, limit });

if (sortBy) params.append('sortBy', sortBy);
if (order) params.append('order', order);
if (statuses) {
for (const status of statuses) {
params.append('statuses', status);
}
}

const response = await fetch(
`https://${baseDomain}/external/apis/v1.0/units?${params}`,
{
method: 'GET',
headers: { 'api-key': process.env.SAKNEEN_API_KEY },
}
);

if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}

return await response.json();
};

// Usage - list available units, sorted by price ascending
const result = await listUnits({
page: 1,
limit: 20,
statuses: ['available'],
sortBy: 'price',
order: 'asc'
});

console.log(`Page 1 of ${result.pagination.pages} (${result.pagination.total} total units)`);
result.data.forEach(unit => {
console.log(`${unit.unitId}: ${unit.title} - ${unit.price} ${unit.priceCurrency}`);
});

Paginate Through All Units

const getAllUnits = async (statuses) => {
const allUnits = [];
let page = 1;
let hasMore = true;

while (hasMore) {
const result = await listUnits({ page, limit: 100, statuses });
allUnits.push(...result.data);

hasMore = page < result.pagination.pages;
page++;
}

return allUnits;
};

// Fetch all available units
const availableUnits = await getAllUnits(['available']);
console.log(`Total available units: ${availableUnits.length}`);

Getting a Single Unit

Retrieve a single unit by its slug for detail pages.

const getUnitBySlug = async (slug) => {
const baseDomain = process.env.SAKNEEN_DOMAIN;

const response = await fetch(
`https://${baseDomain}/external/apis/v1.0/units/${encodeURIComponent(slug)}`,
{
method: 'GET',
headers: { 'api-key': process.env.SAKNEEN_API_KEY },
}
);

if (response.status === 404) {
return null; // Unit not found
}

if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}

const result = await response.json();
return result.data;
};

// Usage
const unit = await getUnitBySlug('luxury-apartment-vh-12');
if (unit) {
console.log(`${unit.title} - ${unit.price} ${unit.priceCurrency}`);
console.log(`Bedrooms: ${unit.beds}, Bathrooms: ${unit.bathrooms}`);
console.log(`Status: ${unit.status}`);
console.log(`Property Type: ${unit.propertyType?.name}`);
} else {
console.log('Unit not found');
}

Error Handling

Comprehensive Error Handling

const handleApiResponse = async (response) => {
if (response.ok) {
return response.json();
}

let errorMessage = `HTTP ${response.status}: ${response.statusText}`;

try {
const errorData = await response.json();
if (errorData.message) {
errorMessage = Array.isArray(errorData.message)
? errorData.message.map(m => typeof m === 'object' ? JSON.stringify(m) : m).join(', ')
: errorData.message;
}
} catch (e) {
// If response is not JSON, use default error message
}

throw new Error(errorMessage);
};

const apiRequest = async (path, options = {}) => {
const baseDomain = process.env.SAKNEEN_DOMAIN;

try {
const response = await fetch(`https://${baseDomain}/external/apis/v1.0${path}`, {
...options,
headers: {
'api-key': process.env.SAKNEEN_API_KEY,
...options.headers,
},
});

return await handleApiResponse(response);
} catch (error) {
console.error(`API request failed [${path}]:`, error.message);
throw error;
}
};

// Usage
const units = await apiRequest('/units?page=1&limit=10');
const unit = await apiRequest('/units/luxury-apartment-vh-12');
const lead = await apiRequest('/leads', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ name: 'John Doe', phoneNumber: '+1234567890' }),
});

Webhook Integration

If you need to receive notifications when leads are processed:

const express = require('express');
const app = express();

app.use(express.json());

// Webhook endpoint to receive lead status updates
app.post('/webhook/lead-status', (req, res) => {
const { leadId, status, timestamp } = req.body;

console.log(`Lead ${leadId} status updated to: ${status} at ${timestamp}`);

// Process the webhook data
// Update your local database, send notifications, etc.

res.status(200).send('OK');
});

app.listen(3001, () => {
console.log('Webhook server listening on port 3001');
});

Best Practices

  1. Always validate input data before sending to the API
  2. Implement proper error handling for all API calls
  3. Use environment variables for sensitive data like API keys
  4. Implement retry logic for transient failures
  5. Log API interactions for debugging and monitoring
  6. Rate limit your requests to avoid overwhelming the API
  7. Use pagination efficiently -- prefer smaller page sizes (10-50) over the maximum (100)
  8. Cache unit slugs when building detail page links to avoid redundant list requests