Appearance
Data Models & Schemas
Table of Contents
- Overview
- Core Entity Models
- Request/Response Models
- Filter Models
- Common Data Types
- Validation Rules
- JSON Schema Definitions
Overview
The Engagifii CRM API uses a comprehensive set of data models that represent the core entities and their relationships within the CRM system. All models follow consistent naming conventions and validation rules.
Model Naming Conventions
- Entity Models: Core business objects (Person, Organization, Committee)
- View Models: Client-facing representations with
*Viewor*ClientViewsuffix - Request Models: Input models for API operations with
*Requestsuffix - Filter Models: Search and filtering models with
*Filtersuffix - Item Models: Lightweight representations with
*Itemsuffix
Common Properties
Most entity models include these standard audit fields:
id: Unique GUID identifiercreatedDate: ISO 8601 timestamp of creationmodifiedDate: ISO 8601 timestamp of last modificationisActive: Boolean indicating active statustenantId: Multi-tenancy identifier (system managed)
Core Entity Models
Person Model
Represents an individual person within the CRM system.
json
{
"id": "123e4567-e89b-12d3-a456-426614174000",
"firstName": "John",
"middleName": "Michael",
"lastName": "Doe",
"suffix": "Jr.",
"displayName": "John M. Doe Jr.",
"email": "john.doe@example.com",
"secondaryEmail": "john.doe.personal@gmail.com",
"phone": "+1-555-123-4567",
"mobilePhone": "+1-555-987-6543",
"title": "Senior Software Engineer",
"department": "Engineering",
"organizationId": "org-123",
"organizationName": "Acme Corporation",
"addresses": [
{
"id": "addr-1",
"type": "Primary",
"street": "123 Main Street",
"street2": "Suite 456",
"city": "New York",
"state": "NY",
"zipCode": "10001",
"country": "USA",
"isActive": true
}
],
"positions": [
{
"id": "pos-1",
"organizationId": "org-123",
"title": "Senior Software Engineer",
"department": "Engineering",
"startDate": "2023-01-15T00:00:00Z",
"endDate": null,
"isActive": true,
"isPrimary": true
}
],
"tags": [
{
"id": "tag-1",
"name": "VIP",
"color": "#FF5733",
"category": "Status"
}
],
"customFields": {
"birthDate": "1985-03-15T00:00:00Z",
"linkedInProfile": "https://linkedin.com/in/johndoe",
"emergencyContact": "Jane Doe",
"notes": "Key stakeholder in platform architecture decisions"
},
"isActive": true,
"createdDate": "2023-01-15T10:30:00Z",
"modifiedDate": "2024-01-20T15:45:00Z"
}Validation Rules:
firstName: Required, max 50 characterslastName: Required, max 50 charactersemail: Required, valid email format, unique per tenantphone: Optional, valid phone formataddresses: At least one address required if specifiedorganizationId: Must reference valid organization
Organization Model
Represents a company, department, or other organizational entity.
json
{
"id": "org-123",
"name": "Acme Corporation",
"shortName": "ACME",
"description": "Leading provider of innovative software solutions",
"organizationType": "Company",
"organizationTypeId": "type-1",
"parentOrganizationId": null,
"website": "https://acme.com",
"email": "info@acme.com",
"phone": "+1-555-000-1234",
"fax": "+1-555-000-1235",
"addresses": [
{
"id": "addr-org-1",
"type": "Headquarters",
"street": "100 Corporate Boulevard",
"city": "San Francisco",
"state": "CA",
"zipCode": "94105",
"country": "USA",
"isActive": true
}
],
"childOrganizations": [
{
"id": "org-124",
"name": "Engineering Department",
"organizationType": "Department",
"memberCount": 25
}
],
"relatedOrganizations": [
{
"id": "org-200",
"name": "Partner Corp",
"relationshipType": "Strategic Partner",
"relationshipStartDate": "2023-01-01T00:00:00Z"
}
],
"tags": [
{
"id": "tag-org-1",
"name": "Fortune 500",
"color": "#1E88E5"
}
],
"memberCount": 150,
"isActive": true,
"createdDate": "2023-01-01T00:00:00Z",
"modifiedDate": "2024-01-20T12:00:00Z"
}Validation Rules:
name: Required, max 200 characters, unique per tenantorganizationType: Required, must be valid typewebsite: Optional, valid URL formatemail: Optional, valid email formatparentOrganizationId: Must reference valid organization, cannot create circular references
Committee Model
Represents committees, boards, or other governance structures.
json
{
"id": "committee-123",
"name": "Board of Directors",
"description": "Executive oversight and strategic direction committee",
"committeeType": "Board",
"committeeTypeId": "ctype-1",
"organizationId": "org-123",
"organizationName": "Acme Corporation",
"startDate": "2023-01-01T00:00:00Z",
"endDate": null,
"meetingFrequency": "Monthly",
"positions": [
{
"id": "pos-1",
"title": "Chairman",
"description": "Committee chair and primary decision maker",
"sequence": 1,
"isRequired": true,
"maxOccupants": 1
},
{
"id": "pos-2",
"title": "Secretary",
"description": "Record keeping and meeting coordination",
"sequence": 2,
"isRequired": true,
"maxOccupants": 1
}
],
"members": [
{
"id": "member-1",
"personId": "person-456",
"personName": "Jane Smith",
"positionId": "pos-1",
"positionTitle": "Chairman",
"startDate": "2023-01-01T00:00:00Z",
"endDate": null,
"isActive": true
}
],
"tags": [
{
"id": "tag-com-1",
"name": "Executive",
"color": "#9C27B0"
}
],
"memberCount": 8,
"isActive": true,
"createdDate": "2023-01-01T00:00:00Z",
"modifiedDate": "2024-01-15T09:30:00Z"
}Validation Rules:
name: Required, max 200 characterscommitteeType: Required, must be valid typeorganizationId: Required, must reference valid organizationstartDate: RequiredendDate: Must be after startDate if specifiedpositions: At least one position required
Advocacy Relationship Model
Represents political or advocacy relationships between people and officials.
json
{
"id": "relationship-123",
"personId": "person-456",
"personName": "John Doe",
"relatedOfficialId": "official-789",
"relatedOfficialName": "Senator Jane Smith",
"relatedOfficialTitle": "U.S. Senator",
"relatedOfficialOffice": "United States Senate",
"relationshipType": "Constituent",
"relationshipTypeId": "rel-type-1",
"relationshipCategory": "Political",
"startDate": "2023-01-01T00:00:00Z",
"endDate": null,
"strength": "Strong",
"notes": "Active constituent relationship with regular communication",
"lastContactDate": "2024-01-15T00:00:00Z",
"nextFollowUpDate": "2024-02-15T00:00:00Z",
"isActive": true,
"createdDate": "2023-01-01T00:00:00Z",
"modifiedDate": "2024-01-15T14:20:00Z"
}Request/Response Models
ListViewRequest Model
Standard request model for paginated list endpoints.
json
{
"pageIndex": 0,
"pageSize": 50,
"sortField": "lastName",
"sortDirection": "asc",
"searchText": "john",
"filter": {
// Endpoint-specific filter properties
}
}Properties:
pageIndex: Integer, zero-based page number, default 0pageSize: Integer, records per page, range 1-500, default 50sortField: String, field name to sort bysortDirection: String, "asc" or "desc", default "asc"searchText: String, general search query, max 200 charactersfilter: Object, endpoint-specific filter criteria
ListViewResult Model
Standard response model for paginated list endpoints.
json
{
"data": [
// Array of result objects
],
"totalCount": 1250,
"pageIndex": 0,
"pageSize": 50,
"totalPages": 25,
"hasNextPage": true,
"hasPreviousPage": false,
"firstItemOnPage": 1,
"lastItemOnPage": 50
}Properties:
data: Array of result objectstotalCount: Total number of records matching filterpageIndex: Current page number (zero-based)pageSize: Number of records per pagetotalPages: Total number of pageshasNextPage: Boolean, whether more pages existhasPreviousPage: Boolean, whether previous pages existfirstItemOnPage: One-based index of first item on current pagelastItemOnPage: One-based index of last item on current page
Filter Models
PeopleListViewBodyFilter
Filter model for people list endpoints.
json
{
"searchText": "john",
"firstName": "John",
"lastName": "Doe",
"email": "john.doe@example.com",
"phone": "+1-555-123-4567",
"organizationId": "org-123",
"organizationName": "Acme",
"personaTypeId": "type-456",
"isActive": true,
"hasEmail": true,
"hasPhone": true,
"hasAddress": true,
"dateRange": {
"startDate": "2023-01-01T00:00:00Z",
"endDate": "2024-01-01T00:00:00Z",
"dateField": "createdDate"
},
"locationFilter": {
"country": "USA",
"state": "CA",
"city": "San Francisco",
"zipCode": "94105",
"radius": 50,
"radiusUnit": "miles"
},
"tagIds": ["tag-1", "tag-2"],
"excludeTagIds": ["tag-exclude-1"],
"positionFilter": {
"title": "Manager",
"department": "Engineering",
"hasActivePosition": true
},
"customFields": {
"customField123": "value1",
"customField456": ["value2", "value3"]
}
}OrganizationListViewBodyFilter
Filter model for organization list endpoints.
json
{
"searchText": "acme",
"name": "Acme Corporation",
"organizationType": "Company",
"organizationTypeId": "type-1",
"parentOrganizationId": "parent-org-1",
"hasParentOrganization": true,
"hasChildOrganizations": true,
"hasMembers": true,
"memberCountRange": {
"min": 10,
"max": 500
},
"isActive": true,
"dateRange": {
"startDate": "2023-01-01T00:00:00Z",
"endDate": "2024-01-01T00:00:00Z",
"dateField": "createdDate"
},
"locationFilter": {
"country": "USA",
"state": "CA"
},
"tagIds": ["tag-org-1"],
"customFields": {
"industry": "Technology"
}
}DateRangeFilter
Common date range filter used across multiple endpoints.
json
{
"startDate": "2023-01-01T00:00:00Z",
"endDate": "2024-01-01T00:00:00Z",
"dateField": "createdDate",
"includeNullDates": false
}Properties:
startDate: ISO 8601 date, inclusive start of rangeendDate: ISO 8601 date, inclusive end of rangedateField: String, name of date field to filter onincludeNullDates: Boolean, whether to include records with null dates
Common Data Types
Address Type
json
{
"id": "addr-1",
"type": "Primary",
"street": "123 Main Street",
"street2": "Suite 456",
"city": "New York",
"state": "NY",
"zipCode": "10001",
"country": "USA",
"latitude": 40.7128,
"longitude": -74.0060,
"isActive": true,
"isPrimary": true
}Address Types:
Primary: Main addressSecondary: Alternative addressHeadquarters: Organization main officeBranch: Organization branch officeBilling: Billing addressShipping: Shipping address
Tag Type
json
{
"id": "tag-1",
"name": "VIP",
"description": "Very Important Person designation",
"color": "#FF5733",
"category": "Status",
"isActive": true,
"usageCount": 150
}Position Type
json
{
"id": "pos-1",
"organizationId": "org-123",
"title": "Senior Software Engineer",
"department": "Engineering",
"level": "Senior",
"startDate": "2023-01-15T00:00:00Z",
"endDate": null,
"isActive": true,
"isPrimary": true,
"reportingManagerId": "person-manager-1",
"salary": {
"amount": 120000,
"currency": "USD",
"frequency": "Annual"
}
}Contact Information Type
json
{
"emails": [
{
"type": "Primary",
"address": "john.doe@company.com",
"isActive": true
},
{
"type": "Personal",
"address": "john.doe@gmail.com",
"isActive": true
}
],
"phones": [
{
"type": "Work",
"number": "+1-555-123-4567",
"extension": "1234",
"isActive": true
},
{
"type": "Mobile",
"number": "+1-555-987-6543",
"isActive": true
}
]
}Contact Types:
- Email:
Primary,Secondary,Personal,Work - Phone:
Work,Mobile,Home,Fax
Validation Rules
General Validation Rules
String Fields:
- All string fields are trimmed of leading/trailing whitespace
- Empty strings are treated as null values
- HTML content is sanitized for security
Date Fields:
- Must be in ISO 8601 format:
YYYY-MM-DDTHH:mm:ssZ - All dates stored in UTC
- Historical dates allowed but cannot be in the future for creation dates
GUID Fields:
- Must be valid GUID format with hyphens:
123e4567-e89b-12d3-a456-426614174000 - Case insensitive
- Cannot be empty GUID (
00000000-0000-0000-0000-000000000000)
Email Fields:
- Must be valid email format per RFC 5322
- Maximum 254 characters
- Case insensitive storage and comparison
- Must be unique per tenant where specified
Phone Fields:
- Supports international formats
- Automatically formatted and validated
- Can include extensions
- Maximum 20 characters for base number
Entity-Specific Validation
Person Validation:
- First name and last name required
- Email required and must be unique per tenant
- Phone number format validated if provided
- At least one address required if addresses provided
Organization Validation:
- Name required and must be unique per tenant
- Cannot set self as parent organization
- Circular parent-child relationships prevented
- Website URL format validated if provided
Committee Validation:
- Name required
- Must belong to a valid organization
- End date must be after start date if provided
- At least one position required
- Position titles must be unique within committee
JSON Schema Definitions
Person Schema
json
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"title": "Person",
"properties": {
"id": {
"type": "string",
"format": "uuid",
"description": "Unique identifier for the person"
},
"firstName": {
"type": "string",
"minLength": 1,
"maxLength": 50,
"description": "Person's first name"
},
"lastName": {
"type": "string",
"minLength": 1,
"maxLength": 50,
"description": "Person's last name"
},
"email": {
"type": "string",
"format": "email",
"maxLength": 254,
"description": "Primary email address"
},
"phone": {
"type": "string",
"pattern": "^[+]?[1-9]\\d{1,14}$",
"description": "Primary phone number in international format"
},
"organizationId": {
"type": "string",
"format": "uuid",
"description": "ID of associated organization"
},
"isActive": {
"type": "boolean",
"description": "Whether the person is active in the system"
},
"createdDate": {
"type": "string",
"format": "date-time",
"description": "Date and time when person was created"
}
},
"required": ["firstName", "lastName", "email"],
"additionalProperties": true
}Organization Schema
json
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"title": "Organization",
"properties": {
"id": {
"type": "string",
"format": "uuid"
},
"name": {
"type": "string",
"minLength": 1,
"maxLength": 200
},
"organizationType": {
"type": "string",
"enum": ["Company", "Department", "NonProfit", "Government", "Educational"]
},
"website": {
"type": "string",
"format": "uri"
},
"email": {
"type": "string",
"format": "email"
},
"parentOrganizationId": {
"type": ["string", "null"],
"format": "uuid"
},
"isActive": {
"type": "boolean"
}
},
"required": ["name", "organizationType"],
"additionalProperties": true
}List Request Schema
json
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"title": "ListViewRequest",
"properties": {
"pageIndex": {
"type": "integer",
"minimum": 0,
"default": 0
},
"pageSize": {
"type": "integer",
"minimum": 1,
"maximum": 500,
"default": 50
},
"sortField": {
"type": "string",
"maxLength": 50
},
"sortDirection": {
"type": "string",
"enum": ["asc", "desc"],
"default": "asc"
},
"searchText": {
"type": "string",
"maxLength": 200
},
"filter": {
"type": "object"
}
},
"additionalProperties": false
}For complete schema definitions and validation rules, refer to the OpenAPI Specification or test interactively using the Swagger Documentation.
