Contacts API

This guide covers the API endpoints for managing contacts in the Revenue Recognition System. Contacts represent individuals associated with your entities (customers, vendors, partners) who serve as points of contact for business relationships and communications.

Overview

Contacts are individual people who represent or work for entities in your system. They can be associated with companies (customers, vendors, partners) and have hierarchical relationships (reporting structures). Each contact can have multiple communication channels and metadata about their role and preferences.

Base URL

https://api.example.com/api/v1

Authentication

All contact API endpoints require authentication with a valid JWT bearer token. The token must include an organization context, which determines which contacts are visible and modifiable.

Authorization: Bearer <your-jwt-token>

Schema

FieldTypeDescriptionRequired
idUUIDUnique identifier (system-generated)Read-only
organizationIdStringOrganization this contact belongs toRead-only
nameStringFull name of the contactYes
displayNameStringDisplay name for the contactNo
codeStringOptional code identifierNo
entityTypesArrayEntity types (always includes 'Contact')Read-only
emailStringEmail address of the contactNo
phoneStringPrimary phone numberNo
websiteStringWebsite URLNo
addressObjectPhysical address details (see below)No
parentEntityIdUUIDID of parent entity (e.g., company)No
primaryContactIdUUIDID of primary contact (for companies)No
taxIdStringTax identification numberNo
descriptionStringBrief description of the contactNo
notesStringAdditional notesNo
customFieldsObjectCustom fields for the contactNo
metadataObjectContact metadata (see below)No
statusStringStatus: 'active', 'inactive', or 'archived'Yes
isActiveBooleanWhether the contact is activeYes
createdAtDateTimeWhen the record was createdRead-only
updatedAtDateTimeWhen the record was last updatedRead-only

Address Object

FieldTypeDescriptionRequired
idUUIDUnique identifier for the addressNo
addresseeStringName of addresseeNo
companyNameStringCompany name for addressNo
attentionStringAttention lineNo
phoneNumberStringPhone number for addressNo
line1StringAddress line 1No
line2StringAddress line 2No
cityStringCityNo
stateProvinceStringState or provinceNo
postalCodeStringPostal or ZIP codeNo
countryCodeStringTwo-letter ISO country codeNo

Contact Metadata Object

FieldTypeDescriptionRequired
titleStringJob title of the contactNo
departmentStringDepartment the contact belongs toNo
reportsToUUIDID of the contact this person reports toNo
mobilePhoneStringMobile phone numberNo
workPhoneStringWork phone numberNo
preferredContactMethodStringPreferred method: 'email', 'phone', 'mobile'No

Endpoints

Create Contact

Create a new contact within your organization.

  • Name
    Endpoint
    Type
    POST /contacts
    Description
  • Name
    Content-Type
    Type
    application/json
    Description

Request Body

  • Name
    name
    Type
    string
    Required
    Description

    Full name of the contact

  • Name
    displayName
    Type
    string
    Description

    Display name for the contact

  • Name
    code
    Type
    string
    Description

    Optional code identifier

  • Name
    entityTypes
    Type
    array
    Description

    Entity types (should include 'Contact' for contacts)

  • Name
    email
    Type
    string
    Description

    Email address of the contact

  • Name
    phone
    Type
    string
    Description

    Primary phone number

  • Name
    website
    Type
    string
    Description

    Website URL

  • Name
    address
    Type
    object
    Description

    Physical address details

  • Name
    parentEntityId
    Type
    string (UUID)
    Description

    ID of parent entity (e.g., company) this contact belongs to

  • Name
    taxId
    Type
    string
    Description

    Tax identification number

  • Name
    description
    Type
    string
    Description

    Brief description of the contact

  • Name
    notes
    Type
    string
    Description

    Additional notes

  • Name
    customFields
    Type
    object
    Description

    Custom fields for the contact

  • Name
    metadata
    Type
    object
    Description

    Contact metadata including job title, department, etc.

  • Name
    status
    Type
    string
    Description

    Status: 'active', 'inactive', or 'archived'

  • Name
    isActive
    Type
    boolean
    Description

    Whether the contact is active

Request

