Technical Guide: Setting Up My Assigned Contacts via the Spoke API

Why Implement Assigned Contacts?

My Assigned Contacts solve critical business challenges around contact visibility and access control within your organization. Here are the key reasons to implement this feature:

Compliance and Security

Many organizations have regulatory requirements or internal policies that restrict which users can access specific customer information. For example:

  • Financial services firms (FINRA compliance) need to prevent lead poaching between advisors
  • Healthcare organizations (HIPAA compliance) must limit patient contact access to authorized personnel
  • Legal firms need to restrict client contact visibility based on conflict of interest rules

Territory Management

Sales and service organizations benefit from territory-based contact assignment:

  • Real estate agents only see listings and contacts for their assigned territories
  • Field service technicians access contacts for their geographic regions
  • Account managers view contacts for their assigned client portfolios

Role-Based Access Control

Different user roles require different contact visibility:

  • Junior staff may only access contacts they're directly working with
  • Senior managers can see broader contact sets for oversight purposes
  • Specialists access contacts relevant to their expertise areas

CRM Integration and Data Governance

Implementing assigned contacts allows you to:

  • Mirror your existing CRM's visibility rules in Spoke
  • Maintain consistent data governance across all business systems
  • Automatically sync contact assignments as your business rules change
  • Prevent information silos while maintaining appropriate access controls

Technical Implementation Overview

The My Assigned Contacts feature uses Spoke's personal phonebook scope with system-managed contacts. This approach provides user-specific contact visibility while maintaining centralized control over the contact data.

Architecture Components

  1. Personal Phonebook Scope: Each user gets a personal phonebook that only they can access
  2. System-Managed Contacts: Contacts are managed via API, not user-editable
  3. Email-Based Addressing: Use user email addresses as phonebook identifiers
  4. Automated Sync Process: Regular updates from your source system (CRM, database, etc.)

Prerequisites

Before implementing assigned contacts, ensure you have:

  • Spoke Phone Developer Account: Sign up at account.spokephone.com/twilio
  • API Credentials: Generate Client ID and Client Secret from your Spoke developer dashboard
  • Source Data System: CRM, database, or other system containing contact assignments
  • Technical Resources: Development team familiar with REST APIs and OAuth 2.0

Step 1: Authentication Setup

Generate API Credentials

  1. Log into your Spoke account at account.spokephone.com
  2. Navigate to the Developer API section
  3. Create new API credentials and record your Client ID and Client Secret

Obtain OAuth 2.0 Access Token

curl -X POST https://auth.spokephone.com/oauth/token \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -H "Accept: application/json" \
  -d "client_id=YOUR_CLIENT_ID&client_secret=YOUR_CLIENT_SECRET&grant_type=client_credentials"

Store the returned access token for use in subsequent API calls.

Step 2: User Phonebook Management

Create Personal Phonebook (if needed)

For each user who needs assigned contacts, create a personal phonebook:

curl -X POST https://integration.spokephone.com/phonebooks \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "My Assigned Contacts",
    "scope": "personal",
    "ownerId": "user@company.com"
  }'

Using Email Shorthand Addressing

Spoke supports email-based phonebook addressing for convenience. This eliminates the need to track internal phonebook IDs:

# List contacts for a user
GET /phonebooks/xxxx@acme.com

# Add/update contacts for a user  
PUT /phonebooks/xxxx@acme/contacts

# Retrieve specific contact
GET /phonebooks/xxxx@acme/contacts/contact_id

# Delete a contact
DELETE /phonebooks/xxxx@acme/contacts/contact_id

When using email addressing:

  • scope is implicitly set to personal
  • userId is automatically determined from the email address

Step 3: Contact Synchronization

Adding System-Managed Contacts

When adding contacts to a user's assigned phonebook, ensure they're marked as system-managed:

curl -X PUT https://integration.spokephone.com/phonebooks/user@company.com/contacts \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "contacts": [
      {
        "id": "external_contact_123",
        "name": "John Smith",
        "company": "ABC Corporation",
        "phone": "+12345678901",
        "email": "john.smith@abc.com",
        "managedBy": "system"
      },
      {
        "id": "external_contact_124", 
        "name": "Jane Doe",
        "company": "XYZ Industries",
        "phone": "+12345678902",
        "email": "jane.doe@xyz.com",
        "managedBy": "system"
      }
    ]
  }'

Key Contact Attributes

  • managedBy: "system": Ensures contacts are read-only for users and manageable via API
  • id: Use your external system's unique identifier for easy updates
  • Contact fields: Include all relevant contact information (name, company, phone, email, etc.)

Step 4: Automated Sync Process

Building a Sync Script

Create a script that regularly syncs contact assignments from your source system:

import requests
import json
from datetime import datetime

