V 2.0
Contact
Overview
The Contact API provides endpoints to manage contacts within the system. It enables operations such as adding, updating, and deleting contacts in contact lists.
Base Path
All Contact API endpoints are under: /api/v2/AddContactApi/
Key Features:
-
Contact Management:
- Add new contacts to contact lists
- Update existing contact information
- Soft delete contacts (mark as deleted)
- Hard delete contacts (permanently remove)
-
Authentication:
- Supports session-based authentication (SSID)
- Supports token-based authentication (userId + token)
- Permission-based access control (ADD_CONTACTS permission required)
-
Flexible Contact List IDs:
- Supports numeric contact list IDs
- Supports MongoDB ObjectId format for contact list IDs
-
Action Types:
- Action 0: Add new contact
- Action 1: Update existing contact
- Action 2: Soft delete contact (mark as deleted)
-
Response Format:
- Success responses include contact_id
- Operation status and message included
- Error codes for troubleshooting
Permissions Required:
-
ADD_CONTACTS- Required for all contact operations
Delete Contact
Endpoint
- Method: POST
-
Path:
v4-api.deepcall.com/api/v2/contact/deleteContact/
Description
The Delete Contact endpoint performs a hard delete operation, permanently removing contacts from the contact list. Unlike soft delete (action 2 in addContact), this operation cannot be undone.
Use Cases
- Permanently removing contacts from the system
- GDPR compliance - data deletion requests
- Cleaning up invalid or spam contacts
- Contact list maintenance
- Removing duplicate contacts
- Purging old or inactive contacts
Request Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| userId | string | Yes* | User ID for authentication (*required if ssid not provided) |
| token | string | Yes* | Authentication token (*required if ssid not provided) |
| ssid | string | Yes* | Session ID (*required if userId/token not provided) |
| clId | number/string | Yes | Contact List ID (numeric or MongoDB ObjectId) |
| delId | string | Yes | Contact ID to delete |
Request Examples
Example 1: Delete Contact with SSID
{
"ssid": "{{ssid}}",
"clId": 123,
"delId": "contact_12345"
}
Example 2: Delete Contact with Token Auth
{
"userId": "{{userid}}",
"token": "{{token}}",
"clId": 123,
"delId": "contact_12345"
}
Example 3: Delete Contact from MongoDB ObjectId List
{
"ssid": "{{ssid}}",
"clId": "507f1f77bcf86cd799439011",
"delId": "contact_67890"
}
Example 4: Delete Multiple Contacts (Sequential Calls)
{
"ssid": "{{ssid}}",
"clId": 123,
"delId": "contact_12345"
}
// Make separate calls for each contact to delete
Response Details
Success Response
Status Code: 200
{
"code": 200,
"status": "success",
"message": "Contact deleted successfully"
}
Response Field Descriptions
| Field | Type | Description |
|---|---|---|
| code | number | Response code (200 for success) |
| status | string | Response status ("success") |
| message | string | Success message |
Error Response Examples
Error 1: Contact Not Found
Status Code: 200
{
"status": "error",
"message": "No data found",
"code": 1012
}
Error 2: Invalid Contact List
Status Code: 200
{
"status": "error",
"message": "Invalid contact list",
"code": 1006
}
Error 3: Permission Denied
Status Code: 200
{
"status": "error",
"message": "Permission denied",
"code": 1015
}
Error 4: Missing Required Fields
Status Code: 200
{
"status": "error",
"message": "Please provide delId",
"code": 1022
}
Important Notes
⚠️ Warning: Hard Delete Operation
This endpoint performs a permanent deletion:
- Contact data is permanently removed from the database
- Operation cannot be undone or reversed
- All contact history and campaign data is lost
- Consider using soft delete (action 2 in addContact) for recoverable deletions
Best Practices
-
Backup Before Delete:
- Export contact data before permanent deletion
- Keep audit logs of deletion operations
-
Use Soft Delete When Possible:
- Use action 2 in addContact for recoverable deletions
- Hard delete only when absolutely necessary
-
Bulk Delete Operations:
- Implement rate limiting for bulk deletions
- Process deletions in batches to avoid timeouts
-
Validation:
- Verify contact ownership before deletion
- Confirm contact list permissions
- Check for active campaign usage
Validation Rules
-
Contact Validation:
- Contact must exist in the specified contact list
- Contact must belong to the authenticated user
- Contact list must be active
-
Permission Validation:
- User must have ADD_CONTACTS permission
- User must own the contact list
- Agent permissions checked if applicable
Delete Contact
var axios = require('axios');
var data = '{"ssid": "{{ssid}}","clId": 123,"delId": "contact_12345"}';
var config = {
method: 'post',
url: '{{brand}}/api/v2/AddContactApi/deleteContact',
headers: {
'Content-Length': ''
},
data : data
};
axios(config)
.then(function (response) {
console.log(JSON.stringify(response.data));
})
.catch(function (error) {
console.log(error);
});
setUrl('{{brand}}/api/v2/AddContactApi/deleteContact');
$request->setMethod(HTTP_Request2::METHOD_POST);
$request->setConfig(array(
'follow_redirects' => TRUE
));
$request->setHeader(array(
'Content-Length' => ''
));
$request->setBody('{"ssid": "{{ssid}}","clId": 123,"delId": "contact_12345"}');
try {
$response = $request->send();
if ($response->getStatus() == 200) {
echo $response->getBody();
}
else {
echo 'Unexpected HTTP status: ' . $response->getStatus() . ' ' .
$response->getReasonPhrase();
}
}
catch(HTTP_Request2_Exception $e) {
echo 'Error: ' . $e->getMessage();
}import http.client
conn = http.client.HTTPSConnection("{{brand}}")
payload = "{\"ssid\": \"{{ssid}}\",\"clId\": 123,\"delId\": \"contact_12345\"}"
headers = {
'Content-Length': ''
}
conn.request("POST", "/api/v2/AddContactApi/deleteContact", payload, headers)
res = conn.getresponse()
data = res.read()
print(data.decode("utf-8"))var client = new RestClient("{{brand}}/api/v2/AddContactApi/deleteContact");
client.Timeout = -1;
var request = new RestRequest(Method.POST);
var body = @"{" + "\n" +
@" ""ssid"": ""{{ssid}}""," + "\n" +
@" ""clId"": 123," + "\n" +
@" ""delId"": ""contact_12345""" + "\n" +
@"}";
request.AddParameter("text/plain", body, ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
Console.WriteLine(response.Content);curl --location -g --request POST '{{brand}}/api/v2/AddContactApi/deleteContact' \
--data-raw '{
"ssid": "{{ssid}}",
"clId": 123,
"delId": "contact_12345"
}'var request = http.Request('POST', Uri.parse('{{brand}}/api/v2/AddContactApi/deleteContact'));
request.body = '''{\n "ssid": "{{ssid}}",\n "clId": 123,\n "delId": "contact_12345"\n}''';
http.StreamedResponse response = await request.send();
if (response.statusCode == 200) {
print(await response.stream.bytesToString());
}
else {
print(response.reasonPhrase);
}
package main
import (
"fmt"
"strings"
"net/http"
"io/ioutil"
)
func main() {
url := "%7B%7Bbrand%7D%7D/api/v2/AddContactApi/deleteContact"
method := "POST"
payload := strings.NewReader(`{
"ssid": "{{ssid}}",
"clId": 123,
"delId": "contact_12345"
}`)
client := &http.Client {
}
req, err := http.NewRequest(method, url, payload)
if err != nil {
fmt.Println(err)
return
}
res, err := client.Do(req)
if err != nil {
fmt.Println(err)
return
}
defer res.Body.Close()
body, err := ioutil.ReadAll(res.Body)
if err != nil {
fmt.Println(err)
return
}
fmt.Println(string(body))
}POST /api/v2/AddContactApi/deleteContact HTTP/1.1
Host: {{brand}}
Content-Length: 67
{
"ssid": "{{ssid}}",
"clId": 123,
"delId": "contact_12345"
}OkHttpClient client = new OkHttpClient().newBuilder()
.build();
MediaType mediaType = MediaType.parse("text/plain");
RequestBody body = RequestBody.create(mediaType, "{\n \"ssid\": \"{{ssid}}\",\n \"clId\": 123,\n \"delId\": \"contact_12345\"\n}");
Request request = new Request.Builder()
.url("{{brand}}/api/v2/AddContactApi/deleteContact")
.method("POST", body)
.addHeader("Content-Length", "")
.build();
Response response = client.newCall(request).execute();var myHeaders = new Headers();
myHeaders.append("Content-Length", "");
var raw = "{\n \"ssid\": \"{{ssid}}\",\n \"clId\": 123,\n \"delId\": \"contact_12345\"\n}";
var requestOptions = {
method: 'POST',
headers: myHeaders,
body: raw,
redirect: 'follow'
};
fetch("{{brand}}/api/v2/AddContactApi/deleteContact", requestOptions)
.then(response => response.text())
.then(result => console.log(result))
.catch(error => console.log('error', error));CURL *curl;
CURLcode res;
curl = curl_easy_init();
if(curl) {
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "POST");
curl_easy_setopt(curl, CURLOPT_URL, "%7B%7Bbrand%7D%7D/api/v2/AddContactApi/deleteContact");
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
curl_easy_setopt(curl, CURLOPT_DEFAULT_PROTOCOL, "https");
struct curl_slist *headers = NULL;
headers = curl_slist_append(headers, "Content-Length: ");
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
const char *data = "{\n \"ssid\": \"{{ssid}}\",\n \"clId\": 123,\n \"delId\": \"contact_12345\"\n}";
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, data);
res = curl_easy_perform(curl);
}
curl_easy_cleanup(curl);
#import
dispatch_semaphore_t sema = dispatch_semaphore_create(0);
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"%7B%7Bbrand%7D%7D/api/v2/AddContactApi/deleteContact"]
cachePolicy:NSURLRequestUseProtocolCachePolicy
timeoutInterval:10.0];
NSDictionary *headers = @{
@"Content-Length": @""
};
[request setAllHTTPHeaderFields:headers];
NSData *postData = [[NSData alloc] initWithData:[@"{\n \"ssid\": \"{{ssid}}\",\n \"clId\": 123,\n \"delId\": \"contact_12345\"\n}" dataUsingEncoding:NSUTF8StringEncoding]];
[request setHTTPBody:postData];
[request setHTTPMethod:@"POST"];
NSURLSession *session = [NSURLSession sharedSession];
NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request
completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
if (error) {
NSLog(@"%@", error);
dispatch_semaphore_signal(sema);
} else {
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *) response;
NSError *parseError = nil;
NSDictionary *responseDictionary = [NSJSONSerialization JSONObjectWithData:data options:0 error:&parseError];
NSLog(@"%@",responseDictionary);
dispatch_semaphore_signal(sema);
}
}];
[dataTask resume];
dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER); open Lwt
open Cohttp
open Cohttp_lwt_unix
let postData = ref "{\n \"ssid\": \"{{ssid}}\",\n \"clId\": 123,\n \"delId\": \"contact_12345\"\n}";;
let reqBody =
let uri = Uri.of_string "%7B%7Bbrand%7D%7D/api/v2/AddContactApi/deleteContact" in
let headers = Header.init ()
|> fun h -> Header.add h "Content-Length" ""
in
let body = Cohttp_lwt.Body.of_string !postData in
Client.call ~headers ~body `POST uri >>= fun (_resp, body) ->
body |> Cohttp_lwt.Body.to_string >|= fun body -> body
let () =
let respBody = Lwt_main.run reqBody in
print_endline (respBody)$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
$headers.Add("Content-Length", "")
$body = "{`n `"ssid`": `"{{ssid}}`",`n `"clId`": 123,`n `"delId`": `"contact_12345`"`n}"
$response = Invoke-RestMethod '{{brand}}/api/v2/AddContactApi/deleteContact' -Method 'POST' -Headers $headers -Body $body
$response | ConvertTo-Jsonrequire "uri"
require "net/http"
url = URI("{{brand}}/api/v2/AddContactApi/deleteContact")
http = Net::HTTP.new(url.host, url.port);
request = Net::HTTP::Post.new(url)
request["Content-Length"] = ""
request.body = "{\n \"ssid\": \"{{ssid}}\",\n \"clId\": 123,\n \"delId\": \"contact_12345\"\n}"
response = http.request(request)
puts response.read_body
printf '{
"ssid": "{{ssid}}",
"clId": 123,
"delId": "contact_12345"
}'| http --follow --timeout 3600 POST '{{brand}}/api/v2/AddContactApi/deleteContact' \
Content-Length:import Foundation
#if canImport(FoundationNetworking)
import FoundationNetworking
#endif
var semaphore = DispatchSemaphore (value: 0)
let parameters = "{\n \"ssid\": \"{{ssid}}\",\n \"clId\": 123,\n \"delId\": \"contact_12345\"\n}"
let postData = parameters.data(using: .utf8)
var request = URLRequest(url: URL(string: "{{brand}}/api/v2/AddContactApi/deleteContact")!,timeoutInterval: Double.infinity)
request.addValue("", forHTTPHeaderField: "Content-Length")
request.httpMethod = "POST"
request.httpBody = postData
let task = URLSession.shared.dataTask(with: request) { data, response, error in
guard let data = data else {
print(String(describing: error))
semaphore.signal()
return
}
print(String(data: data, encoding: .utf8)!)
semaphore.signal()
}
task.resume()
semaphore.wait()
Example Response
[{"key":"Date"
"value":"Sun
23 Nov 2025 12:00:00 GMT"}
{"key":"Content-Type"
"value":"application\/json; charset=utf-8"}
{"key":"Connection"
"value":"keep-alive"}
{"key":"Access-Control-Allow-Origin"
"value":"*"}]
{
"message": "Contact deleted successfully",
"status": "success",
"code": 200
}