curl -X POST https://api.example.com/api/v1/contacts \
  -H "Authorization: Bearer <your-jwt-token>" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "John Smith",
    "displayName": "John",
    "email": "john.smith@acme.com",
    "phone": "555-123-4567",
    "entityTypes": ["Contact"],
    "parentEntityId": "d45f8e21-3ab2-4389-9e0d-9c12654b8e7a",
    "address": {
      "line1": "123 Main St",
      "city": "San Francisco",
      "stateProvince": "CA",
      "postalCode": "94105",
      "countryCode": "US"
    },
    "metadata": {
      "title": "Sales Director",
      "department": "Sales",
      "workPhone": "555-123-4568",
      "preferredContactMethod": "email"
    },
    "status": "active"
  }'

Response

{
  "id": "c12f8e21-4ab2-4589-ae0d-9c12654b8e7a",
  "organizationId": "org_123456789",
  "name": "John Smith",
  "displayName": "John",
  "code": null,
  "entityTypes": ["Contact"],
  "email": "john.smith@acme.com",
  "phone": "555-123-4567",
  "website": null,
  "address": {
    "id": "addr_987654321",
    "line1": "123 Main St",
    "line2": null,
    "city": "San Francisco",
    "stateProvince": "CA",
    "postalCode": "94105",
    "countryCode": "US"
  },
  "parentEntityId": "d45f8e21-3ab2-4389-9e0d-9c12654b8e7a",
  "primaryContactId": null,
  "taxId": null,
  "description": null,
  "notes": null,
  "customFields": null,
  "metadata": {
    "title": "Sales Director",
    "department": "Sales",
    "reportsTo": null,
    "mobilePhone": null,
    "workPhone": "555-123-4568",
    "preferredContactMethod": "email"
  },
  "status": "active",
  "isActive": true,
  "createdAt": "2025-06-03T10:15:30.000Z",
  "updatedAt": "2025-06-03T10:15:30.000Z"
}

List Contacts

Retrieve a paginated list of contacts in your organization.

  • Name
    Endpoint
    Type
    GET /contacts
    Description

Query Parameters

  • Name
    page
    Type
    number
    Description

    Page number for pagination

  • Name
    limit
    Type
    number
    Description

    Number of items per page (max: 100)

  • Name
    orderBy
    Type
    string
    Description

    Field to sort by (name, createdAt, updatedAt)

  • Name
    orderDirection
    Type
    string
    Description

    Sort direction (asc, desc)

  • Name
    status
    Type
    string
    Description

    Filter by status (active, inactive, archived)

  • Name
    search
    Type
    string
    Description

    Search query string (searches in name, email, phone)

  • Name
    parentEntityId
    Type
    string (UUID)
    Description

    Filter by parent entity ID

  • Name
    isActive
    Type
    boolean
    Description

    Filter by active status

Request

curl -X GET "https://api.example.com/api/v1/contacts?page=1&limit=20&status=active&search=john" \
  -H "Authorization: Bearer <your-jwt-token>"

Response

{
  "data": [
    {
      "id": "c12f8e21-4ab2-4589-ae0d-9c12654b8e7a",
      "organizationId": "org_123456789",
      "name": "John Smith",
      "displayName": "John",
      "code": null,
      "entityTypes": ["Contact"],
      "email": "john.smith@acme.com",
      "phone": "555-123-4567",
      "website": null,
      "address": {
        "line1": "123 Main St",
        "city": "San Francisco",
        "stateProvince": "CA",
        "postalCode": "94105",
        "countryCode": "US"
      },
      "parentEntityId": "d45f8e21-3ab2-4389-9e0d-9c12654b8e7a",
      "primaryContactId": null,
      "metadata": {
        "title": "Sales Director",
        "department": "Sales",
        "preferredContactMethod": "email"
      },
      "status": "active",
      "isActive": true,
      "createdAt": "2025-06-03T10:15:30.000Z",
      "updatedAt": "2025-06-03T10:15:30.000Z"
    }
  ],
  "total": 1,
  "page": 1,
  "limit": 20,
  "totalPages": 1
}

Get Contact

Retrieve a specific contact by ID.

  • Name
    Endpoint
    Type
    GET /contacts/{id}
    Description

Path Parameters

  • Name
    id
    Type
    string (UUID)
    Required
    Description

    ID of the contact to retrieve