class SpokeContactSync:
    def __init__(self, client_id, client_secret):
        self.client_id = client_id
        self.client_secret = client_secret
        self.access_token = self.get_access_token()
    
    def get_access_token(self):
        """Obtain OAuth 2.0 access token"""
        url = "https://auth.spokephone.com/oauth/token"
        headers = {
            "Content-Type": "application/x-www-form-urlencoded",
            "Accept": "application/json"
        }
        data = {
            "client_id": self.client_id,
            "client_secret": self.client_secret,
            "grant_type": "client_credentials"
        }
        
        response = requests.post(url, headers=headers, data=data)
        return response.json()["access_token"]
    
    def sync_user_contacts(self, user_email, assigned_contacts):
        """Sync assigned contacts for a specific user"""
        url = f"https://integration.spokephone.com/phonebooks/{user_email}/contacts"
        headers = {
            "Authorization": f"Bearer {self.access_token}",
            "Content-Type": "application/json"
        }
        
        # Format contacts for Spoke API
        formatted_contacts = []
        for contact in assigned_contacts:
            formatted_contacts.append({
                "id": contact["external_id"],
                "name": contact["name"],
                "company": contact["company"],
                "phone": contact["phone"],
                "email": contact["email"],
                "managedBy": "system"
            })
        
        payload = {"contacts": formatted_contacts}
        
        response = requests.put(url, headers=headers, json=payload)
        
        if response.status_code == 200:
            print(f"Successfully synced {len(formatted_contacts)} contacts for {user_email}")
        else:
            print(f"Error syncing contacts for {user_email}: {response.status_code}")
            print(response.text)
    
    def get_user_assignments_from_crm(self, user_email):
        """Get assigned contacts for a user from your CRM/database"""
        # Replace this with your actual CRM/database query
        # This is just an example
        assigned_contacts = [
            {
                "external_id": "crm_123",
                "name": "Customer A",
                "company": "Company A",
                "phone": "+15551234567",
                "email": "contact@companya.com"
            }
            # ... more contacts
        ]
        return assigned_contacts

# Usage example
sync = SpokeContactSync("YOUR_CLIENT_ID", "YOUR_CLIENT_SECRET")

users_to_sync = ["sales1@company.com", "sales2@company.com", "manager@company.com"]

for user_email in users_to_sync:
    assigned_contacts = sync.get_user_assignments_from_crm(user_email)
    sync.sync_user_contacts(user_email, assigned_contacts)

Scheduling Regular Syncs

Set up automated syncing based on your business needs:

  • Real-time: Use webhooks to sync immediately when assignments change in your CRM
  • Hourly: For frequently changing assignments (sales territories)
  • Daily: For more stable assignment structures
  • Weekly: For static organizational structures

Step 5: Error Handling and Monitoring

API Response Codes

Monitor for these key response codes:

  • 200 OK: User has rights to personal phonebook, operation successful
  • 404 Not Found: No user found with the specified email address
  • 403 Access Denied: User lacks rights to the phonebook
  • 401 Unauthorized: Invalid or expired access token

Logging and Monitoring

Implement comprehensive logging for:

  • Successful sync operations with contact counts
  • Failed API calls with error details
  • Access token refresh cycles
  • Data validation errors from source systems

Error Recovery Strategies

def sync_with_retry(self, user_email, contacts, max_retries=3):
    """Sync contacts with retry logic"""
    for attempt in range(max_retries):
        try:
            self.sync_user_contacts(user_email, contacts)
            return True
        except requests.exceptions.RequestException as e:
            if attempt == max_retries - 1:
                self.log_error(f"Failed to sync {user_email} after {max_retries} attempts: {e}")
                return False
            else:
                time.sleep(2 ** attempt)  # Exponential backoff
    return False

Step 6: Testing and Validation

Testing Checklist

  1. Authentication: Verify OAuth token generation and refresh
  2. Contact Creation: Test adding contacts to user phonebooks
  3. Contact Updates: Test modifying existing assigned contacts
  4. Contact Deletion: Test removing contacts from assignments
  5. Search Functionality: Verify contacts appear in Spoke app searches
  6. Access Controls: Confirm users only see their assigned contacts

Best Practices

Data Management

  • Use consistent external IDs from your source system for easy updates
  • Implement data validation before sending to Spoke API
  • Handle contact merging/deduplication in your source system
  • Maintain audit logs of contact assignment changes

Performance Optimization

  • Batch contact updates when possible
  • Implement incremental sync (only changed contacts)
  • Use connection pooling for high-volume operations
  • Cache access tokens and refresh proactively

Security Considerations

  • Store API credentials securely (environment variables, key management systems)
  • Use HTTPS for all API communications
  • Implement proper access controls on your sync processes
  • Regularly rotate API credentials

Business Process Integration

  • Sync contact assignments when user roles change
  • Remove contacts when users leave the organization
  • Update assignments when territories are restructured
  • Provide fallback mechanisms for sync failures

Troubleshooting Common Issues

"403 Access Denied" Errors

  • Verify the user exists in your Spoke account
  • Ensure the user's email address exactly matches their Spoke account email
  • Check that personal phonebooks are enabled for your account

Contact Not Appearing in Search

  • Verify managedBy is set to "system"
  • Confirm the contact was successfully added via API validation
  • Check that the user is searching the External directory in Spoke

Token Expiration Issues

  • Implement automatic token refresh logic
  • Monitor token expiration times
  • Have fallback authentication procedures

Performance Issues

  • Reduce batch sizes for contact updates
  • Implement rate limiting in your sync process
  • Use incremental sync strategies for large contact sets

Support and Resources

For additional help with your assigned contacts implementation:


This technical guide provides the foundation for implementing My Assigned Contacts via the Spoke API. Adapt the examples and processes to fit your specific business requirements and technical environment.

Was this article helpful?
0 out of 0 found this helpful