Skip to main content
The Contacts API provides comprehensive contact management functionality for real estate professionals, enabling lead tracking, client management, and relationship building through a robust set of endpoints.

Contact Object

Contact Properties

{
  "id": "contact_123e4567-e89b-12d3-a456-426614174000",
  "organizationId": "org_123e4567-e89b-12d3-a456-426614174000",
  "firstName": "John",
  "lastName": "Doe",
  "email": "john.doe@example.com",
  "phone": "+1-555-123-4567",
  "secondaryPhone": "+1-555-987-6543",
  "address": {
    "street": "123 Main St",
    "city": "Miami",
    "state": "FL",
    "zipCode": "33101",
    "country": "US"
  },
  "type": "LEAD",
  "status": "ACTIVE",
  "source": "WEBSITE",
  "leadScore": 85,
  "tags": ["first-time-buyer", "luxury-market"],
  "notes": "Interested in waterfront properties",
  "preferences": {
    "communicationMethod": "EMAIL",
    "propertyTypes": ["CONDO", "TOWNHOUSE"],
    "priceRange": {
      "min": 300000,
      "max": 800000
    },
    "locations": ["Miami Beach", "Brickell"]
  },
  "assignedTo": "agent_123e4567-e89b-12d3-a456-426614174000",
  "createdAt": "2024-01-15T10:30:00Z",
  "updatedAt": "2024-01-15T15:45:00Z",
  "lastContactedAt": "2024-01-15T14:20:00Z"
}

Contact Types

TypeDescription
LEADPotential client or prospect
CLIENTActive client with ongoing business
PAST_CLIENTPrevious client for referral tracking
REFERRALContact from referral source
VENDORService provider or contractor

Contact Status

StatusDescription
ACTIVEActively engaged contact
INACTIVENot currently engaged
CONVERTEDLead converted to client
DISQUALIFIEDNot a qualified prospect
DO_NOT_CONTACTRequested no further contact

Endpoints

List Contacts

Retrieve a paginated list of contacts with optional filtering and sorting.
curl -X GET "https://api.winnerr.com/v1/contacts" \
  -H "Authorization: Bearer YOUR_JWT_TOKEN" \
  -H "Content-Type: application/json"
Query Parameters:
ParameterTypeDescription
limitintegerNumber of contacts to return (1-100, default: 25)
cursorstringPagination cursor for next page
typestringFilter by contact type
statusstringFilter by contact status
sourcestringFilter by lead source
assignedTostringFilter by assigned agent
tagsstringFilter by tags (comma-separated)
leadScore[gte]integerFilter by minimum lead score
leadScore[lte]integerFilter by maximum lead score
createdAt[gte]stringFilter by creation date (ISO 8601)
createdAt[lte]stringFilter by creation date (ISO 8601)
sortstringSort order (e.g., “createdAt:desc,leadScore:desc”)
includestringInclude related data (e.g., “deals,communications”)
Response:
{
  "success": true,
  "data": [
    {
      "id": "contact_123",
      "firstName": "John",
      "lastName": "Doe",
      "email": "john.doe@example.com",
      "phone": "+1-555-123-4567",
      "type": "LEAD",
      "status": "ACTIVE",
      "leadScore": 85,
      "createdAt": "2024-01-15T10:30:00Z"
    }
  ],
  "pagination": {
    "hasMore": true,
    "nextCursor": "eyJpZCI6IjEyNCJ9",
    "total": 150,
    "limit": 25
  }
}

Get Contact

Retrieve a specific contact by ID.
curl -X GET "https://api.winnerr.com/v1/contacts/contact_123" \
  -H "Authorization: Bearer YOUR_JWT_TOKEN"
Path Parameters:
ParameterTypeDescription
idstringContact ID
Query Parameters:
ParameterTypeDescription
includestringInclude related data (e.g., “deals,communications,activities”)
Response:
{
  "success": true,
  "data": {
    "id": "contact_123",
    "firstName": "John",
    "lastName": "Doe",
    "email": "john.doe@example.com",
    "phone": "+1-555-123-4567",
    "type": "LEAD",
    "status": "ACTIVE",
    "leadScore": 85,
    "deals": [
      {
        "id": "deal_456",
        "title": "Miami Condo Purchase",
        "amount": 450000,
        "stage": "NEGOTIATION"
      }
    ],
    "communications": [
      {
        "id": "comm_789",
        "type": "EMAIL",
        "subject": "Property Inquiry",
        "createdAt": "2024-01-15T14:20:00Z"
      }
    ]
  }
}