Request

curl -X GET https://api.example.com/api/v1/contacts/c12f8e21-4ab2-4589-ae0d-9c12654b8e7a \
  -H "Authorization: Bearer <your-jwt-token>"

Response

{
  "id": "c12f8e21-4ab2-4589-ae0d-9c12654b8e7a",
  "organizationId": "org_123456789",
  "name": "John Smith",
  "displayName": "John",
  "code": null,
  "entityTypes": ["Contact"],
  "email": "john.smith@acme.com",
  "phone": "555-123-4567",
  "website": null,
  "address": {
    "id": "addr_987654321",
    "line1": "123 Main St",
    "line2": null,
    "city": "San Francisco",
    "stateProvince": "CA",
    "postalCode": "94105",
    "countryCode": "US"
  },
  "parentEntityId": "d45f8e21-3ab2-4389-9e0d-9c12654b8e7a",
  "primaryContactId": null,
  "taxId": null,
  "description": null,
  "notes": null,
  "customFields": null,
  "metadata": {
    "title": "Sales Director",
    "department": "Sales",
    "reportsTo": null,
    "mobilePhone": null,
    "workPhone": "555-123-4568",
    "preferredContactMethod": "email"
  },
  "status": "active",
  "isActive": true,
  "createdAt": "2025-06-03T10:15:30.000Z",
  "updatedAt": "2025-06-03T10:15:30.000Z"
}

Update Contact

Update an existing contact.

  • Name
    Endpoint
    Type
    PUT /contacts/{id}
    Description
  • Name
    Content-Type
    Type
    application/json
    Description

Path Parameters

  • Name
    id
    Type
    string (UUID)
    Required
    Description

    ID of the contact to update

Request Body

All fields are optional. Only include fields you want to update.

  • Name
    name
    Type
    string
    Description

    Full name of the contact

  • Name
    displayName
    Type
    string
    Description

    Display name for the contact

  • Name
    code
    Type
    string
    Description

    Optional code identifier

  • Name
    email
    Type
    string
    Description

    Email address of the contact

  • Name
    phone
    Type
    string
    Description

    Primary phone number

  • Name
    website
    Type
    string
    Description

    Website URL

  • Name
    address
    Type
    object
    Description

    Physical address details

  • Name
    parentEntityId
    Type
    string (UUID)
    Description

    ID of parent entity

  • Name
    taxId
    Type
    string
    Description

    Tax identification number

  • Name
    description
    Type
    string
    Description

    Brief description of the contact

  • Name
    notes
    Type
    string
    Description

    Additional notes

  • Name
    customFields
    Type
    object
    Description

    Custom fields for the contact

  • Name
    metadata
    Type
    object
    Description

    Contact metadata

  • Name
    status
    Type
    string
    Description

    Status: 'active', 'inactive', or 'archived'

  • Name
    isActive
    Type
    boolean
    Description

    Whether the contact is active

Request

curl -X PUT https://api.example.com/api/v1/contacts/c12f8e21-4ab2-4589-ae0d-9c12654b8e7a \
  -H "Authorization: Bearer <your-jwt-token>" \
  -H "Content-Type: application/json" \
  -d '{
    "displayName": "Johnny",
    "metadata": {
      "title": "VP of Sales",
      "mobilePhone": "555-999-8888",
      "preferredContactMethod": "mobile"
    }
  }'

Response

{
  "id": "c12f8e21-4ab2-4589-ae0d-9c12654b8e7a",
  "organizationId": "org_123456789",
  "name": "John Smith",
  "displayName": "Johnny",
  "code": null,
  "entityTypes": ["Contact"],
  "email": "john.smith@acme.com",
  "phone": "555-123-4567",
  "website": null,
  "address": {
    "id": "addr_987654321",
    "line1": "123 Main St",
    "line2": null,
    "city": "San Francisco",
    "stateProvince": "CA",
    "postalCode": "94105",
    "countryCode": "US"
  },
  "parentEntityId": "d45f8e21-3ab2-4389-9e0d-9c12654b8e7a",
  "primaryContactId": null,
  "taxId": null,
  "description": null,
  "notes": null,
  "customFields": null,
  "metadata": {
    "title": "VP of Sales",
    "department": "Sales",
    "reportsTo": null,
    "mobilePhone": "555-999-8888",
    "workPhone": "555-123-4568",
    "preferredContactMethod": "mobile"
  },
  "status": "active",
  "isActive": true,
  "createdAt": "2025-06-03T10:15:30.000Z",
  "updatedAt": "2025-06-03T11:30:45.000Z"
}

