Managing Phone Numbers
Learn how to provision, configure, and manage phone numbers for sending and receiving SMS/MMS messages through the Approved Contact API. This guide covers both P2P (Person-to-Person) and A2P (Application-to-Person) messaging scenarios.
Provisioning Phone Numbers
Before provisioning, you'll need to coordinate with Approved Contact support to identify available phone numbers in your desired area code or region. Once you have the phone numbers you want to provision, use the provision endpoint to activate them for SMS/MMS messaging.
Provision Types
- P2P (Person-to-Person): Lower throughput, suitable for conversational messaging, no campaign registration required
- A2P (Application-to-Person): Higher throughput, requires 10DLC campaign registration, suitable for marketing and notifications
Example: Provision a Phone Number
curl -X POST https://api.approvedcontact.com/api/v1/phone-numbers/provision \
-u "your-email@example.com:your-password" \
-H "Content-Type: application/json" \
-d '{
"action": "Provision",
"tenantId": "00000000-0000-0000-0000-000000000000",
"phoneNumbers": [
{
"number": "+14155551234",
"email": "support@example.com",
"description": "Customer Support Line",
"platformType": "TeamsIndividual",
"messagingFeature": {
"provisionType": "SMSMMS",
"provisionClass": "P2P"
},
"billingPlan": "P2P500"
}
]
}'
import requests
import base64
credentials = base64.b64encode(b'your-email@example.com:your-password').decode()
response = requests.post(
'https://api.approvedcontact.com/api/v1/phone-numbers/provision',
headers={'Authorization': f'Basic {credentials}'},
json={
'action': 'Provision',
'tenantId': '00000000-0000-0000-0000-000000000000',
'phoneNumbers': [
{
'number': '+14155551234',
'email': 'support@example.com',
'description': 'Customer Support Line',
'platformType': 'TeamsIndividual',
'messagingFeature': {
'provisionType': 'SMSMMS',
'provisionClass': 'P2P'
},
'billingPlan': 'P2P500'
}
]
}
)
result = response.json()
print(f"Order ID: {result['orderId']}")
print(f"Status: {result['status']}")
var client = new HttpClient();
var credentials = Convert.ToBase64String(
Encoding.ASCII.GetBytes("your-email@example.com:your-password"));
client.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("Basic", credentials);
var request = new
{
action = "Provision",
tenantId = "00000000-0000-0000-0000-000000000000",
phoneNumbers = new[]
{
new
{
number = "+14155551234",
email = "support@example.com",
description = "Customer Support Line",
platformType = "TeamsIndividual",
messagingFeature = new
{
provisionType = "SMSMMS",
provisionClass = "P2P"
},
billingPlan = "P2P500"
}
}
};
var response = await client.PostAsJsonAsync(
"https://api.approvedcontact.com/api/v1/phone-numbers/provision",
request
);
var result = await response.Content.ReadFromJsonAsync();
Console.WriteLine($"Order ID: {result.OrderId}");
const axios = require('axios');
const credentials = Buffer.from('your-email@example.com:your-password').toString('base64');
axios.post(
'https://api.approvedcontact.com/api/v1/phone-numbers/provision',
{
action: 'Provision',
tenantId: '00000000-0000-0000-0000-000000000000',
phoneNumbers: [
{
number: '+14155551234',
email: 'support@example.com',
description: 'Customer Support Line',
platformType: 'TeamsIndividual',
messagingFeature: {
provisionType: 'SMSMMS',
provisionClass: 'P2P'
},
billingPlan: 'P2P500'
}
]
},
{
headers: { 'Authorization': `Basic ${credentials}` }
}
)
.then(response => {
console.log(`Order ID: ${response.data.orderId}`);
console.log(`Status: ${response.data.status}`);
});
Provision Request Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
action |
enum | Yes | "Provision" or "Unprovision" |
tenantId |
GUID | Yes | Your tenant identifier |
phoneNumbers |
array | Yes | Array of phone number objects to provision |
Phone Number Object Fields
| Field | Type | Required | Description |
|---|---|---|---|
number |
string | Yes | Phone number in E.164 format |
email |
string | No | Email address for notifications |
description |
string | No | Description of the phone number |
domain |
string | No | Domain to assign (defaults to email domain) |
platformType |
enum | No | TeamsIndividual, TeamsChannel, WebexSpace, RingCentral, Zoom |
campaignId |
string | A2P only | 10DLC Campaign ID (required for A2P) |
brandId |
string | A2P only | 10DLC Brand ID (required for A2P) |
loaUrl |
string | No | LOA document URL (from POST /phone-numbers/loa) |
messagingFeature |
object | Yes | Provision type and class configuration |
billingPlan |
string | No | P2P250, P2P500, P2P1000, P2P2000, P2PPooled, A2P250, etc. |
settings |
object | No | Phone number settings (notifications, auto-response, etc.) |
MessagingFeature Object
| Field | Value | Description |
|---|---|---|
provisionType |
SMS, MMS, SMSMMS | Message types supported |
provisionClass |
P2P, A2P | Person-to-Person or Application-to-Person |
Tracking Order Status
After submitting a provisioning request, you can track its progress using the order ID.
Get Order Information
curl -X GET https://api.approvedcontact.com/api/v1/phone-numbers/orders/12345 \
-u "your-email@example.com:your-password"
Order Response
{
"orderId": 12345,
"status": "Completed",
"action": "Provision",
"tenantId": "00000000-0000-0000-0000-000000000000",
"provisionClass": "P2P",
"provisionType": "SMSMMS",
"createDate": "2025-01-11T10:00:00Z",
"completionDate": "2025-01-11T10:05:30Z",
"phoneNumbers": [
{
"number": "+14155551234",
"phoneNumberId": "550e8400-e29b-41d4-a716-446655440000",
"status": "Completed",
"email": "support@example.com"
}
]
}
Order Status Values
Pending- Order is queued for processingInProgress- Actively being processedCompleted- Successfully completedPartiallyComplete- Some numbers succeeded, some failedFailed- Order failed completely
Managing Phone Numbers
You can list, view details, and manage all your provisioned phone numbers through the API.
List Active Phone Numbers
curl -X GET "https://api.approvedcontact.com/api/v1/phone-numbers/active?page=1&limit=100" \
-u "your-email@example.com:your-password"
Get Phone Number Details
curl -X GET https://api.approvedcontact.com/api/v1/phone-numbers/%2B14155551234 \
-u "your-email@example.com:your-password"
Response Example
{
"phoneNumberId": "550e8400-e29b-41d4-a716-446655440000",
"phoneNumber": "+14155551234",
"friendlyName": "(415) 555-1234",
"email": "support@example.com",
"status": "Active",
"provisionType": "SMSMMS",
"provisionClass": "P2P",
"capabilities": {
"sms": true,
"mms": true
},
"createdAt": "2025-01-11T10:30:00Z",
"activatedAt": "2025-01-11T10:32:15Z"
}
Updating Phone Number Settings
After provisioning, you can update various settings for your phone number including user assignment, campaign/brand associations, billing plans, and comprehensive notification/messaging settings.
Update Phone Number
curl -X PUT https://api.approvedcontact.com/api/v1/phone-numbers/%2B14155551234 \
-u "your-email@example.com:your-password" \
-H "Content-Type: application/json" \
-d '{
"userId": "new-user@example.com",
"description": "Updated description",
"billingPlanName": "500",
"campaignId": "C67890",
"brandId": "B12345",
"isActivated": true,
"isMMSEnabled": true,
"settings": {
"notifications": {
"enableSound": true,
"microsoftTeams": {
"enabled": true
}
},
"autoResponse": {
"enabled": true,
"message": "Thanks for contacting us!",
"newThreadsOnly": true
},
"optOut": {
"enabled": true,
"text": "STOP",
"textResponse": "You have been unsubscribed"
}
}
}'
Updatable Fields
| Field | Type | Description |
|---|---|---|
userId |
string | User ID/email associated with the phone number |
platformType |
enum | TeamsIndividual, TeamsChannel, WebexSpace, RingCentral, Zoom |
description |
string | Description of the phone number |
externalId |
string | External ID for your own tracking |
campaignId |
string | 10DLC Campaign ID (for A2P numbers) |
brandId |
string | 10DLC Brand ID (for A2P numbers) |
loaUrl |
string | LOA document URL |
isActivated |
boolean | Whether the phone number is activated |
isMMSEnabled |
boolean | Whether MMS is enabled |
billingPlanName |
string | Plan name: "250", "500", "1000", "2000", "Pooled", "Volume Pricing" |
settings |
object | Comprehensive settings object (see below) |
Settings Object
The settings object supports extensive configuration options:
Notifications
{
"notifications": {
"enableSound": true,
"selectedSound": "chime.mp3",
"microsoftTeams": {
"enabled": true,
"notificationName": "SMS Notification"
},
"webex": {
"enabled": false
}
}
}
Auto-Response
{
"autoResponse": {
"enabled": true,
"message": "Thanks for your message! We'll respond soon.",
"newThreadsOnly": true
}
}
Opt-In/Opt-Out
{
"optIn": {
"enabled": true,
"name": "Marketing Updates",
"text": "START",
"message": "You are now opted in to receive marketing updates.",
"allText": "START ALL",
"allMessage": "You are opted in to all communications."
},
"optOut": {
"enabled": true,
"text": "STOP",
"textResponse": "You have been unsubscribed. Reply START to resubscribe.",
"allText": "STOP ALL",
"allTextResponse": "You've been removed from all lists.",
"periodicEnabled": true,
"periodicCron": "0 0 1 * *"
}
}
Auto-Forward
{
"autoForward": {
"enabled": true,
"emailAddresses": [
"support@example.com",
"manager@example.com"
]
}
}
Out of Office
{
"outOfOffice": {
"enabled": true,
"message": "We're currently out of office. We'll respond on Monday.",
"startDate": "2025-01-15T00:00:00Z",
"endDate": "2025-01-16T23:59:59Z"
}
}
Signature
{
"signature": {
"enabled": true,
"message": "\n\n--\nAcme Corp\nsupport@acme.com"
}
}
AI Settings
{
"aiSettings": {
"isEnabled": true,
"responseGenerationContext": "You are a helpful customer service agent for Acme Corp. Be friendly and professional."
}
}
Rate Limiting
{
"rateLimit": 2000,
"noOutboundTexts": false
}
Complete Update Example
{
"userId": "support@example.com",
"description": "Customer Support - Primary Line",
"campaignId": "C67890",
"brandId": "B12345",
"billingPlanName": "1000",
"isActivated": true,
"isMMSEnabled": true,
"settings": {
"notifications": {
"enableSound": true,
"microsoftTeams": {
"enabled": true,
"notificationName": "Support SMS"
}
},
"autoResponse": {
"enabled": true,
"message": "Thank you for contacting Acme support!",
"newThreadsOnly": true
},
"optOut": {
"enabled": true,
"text": "STOP",
"textResponse": "You have been unsubscribed.",
"periodicEnabled": true
},
"signature": {
"enabled": true,
"message": "\n--\nAcme Corp Support"
},
"rateLimit": 1000
}
}
Best Practices
Number Selection
- Choose local area codes to improve deliverability and trust
- Avoid "vanity" patterns that might be flagged as spam
- Consider toll-free numbers for customer support use cases
- Work with Approved Contact support to identify available numbers
P2P vs A2P
- Use P2P for: Two-way conversations, customer support, low-volume notifications
- Use A2P for: Marketing campaigns, high-volume alerts, one-way notifications
- A2P requires 10DLC registration but offers higher throughput
- P2P is faster to provision but has lower message limits
Webhook Configuration
- Configure webhooks at the tenant level to receive order status updates
- Validate webhook signatures using the shared secret
- Return 200-299 status codes promptly to avoid retries
- Implement idempotency to handle duplicate webhook deliveries
Monitoring
- Regularly check provisioning order status for pending numbers
- Monitor message delivery rates per phone number using the ratios endpoint
- Track opt-out rates to identify problematic messaging patterns
- Set up alerts for provisioning failures or unexpected status changes