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.
{
"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"
}
| Type | Description |
|---|
LEAD | Potential client or prospect |
CLIENT | Active client with ongoing business |
PAST_CLIENT | Previous client for referral tracking |
REFERRAL | Contact from referral source |
VENDOR | Service provider or contractor |
| Status | Description |
|---|
ACTIVE | Actively engaged contact |
INACTIVE | Not currently engaged |
CONVERTED | Lead converted to client |
DISQUALIFIED | Not a qualified prospect |
DO_NOT_CONTACT | Requested no further contact |
Endpoints
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:
| Parameter | Type | Description |
|---|
limit | integer | Number of contacts to return (1-100, default: 25) |
cursor | string | Pagination cursor for next page |
type | string | Filter by contact type |
status | string | Filter by contact status |
source | string | Filter by lead source |
assignedTo | string | Filter by assigned agent |
tags | string | Filter by tags (comma-separated) |
leadScore[gte] | integer | Filter by minimum lead score |
leadScore[lte] | integer | Filter by maximum lead score |
createdAt[gte] | string | Filter by creation date (ISO 8601) |
createdAt[lte] | string | Filter by creation date (ISO 8601) |
sort | string | Sort order (e.g., “createdAt:desc,leadScore:desc”) |
include | string | Include 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
}
}
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:
| Parameter | Type | Description |
|---|
id | string | Contact ID |
Query Parameters:
| Parameter | Type | Description |
|---|
include | string | Include 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 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:
| Field | Type | Required | Description |
|---|
firstName | string | Yes | Contact’s first name |
lastName | string | Yes | Contact’s last name |
email | string | Yes | Contact’s email address |
phone | string | No | Primary phone number |
secondaryPhone | string | No | Secondary phone number |
address | object | No | Contact’s address |
type | string | No | Contact type (default: LEAD) |
source | string | No | Lead source |
tags | array | No | Array of tags |
notes | string | No | Additional notes |
preferences | object | No | Contact preferences |
assignedTo | string | No | Assigned 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 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:
| Parameter | Type | Description |
|---|
id | string | Contact 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 a contact from the system.
curl -X DELETE "https://api.winnerr.com/v1/contacts/contact_123" \
-H "Authorization: Bearer YOUR_JWT_TOKEN"
Path Parameters:
| Parameter | Type | Description |
|---|
id | string | Contact ID |
Response:
{
"success": true,
"message": "Contact deleted successfully"
}
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"
}
}
]
}
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"
}
}'
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 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
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.