Contact Models

Contact models for the ACPortal API.

class ab.api.models.contacts.ContactSimple(*, id=None, firstName=None, lastName=None, fullName=None, email=None, phone=None, companyId=None, companyName=None, addressesList=None, assistant=None, birthDate=None, bolNotes=None, careOf=None, company=None, contactDisplayId=None, contactTypeId=None, department=None, editable=None, emailsList=None, fax=None, fullNameUpdateRequired=None, isActive=None, isBusiness=None, isEmpty=None, isPayer=None, isPrefered=None, isPrimary=None, isPrivate=None, jobTitle=None, jobTitleId=None, legacyGuid=None, ownerFranchiseeId=None, phonesList=None, primaryEmail=None, primaryPhone=None, rootContactId=None, taxId=None, webSite=None, **extra_data)[source]

Bases: ResponseModel, IdentifiedModel

Lightweight contact — GET /contacts/{id} and GET /contacts/user.

The /contacts/user endpoint returns fullName, companyId, companyName instead of firstName/lastName — all fields are optional to accommodate both shapes.

Parameters:
  • id (str | int | None)

  • firstName (str | None)

  • lastName (str | None)

  • fullName (str | None)

  • email (str | None)

  • phone (str | None)

  • companyId (str | None)

  • companyName (str | None)

  • addressesList (List[dict] | None)

  • assistant (str | None)

  • birthDate (str | None)

  • bolNotes (str | None)

  • careOf (str | None)

  • company (dict | None)

  • contactDisplayId (str | None)

  • contactTypeId (int | None)

  • department (str | None)

  • editable (bool | None)

  • emailsList (List[dict] | None)

  • fax (str | None)

  • fullNameUpdateRequired (bool | None)

  • isActive (bool | None)

  • isBusiness (bool | None)

  • isEmpty (bool | None)

  • isPayer (bool | None)

  • isPrefered (bool | None)

  • isPrimary (bool | None)

  • isPrivate (bool | None)

  • jobTitle (str | None)

  • jobTitleId (int | None)

  • legacyGuid (str | None)

  • ownerFranchiseeId (str | None)

  • phonesList (List[dict] | None)

  • primaryEmail (str | None)

  • primaryPhone (str | None)

  • rootContactId (int | None)

  • taxId (str | None)

  • webSite (str | None)

  • extra_data (Any)