Delete Contact

Delete a contact.

  • Name
    Endpoint
    Type
    DELETE /contacts/{id}
    Description

Path Parameters

  • Name
    id
    Type
    string (UUID)
    Required
    Description

    ID of the contact to delete

Request

curl -X DELETE https://api.example.com/api/v1/contacts/c12f8e21-4ab2-4589-ae0d-9c12654b8e7a \
  -H "Authorization: Bearer <your-jwt-token>"

Response

HTTP/1.1 204 No Content

Get Contact Hierarchy

Returns a hierarchy map showing which contacts report to whom.

  • Name
    Endpoint
    Type
    GET /contacts/hierarchy
    Description

Request

curl -X GET https://api.example.com/api/v1/contacts/hierarchy \
  -H "Authorization: Bearer <your-jwt-token>"

Response

{
  "a23f8e21-3bb2-4589-be0d-8c32654b8e7b": [
    {
      "id": "c12f8e21-4ab2-4589-ae0d-9c12654b8e7a",
      "name": "John Smith",
      "displayName": "John",
      "metadata": {
        "title": "Sales Manager",
        "department": "Sales"
      }
    },
    {
      "id": "d34f9e32-5cc3-4690-cf1e-9d43765c9f8c",
      "name": "Jane Doe",
      "displayName": "Jane",
      "metadata": {
        "title": "Account Executive",
        "department": "Sales"
      }
    }
  ]
}

Find Contacts by Company

Get all contacts associated with a specific company/entity.

  • Name
    Endpoint
    Type
    GET /contacts/company/{companyId}
    Description

Path Parameters

  • Name
    companyId
    Type
    string (UUID)
    Required
    Description

    ID of the company

Request

curl -X GET https://api.example.com/api/v1/contacts/company/d45f8e21-3ab2-4389-9e0d-9c12654b8e7a \
  -H "Authorization: Bearer <your-jwt-token>"

Response

{
  "data": [
    {
      "id": "c12f8e21-4ab2-4589-ae0d-9c12654b8e7a",
      "name": "John Smith",
      "displayName": "John",
      "email": "john.smith@acme.com",
      "phone": "555-123-4567",
      "metadata": {
        "title": "Sales Director",
        "department": "Sales"
      },
      "status": "active"
    },
    {
      "id": "e45f0e43-6dd4-4701-df2f-0e54876d0g9d",
      "name": "Sarah Johnson",
      "displayName": "Sarah",
      "email": "sarah.johnson@acme.com",
      "phone": "555-234-5678",
      "metadata": {
        "title": "Marketing Manager",
        "department": "Marketing"
      },
      "status": "active"
    }
  ]
}

Find Contacts by Department

Get all contacts in a specific department.

  • Name
    Endpoint
    Type
    GET /contacts/department/{department}
    Description

Path Parameters

  • Name
    department
    Type
    string
    Required
    Description

    Department name

Request

curl -X GET https://api.example.com/api/v1/contacts/department/Sales \
  -H "Authorization: Bearer <your-jwt-token>"

Response

{
  "data": [
    {
      "id": "c12f8e21-4ab2-4589-ae0d-9c12654b8e7a",
      "name": "John Smith",
      "displayName": "John",
      "email": "john.smith@acme.com",
      "metadata": {
        "title": "Sales Director",
        "department": "Sales"
      }
    },
    {
      "id": "d34f9e32-5cc3-4690-cf1e-9d43765c9f8c",
      "name": "Jane Doe",
      "displayName": "Jane",
      "email": "jane.doe@acme.com",
      "metadata": {
        "title": "Account Executive",
        "department": "Sales"
      }
    }
  ]
}

Set Primary Contact

Designate a contact as the primary contact for a specific company.

  • Name
    Endpoint
    Type
    POST /contacts/{id}/set-primary/{companyId}
    Description

