Python client for CloudContactAI API
Project description
CCAI Python Client
Version: 1.1.0
A Python client for interacting with the CloudContactAI API.
Installation
pip install ccai-python
Usage
SMS
from ccai_python import CCAI
# Initialize the client
ccai = CCAI(
client_id="YOUR-CLIENT-ID",
api_key="YOUR-API-KEY"
)
# Send a single SMS
response = ccai.sms.send_single(
first_name="John",
last_name="Doe",
phone="+15551234567",
message="Hello ${first_name}, this is a test message!",
title="Test Campaign"
)
print(f"Message sent with ID: {response.id}")
# Send to multiple recipients
accounts = [
{"first_name": "John", "last_name": "Doe", "phone": "+15551234567"},
{"first_name": "Jane", "last_name": "Smith", "phone": "+15559876543"}
]
campaign_response = ccai.sms.send(
accounts=accounts,
message="Hello ${first_name} ${last_name}, this is a test message!",
title="Bulk Test Campaign"
)
print(f"Campaign sent with ID: {campaign_response.campaign_id}")
MMS
from ccai_python import CCAI, Account, SMSOptions
# Initialize the client
ccai = CCAI(
client_id="YOUR-CLIENT-ID",
api_key="YOUR-API-KEY"
)
# Define a progress callback
def track_progress(status):
print(f"Progress: {status}")
# Create options with progress tracking
options = SMSOptions(
timeout=60,
retries=3,
on_progress=track_progress
)
# Complete MMS workflow (get URL, upload image, send MMS)
image_path = "path/to/your/image.jpg"
content_type = "image/jpeg"
# Define recipient
account = Account(
first_name="John",
last_name="Doe",
phone="+15551234567" # Use E.164 format
)
# Send MMS with image in one step
response = ccai.mms.send_with_image(
image_path=image_path,
content_type=content_type,
accounts=[account],
message="Hello ${first_name}, check out this image!",
title="MMS Campaign Example",
options=options
)
print(f"MMS sent! Campaign ID: {response.campaign_id}")
from ccai_python import CCAI, EmailAccount, EmailCampaign
from datetime import datetime, timedelta
# Initialize the client
ccai = CCAI(
client_id="YOUR-CLIENT-ID",
api_key="YOUR-API-KEY"
)
# Send a single email
response = ccai.email.send_single(
first_name="John",
last_name="Doe",
email="john@example.com",
subject="Welcome to Our Service",
message="<p>Hello John,</p><p>Thank you for signing up!</p>",
sender_email="noreply@yourcompany.com",
reply_email="support@yourcompany.com",
sender_name="Your Company",
title="Welcome Email"
)
print(f"Email sent with ID: {response.id}")
# Send email campaign to multiple recipients
accounts = [
EmailAccount(
first_name="John",
last_name="Doe",
email="john@example.com",
phone=""
),
EmailAccount(
first_name="Jane",
last_name="Smith",
email="jane@example.com",
phone=""
)
]
campaign = EmailCampaign(
subject="Monthly Newsletter",
title="July 2025 Newsletter",
message="<h1>Hello ${firstName}!</h1><p>Here's our monthly update...</p>",
sender_email="newsletter@yourcompany.com",
reply_email="support@yourcompany.com",
sender_name="Your Company Newsletter",
accounts=accounts
)
response = ccai.email.send_campaign(campaign)
print(f"Email campaign sent: {response}")
# Schedule an email for future delivery
tomorrow = datetime.now() + timedelta(days=1)
tomorrow = tomorrow.replace(hour=10, minute=0, second=0, microsecond=0)
scheduled_campaign = EmailCampaign(
subject="Scheduled Email",
title="Future Email",
message="<p>This email was scheduled in advance!</p>",
sender_email="scheduled@yourcompany.com",
reply_email="support@yourcompany.com",
sender_name="Your Company",
accounts=[accounts[0]],
scheduled_timestamp=tomorrow.isoformat(),
scheduled_timezone="America/New_York"
)
response = ccai.email.send_campaign(scheduled_campaign)
print(f"Email scheduled: {response}")
Contacts
from ccai_python import CCAI
# Initialize the client
ccai = CCAI(
client_id="YOUR-CLIENT-ID",
api_key="YOUR-API-KEY"
)
# Set do not text status using contact ID
response = ccai.contact.set_do_not_text(
do_not_text=True,
contact_id="your-contact-id"
)
print(f"Contact {response.contact_id} do not text set to {response.do_not_text}")
# Set do not text status using phone number
response = ccai.contact.set_do_not_text(
do_not_text=True,
phone="+15551234567"
)
print(f"Contact {response.contact_id} ({response.phone}) do not text set to {response.do_not_text}")
# Remove do not text status from a contact
response = ccai.contact.set_do_not_text(
do_not_text=False,
contact_id="your-contact-id"
)
print(f"Contact {response.contact_id} do not text removed: {response.do_not_text}")
Contact Validator
Validate email addresses and phone numbers.
Bulk endpoints accept up to 50 contacts per request and are processed server-side in chunks.
from ccai_python import CCAI
ccai = CCAI(
client_id="YOUR-CLIENT-ID",
api_key="YOUR-API-KEY"
)
# Validate a single email
email_result = ccai.contact_validator.validate_email("user@example.com")
print(email_result.status) # "valid" | "invalid" | "risky"
print(email_result.metadata.get("safe_to_send")) # True | False
# Validate multiple emails (up to 50, processed server-side in chunks)
bulk_emails = ccai.contact_validator.validate_emails(["user@example.com", "bad@invalid.xyz"])
print(bulk_emails.summary.model_dump()) # {"total": 2, "valid": 1, "invalid": 1, "risky": 0, "landline": 0}
# Validate a single phone number
phone_result = ccai.contact_validator.validate_phone("+15551234567", country_code="US")
print(phone_result.status) # "valid" | "invalid" | "landline"
print(phone_result.metadata.get("carrier_type")) # "mobile" | "landline" | "voip"
# Validate multiple phone numbers (up to 50, processed server-side in chunks)
bulk_phones = ccai.contact_validator.validate_phones([
{"phone": "+15551234567"},
{"phone": "+15559876543", "countryCode": "US"}
])
print(bulk_phones.summary.model_dump()) # {"total": 2, "valid": 1, "invalid": 0, "risky": 0, "landline": 1}
Webhooks
from ccai_python import CCAI, WebhookConfig, WebhookEventType
# Initialize the client
ccai = CCAI(
client_id="YOUR-CLIENT-ID",
api_key="YOUR-API-KEY"
)
# Example 1: Register a webhook with auto-generated secret
# If secret is not provided, the server will auto-generate one
config = WebhookConfig(
url="https://your-domain.com/api/ccai-webhook",
events=[WebhookEventType.MESSAGE_SENT, WebhookEventType.MESSAGE_RECEIVED]
# secret not provided - server will auto-generate and return it
)
webhook = ccai.webhook.register(config)
print(f"Webhook registered with ID: {webhook.id}")
print(f"Auto-generated Secret: {webhook.secretKey}")
# Example 2: Register a webhook with a custom secret
config_custom = WebhookConfig(
url="https://your-domain.com/api/ccai-webhook-v2",
events=[WebhookEventType.MESSAGE_SENT, WebhookEventType.MESSAGE_RECEIVED],
secret="your-custom-secret-key"
)
webhook_custom = ccai.webhook.register(config_custom)
print(f"Webhook with custom secret registered: {webhook_custom.id}")
# List all webhooks
webhooks = ccai.webhook.list()
print(f"Found {len(webhooks)} webhooks")
# Update a webhook
updated_webhook = ccai.webhook.update(webhook.id, {
"url": "https://your-domain.com/api/ccai-webhook-v3"
})
print(f"Webhook updated: {updated_webhook.url}")
# Delete a webhook
result = ccai.webhook.delete(webhook.id)
print(f"Webhook deleted: {result}")
# Verify webhook signature in your handler
def verify_and_handle_webhook(signature, client_id, event_hash, secret):
if ccai.webhook.verify_signature(signature, client_id, event_hash, secret):
print(f"Valid webhook signature verified")
else:
print("Invalid signature")
# Create a webhook handler for web frameworks
def handle_message_sent(event):
print(f"Message sent: {event.message} to {event.to}")
def handle_message_received(event):
print(f"Message received: {event.message} from {event.from_}")
handlers = {
'on_message_sent': handle_message_sent,
'on_message_received': handle_message_received
}
webhook_handler = ccai.webhook.create_handler(handlers)
# Use with Flask
from flask import Flask, request, jsonify
import json
app = Flask(__name__)
@app.route('/api/ccai-webhook', methods=['POST'])
def handle_webhook():
signature = request.headers.get('X-CCAI-Signature', '')
body = request.get_data(as_text=True)
secret = 'your-webhook-secret-key' # Use the secret from webhook registration
# Parse payload to get client_id and event_hash
payload = json.loads(body)
client_id = os.getenv('CCAI_CLIENT_ID')
event_hash = payload.get('eventHash', '')
# Verify signature
if not ccai.webhook.verify_signature(signature, client_id, event_hash, secret):
return jsonify({"error": "Invalid signature"}), 401
# Process webhook
result = webhook_handler(payload)
return jsonify(result)
Brands
Register and manage brands for TCR (The Campaign Registry) business verification.
from ccai_python import CCAI
ccai = CCAI(
client_id="YOUR-CLIENT-ID",
api_key="YOUR-API-KEY"
)
# Create a brand
brand = ccai.brands.create({
"legalCompanyName": "Collect.org Inc.",
"dba": "Collect",
"entityType": "NON_PROFIT",
"taxId": "123456789",
"taxIdCountry": "US",
"country": "US",
"verticalType": "NON_PROFIT",
"websiteUrl": "https://www.collect.org",
"street": "123 Main Street",
"city": "San Francisco",
"state": "CA",
"postalCode": "94105",
"contactFirstName": "Jane",
"contactLastName": "Doe",
"contactEmail": "jane@collect.org",
"contactPhone": "+14155551234",
})
print(f"Brand created with ID: {brand['id']}")
# Get a brand by ID
fetched = ccai.brands.get(brand["id"])
print(f"Website match score: {fetched.get('websiteMatchScore')}")
# List all brands for the account
brands = ccai.brands.list()
print(f"Found {len(brands)} brand(s)")
# Update a brand (partial update)
updated = ccai.brands.update(brand["id"], {
"street": "456 Oak Avenue",
"city": "Los Angeles",
})
# Delete a brand
ccai.brands.delete(brand["id"])
Entity Types
PRIVATE_PROFIT, PUBLIC_PROFIT, NON_PROFIT, GOVERNMENT, SOLE_PROPRIETOR
Note:
PUBLIC_PROFITentities requirestockSymbolandstockExchangefields.
Vertical Types
AUTOMOTIVE, AGRICULTURE, BANKING, COMMUNICATION, CONSTRUCTION, EDUCATION, ENERGY, ENTERTAINMENT, GOVERNMENT, HEALTHCARE, HOSPITALITY, INSURANCE, LEGAL, MANUFACTURING, NON_PROFIT, PROFESSIONAL, REAL_ESTATE, RETAIL, TECHNOLOGY, TRANSPORTATION
Campaigns
Register and manage campaigns for TCR (The Campaign Registry) carrier vetting. Each campaign must be linked to a verified brand.
from ccai_python import CCAI
ccai = CCAI(
client_id="YOUR-CLIENT-ID",
api_key="YOUR-API-KEY"
)
# Create a campaign
campaign = ccai.campaigns.create({
"brandId": 1,
"useCase": "MIXED",
"subUseCases": ["CUSTOMER_CARE", "TWO_FACTOR_AUTHENTICATION", "ACCOUNT_NOTIFICATION"],
"description": "Security codes and support messaging.",
"messageFlow": "Users opt-in via signup form at https://example.com/signup",
"hasEmbeddedLinks": True,
"hasEmbeddedPhone": False,
"isAgeGated": False,
"isDirectLending": False,
"optInKeywords": ["START"],
"optInMessage": "Welcome! Reply STOP to cancel.",
"optInProofUrl": "https://example.com/opt-in-proof.png",
"helpKeywords": ["HELP"],
"helpMessage": "For HELP email support@example.com.",
"optOutKeywords": ["STOP"],
"optOutMessage": "STOP received. You are unsubscribed.",
"sampleMessages": [
"Your code is 554321. Reply STOP to cancel.",
"Your ticket has been updated. Reply HELP for info."
]
})
print(f"Campaign created with ID: {campaign['id']}")
# Get a campaign by ID
fetched = ccai.campaigns.get(campaign["id"])
# List all campaigns for the account
campaigns = ccai.campaigns.list()
print(f"Found {len(campaigns)} campaign(s)")
# Update a campaign (partial update)
updated = ccai.campaigns.update(campaign["id"], {
"description": "Updated description."
})
# Delete a campaign
ccai.campaigns.delete(campaign["id"])
Use Cases
TWO_FACTOR_AUTHENTICATION, ACCOUNT_NOTIFICATION, CUSTOMER_CARE, DELIVERY_NOTIFICATION, FRAUD_ALERT, HIGHER_EDUCATION, LOW_VOLUME_MIXED, MARKETING, MIXED, POLLING_VOTING, PUBLIC_SERVICE_ANNOUNCEMENT, SECURITY_ALERT
Note:
MIXEDandLOW_VOLUME_MIXEDcampaigns require 2–3subUseCases.
Sub-Use Cases
TWO_FACTOR_AUTHENTICATION, ACCOUNT_NOTIFICATION, CUSTOMER_CARE, DELIVERY_NOTIFICATION, FRAUD_ALERT, MARKETING, POLLING_VOTING
Features
- Send SMS messages to single or multiple recipients
- Send MMS messages with images
- Send Email campaigns with HTML content
- Schedule emails for future delivery
- Brand registration and management for TCR verification
- Campaign registration and management for TCR carrier vetting
- Webhook management (register, update, list, delete)
- Webhook event handling for web frameworks
- Validate email addresses (valid/invalid/risky) and phone numbers (valid/invalid/landline)
- Upload images to S3 with signed URLs
- Variable substitution in messages
- Progress tracking callbacks
- Type hints for better IDE integration
- Comprehensive error handling
Requirements
- Python 3.10 or higher
requestslibrarypydanticlibrary
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file ccai_python-1.1.0.tar.gz.
File metadata
- Download URL: ccai_python-1.1.0.tar.gz
- Upload date:
- Size: 32.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
dbf06af2fed327e8a82e438cdce75a0c21c7fa14fa09dcf2505a0316b0a6bffe
|
|
| MD5 |
0435e8d8a9f8c3913f7ad45113a7795c
|
|
| BLAKE2b-256 |
e3ea7a3745210babc209e713bfe96872e0b4b22c05b8285eda2ddf394ec9e354
|
File details
Details for the file ccai_python-1.1.0-py3-none-any.whl.
File metadata
- Download URL: ccai_python-1.1.0-py3-none-any.whl
- Upload date:
- Size: 29.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7b32fd512355825f4cce59f31cf04ea3222754b721fd37f5aed437fba2d691b2
|
|
| MD5 |
c5feb21988996eb8bff7b55e8221f56d
|
|
| BLAKE2b-256 |
974c8bb8932dc276e201ce7c0f26a9889de4d13791e1eb5b36b9c59d4d2a64b6
|