first_name: str | None
last_name: str | None
full_name: str | None
email: str | None
phone: str | None
company_id: str | None
company_name: str | None
addresses_list: List[dict] | None
assistant: str | None
birth_date: str | None
bol_notes: str | None
care_of: str | None
company: dict | None
contact_display_id: str | None
contact_type_id: int | None
department: str | None
editable: bool | None
emails_list: List[dict] | None
fax: str | None
full_name_update_required: bool | None
is_active: bool | None
is_business: bool | None
is_empty: bool | None
is_payer: bool | None
is_prefered: bool | None
is_primary: bool | None
is_private: bool | None
job_title: str | None
job_title_id: int | None
legacy_guid: str | None
owner_franchisee_id: str | None
phones_list: List[dict] | None
primary_email: str | None
primary_phone: str | None
root_contact_id: int | None
tax_id: str | None
web_site: str | None
model_config = {'alias_generator': <function _to_camel>, 'extra': 'allow', 'populate_by_name': True, 'str_strip_whitespace': True, 'use_enum_values': True, 'validate_by_alias': True, 'validate_by_name': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

class ab.api.models.contacts.EmailDetails(*, id=None, email=None, invalid=None, dontSpam=None, **extra_data)[source]

Bases: ResponseModel

Inner email object within ContactEmailEntry — maps to C# EmailDetails.

Parameters:
  • id (int | None)

  • email (str | None)

  • invalid (bool | None)

  • dontSpam (bool | None)

  • extra_data (Any)

id: int | None
email: str | None
invalid: bool | None
dont_spam: bool | None
model_config = {'alias_generator': <function _to_camel>, 'extra': 'allow', 'populate_by_name': True, 'str_strip_whitespace': True, 'use_enum_values': True, 'validate_by_alias': True, 'validate_by_name': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

class ab.api.models.contacts.PhoneDetails(*, id=None, phone=None, **extra_data)[source]

Bases: ResponseModel

Inner phone object within ContactPhoneEntry — maps to C# PhoneDetails.

Parameters:
  • id (int | None)

  • phone (str | None)

  • extra_data (Any)

id: int | None
phone: str | None
model_config = {'alias_generator': <function _to_camel>, 'extra': 'allow', 'populate_by_name': True, 'str_strip_whitespace': True, 'use_enum_values': True, 'validate_by_alias': True, 'validate_by_name': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

class ab.api.models.contacts.ContactEmailEntry(*, id=None, isActive=None, deactivatedReason=None, metaData=None, editable=None, email=None, **extra_data)[source]

Bases: ResponseModel

Email list entry — maps to C# ContactEmailEditDetails (DetailBindingBase).

Parameters:
  • id (int | None)

  • isActive (bool | None)

  • deactivatedReason (str | None)

  • metaData (str | None)

  • editable (bool | None)

  • email (EmailDetails | None)

  • extra_data (Any)

id: int | None
is_active: bool | None
deactivated_reason: str | None
meta_data: str | None
editable: bool | None
email: EmailDetails | None
model_config = {'alias_generator': <function _to_camel>, 'extra': 'allow', 'populate_by_name': True, 'str_strip_whitespace': True, 'use_enum_values': True, 'validate_by_alias': True, 'validate_by_name': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

class ab.api.models.contacts.ContactPhoneEntry(*, id=None, isActive=None, deactivatedReason=None, metaData=None, editable=None, phone=None, **extra_data)[source]

Bases: ResponseModel

Phone list entry — maps to C# ContactPhoneEditDetails (DetailBindingBase).

Parameters:
  • id (int | None)

  • isActive (bool | None)

  • deactivatedReason (str | None)

  • metaData (str | None)

  • editable (bool | None)

  • phone (PhoneDetails | None)

  • extra_data (Any)

id: int | None
is_active: bool | None
deactivated_reason: str | None
meta_data: str | None
editable: bool | None
phone: PhoneDetails | None
model_config = {'alias_generator': <function _to_camel>, 'extra': 'allow', 'populate_by_name': True, 'str_strip_whitespace': True, 'use_enum_values': True, 'validate_by_alias': True, 'validate_by_name': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

class ab.api.models.contacts.ContactAddressEntry(*, id=None, isActive=None, deactivatedReason=None, metaData=None, editable=None, address=None, **extra_data)[source]

Bases: ResponseModel

Address list entry — maps to C# ContactAddressEditDetails (DetailBindingBase).

Parameters:
id: int | None
is_active: bool | None
deactivated_reason: str | None
meta_data: str | None
editable: bool | None
address: CompanyAddress | None
model_config = {'alias_generator': <function _to_camel>, 'extra': 'allow', 'populate_by_name': True, 'str_strip_whitespace': True, 'use_enum_values': True, 'validate_by_alias': True, 'validate_by_name': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

class ab.api.models.contacts.ContactDetailedInfo(*, isActive=None, createdDate=None, modifiedDate=None, createdBy=None, modifiedBy=None, id=None, firstName=None, lastName=None, email=None, phone=None, contactDisplayId=None, fullName=None, contactTypeId=None, careOf=None, bolNotes=None, taxId=None, isBusiness=None, isPayer=None, isPrefered=None, isPrivate=None, isPrimary=None, companyId=None, rootContactId=None, ownerFranchiseeId=None, company=None, legacyGuid=None, assistant=None, department=None, webSite=None, birthDate=None, jobTitleId=None, jobTitle=None, emailsList=None, phonesList=None, addressesList=None, fax=None, primaryPhone=None, primaryEmail=None, editable=None, addresses=None, phones=None, emails=None, companyInfo=None, contactDetailsCompanyInfo=None, fullNameUpdateRequired=None, isEmpty=None, **extra_data)[source]

Bases: ResponseModel, FullAuditModel

Full editable contact details — GET /contacts/{id}/editdetails.

Maps to C# ContactEditDetails → ContactExtendedDetails<T> → ContactBaseDetails.

Parameters:
  • isActive (bool | None)

  • createdDate (datetime | None)

  • modifiedDate (datetime | None)

  • createdBy (str | None)

  • modifiedBy (str | None)

  • id (str | int | None)

  • firstName (str | None)

  • lastName (str | None)

  • email (str | None)

  • phone (str | None)

  • contactDisplayId (str | None)

  • fullName (str | None)

  • contactTypeId (int | None)

  • careOf (str | None)

  • bolNotes (str | None)

  • taxId (str | None)

  • isBusiness (bool | None)

  • isPayer (bool | None)

  • isPrefered (bool | None)

  • isPrivate (bool | None)

  • isPrimary (bool | None)

  • companyId (str | None)

  • rootContactId (int | None)

  • ownerFranchiseeId (str | None)

  • company (dict | None)

  • legacyGuid (str | None)

  • assistant (str | None)

  • department (str | None)

  • webSite (str | None)

  • birthDate (str | None)

  • jobTitleId (int | None)

  • jobTitle (str | None)

  • emailsList (List[ContactEmailEntry] | None)

  • phonesList (List[ContactPhoneEntry] | None)

  • addressesList (List[ContactAddressEntry] | None)

  • fax (str | None)

  • primaryPhone (str | None)

  • primaryEmail (str | None)

  • editable (bool | None)

  • addresses (List[dict] | None)

  • phones (List[dict] | None)

  • emails (List[dict] | None)

  • companyInfo (dict | None)

  • contactDetailsCompanyInfo (dict | None)

  • fullNameUpdateRequired (bool | None)

  • isEmpty (bool | None)

  • extra_data (Any)

first_name: str | None
last_name: str | None
email: str | None
phone: str | None
contact_display_id: str | None
full_name: str | None
contact_type_id: int | None
care_of: str | None
bol_notes: str | None
tax_id: str | None
is_business: bool | None
is_payer: bool | None
is_prefered: bool | None
is_private: bool | None
is_primary: bool | None
company_id: str | None
root_contact_id: int | None
owner_franchisee_id: str | None
company: dict | None
legacy_guid: str | None
assistant: str | None
department: str | None
web_site: str | None
birth_date: str | None
job_title_id: int | None
job_title: str | None
emails_list: List[ContactEmailEntry] | None
phones_list: List[ContactPhoneEntry] | None
addresses_list: List[ContactAddressEntry] | None
fax: str | None
primary_phone: str | None
primary_email: str | None
editable: bool | None
addresses: List[dict] | None
phones: List[dict] | None
emails: List[dict] | None
company_info: dict | None
contact_details_company_info: dict | None
full_name_update_required: bool | None
is_empty: bool | None
model_config = {'alias_generator': <function _to_camel>, 'extra': 'allow', 'populate_by_name': True, 'str_strip_whitespace': True, 'use_enum_values': True, 'validate_by_alias': True, 'validate_by_name': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

class ab.api.models.contacts.ContactPrimaryDetails(*, id=None, fullName=None, email=None, phone=None, company=None, companyId=None, companyName=None, cellPhone=None, fax=None, address=None, **extra_data)[source]

Bases: ResponseModel

Primary contact info — GET /contacts/{id}/primarydetails.

The live API returns company as a nested dict (full company object) rather than a plain string as swagger implies.

Parameters:
  • id (int | None)

  • fullName (str | None)

  • email (str | None)

  • phone (str | None)

  • company (dict | None)

  • companyId (str | None)

  • companyName (str | None)

  • cellPhone (str | None)

  • fax (str | None)

  • address (CompanyAddress | None)

  • extra_data (Any)

id: int | None
full_name: str | None
email: str | None
phone: str | None
company: dict | None
company_id: str | None
company_name: str | None
cell_phone: str | None
fax: str | None
address: CompanyAddress | None
model_config = {'alias_generator': <function _to_camel>, 'extra': 'allow', 'populate_by_name': True, 'str_strip_whitespace': True, 'use_enum_values': True, 'validate_by_alias': True, 'validate_by_name': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

class ab.api.models.contacts.SearchContactEntityResult(*, contactID=None, customerCell=None, contactDisplayId=None, contactFullName=None, contactPhone=None, contactHomePhone=None, contactEmail=None, masterConstantValue=None, contactDept=None, address1=None, address2=None, city=None, state=None, zipCode=None, countryName=None, companyCode=None, companyID=None, companyName=None, companyDisplayId=None, isPrefered=None, industryType=None, totalRecords=None, **extra_data)[source]

Bases: ResponseModel

Single result row from POST /contacts/v2/search.

Maps to C# SearchContactEntityResult entity (22 properties). Each row contains contact details, address fields, company info, and a denormalized totalRecords count.

Parameters:
  • contactID (int | None)

  • customerCell (str | None)

  • contactDisplayId (str | None)

  • contactFullName (str | None)

  • contactPhone (str | None)

  • contactHomePhone (str | None)

  • contactEmail (str | None)

  • masterConstantValue (str | None)

  • contactDept (str | None)

  • address1 (str | None)

  • address2 (str | None)

  • city (str | None)

  • state (str | None)

  • zipCode (str | None)

  • countryName (str | None)

  • companyCode (str | None)

  • companyID (str | None)

  • companyName (str | None)

  • companyDisplayId (str | None)

  • isPrefered (bool | None)

  • industryType (str | None)

  • totalRecords (int | None)

  • extra_data (Any)

contact_id: int | None
customer_cell: str | None
contact_display_id: str | None
contact_full_name: str | None
contact_phone: str | None
contact_home_phone: str | None
contact_email: str | None
master_constant_value: str | None
contact_dept: str | None
address1: str | None
address2: str | None
city: str | None
state: str | None
zip_code: str | None
country_name: str | None
company_code: str | None
company_id: str | None
company_name: str | None
company_display_id: str | None
is_prefered: bool | None
industry_type: str | None
total_records: int | None
model_config = {'alias_generator': <function _to_camel>, 'extra': 'allow', 'populate_by_name': True, 'str_strip_whitespace': True, 'use_enum_values': True, 'validate_by_alias': True, 'validate_by_name': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

class ab.api.models.contacts.ContactSearchParams(*, contactDisplayId=None, fullName=None, companyName=None, companyCode=None, email=None, phone=None, companyDisplayId=None)[source]

Bases: RequestModel

Search filter parameters — the mainSearchRequest sub-object of POST /contacts/v2/search.

Maps to swagger MergeContactsSearchRequestParameters. All fields are optional; omit entirely for unfiltered results.

Parameters:
  • contactDisplayId (int | None)

  • fullName (str | None)

  • companyName (str | None)

  • companyCode (str | None)

  • email (str | None)

  • phone (str | None)

  • companyDisplayId (int | None)

contact_display_id: int | None
full_name: str | None
company_name: str | None
company_code: str | None
email: str | None
phone: str | None
company_display_id: int | None
model_config = {'alias_generator': <function _to_camel>, 'extra': 'forbid', 'populate_by_name': True, 'str_strip_whitespace': True, 'use_enum_values': True, 'validate_by_alias': True, 'validate_by_name': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

class ab.api.models.contacts.PageOrderedRequest(*, pageNumber, pageSize, sortingBy=None, sortingDirection=None)[source]

Bases: RequestModel

Pagination and sorting options — the loadOptions sub-object of POST /contacts/v2/search.

Maps to swagger PageOrderedRequestModel / C# PagedOrderedRequest.

Parameters:
  • pageNumber (int)

  • pageSize (int)

  • sortingBy (str | None)

  • sortingDirection (int | None)

page_number: int
page_size: int
sorting_by: str | None
sorting_direction: int | None
model_config = {'alias_generator': <function _to_camel>, 'extra': 'forbid', 'populate_by_name': True, 'str_strip_whitespace': True, 'use_enum_values': True, 'validate_by_alias': True, 'validate_by_name': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

class ab.api.models.contacts.ContactEditParams(*, franchiseeId=None)[source]

Bases: RequestModel

Query parameters for contact edit operations.

Parameters:

franchiseeId (str | None)

franchisee_id: str | None
model_config = {'alias_generator': <function _to_camel>, 'extra': 'forbid', 'populate_by_name': True, 'str_strip_whitespace': True, 'use_enum_values': True, 'validate_by_alias': True, 'validate_by_name': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

class ab.api.models.contacts.ContactHistoryParams(*, statuses=None)[source]

Bases: RequestModel

Query parameters for contact history operations.

Parameters:

statuses (str | None)

statuses: str | None
model_config = {'alias_generator': <function _to_camel>, 'extra': 'forbid', 'populate_by_name': True, 'str_strip_whitespace': True, 'use_enum_values': True, 'validate_by_alias': True, 'validate_by_name': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

class ab.api.models.contacts.ContactEditRequest(*, firstName=None, lastName=None, email=None, phone=None, addresses=None)[source]

Bases: RequestModel

Body for PUT /contacts/{id}/editdetails and POST /contacts/editdetails.

Parameters:
  • firstName (str | None)

  • lastName (str | None)

  • email (str | None)

  • phone (str | None)

  • addresses (List[dict] | None)

first_name: str | None
last_name: str | None
email: str | None
phone: str | None
addresses: List[dict] | None
model_config = {'alias_generator': <function _to_camel>, 'extra': 'forbid', 'populate_by_name': True, 'str_strip_whitespace': True, 'use_enum_values': True, 'validate_by_alias': True, 'validate_by_name': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

class ab.api.models.contacts.ContactSearchRequest(*, mainSearchRequest=None, loadOptions)[source]

Bases: RequestModel

Body for POST /contacts/v2/search.

Uses a nested structure with mainSearchRequest (search filter parameters) and loadOptions (pagination/sort). The flat mixin fields (page, pageSize, searchText) are replaced by typed sub-models that match the API’s expected shape.

Parameters:
main_search_request: ContactSearchParams | None
load_options: PageOrderedRequest
model_config = {'alias_generator': <function _to_camel>, 'extra': 'forbid', 'populate_by_name': True, 'str_strip_whitespace': True, 'use_enum_values': True, 'validate_by_alias': True, 'validate_by_name': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

class ab.api.models.contacts.ContactHistory(*, events=None, totalCount=None, **extra_data)[source]

Bases: ResponseModel

Contact interaction history — POST /contacts/{contactId}/history.

Parameters:
events: List[dict] | None
total_count: int | None
model_config = {'alias_generator': <function _to_camel>, 'extra': 'allow', 'populate_by_name': True, 'str_strip_whitespace': True, 'use_enum_values': True, 'validate_by_alias': True, 'validate_by_name': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

class ab.api.models.contacts.ContactHistoryAggregated(*, summary=None, byType=None, **extra_data)[source]

Bases: ResponseModel

Aggregated history — GET /contacts/{contactId}/history/aggregated.

Parameters:
summary: dict | None
by_type: List[dict] | None
model_config = {'alias_generator': <function _to_camel>, 'extra': 'allow', 'populate_by_name': True, 'str_strip_whitespace': True, 'use_enum_values': True, 'validate_by_alias': True, 'validate_by_name': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

class ab.api.models.contacts.ContactGraphData(*, dataPoints=None, labels=None, **extra_data)[source]

Bases: ResponseModel

Contact graph data — GET /contacts/{contactId}/history/graphdata.

Parameters:
data_points: List[dict] | None
labels: List[str] | None
model_config = {'alias_generator': <function _to_camel>, 'extra': 'allow', 'populate_by_name': True, 'str_strip_whitespace': True, 'use_enum_values': True, 'validate_by_alias': True, 'validate_by_name': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

class ab.api.models.contacts.ContactMergePreview(*, mergeTo=None, mergeFrom=None, conflicts=None, **extra_data)[source]

Bases: ResponseModel

Merge preview result — POST /contacts/{mergeToId}/merge/preview.

Parameters:
merge_to: dict | None
merge_from: dict | None
conflicts: List[dict] | None
model_config = {'alias_generator': <function _to_camel>, 'extra': 'allow', 'populate_by_name': True, 'str_strip_whitespace': True, 'use_enum_values': True, 'validate_by_alias': True, 'validate_by_name': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

class ab.api.models.contacts.ContactHistoryCreateRequest(*, statuses=None)[source]

Bases: RequestModel

Body for POST /contacts/{contactId}/history.

Parameters:

statuses (str | None)

statuses: str | None
model_config = {'alias_generator': <function _to_camel>, 'extra': 'forbid', 'populate_by_name': True, 'str_strip_whitespace': True, 'use_enum_values': True, 'validate_by_alias': True, 'validate_by_name': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

class ab.api.models.contacts.ContactMergeRequest(*, mergeFromId=None)[source]

Bases: RequestModel

Body for POST /contacts/{mergeToId}/merge/preview and PUT /contacts/{mergeToId}/merge.

Parameters:

mergeFromId (str | None)

merge_from_id: str | None
model_config = {'alias_generator': <function _to_camel>, 'extra': 'forbid', 'populate_by_name': True, 'str_strip_whitespace': True, 'use_enum_values': True, 'validate_by_alias': True, 'validate_by_name': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].