Sync Patterns Guide

Keep your CRM in sync with your Propstreet network.

Your professional network is your most valuable asset. This guide shows you how to sync contacts, companies, and relationships between Propstreet and your CRM so nothing falls through the cracks.

Cursor-Based Pagination

All list endpoints use cursor-based pagination for efficient handling of large networks.

How It Works

  1. Request with page_size (max 500, default 500)
  2. Response includes nextCursor if more data exists
  3. Pass cursor to the next request
  4. Continue until hasMore is false

Example

# First request
curl "https://app.propstreet.com/api/v1/network/contacts?page_size=500" \
  -H "Authorization: Bearer $TOKEN"

Response:

{
  "data": [...],
  "hasMore": true,
  "nextCursor": "eyJ1IjoiMjAyNS0wMS0xNVQxMDowMDowMFoiLCJpIjoxMjM0NX0="
}
# Subsequent requests
curl "https://app.propstreet.com/api/v1/network/contacts?cursor=eyJ1Ijo..." \
  -H "Authorization: Bearer $TOKEN"

How Long Will My Sync Take?

Network Size Pages Time (at 600 req/min)
10,000 contacts 20 ~2 seconds
50,000 contacts 100 ~10 seconds
100,000 contacts 200 ~20 seconds

Delta Sync

After the initial sync, use delta sync to fetch only changes. This keeps your CRM current without re-downloading everything.

How It Works

  1. Store updatedUtc from your last sync
  2. Use updated_since parameter with that timestamp
  3. Set include_deleted=true to discover removed contacts
  4. Check deletedUtc to detect deletions

Example

# Get all changes since last sync
curl "https://app.propstreet.com/api/v1/network/contacts?\
updated_since=2025-01-15T10:00:00Z&\
include_deleted=true&\
page_size=500" \
  -H "Authorization: Bearer $TOKEN"

Response includes both updated and deleted records:

{
  "data": [
    {
      "id": 123,
      "firstName": "Jane",
      "updatedUtc": "2025-01-16T08:30:00Z",
      "deletedUtc": null
    },
    {
      "id": 456,
      "firstName": "John",
      "updatedUtc": "2025-01-16T09:00:00Z",
      "deletedUtc": "2025-01-16T09:00:00Z"
    }
  ]
}

[!important] Always use include_deleted=true for bidirectional sync. Otherwise you won't know when contacts are removed from Propstreet.

1. Fetch all pages with page_size=500
2. Store each contact/company in your CRM
3. Record the highest updatedUtc as your sync checkpoint
1. Fetch with updated_since={checkpoint}&include_deleted=true
2. For each record:
   - If deletedUtc is set → remove from your CRM
   - Otherwise → create or update in your CRM
3. Update your checkpoint to the highest updatedUtc seen

When syncing changes from your CRM back to Propstreet:

  1. Compare updatedUtc timestamps
  2. If Propstreet is newer → update your CRM
  3. If your CRM is newer → push to Propstreet
  4. For simultaneous edits → use business rules to decide

External References

Track your CRM's IDs in Propstreet using externalRefs:

curl -X POST "https://app.propstreet.com/api/v1/network/contacts" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "firstName": "Jane",
    "lastName": "Doe",
    "externalRefs": [
      {"source": "salesforce", "externalId": "003xx000004TmiN"}
    ]
  }'

Benefits:

  • Find Propstreet contacts by your CRM's ID
  • Avoid duplicates during sync
  • Track which records came from which system