Skip to content

Contacts API

The Contacts API allows you to programmatically create, retrieve, update, and delete contacts in your TextFlow account.

All contact endpoints are available at:

https://textflow.telair.net/api/v1/contacts

All requests require API key authentication via the X-API-Key header:

Terminal window
curl -H "X-API-Key: sk_live_your_api_key_here" \
https://textflow.telair.net/api/v1/contacts

Retrieve a paginated list of contacts.

GET /v1/contacts
ParameterTypeDescription
pageintegerPage number (default: 1)
limitintegerResults per page, max 100 (default: 50)
searchstringSearch by name, phone, or email
tagsstringFilter by tags (comma-separated)
Terminal window
curl -X GET "https://textflow.telair.net/api/v1/contacts?page=1&limit=20&search=john" \
-H "X-API-Key: sk_live_your_api_key_here"
{
"success": true,
"data": [
{
"id": 123,
"uuid": "550e8400-e29b-41d4-a716-446655440000",
"phone_number": "+15551234567",
"first_name": "John",
"last_name": "Doe",
"email": "john@example.com",
"tags": ["customer", "vip"],
"custom_fields": {},
"consent_status": "explicit",
"is_opted_out": false,
"created_at": "2024-01-15T10:30:00Z",
"updated_at": "2024-01-15T10:30:00Z"
}
],
"pagination": {
"page": 1,
"limit": 20,
"total": 150,
"pages": 8
}
}

Retrieve a single contact by ID or UUID.

GET /v1/contacts/:id
Terminal window
curl -X GET "https://textflow.telair.net/api/v1/contacts/123" \
-H "X-API-Key: sk_live_your_api_key_here"

Or using UUID:

Terminal window
curl -X GET "https://textflow.telair.net/api/v1/contacts/550e8400-e29b-41d4-a716-446655440000" \
-H "X-API-Key: sk_live_your_api_key_here"
{
"success": true,
"data": {
"id": 123,
"uuid": "550e8400-e29b-41d4-a716-446655440000",
"phone_number": "+15551234567",
"first_name": "John",
"last_name": "Doe",
"email": "john@example.com",
"tags": ["customer", "vip"],
"custom_fields": {"company": "Acme Inc"},
"consent_status": "explicit",
"is_opted_out": false,
"created_at": "2024-01-15T10:30:00Z",
"updated_at": "2024-01-15T10:30:00Z"
}
}

Create a new contact.

POST /v1/contacts
FieldTypeRequiredDescription
phoneNumberstringYesPhone number (10 or 11 digits)
firstNamestringNoFirst name
lastNamestringNoLast name
emailstringNoEmail address
tagsarrayNoArray of tag strings
customFieldsobjectNoCustom field key-value pairs
consentStatusstringNo"explicit", "implicit", or "implied"
Terminal window
curl -X POST "https://textflow.telair.net/api/v1/contacts" \
-H "X-API-Key: sk_live_your_api_key_here" \
-H "Content-Type: application/json" \
-d '{
"phoneNumber": "+15551234567",
"firstName": "John",
"lastName": "Doe",
"email": "john@example.com",
"tags": ["customer", "newsletter"],
"customFields": {"company": "Acme Inc"},
"consentStatus": "explicit"
}'
{
"success": true,
"message": "Contact created successfully",
"data": {
"id": 124,
"uuid": "660e8400-e29b-41d4-a716-446655440001",
"phone_number": "+15551234567",
"first_name": "John",
"last_name": "Doe",
"email": "john@example.com",
"tags": ["customer", "newsletter"],
"custom_fields": {"company": "Acme Inc"},
"consent_status": "explicit",
"created_at": "2024-01-15T12:00:00Z",
"updated_at": "2024-01-15T12:00:00Z"
}
}

Update an existing contact.

PUT /v1/contacts/:id

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

FieldTypeDescription
phoneNumberstringPhone number (10 or 11 digits)
firstNamestringFirst name
lastNamestringLast name
emailstringEmail address
tagsarrayArray of tag strings (replaces existing)
customFieldsobjectCustom field key-value pairs (replaces existing)
consentStatusstring"explicit", "implicit", or "implied"
Terminal window
curl -X PUT "https://textflow.telair.net/api/v1/contacts/123" \
-H "X-API-Key: sk_live_your_api_key_here" \
-H "Content-Type: application/json" \
-d '{
"firstName": "Jonathan",
"tags": ["customer", "vip", "newsletter"]
}'
{
"success": true,
"message": "Contact updated successfully",
"data": {
"id": 123,
"uuid": "550e8400-e29b-41d4-a716-446655440000",
"phone_number": "+15551234567",
"first_name": "Jonathan",
"last_name": "Doe",
"email": "john@example.com",
"tags": ["customer", "vip", "newsletter"],
"custom_fields": {"company": "Acme Inc"},
"consent_status": "explicit",
"created_at": "2024-01-15T10:30:00Z",
"updated_at": "2024-01-15T14:00:00Z"
}
}

