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
| 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 |
Contact Status
| 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
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"
const response = await fetch('https://api.winnerr.com/v1/contacts', {
headers: {
'Authorization': 'Bearer YOUR_JWT_TOKEN',
'Content-Type': 'application/json'
}
});
const data = await response.json();
import requests
response = requests.get(
'https://api.winnerr.com/v1/contacts',
headers={
'Authorization': 'Bearer YOUR_JWT_TOKEN',
'Content-Type': 'application/json'
}
)
data = response.json()
| 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”) |
{
"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"
const response = await fetch('https://api.winnerr.com/v1/contacts/contact_123', {
headers: {
'Authorization': 'Bearer YOUR_JWT_TOKEN'
}
});
const contact = await response.json();
| Parameter | Type | Description |
|---|---|---|
id | string | Contact ID |
| Parameter | Type | Description |
|---|---|---|
include | string | Include related data (e.g., “deals,communications,activities”) |
{
"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
}
}
}'
const response = await fetch('https://api.winnerr.com/v1/contacts', {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_JWT_TOKEN',
'Content-Type': 'application/json'
},
body: JSON.stringify({
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
}
}
})
});
const contact = await response.json();
| 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 |
{
"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"]
}'
const response = await fetch('https://api.winnerr.com/v1/contacts/contact_123', {
method: 'PUT',
headers: {
'Authorization': 'Bearer YOUR_JWT_TOKEN',
'Content-Type': 'application/json'
},
body: JSON.stringify({
phone: '+1-555-111-2222',
status: 'CLIENT',
notes: 'Successfully closed on waterfront condo',
tags: ['past-client', 'referral-source']
})
});
const contact = await response.json();
| Parameter | Type | Description |
|---|---|---|
id | string | Contact ID |
{
"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"
const response = await fetch('https://api.winnerr.com/v1/contacts/contact_123', {
method: 'DELETE',
headers: {
'Authorization': 'Bearer YOUR_JWT_TOKEN'
}
});
| Parameter | Type | Description |
|---|---|---|
id | string | Contact ID |
{
"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"
const response = await fetch('https://api.winnerr.com/v1/contacts/contact_123/activities', {
headers: {
'Authorization': 'Bearer YOUR_JWT_TOKEN'
}
});
const activities = await response.json();
{
"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"
}
}'
const response = 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: 'MEETING',
description: 'Property showing at 123 Ocean Drive',
scheduledAt: '2024-01-20T14:00:00Z',
metadata: {
propertyId: 'property_456',
location: '123 Ocean Drive, Miami Beach'
}
})
});
const activity = await response.json();
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"
const response = await fetch('https://api.winnerr.com/v1/contacts/tags', {
headers: {
'Authorization': 'Bearer YOUR_JWT_TOKEN'
}
});
const tags = await response.json();
{
"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"]
}'
const response = await fetch('https://api.winnerr.com/v1/contacts/contact_123/tags', {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_JWT_TOKEN',
'Content-Type': 'application/json'
},
body: JSON.stringify({
tags: ['investor', 'cash-buyer']
})
});
const result = await response.json();
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"
}
}'
const response = 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: ['contact_123', 'contact_456'],
updates: {
assignedTo: 'agent_789',
status: 'ACTIVE'
}
})
});
const result = await response.json();
{
"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"
}
}
{
"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"
}
]
}
}
{
"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.