Create Contact

Create a new contact in the system.
curl -X POST "https://api.winnerr.com/v1/contacts" \
  -H "Authorization: Bearer YOUR_JWT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "firstName": "Jane",
    "lastName": "Smith",
    "email": "jane.smith@example.com",
    "phone": "+1-555-987-6543",
    "type": "LEAD",
    "source": "REFERRAL",
    "tags": ["luxury-market"],
    "preferences": {
      "communicationMethod": "PHONE",
      "propertyTypes": ["SINGLE_FAMILY"],
      "priceRange": {
        "min": 500000,
        "max": 1000000
      }
    }
  }'
Request Body:
FieldTypeRequiredDescription
firstNamestringYesContact’s first name
lastNamestringYesContact’s last name
emailstringYesContact’s email address
phonestringNoPrimary phone number
secondaryPhonestringNoSecondary phone number
addressobjectNoContact’s address
typestringNoContact type (default: LEAD)
sourcestringNoLead source
tagsarrayNoArray of tags
notesstringNoAdditional notes
preferencesobjectNoContact preferences
assignedTostringNoAssigned agent ID
Response:
{
  "success": true,
  "data": {
    "id": "contact_456",
    "firstName": "Jane",
    "lastName": "Smith",
    "email": "jane.smith@example.com",
    "phone": "+1-555-987-6543",
    "type": "LEAD",
    "status": "ACTIVE",
    "source": "REFERRAL",
    "leadScore": 60,
    "tags": ["luxury-market"],
    "createdAt": "2024-01-15T16:00:00Z",
    "updatedAt": "2024-01-15T16:00:00Z"
  }
}

Update Contact

Update an existing contact’s information.
curl -X PUT "https://api.winnerr.com/v1/contacts/contact_123" \
  -H "Authorization: Bearer YOUR_JWT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "phone": "+1-555-111-2222",
    "status": "CLIENT",
    "notes": "Successfully closed on waterfront condo",
    "tags": ["past-client", "referral-source"]
  }'
Path Parameters:
ParameterTypeDescription
idstringContact ID
Request Body: Same fields as create contact (all optional for updates) Response:
{
  "success": true,
  "data": {
    "id": "contact_123",
    "firstName": "John",
    "lastName": "Doe",
    "email": "john.doe@example.com",
    "phone": "+1-555-111-2222",
    "status": "CLIENT",
    "notes": "Successfully closed on waterfront condo",
    "tags": ["past-client", "referral-source"],
    "updatedAt": "2024-01-15T17:30:00Z"
  }
}

Delete Contact

Delete a contact from the system.
curl -X DELETE "https://api.winnerr.com/v1/contacts/contact_123" \
  -H "Authorization: Bearer YOUR_JWT_TOKEN"
Path Parameters:
ParameterTypeDescription
idstringContact ID
Response:
{
  "success": true,
  "message": "Contact deleted successfully"
}

Contact Activities

List Contact Activities

Retrieve activity history for a specific contact.
curl -X GET "https://api.winnerr.com/v1/contacts/contact_123/activities" \
  -H "Authorization: Bearer YOUR_JWT_TOKEN"
Response:
{
  "success": true,
  "data": [
    {
      "id": "activity_123",
      "type": "EMAIL_SENT",
      "description": "Property inquiry follow-up email sent",
      "createdAt": "2024-01-15T14:20:00Z",
      "metadata": {
        "subject": "Re: Waterfront Properties",
        "emailId": "email_456"
      }
    },
    {
      "id": "activity_124",
      "type": "PHONE_CALL",
      "description": "Discussed property preferences",
      "createdAt": "2024-01-15T10:15:00Z",
      "metadata": {
        "duration": 900,
        "callId": "call_789"
      }
    }
  ]
}

Add Contact Activity

Record a new activity for a contact.
curl -X POST "https://api.winnerr.com/v1/contacts/contact_123/activities" \
  -H "Authorization: Bearer YOUR_JWT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "MEETING",
    "description": "Property showing at 123 Ocean Drive",
    "scheduledAt": "2024-01-20T14:00:00Z",
    "metadata": {
      "propertyId": "property_456",
      "location": "123 Ocean Drive, Miami Beach"
    }
  }'