Path Parameters

  • Name
    id
    Type
    string (UUID)
    Required
    Description

    ID of the contact

  • Name
    companyId
    Type
    string (UUID)
    Required
    Description

    ID of the company

Request

curl -X POST https://api.example.com/api/v1/contacts/c12f8e21-4ab2-4589-ae0d-9c12654b8e7a/set-primary/d45f8e21-3ab2-4389-9e0d-9c12654b8e7a \
  -H "Authorization: Bearer <your-jwt-token>"

Response

{
  "contact": {
    "id": "c12f8e21-4ab2-4589-ae0d-9c12654b8e7a",
    "name": "John Smith",
    "displayName": "John",
    "email": "john.smith@acme.com",
    "parentEntityId": "d45f8e21-3ab2-4389-9e0d-9c12654b8e7a"
  },
  "company": {
    "id": "d45f8e21-3ab2-4389-9e0d-9c12654b8e7a",
    "name": "Acme Corporation",
    "primaryContactId": "c12f8e21-4ab2-4589-ae0d-9c12654b8e7a"
  }
}

Find Contacts by Preferred Contact Method

Get all contacts with a specific preferred contact method.

  • Name
    Endpoint
    Type
    GET /contacts/contact-method/{method}
    Description

Path Parameters

  • Name
    method
    Type
    string
    Required
    Description

    Contact method: 'email', 'phone', or 'mobile'

Request

curl -X GET https://api.example.com/api/v1/contacts/contact-method/email \
  -H "Authorization: Bearer <your-jwt-token>"

Response

{
  "data": [
    {
      "id": "c12f8e21-4ab2-4589-ae0d-9c12654b8e7a",
      "name": "John Smith",
      "email": "john.smith@acme.com",
      "phone": "555-123-4567",
      "metadata": {
        "preferredContactMethod": "email"
      }
    },
    {
      "id": "f56g1f54-7ee5-4812-eg3g-1f65987e1h0e",
      "name": "Emily Chen",
      "email": "emily.chen@globex.com",
      "phone": "555-345-6789",
      "metadata": {
        "preferredContactMethod": "email"
      }
    }
  ]
}

Error Responses

The API returns standard HTTP status codes and error messages in a consistent format.

{
  "error": "ERROR_CODE",
  "message": "Human-readable error description",
  "details": [
    {
      "field": "email",
      "message": "Invalid email format"
    }
  ]
}

Common errors include:

Status CodeError CodeDescription
400VALIDATION_ERRORRequest data failed validation
400INVALID_ENTITY_TYPEContact does not belong to the specified company
401UNAUTHORIZEDMissing or invalid authentication token
404CONTACT_NOT_FOUNDThe requested contact was not found
404COMPANY_NOT_FOUNDThe specified company was not found
500INTERNAL_SERVER_ERRORAn unexpected error occurred

Rate Limiting

The contacts API is rate-limited to ensure fair usage:

  • Rate limit: 1000 requests per hour per organization
  • Burst limit: 100 requests per minute
  • Headers returned:
    • X-RateLimit-Limit: Maximum requests per hour
    • X-RateLimit-Remaining: Remaining requests in current window
    • X-RateLimit-Reset: Unix timestamp when the limit resets

When rate limited, the API returns a 429 Too Many Requests status code.

Code Examples

JavaScript/TypeScript

// Using fetch API
const baseUrl = 'https://api.example.com/api/v1';
const token = 'your-jwt-token';

