Introduction
API Endpoint
https://api.persistiq.com
Welcome to the PersistIQ API!
Authentication
Example Request
curl "https://api.persistiq.com/v1/leads" \
-H "x-api-key: YOUR_API_KEY"
Make sure to replace
YOUR_API_KEY
with your actual API key.
Your API key grants access to read and write into your account database. Be sure to guard it like a password. This API key is a company wide key. It grants access all users’ data within the company.
Authenticate to the API by including the API key in the header of every request.
x-api-key: YOUR_API_KEY
Users
List all users
curl "https://api.persistiq.com/v1/users" \
-H "x-api-key: YOUR_API_KEY" \
The above curl request returns the following JSON
{
"status": "success",
"errors": [],
"users": [
{
"id": "u_q3e537",
"name": "Tiana Eichmann MD",
"email": "[email protected]",
"activated": true,
"default_mailbox_id": "mbox_...",
"salesforce_id": null
},
{
"id": "u_2ljD34",
"name": "Brendan Reichert",
"email": "[email protected]",
"activated": true,
"default_mailbox_id": "mbox_...",
"salesforce_id": null
},
{
"id": "u_M3kXp2",
"name": "Chester Lind",
"email": "[email protected]",
"activated": false,
"default_mailbox_id": "mbox_...",
"salesforce_id": null
}
]}
This endpoint retrieves all non-archived users in your company.
HTTP Request
GET https://api.persistiq.com/v1/users
Leads
List leads
curl "https://api.persistiq.com/v1/leads" \
-H "x-api-key: YOUR_API_KEY" \
The above curl request returns the following JSON
{
"status": "success",
"errors": [],
"has_more": true,
"next_page": "https://....",
"leads": [
{
"id": "l_abc001",
"status": "replied",
"data": {
"company_name": "Test Inc",
"email": "[email protected]",
"first_name": "bob",
"last_name": null,
"address": null,
"city": null,
"state": null,
"phone": null,
"title": null,
"industry": null,
"snippet": null,
"snippet2": null,
"snippet3": null,
"snippet4": null
}
},
{
"id": "l_jfkaaf",
"status": "active",
"data": {
"company_name": "Mo Coffee",
"email": "[email protected]",
"first_name": "Joe",
"last_name": null,
"address": null,
"city": null,
"state": null,
"phone": null,
"title": "Chief Barista",
"industry": null,
"snippet": null,
"snippet2": null,
"snippet3": null,
"snippet4": null
}
}
]
}
Each response contains maximum of 100 leads. If there are more leads, has_more
will be true
, and next_page
will contain the url to retrieve the next 100.
Query Parameters
Parameter | Example | Description | |
---|---|---|---|
status | optional | "active" |
Filters leads by status name |
updated_after | optional | "2017-10-17T07:37:00-07:00" |
Gets leads after specified time |
HTTP Request
GET https://api.persistiq.com/v1/leads
View a single lead
curl "https://api.persistiq.com/v1/leads/l_1abc" \
-H "x-api-key: YOUR_API_KEY" \
The above curl request returns the following JSON
{
"status": "success",
"errors": null,
"leads": [
{
"id": "l_1abc",
"status": "replied",
"data": {
"company_name": "Test Inc",
"email": "[email protected]",
"first_name": "bob",
"last_name": null,
"address": null,
"city": null,
"state": null,
"phone": null,
"title": null,
"industry": null,
"snippet": null,
"snippet2": null,
"snippet3": null,
"snippet4": null
}
}
]
}
This endpoint retrieves a single lead.
HTTP Request
GET https://api.persistiq.com/v1/leads/:lead_id
Create leads
curl "https://api.persistiq.com/v1/leads" \
-H "x-api-key: YOUR_API_KEY" \
-d '{
"dup" : "update",
"leads" : [
{
"email" : "[email protected]",
"first_name":"Ivan"
},
{
"email": "",
}
]
}'
The above command returns the following JSON
{
"status": "error",
"errors": [
{
"reason": "invalid_request",
"message": "Email can't be blank",
"lead": {
"id": null,
"status": "active",
"data": {
"email": ""
}
}
}
],
"leads": [
{
"id": "l_2lj1Dp",
"status": "active",
"data": {
"company_name": null,
"email": "[email protected]",
"first_name": "Ivan",
"last_name": null,
"address": null,
"city": null,
"state": null,
"phone": null,
"title": null,
"industry": null,
"snippet": null,
"snippet2": null,
"snippet3": null,
"snippet4": null
}
}
]
}
This endpoint creates leads, up to 10 at a time. If you have more than 10 leads, you can call this end point sequentially until all your leads have been created.
If another lead with the same email already exists (a duplicate), you can choose to update the existing lead in the system via dup = 'update'
or dup = 'skip'
to skip it.
If creator_id
is specified, then all newly created leads will have that user as creator. List of company user ids can be obtained by using the /users
end point. If the lead already exists in the system, the creator_id in the request will be ignored.
HTTP Request
POST https://api.persistiq.com/v1/leads
Arguments
Parameter | Description |
---|---|
dup | optional, skip or update , Default is skip |
creator_id | optional, id of the user who is creating the lead, use the user api end point to get a list of valid user ids |
leads | required, array of leads in json format |
json format for a lead
Parameter | Description |
---|---|
required | |
first_name | optional |
last_name | optional |
address | optional |
city | optional |
state | optional |
company_name | optional |
industry | optional |
title | optional |
phone | optional |
snippet | optional |
Update a lead
curl "https://api.persistiq.com/v1/leads/l_1abc" \
-X PUT \
-H "Content-Type: application/json" \
-H "x-api-key: YOUR_API_KEY" \
-d '{
"bounced": true,
"status": "bounced",
"data": {
"email": "[email protected]",
"title": ""
}
}'
The above command returns the following JSON
{
"status": "success",
"error": null,
"lead": {
"id": "l_1abc",
"status": "bounced",
"bounced": "true",
"data": {
"first_name": "Bob",
"last_name": "Smith",
"company_name": "Test Inc",
"email": "[email protected]",
"address": null,
"city": null,
"state": null,
"phone": null,
"title": null,
"industry": null,
"snippet": null,
"snippet2": null,
"snippet3": null,
"snippet4": null
}
}
}
This endpoint updates a single lead. If status
or status_id
are specified, it changes the lead’s status.
The data hash can be used to set custom and built-in lead attributes.
HTTP Request
PUT https://api.persistiq.com/v1/leads
or
PATCH https://api.persistiq.com/v1/leads
Arguments
Parameter | Description |
---|---|
status | optional, name of lead status |
status_id | optional, id of lead status |
bounced | optional, sets the lead as bounced |
optedout | optional, sets the lead as optedout |
data | optional, hash containing the data attributes of a lead |
Lead Statuses
List all lead statuses
curl "https://api.persistiq.com/v1/lead_statuses" \
-H "x-api-key: YOUR_API_KEY"
The above curl request returns the following JSON
{
"status": "success",
"errors": [],
"lead_statuses": [
{
"id": "lss_3kJ5MN",
"name": "engaged"
},
{
"id": "lss_lj4YX3",
"name": "working"
},
{
"id": "lss_N60GGp",
"name": "unresponsive"
}
]
}
This endpoint retrieves all lead statuses for your company.
HTTP Request
GET https://api.persistiq.com/v1/lead_statuses
Lead Fields
List all lead fields
curl "https://api.persistiq.com/v1/lead_fields" \
-H "x-api-key: YOUR_API_KEY"
The above curl request returns the following JSON
{
"status": "success",
"errors": [],
"lead_fields": [
{
"id": "lcf_3kJ5MN",
"name": "email",
"label": "email"
},
{
"id": "lcf_lj4YX3",
"name": "snippet",
"label": "snippet"
}
]
}
This endpoint retrieves all lead fields for your company.
HTTP Request
GET https://api.persistiq.com/v1/lead_fields
Campaigns
List campaigns
curl "https://api.persistiq.com/v1/campaigns" \
-H "x-api-key: YOUR_API_KEY"
The above command returns the following JSON
{
"status": "success",
"errors": [],
"has_more": true,
"next_page": "https://...",
"campaigns": [
{
"id": "c_9N9GpR",
"name": "Estevan Crooks",
"creator": {
"id": "u_q3e537",
"name": "Tiana Eichmann MD",
"email": "[email protected]"
},
"stats": {
"prospects_contacted": 5,
"prospects_reached": 17,
"prospects_opened": 9,
"prospects_replied": 5,
"prospects_bounced": 0,
"prospects_optedout": 0
}
},
{
"id": "c_9lWrpz",
"name": "Barley Corn",
"creator": {
"id": "u_2ljD34",
"name": "Brendan Reichert",
"email": "[email protected]"
},
"stats": {
"prospects_contacted": 0,
"prospects_reached": 0,
"prospects_opened": 0,
"prospects_replied": 0,
"prospects_bounced": 0,
"prospects_optedout": 0
}
}
]
}
Each response contains maximum of 100 campaigns. If there are more campaigns, has_more
will be true
, and next_page
will contain the url to retrieve the next 100.
Query Parameters
Parameter | Default | Required | Description |
---|---|---|---|
lead_id | false |
Campaigns which the lead belongs to | |
owner_id | false |
Campaigns with owner that has specified ID | |
name | false |
Campaigns with specified name |
HTTP Request
GET https://api.persistiq.com/v1/campaigns
Add lead to a campaign
curl "https://api.persistiq.com/v1/campaigns/c_9lWrpz/leads" \
-H "x-api-key: YOUR_API_KEY" \
-d '{
"mailbox_id": "mbox_W3rR3m",
"leads" : [
{ "id" : "l_9N2XDp" },
{ "id" : "l_9N2XDp" }
]
}'
The above command will add leads to a campaign, and respond with the following JSON
{
"status": "error",
"errors": [
{
"reason": "invalid_request",
"message": "Lead has already been taken",
"campaign_lead": {
"id": null,
"campaign_id": "c_9lWrpz",
"mailbox_id": "mbox_W3rR3m",
"lead": {
"id": "l_9N2XDp",
"...": "..."
}
}
}
],
"campaign_leads": [
{
"id": "cl_...",
"campaign_id": "c_9lWrpz",
"mailbox_id": "mbox_W3rR3m",
"lead": {
"id": "l_9N2XDp",
"...": "..."
}
}
]
}
This endpoint adds up to 100 leads to a campaign. If more than 100 lead ids are provided, it will respond with 400 (Bad Request)
.
HTTP Request
POST https://api.persistiq.com/v1/campaigns/:campaign_id/leads
Arguments
Parameter | Description |
---|---|
leads | required (if lead_id is not given), array of lead ids. |
lead_id | required (if leads is not given), an id of lead. |
mailbox_id | optional, an id of the mailbox to which the lead should be added. |
Remove lead from a campaign
curl "https://api.persistiq.com/v1/campaigns/c_9lWrpz/leads/l_9N2XDp"
-X DELETE
-H "x-api-key: YOUR_API_KEY"
The above command will remove a lead from a camapign, and respond with
200 (Success)
This endpoint removes a lead from a campaign.
HTTP Request
DELETE https://api.persistiq.com/v1/campaigns/:campaign_id/leads/:lead_id
Events
List Events
curl "https://api.persistiq.com/v1/events" \
-H "x-api-key: YOUR_API_KEY" \
The above curl request returns the following JSON
{
"has_more":false,
"next_page":null,
"status":"success",
"errors":[
],
"events":[
{
"id":"evt_g3gZjN",
"kind":"lead_created",
"event_at":"2020-06-19T12:10:34.514-07:00",
"user_id":"u_XpYX3J",
"user":{
"id":"u_XpYX3J",
"name":"[email protected] [email protected]",
"email":"[email protected]"
},
"campaign":null,
"lead":{
"id":"l_WpBWbl",
"email":"[email protected]",
"last_name":"Ahmadizadeh",
"first_name":"Daniel"
},
"params":{
"email":"[email protected]",
"last_name":"Ahmadizadeh",
"first_name":"Daniel"
},
"diff":null
},
{
"id":"evt_PNMm0N",
"kind":"lead_created",
"event_at":"2020-06-19T12:10:34.584-07:00",
"user_id":"u_XpYX3J",
"user":{
"id":"u_XpYX3J",
"name":"[email protected] [email protected]",
"email":"[email protected]"
},
"campaign":null,
"lead":{
"id":"l_XpYOXN",
"email":"[email protected]",
"last_name":"Labay",
"first_name":"Bryan"
},
"params":{
"email":"[email protected]",
"last_name":"Labay",
"first_name":"Bryan"
},
"diff":null
},
{
"id":"evt_X3an1p",
"kind":"lead_created",
"event_at":"2020-06-19T12:10:34.636-07:00",
"user_id":"u_XpYX3J",
"user":{
"id":"u_XpYX3J",
"name":"[email protected] [email protected]",
"email":"[email protected]"
},
"campaign":null,
"lead":{
"id":"l_6pD8jp",
"email":"[email protected]",
"last_name":"[email protected]",
"first_name":"[email protected]"
},
"params":{
"email":"[email protected]",
"last_name":"[email protected]",
"first_name":"[email protected]"
},
"diff":null
},
{
"id":"evt_OpQgGN",
"kind":"campaign_step_created",
"event_at":"2020-06-19T12:10:34.792-07:00",
"user_id":"u_XpYX3J",
"user":{
"id":"u_XpYX3J",
"name":"[email protected] [email protected]",
"email":"[email protected]"
},
"campaign":{
"id":"c_XpYOXN",
"name":"Schedule Meetings with CEOs (sample campaign)"
},
"lead":null,
"params":null,
"diff":null
},
]
}
Each response contains maximum of 500 events. If there are more events, has_more
will be true
, and next_page
will contain the url to retrieve the next 100.
Query Parameters
Parameter | Example | Description | |
---|---|---|---|
group | optional | "campaign" |
The types of events to return, more information below |
campaign | optional | "c_Q3zQ8N" |
Filters leads about a specific campaign |
lead | optional | "l_Z3Zg8p" |
Filters events about a certain lead |
user | optional | "u_6pDjN9" |
Filters events performed by certain user |
start_at | optional | "2017-10-17T07:37:00-07:00" |
Gets events after specified time |
end_at | optional | "2017-10-17T07:37:00-07:00" |
Gets events before specified time |
HTTP Request
GET https://api.persistiq.com/v1/leads
Group
You may pass group
as parameter which represents the group of events that you would like the endpoint to return. Below are the different groups of events that you may pass and the kinds of events that fall under that group.
‘campaign’
'campaign_created’, 'campaign_updated’, 'campaign_paused’, 'campaign_unpaused’, 'campaign_step_created’, 'campaign_step_deleted’, 'campaign_deleted’, 'campaign_step_postion_updated]
'settings’
'lead_status_object_created’, 'lead_status_object_updated’, 'lead_status_object_deleted’, 'trigger_action_created’, 'trigger_action_updated’, 'trigger_created’, 'trigger_updated’, 'trigger_deleted’, 'schedule_created’, 'schedule_updated’, 'schedule_deleted’, lead_status’, 'lead_status_object_created’, 'lead_status_object_updated’, 'lead_status_object_deleted’
'lead_detail’
'lead_created’, 'lead_updated’, 'lead_deleted’, 'lead_status_updated’, 'lead_owner_updated’, 'lead_linked’, 'lead_tagged’, 'lead_untagged’, 'lead_unlinked’, 'campaign_lead_created’, 'message_sent’, 'message_received’*, 'message_bounced’, 'message_optout’, 'message_opened’, 'message_clicked’
- 'message_received’ event kind represents when a lead has replied to a campaign.
Do Not Contact Domains
List all DNC domains
curl "https://api.persistiq.com/v1/dnc_domains" \
-H "x-api-key: YOUR_API_KEY"
The above curl request returns the following JSON
{
"status": "success",
"errors": [],
"has_more": true,
"next_page": "https://...",
"dnc_domains": [
{
"id": "dom_3eWoGj",
"name": "test.com"
},
{
"id": "dom_N2X8dM",
"name": "example.com"
}
]}
Do Not Contact domains prevent email being sent to email addresses at their domain.
Each response contains a maximum of 100 domains. If there are more domains, has_more
will be true
, and next_page
will contain the url to retrieve the next 100.
HTTP Request
GET https://api.persistiq.com/v1/dnc_domains
Create DNC domain
curl "https://api.persistiq.com/v1/dnc_domains" \
-H "x-api-key: YOUR_API_KEY" \
-d '{
"name" : "example.com"
}'
The above command returns the following JSON
{
"status": "success",
"errors": null,
"dnc_domain": {
"id": "dom_N2X8dM",
"name": "example.com"
}
}
This endpoint creates a Do Not Contact domain. This will prevent emails from being sent (without manual approval) to email addresses at this domain.
HTTP Request
POST https://api.persistiq.com/v1/dnc_domains
Arguments
Parameter | Description |
---|---|
name | Do Not Contact domain name |
Errors
Error codes
Example error response
{
"status": "error",
"error": {
"reason": "bad_params",
"message": "Email is missing"
}
}
The PersistIQ API uses the following HTTP codes when a request fails:
HTTP Status Code | Meaning |
---|---|
400 | Bad Request – missing a required parameters |
401 | Unauthorized – Your API key is wrong |
404 | Not Found – The specified data could not be found |
429 | Too Many Requests – Too many requests have been sent in a short period of time. |
500 | Internal Server Error – We had a problem with our server. Try again later. |
Attributes | Description |
---|---|
reason | the type of error returned. Values can be invalid_request_error , api_error |
message | a human-readable message that describes the error in more detail. These messages are user friendly. |
Rate Limit
Example 429 response
{
"error": {
"reason": "too_many_requests",
"message": "You performed more than 100 requests per minute. Limit will be reseted at 1450200216."
}
}
It’s allowed to perform no more than 100 requests in 1 (one) minute time window. Rate limit is enforced per API key, i.e. per user basis.
When rate limit is exceeded, 429 Too Many Request response is returned.
You can get information about number of remaining requests and current time window from the headers which are returned along with the response for each API request:
X-RateLimit-Limit
: Maximum allowed request per minute.X-RateLimit-Remaining
: The number of requests left for the current time window.X-RateLimit-Reset
: The time at which current time window ends and rate limit resets in UTC epoch seconds.