Contact Tags

Get Contact Tags

Retrieve all available tags for contacts.
curl -X GET "https://api.winnerr.com/v1/contacts/tags" \
  -H "Authorization: Bearer YOUR_JWT_TOKEN"
Response:
{
  "success": true,
  "data": [
    {
      "name": "first-time-buyer",
      "color": "#2563eb",
      "count": 45
    },
    {
      "name": "luxury-market",
      "color": "#dc2626",
      "count": 23
    },
    {
      "name": "investor",
      "color": "#059669",
      "count": 18
    }
  ]
}

Add Contact Tags

Add tags to a contact.
curl -X POST "https://api.winnerr.com/v1/contacts/contact_123/tags" \
  -H "Authorization: Bearer YOUR_JWT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "tags": ["investor", "cash-buyer"]
  }'

Bulk Operations

Bulk Update Contacts

Update multiple contacts in a single request.
curl -X PATCH "https://api.winnerr.com/v1/contacts/bulk" \
  -H "Authorization: Bearer YOUR_JWT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "contactIds": ["contact_123", "contact_456"],
    "updates": {
      "assignedTo": "agent_789",
      "status": "ACTIVE"
    }
  }'
Response:
{
  "success": true,
  "data": {
    "updated": 2,
    "failed": 0,
    "results": [
      {
        "id": "contact_123",
        "success": true
      },
      {
        "id": "contact_456",
        "success": true
      }
    ]
  }
}

Error Handling

Common Error Responses

Contact Not Found (404):
{
  "success": false,
  "error": {
    "type": "not_found_error",
    "title": "Contact Not Found",
    "status": 404,
    "detail": "Contact with ID 'contact_123' was not found"
  }
}
Validation Error (422):
{
  "success": false,
  "error": {
    "type": "validation_error",
    "title": "Validation Error",
    "status": 422,
    "detail": "Request validation failed",
    "errors": [
      {
        "field": "email",
        "code": "invalid_email",
        "message": "Email must be a valid email address"
      }
    ]
  }
}
Duplicate Contact (409):
{
  "success": false,
  "error": {
    "type": "conflict_error",
    "title": "Duplicate Contact",
    "status": 409,
    "detail": "Contact with email 'john.doe@example.com' already exists"
  }
}

Best Practices

1. Lead Scoring Integration

Automatically calculate lead scores when creating or updating contacts:
const contact = await fetch('https://api.winnerr.com/v1/contacts', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer YOUR_JWT_TOKEN',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    firstName: 'John',
    lastName: 'Doe',
    email: 'john.doe@example.com',
    source: 'WEBSITE',
    preferences: {
      priceRange: { min: 300000, max: 600000 }
    },
    calculateLeadScore: true // Automatically calculate lead score
  })
});

2. Efficient Filtering

Use efficient filtering to reduce API response size:
// Get high-value leads only
const highValueLeads = await fetch(
  'https://api.winnerr.com/v1/contacts?leadScore[gte]=80&type=LEAD&status=ACTIVE&fields=id,firstName,lastName,email,leadScore',
  {
    headers: { 'Authorization': 'Bearer YOUR_JWT_TOKEN' }
  }
);

3. Batch Operations

Use bulk operations for efficiency when updating multiple contacts:
// Bulk assign contacts to agent
const result = await fetch('https://api.winnerr.com/v1/contacts/bulk', {
  method: 'PATCH',
  headers: {
    'Authorization': 'Bearer YOUR_JWT_TOKEN',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    contactIds: leadIds,
    updates: { assignedTo: 'agent_123' }
  })
});

4. Activity Tracking

Always track contact interactions for better relationship management:
// Record contact activity after interaction
await fetch('https://api.winnerr.com/v1/contacts/contact_123/activities', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer YOUR_JWT_TOKEN',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    type: 'EMAIL_SENT',
    description: 'Follow-up email about property inquiry',
    metadata: { emailId: 'email_456' }
  })
});

Contact data is automatically synchronized with your CRM dashboard and real-time analytics. All contact interactions are logged for compliance and relationship management purposes.