Skip to main content

Setup

import { SDK } from '@vepler/sdk';

const vepler = new SDK({
  apiKey: process.env.VEPLER_API_KEY
});

Property Examples

Get Properties by Location ID

async function getProperties() {
  const response = await vepler.property.getV1PropertyLocationIds({
    locationIds: 'p_0x000123456789'
  });

  if (response.propertyListResponse) {
    const properties = response.propertyListResponse.result;
    console.log(`Found ${properties.length} properties`);

    for (const property of properties) {
      console.log(property);
    }
  }
}

Query Properties with Filters

async function searchProperties() {
  const response = await vepler.property.postV1PropertyQuery({
    area: [{
      type: 'postcode',
      value: 'SW1A'
    }],
    query: {
      priceMin: 250000,
      priceMax: 500000,
      beds: [2, 3],
      propertyType: ['flat', 'terraced']
    },
    limit: 25,
    offset: 0,
    sortBy: 'price',
    sortOrder: 'desc'
  });

  if (response.propertyListResponse) {
    console.log(`Total results: ${response.propertyListResponse.totalSize}`);
    console.log(`Has more: ${response.propertyListResponse.hasMore}`);
  }
}

Get Properties by Slugs

async function getBySlug() {
  const response = await vepler.property.postV1PropertyPropertiesBySlugs({
    slugs: ['10-downing-street-london-sw1a-2aa'],
    limit: 10
  });

  if (response.propertyListResponse) {
    console.log(response.propertyListResponse.result);
  }
}

Planning Application Examples

Search Planning Applications

async function searchPlanning() {
  const response = await vepler.planning.postV1PlanningQuery({
    query: {
      councils: ['Westminster', 'Camden'],
      statuses: ['approved', 'pending_decision'],
      receivedDateFrom: '2024-01-01',
      receivedDateTo: '2024-12-31'
    },
    limit: 50,
    offset: 0,
    sortBy: 'receivedDate',
    sortOrder: 'desc'
  });

  if (response.planningListResponse) {
    for (const app of response.planningListResponse.applications) {
      console.log(`${app.key}: ${app.description}`);
      console.log(`  Status: ${app.status}`);
      console.log(`  Provider: ${app.provider}`);
    }
  }
}

Pagination Example

async function getAllProperties(locationId: string) {
  const allProperties: unknown[] = [];
  let offset = 0;
  const limit = 100;

  while (true) {
    const response = await vepler.property.getV1PropertyLocationIds({
      locationIds: locationId,
      limit: String(limit),
      offset: String(offset)
    });

    if (response.propertyListResponse) {
      allProperties.push(...response.propertyListResponse.result);

      if (!response.propertyListResponse.hasMore) {
        break;
      }

      offset += limit;
    } else {
      break;
    }

    // Small delay between pages
    await new Promise(resolve => setTimeout(resolve, 100));
  }

  return allProperties;
}

Error Handling Example

async function robustFetch(id: string) {
  const maxRetries = 3;
  let retries = 0;

  while (retries < maxRetries) {
    try {
      const response = await vepler.property.getV1PropertyLocationIds({
        locationIds: id
      });

      if (response.errorResponse) {
        console.error('API error:', response.errorResponse.error);
        return null;
      }

      return response.propertyListResponse;
    } catch (error) {
      const err = error as { statusCode?: number };

      if (err.statusCode === 404) {
        console.log('Property not found');
        return null;
      }

      if (err.statusCode === 429) {
        retries++;
        const delay = Math.pow(2, retries) * 1000;
        console.log(`Rate limited. Retry ${retries}/${maxRetries} in ${delay}ms`);
        await new Promise(resolve => setTimeout(resolve, delay));
        continue;
      }

      if (err.statusCode && err.statusCode >= 500) {
        retries++;
        const delay = Math.pow(2, retries) * 1000;
        console.log(`Server error. Retry ${retries}/${maxRetries} in ${delay}ms`);
        await new Promise(resolve => setTimeout(resolve, delay));
        continue;
      }

      throw error;
    }
  }

  throw new Error('Max retries exceeded');
}

Batch Operations Example

async function batchLookup(ids: string[]) {
  // Use comma-separated IDs for batch lookups
  const batchSize = 10;
  const results: unknown[] = [];

  for (let i = 0; i < ids.length; i += batchSize) {
    const batch = ids.slice(i, i + batchSize);
    const response = await vepler.property.getV1PropertyLocationIds({
      locationIds: batch.join(',')
    });

    if (response.propertyListResponse) {
      results.push(...response.propertyListResponse.result);
    }

    // Delay between batches
    if (i + batchSize < ids.length) {
      await new Promise(resolve => setTimeout(resolve, 200));
    }
  }

  return results;
}

Next Steps