// Create a contact
async function createContact(contactData) {
  const response = await fetch(`${baseUrl}/contacts`, {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${token}`,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify(contactData)
  });

  if (!response.ok) {
    throw new Error(`Error: ${response.status}`);
  }

  return response.json();
}

// List contacts for a company
async function getCompanyContacts(companyId) {
  const response = await fetch(`${baseUrl}/contacts/company/${companyId}`, {
    headers: {
      'Authorization': `Bearer ${token}`
    }
  });

  if (!response.ok) {
    throw new Error(`Error: ${response.status}`);
  }

  return response.json();
}

// Update contact
async function updateContact(contactId, updates) {
  const response = await fetch(`${baseUrl}/contacts/${contactId}`, {
    method: 'PUT',
    headers: {
      'Authorization': `Bearer ${token}`,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify(updates)
  });

  if (!response.ok) {
    throw new Error(`Error: ${response.status}`);
  }

  return response.json();
}

// Example usage
const newContact = await createContact({
  name: 'John Smith',
  email: 'john.smith@acme.com',
  entityTypes: ['Contact'],
  parentEntityId: 'd45f8e21-3ab2-4389-9e0d-9c12654b8e7a',
  metadata: {
    title: 'Sales Director',
    department: 'Sales',
    preferredContactMethod: 'email'
  }
});

console.log('Created contact:', newContact);

Python

import requests
import json

base_url = 'https://api.example.com/api/v1'
headers = {
    'Authorization': 'Bearer your-jwt-token',
    'Content-Type': 'application/json'
}

# Create a contact
def create_contact(contact_data):
    response = requests.post(
        f'{base_url}/contacts',
        headers=headers,
        json=contact_data
    )
    response.raise_for_status()
    return response.json()

# List contacts with filters
def list_contacts(page=1, limit=20, status='active', search=None):
    params = {
        'page': page,
        'limit': limit,
        'status': status
    }
    if search:
        params['search'] = search
    
    response = requests.get(
        f'{base_url}/contacts',
        headers=headers,
        params=params
    )
    response.raise_for_status()
    return response.json()

# Get contact hierarchy
def get_contact_hierarchy():
    response = requests.get(
        f'{base_url}/contacts/hierarchy',
        headers=headers
    )
    response.raise_for_status()
    return response.json()

# Set primary contact for company
def set_primary_contact(contact_id, company_id):
    response = requests.post(
        f'{base_url}/contacts/{contact_id}/set-primary/{company_id}',
        headers=headers
    )
    response.raise_for_status()
    return response.json()

# Example usage
new_contact = create_contact({
    'name': 'Jane Doe',
    'email': 'jane.doe@example.com',
    'entityTypes': ['Contact'],
    'phone': '555-987-6543',
    'metadata': {
        'title': 'Product Manager',
        'department': 'Product',
        'preferredContactMethod': 'email'
    }
})

print(f"Created contact: {new_contact['id']}")

# List all active contacts
contacts = list_contacts(status='active')
print(f"Found {contacts['total']} active contacts")

Webhooks

The contacts API supports webhooks for real-time notifications of contact events. To configure webhooks, see the Webhooks documentation.

Available webhook events:

  • contact.created - Fired when a new contact is created
  • contact.updated - Fired when a contact is updated
  • contact.deleted - Fired when a contact is deleted
  • contact.status_changed - Fired when a contact's status changes
  • contact.primary_set - Fired when a contact is set as primary for a company

Example webhook payload:

{
  "event": "contact.created",
  "timestamp": "2025-06-03T10:15:30.000Z",
  "data": {
    "id": "c12f8e21-4ab2-4589-ae0d-9c12654b8e7a",
    "organizationId": "org_123456789",
    "name": "John Smith",
    "email": "john.smith@acme.com",
    "parentEntityId": "d45f8e21-3ab2-4389-9e0d-9c12654b8e7a",
    "status": "active"
  }
}

Best Practices

Contact Management

  1. Use meaningful display names: Set display names that are commonly used in communication to make contacts easier to identify.

  2. Link contacts to companies: Always set the parentEntityId to associate contacts with their companies for better organization.

  3. Track reporting structures: Use the metadata.reportsTo field to build organizational hierarchies within companies.

  4. Set preferred contact methods: Always specify the preferred contact method to ensure communications are sent through the right channel.

Data Quality

  1. Validate email addresses: Ensure email addresses are valid before creating or updating contacts.

  2. Use consistent naming: Establish naming conventions for contacts to maintain consistency.

  3. Keep contact information current: Regularly update contact information, especially when employees change roles or companies.

  4. Archive instead of delete: Use the 'archived' status instead of deleting contacts to maintain historical records.

Performance

  1. Use pagination: Always paginate results when listing contacts to avoid performance issues.

  2. Filter efficiently: Use specific filters (status, parentEntityId) to reduce the result set.

  3. Cache frequently accessed data: Cache contact data that doesn't change often to reduce API calls.

Changelog

For the latest updates and changes to the contacts API, see the API Changelog.

Was this page helpful?