Getting Started
Welcome to Squadvoice API! SquadVoice provides businesses with an omni-channel outreach engine + distributed team of expert calling reps. Our platform qualifies your Leads faster and provides more sales opportunities. You can use this API to access our API endpoints such as Leads API to add Leads to your campaigns or Response API to know status of your leads.
Authentication
Get Access Token
import requests
url = "https://api.squadstack.com/oauth/token/"
payload = {
"grant_type": "password",
"client_id": "test_client_id",
"client_secret": "test_client_secret",
"username": "test_api_user",
"password": "test_api_user"
}
response = requests.post(url, payload)
response.json()
curl -X POST -d \
"client_id=test_client_id&client_secret=test_client_secret
&grant_type=password&username=test_api_user
&password=test_api_user" \https://api.squadstack.com/oauth/token/
The above script returns JSON structured like this:
{
"access_token": "OBs8bc5PdrzQNd3FaMRp5CkHFhinD9",
"token_type": "Bearer",
"expires_in": 36000,
"refresh_token": "tEonECLhjMlLf4ZWs56LT43HOrivEt",
"scope": "read write"
}
All the API requests to SQUAD are authenticated via Bearer
auth.
Use this API to generate an access token that can be used for authentication in subsequent API requests.
HTTP Request
POST https://api.squadstack.com/oauth/token/
Request Content-Type
application/x-www-form-urlencoded
Body Parameters
Parameter | Required | Description |
---|---|---|
client_id |
True | Client Identifier |
client_secret |
True | Client Secret |
grant_type |
True | "password" is the grant_type that should be sent initially |
username |
True | Username related to the client_id |
password |
True | Password for the above username |
Response Content-Type
application/json
Response Format
Parameter | Description |
---|---|
access_token |
Access token to be used to authenticate every request. |
refresh_token |
Refresh token to be used to get a refreshed access token. |
token_type |
Bearer |
expires_in |
Seconds after which the access token will expire. Once the access token has expired, you'll need the refresh_token to get a new access token. |
scope |
Scopes granted for the access token |
How to get the credentials
They can be found by signing up on SquadVoice's Client Dashboard.
client_id
and client_secret
can be found on the API Integration Page on the dashboard.
Refresh Access Token
import requests
url = "https://api.squadstack.com/oauth/token/"
payload = {
"grant_type": "refresh_token",
"client_id": "test_client_id",
"client_secret": "test_client_secret",
"refresh_token": "refresh_token_value",
}
response = requests.post(url, payload)
response.json()
curl -X POST -d \
"client_id=test_client_id&client_secret=test_client_secret
&grant_type=refresh_token&refresh_token=refresh_token_value" \https://api.squadstack.com/oauth/token/
The above script returns JSON structured like this:
{
"access_token": "OBs8bc5PdrzQNd3FaMRp5CkHFhinD9",
"token_type": "Bearer",
"expires_in": 36000,
"refresh_token": "tEonECLhjMlLf4ZWs56LT43HOrivEt",
"scope": "read write"
}
Use this API to refresh the access token.
HTTP Request
POST https://api.squadstack.com/oauth/token/
Request Content-Type
application/x-www-form-urlencoded
Request Body Parameters
Parameter | Required | Description |
---|---|---|
client_id |
True | Client Identifier |
client_secret |
True | Client Secret |
grant_type |
True | refresh_token is the grant_type at this stage. |
refresh_token |
True | Refresh token that we got in the response for the get access token. |
Response Content-Type
application/json
Response Format
Parameter | Description |
---|---|
access_token |
New access token to be used to authenticate every request. |
refresh_token |
New refresh token to be used to get a refreshed access token. |
token_type |
Bearer |
expires_in |
Seconds after which the access token will expire. Once the access token has expired, you'll need the refresh_token to get a new access token. |
scope |
Scopes granted for the access token |
Revoke the Access Token
import requests
url = "https://api.squadstack.com/oauth/revoke_token/"
payload = {
"client_id": "test_client_id",
"client_secret": "test_client_secret",
"token": "your_access_token",
}
response = requests.post(url, payload)
response.json()
curl -X POST -d \
"client_id=test_client_id&client_secret=test_client_secret
&token=your_access_token" \https://api.squadstack.com/oauth/revoke_token/
Use this API to revoke the access token.
HTTP Request
POST https://api.squadstack.com/oauth/revoke_token/
Request Content-Type
application/x-www-form-urlencoded
Request Body Parameters
Parameter | Required | Description |
---|---|---|
client_id |
True | Client Identifier |
client_secret |
True | Client Secret |
token |
True | Token that we want to refresh |
Response Content-Type
text/html; charset=utf-8
Leads
Create a Lead
import requests
import json
url = "https://api.squadstack.com/api/v1/leads/create/{campaign_id}/"
payload = [
{
"lead_id": 1,
"phone_number": "{valid phone number}",
"contact_name": "John Doe"
"{custom_field_1}": "{custom_value}",
"{custom_field_2}": "{custom_value}"
},
{
"lead_id": 2,
"phone_number": "{valid phone number}",
"contact_name": "John Smith"
"{custom_field_1}": "{custom_value}",
"{custom_field_2}": "{custom_value}"
}
]
headers = {
"Authorization": "Bearer test_token",
"Content-Type": "application/json"
}
response = requests.post(url, json.dumps(payload), headers=headers)
response.json()
curl 'https://api.squadstack.com/api/v1/leads/create/{campaign_id}/' \
-H 'Authorization: Bearer test_token' \
-H 'Content-Type: application/json' \
--data-binary $'{"lead_id": 1, "phone_number": "{valid phone number}", \
"contact_name": "John Doe", "{custom_field_1}": "{custom_value}", "{custom_field_2}": "{custom_value}"}'
Use this API to create a new Lead in your Squadvoice Campaign.
HTTP Request
POST https://api.squadstack.com/api/v1/leads/create/{campaign_id}/
Headers
Parameter | Value |
---|---|
Content-Type | "application/json" |
Authorization | "Bearer {access_token}" |
Path Parameters
Parameter | Required | Description |
---|---|---|
campaign_id | True | The ID of the Campaign |
Body Parameters
Parameter | Required | Description |
---|---|---|
lead_id | True | Unique Identifier of the Lead |
phone_number | True | Valid phone number of the Lead |
contact_name | True | Name of the Lead being contacted |
state_code | True | Two letter State Code |
ebr_datetime | False | EBR Datetime for the Lead |
custom_field | True | Any key value pair other than this |
Get Leads
import requests
url = "https://api.squadstack.com/api/v1/leads/responses/{campaign_id}/?page_size=1"
headers = {"Authorization": "Bearer test_token"}
params = {
"min_called_at": 1479973282000,
"lead_id": 8
}
response = requests.get(url, params=params, headers=headers)
response.json()
curl
-H "Authorization: Bearer test_token"
-X GET "https://api.squadstack.com/api/v1/leads/responses/{campaign_id}/?page_size=1"
The above command returns JSON structured like this:
{
"count": 1,
"next": "http://api.squadstack.com/api/v1/leads/responses/{campaign_id}/?page=2&page_size=1",
"previous": null,
"results": [
{
"lead_id": 10,
"phone_number": "919899550412",
"contact_number": "919899550412",
"created_at": 1531409739413,
"campaign_id": "0PT711",
"country_code": "IN",
"campaign_name": "{Name of the Campaign}",
"contact_name": "John Doe",
"call_attempt_keys": [],
"last_call_attempt_keys": []
}
]
}
Use this API to get information about a Lead/Leads.
HTTP Request
GET https://api.squadstack.com/api/v1/leads/responses/{campaign_id}/
Headers
Parameter | Value |
---|---|
Content-Type | "application/json" |
Authorization | "Bearer {access_token}" |
Path Parameters
Parameter | Required | Description |
---|---|---|
campaign_id | True | The ID of the Campaign |
Query Parameters
Parameter | Required | Default | Description |
---|---|---|---|
lead_id | False | - | Unique Identifier of the Lead |
processed_after | False | - | Epoch timestamp |
processed_before | False | - | Epoch timestamp |
page | False | - | Page number to return |
page_size | False | 100 | Number of leads to return per page |
Response Structure
The response you will get is a combination of some fixed keys and some dynamic keys based on the custom fields that you sent while creating the Lead, the stage at which the Lead is and how you have set up your campaign.
Fixed Keys
Key | Description |
---|---|
lead_id | Unique Identifier of the Lead |
phone_number | Phone number of the Lead |
contact_name | Name of the Lead |
created_at | Epoch timestamp |
campaign_id | Campaign ID which you sent in the URL too |
campaign_name | Name of the Campaign |
country_code | Country Code |
state_code | Two letter State Code |
call_attempt_keys | List of keys that contain the answers of Call Attempts |
last_call_attempt_keys | List of keys that contain the answer of the last call attempt |
total_cost | Cost of processing the Lead |
Extra keys if the Lead is Processed
Key | Description |
---|---|
processed_at | Epoch timestamp for when the Lead was processed |
outcome_name | Phone number of the Lead |
outcome_id | Name of the Lead |
Disable a Lead
import requests
import json
url = "https://api.squadstack.com/api/v1/leads/disable/{campaign_id}/"
payload = [
{"lead_id": 1},
{"lead_id": 2}
]
headers = {
"Authorization": "Bearer test_token",
"Content-Type": "application/json"
}
response = requests.post(url, json.dumps(payload), headers=headers)
response.json()
curl 'https://api.squadstack.com/api/v1/leads/disable/{campaign_id}/' \
-H 'Authorization: Bearer test_token' \
-H 'Content-Type: application/json' \
--data-binary $'{"lead_id": 1}'
Use this API to disable a Lead in your Squadvoice Campaign.
HTTP Request
POST https://api.squadstack.com/api/v1/leads/disable/{campaign_id}/
Headers
Parameter | Value |
---|---|
Content-Type | "application/json" |
Authorization | "Bearer {access_token}" |
Path Parameters
Parameter | Required | Description |
---|---|---|
campaign_id | True | The ID of the Campaign |
Body Parameters
Parameter | Required | Description |
---|---|---|
lead_id | True | Unique Identifier of the Lead |
Response Formats
SquadVoice's extensive API response sends each and every data point related to your campaign. That means, if an Email was sent out to the Lead, the API response will contain the information about the Email sent as well.
Some variables used in the keys
are:
- campaign_name: This is the name you set while creating the Campaign.
- block_name: This is the name of the block you define in your sequence.
Following are the different formats for each outreach type.
Call Attempt
"call_attempt_{campaign_name}_1": [
{
"reference_id": "H8Y4RMP1",
"outcome_id": 21,
"outcome_name": "Wrong Number",
"call_duration": 91,
"called_at": 1531241588351,
"report_keys_order": [
"status",
"additional_notes",
"question_1",
"question_n"
],
"status": "review_completed",
"question_1": "answer 1",
"additional_notes": "Ex boyfriend's number.",
"question_n": "answer n"
}
]
"last_call_attempt_{campaign_name}_1": {
"reference_id": "H8Y4RMP1",
"outcome_id": 21,
"outcome_name": "Wrong Number",
"call_duration": 91,
"called_at": 1531241588351,
"report_keys_order": [
"status",
"additional_notes",
"question_1",
"question_n"
],
"status": "review_completed",
"question_1": "answer 1",
"additional_notes": "Ex boyfriend's number.",
"question_n": "answer n"
}
A Call Attempt is made when you add a script etc. to the Campaign.
It adds the following keys
to the json
response:
- call_attempt_{campaign_name}_1: Since for each Lead, we might make multiple attempts, we add each attempt to a list.
- last_call_attempt_{campaign_name}_1: Also, to make it easy to consume without writing code, we send out the answers for the last call attempt that was made for that lead also separately in this key.
Response Format
Key | Description |
---|---|
reference_id | Unique Identifier of the Call Attempt |
outcome_id | ID of the outcome of the Call Attempt |
outcome_name | Name of the outcome |
call_duration | Duration of the Call |
called_at | Epoch timestamp |
report_keys_order | List of keys in order of which they were asked by the Lead |
question_1 | answer 1 (these are based on the script that you created) |
Gmail
"gmail_{block_name}": {
"cost": "PENDING OR NOT AVAILABLE",
"google_email": "owlcity@gmail.com",
"subject": "Owl City Subject",
"to": "fireflies@gmail.com",
"from": "owlcity@gmail.com",
"sent_at": 1531241588351
}
It adds the following keys
to the json
response:
- gmail_{block_name}
Response Format
Key | Description |
---|---|
cost | Cost for the operation |
google_email | Email ID from which the email was sent |
subject | Subject of the Email |
to | Email ID of the recipient |
from | Email ID of the Sender |
sent_at | Epoch timestamp of when the operation was performed |
IVR
"ivr_{block_name}": {
"status": "PENDING OR NOT AVAILABLE",
"cost": "PENDING OR NOT AVAILABLE",
"text_to_speak": "Test Test",
"multi_text_to_speak": {"owlcity": "fireflies"},
"dtmf_response": "1",
"duration": null,
"sent_at": 1531241588351
}
It adds the following keys
to the json
response:
- ivr_{block_name}
Response Format
Key | Description |
---|---|
cost | Cost for the operation |
status | Status of the operation |
text_to_speak | Text that was spoken |
multi_text_to_speak | Multiple text that was spoken |
dtmf_response | Response by the Lead, if any |
duration | Number of seconds for which the IVR was played |
sent_at | Epoch timestamp of when the operation was performed |
SMS
"sms_{block_name}": {
"status": "PENDING OR NOT AVAILABLE",
"cost": "PENDING OR NOT AVAILABLE",
"body": "Test Test",
"sent_at": 1531241588351
}
It adds the following keys
to the json
response:
- sms_{block_name}
Response Format
Key | Description |
---|---|
cost | Cost for the operation |
status | Status of the operation |
body | Body of the SMS |
sent_at | Epoch timestamp of when the operation was performed |
Status and Errors
The SquadStack API uses the following error codes:
Error Code | Meaning |
---|---|
400 | Bad Request -- Your request is invalid. |
401 | Unauthorized -- Authentication failed. API credentials are incorrect. |
403 | Forbidden -- You do not have permission to perform this action. |
404 | Not Found |
405 | Method Not Allowed -- You tried to access an endpoing with an invalid method. |
429 | Too Many Requests -- You hit a rate limit! |
500 | Internal Server Error -- We had a problem with our server. Try again later. |
503 | Service Unavailable -- We're temporarily offline for maintenance. Please try again later. |