Delete a contact (soft delete).

DELETE /v1/contacts/:id
Terminal window
curl -X DELETE "https://textflow.telair.net/api/v1/contacts/123" \
-H "X-API-Key: sk_live_your_api_key_here"
{
"success": true,
"message": "Contact deleted successfully"
}

StatusErrorDescription
400Invalid phone number formatPhone must be 10 or 11 digits
401API key requiredMissing X-API-Key header
401Invalid or inactive API keyAPI key is invalid or revoked
403API access not enabledYour plan doesn’t include API access
403Contact limit reachedPlan contact limit exceeded
404Contact not foundContact doesn’t exist or was deleted
409Duplicate contactPhone number already exists
429Rate limit exceededToo many requests
{
"success": false,
"error": "Error message describing what went wrong",
"code": "ERROR_CODE"
}

import requests
API_KEY = "sk_live_your_api_key_here"
BASE_URL = "https://textflow.telair.net/api"
def create_contact(phone, first_name=None, last_name=None, email=None, tags=None):
"""Create a new contact"""
headers = {
"X-API-Key": API_KEY,
"Content-Type": "application/json"
}
payload = {"phoneNumber": phone}
if first_name:
payload["firstName"] = first_name
if last_name:
payload["lastName"] = last_name
if email:
payload["email"] = email
if tags:
payload["tags"] = tags
response = requests.post(f"{BASE_URL}/v1/contacts", json=payload, headers=headers)
return response.json()
def get_contacts(page=1, limit=50, search=None):
"""List contacts with pagination"""
headers = {"X-API-Key": API_KEY}
params = {"page": page, "limit": limit}
if search:
params["search"] = search
response = requests.get(f"{BASE_URL}/v1/contacts", params=params, headers=headers)
return response.json()
# Usage
result = create_contact("+15551234567", "John", "Doe", "john@example.com", ["customer"])
print(result)
contacts = get_contacts(search="john")
print(f"Found {contacts['pagination']['total']} contacts")
const axios = require('axios');
const API_KEY = 'sk_live_your_api_key_here';
const BASE_URL = 'https://textflow.telair.net/api';
async function createContact(phoneNumber, options = {}) {
const response = await axios.post(
`${BASE_URL}/v1/contacts`,
{ phoneNumber, ...options },
{ headers: { 'X-API-Key': API_KEY, 'Content-Type': 'application/json' } }
);
return response.data;
}
async function getContacts(params = {}) {
const response = await axios.get(`${BASE_URL}/v1/contacts`, {
params,
headers: { 'X-API-Key': API_KEY }
});
return response.data;
}
async function updateContact(id, updates) {
const response = await axios.put(
`${BASE_URL}/v1/contacts/${id}`,
updates,
{ headers: { 'X-API-Key': API_KEY, 'Content-Type': 'application/json' } }
);
return response.data;
}
// Usage
createContact('+15551234567', {
firstName: 'John',
lastName: 'Doe',
tags: ['customer']
}).then(result => console.log('Created:', result));
getContacts({ search: 'john', limit: 10 })
.then(result => console.log(`Found ${result.pagination.total} contacts`));
<?php
$apiKey = 'sk_live_your_api_key_here';
$baseUrl = 'https://textflow.telair.net/api';
function createContact($phoneNumber, $firstName = null, $lastName = null, $email = null, $tags = []) {
global $apiKey, $baseUrl;
$data = ['phoneNumber' => $phoneNumber];
if ($firstName) $data['firstName'] = $firstName;
if ($lastName) $data['lastName'] = $lastName;
if ($email) $data['email'] = $email;
if (!empty($tags)) $data['tags'] = $tags;
$options = [
'http' => [
'header' => [
"X-API-Key: $apiKey",
'Content-Type: application/json'
],
'method' => 'POST',
'content' => json_encode($data)
]
];
$context = stream_context_create($options);
$result = file_get_contents("$baseUrl/v1/contacts", false, $context);
return json_decode($result, true);
}
// Usage
$contact = createContact('+15551234567', 'John', 'Doe', 'john@example.com', ['customer']);
print_r($contact);
?>

Contact API requests share the same rate limits as other API endpoints:

PlanPer-Minute Limit
Starter100
Marketer300
EnterpriseCustom