CompleteTrack API
Current Version
By default, all requests to https://api.completetrack.io receive the v1 version of the REST API. We encourage you to explicitly request this version via the Accept
header.
Accept: application/vnd.completetrack.v1+json
Schema
All API access is over HTTPS, and accessed from the https://api.completetrack.io. All data is sent and received as JSON.
Blank fields are included as null
instead of being omitted.
All timestamps return in ISO 8601 format:
YYYY-MM-DDTHH:MM:SSZ
Summary Representations
When you fetch a list of resources, the response includes a subset of the attributes for that resource. This is the “summary” representation of the resource.
Detailed Representations
When you fetch an individual resource, the response typically includes all attributes for that resource. This is the “detailed” representation of the resource. (Note that authorization sometimes influences the amount of detail included in the representation.)
Parameters
Many API methods take optional parameters. For GET requests, any parameters not specified as a segment in the path can be passed as an HTTP query string parameter.
For POST, PATCH, PUT, and DELETE requests, parameters not included in the URL should be encoded as JSON with a Content-Type of ‘application/json’.
Client Errors
There are three possible types of client errors on API calls that receive request bodies:
-
Sending invalid JSON will result in a
400 Bad Request
response. -
Sending the wrong type of JSON values will result in a
400 Bad Request
response. -
Sending invalid fields will result in a
422 Unprocessable Entity
response.
Errors will always have a message
field describing the error and may enumerate
the specific errors via the error
array.
HTTP Verbs
Where possible, the API strives to use appropriate HTTP verbs for each action.
Verb | Description |
---|---|
HEAD | Can be issued against any resource to get just the HTTP header info. |
GET | Used for retrieving resources. |
POST | Used for creating resources. |
PATCH | Used for updating resources with partial JSON data. A PATCH request may accept one or more of the attributes to update the resource. PATCH is a relatively new and uncommon HTTP verb, so resource endpoints also accept POST requests. |
PUT | Used for replacing resources or collections. For PUT requests with no body attribute, be sure to set the Content-Length header to zero. |
DELETE | Used for deleting resources. |
Authentication
There are two ways to authenticate through the API. Requests that require authentication will return 404 Not Found
, instead of 403 Forbidden
, in some places. This is to prevent the accidental leakage of private information to unauthorized users.
-
Basic Authentication
-
OAuth2 Token (sent in the
Authorization
header) -
OAuth2 Token (sent via the
access_token
parameter)
Tokens for OAuth Apps can be obtained by issuing a POST to https://api.completetrack.io/oauth/token
. Currently the
only supported workflow is server-to-server (i.e. client_credentials
):
curl -X POST http://api.completetrack.io/oauth/token?
grant_type=client_credentials
&client_id=CLIENT_ID
&client_secret=CLIENT_SECRET
Pagination
Requests that return multiple items will be paginated to 30 items by default. You can specify further pages with the ?page
parameter. For some resources, you can also set a custom page size up to 100 with the ?per_page
parameter. Note that for technical reasons not all endpoints respect the ?per_page
parameter.
Note that page numbering is 1-based and that omitting the ?page
parameter will return the first page.
User Agent Required
All API requests MUST include a valid User-Agent
header. Requests with no User-Agent header will be rejected. We request that you use your account, organization, or the name of your application, for the User-Agent
header value. This allows us to contact you if there are problems.
Cross Origin Resource Sharing
The API supports Cross Origin Resource Sharing (CORS) for AJAX requests from any origin. You can read the CORS W3C Recommendation, or this intro from the HTML 5 Security Guide.
Contacts ¶
A Contact captures any and all information about an individual customer or client. The information can be entered manually, collected automatically from an inbound communication, and/or annotated by an external process or source.
Contact Collection ¶
List all ContactsGET/accounts/contacts
List all contacts for a given account
Example URI
- labels
list[string]
(optional) Example: mover,shakerA list of comma separated label names.
- sort
string
(optional)What to sort results by.
- order
string
(optional)The order of the sort.
- Default
string
(required) Example: desc- Members
string
(required)-
asc
-
desc
-
200
Headers
Content-Type: application/json
Body
[
{
"id": "5225667016f2f72d21000003",
"labels": [
"presidential"
],
"first_name": "George",
"last_name": "Washington",
"phone_one": "4567890123",
"email": "george@washington.gov",
"address": "1 Apple Tree Ln.",
"city": "Richmond",
"region": "Virginia",
"postal_code": "34569"
}
]
Create a ContactPOST/accounts/contacts
The following fields are considered the “core” schema for a contact:
-
company
-
first_name
-
last_name
-
phone_one
-
email
-
address
-
city
-
region
-
postal_code
These fields are available for every contact and are used by other services internally for matching, enrichment, and further analysis.
Additional information/data can be added to any contact for use by external applications via the extra
field. This field is an opaque hash which can be used to store any data permitted via JSON. The one restriction is that the key names cannot contain a period (’.’).
Example URI
Headers
Content-Type: application/json
Body
{
"first_name": "Gilbert",
"last_name": "Sullivan",
"phone_one": "3457890123",
"company": "Music & More"
}
201
Headers
Content-Type: application/json
Location: https://api.completetrack.io/accounts/test-account/contacts/52b3cc3f4d61637653100000
Body
{
"id": "52b3cc3f4d61637653100000",
"first_name": "Gilbert",
"last_name": "Sullivan",
"phone_one": "3457890123",
"company": "Music & More",
"created_at": "2013-12-20T04:49:03.606Z",
"updated_at": "2013-12-20T04:49:03.606Z"
}
Contact ¶
Get a single ContactGET/accounts/contacts/
Example URI
200
Headers
Content-Type: application/json
Body
{
"id": "52b3cc3f4d61637653100000",
"first_name": "Gilbert",
"last_name": "Sullivan",
"phone_one": "3457890123",
"company": "Music & More",
"created_at": "2013-12-20T04:49:03.606Z",
"updated_at": "2013-12-20T04:49:03.606Z"
}
Edit a single ContactPATCH/accounts/contacts/
Example URI
Headers
Content-Type: application/json
Body
{
"labels": [
"musical"
]
}
200
Headers
Content-Type: application/json
Body
{
"id": "52b3cc3f4d61637653100000",
"labels": [
"musical"
],
"first_name": "Gilbert",
"last_name": "Sullivan",
"phone_one": "3457890123",
"company": "Music & More",
"created_at": "2013-12-20T04:49:03.606Z",
"updated_at": "2014-11-12T01:12:41.101Z"
}
Tickets ¶
Tickets encapsulate a singular “encounter” or “interaction” with a Contact. A ticket provides actions and documents the details required to drive a ticket to a particular resolution.
A Contact can have multiple Tickets.
Ticket Collection ¶
List all TicketsGET/accounts/tickets
List all tickets for a given account
Example URI
- state
string
(optional)Indicates the state of tickets to return.
- labels
list[string]
(optional) Example: tier-two,pr-signedA list of comma separated label names.
- contact
string
(optional)Return only tickets associated with this contact
- sort
string
(optional)What to sort results by.
- direction
string
(optional)The direction of the sort.
- Default
string
(required) Example: desc- Members
string
(required)-
asc
-
desc
-
200
Headers
Content-Type: application/json
Body
[
{
"id": "1234",
"description": "Unable to access account",
"status": "open",
"labels": [
"referral"
],
"disposition": [
"Support",
"Account"
],
"channel": "phone",
"contact": {
"id": "5963c55acda6ce6f84cf20d3",
"first_name": "Mary",
"last_name": "Sunshine",
"phone_one": "1234567890"
},
"fields": {
"qid.model": "ABC-123"
},
"created_at": "2014-11-11T08:40:51.620Z",
"updated_at": "2014-11-11T08:40:51.620Z"
}
]
Create a TicketPOST/accounts/tickets
Note: contact_id
or contact
with appropriate fields can be passed in when
creating a ticket, however, they are mutually exclusive. Passing in both will result
in an error being returned.
Example URI
Headers
Content-Type: application/json
Body
{
"description": "Customer interested in upgrading",
"status": "open",
"labels": [
"loyalty",
"tier-two"
],
"disposition": [
"Sales",
"Existing Customer",
"Upgrade"
],
"channel": "phone",
"contact_id": "5225667016f2f72d21000003",
"fields": {
"qid.products": [
"Boom",
"Blam"
],
"qid.warranty": false
},
"assignee_id": "522cebd016f2f70114000011"
}
201
Headers
Content-Type: application/json
Location: https://api.completetrack.io/accounts/test-account/tickets/4567
Body
{
"id": "4567",
"description": "Customer interested in upgrading",
"status": "open",
"labels": [
"loyalty",
"tier-two"
],
"disposition": [
"Sales",
"Existing Customer",
"Upgrade"
],
"channel": "phone",
"contact": {
"id": "5225667016f2f72d21000003",
"first_name": "George",
"last_name": "Washington",
"phone_one": "4567890123",
"address": "1 Apple Tree Ln. Richmond, Virginia 34569"
},
"fields": {
"qid.products": [
"Boom",
"Blam"
],
"qid.warranty": false
},
"assignee": {
"id": "522cebd016f2f70114000011",
"display_name": "Luxanna Troi"
},
"created_at": "2015-10-17T01:30:11.123Z",
"updated_at": "2015-10-17T01:30:11.123Z"
}
Ticket ¶
Get a single TicketGET/accounts/tickets/
Example URI
200
Headers
Content-Type: application/json
Body
{
"id": "1234",
"description": "Unable to access account",
"status": "open",
"labels": [
"referral"
],
"disposition": [
"Support",
"Account"
],
"channel": "phone",
"contact": {
"id": "5963c55acda6ce6f84cf20d3",
"first_name": "Mary",
"last_name": "Sunshine",
"phone_one": "1234567890"
},
"fields": {
"qid.model": "ABC-123"
},
"created_at": "2014-11-11T08:40:51.620Z",
"updated_at": "2014-11-11T08:40:51.620Z"
}
Edit a single TicketPATCH/accounts/tickets/
Note: Changing the status
, labels
, disposition
, or value of any of the fields
could cause additional workflow to be executed which might also impact the various aspects of the ticket.
Example URI
Headers
Content-Type: application/json
Body
{
"description": "Not able to login to access account"
}
200
Headers
Content-Type: application/json
Body
{
"id": "1234",
"description": "Not able to login to access account",
"status": "open",
"labels": [
"referral"
],
"disposition": [
"Support",
"Account"
],
"channel": "phone",
"contact": {
"id": "5963c55acda6ce6f84cf20d3",
"first_name": "Mary",
"last_name": "Sunshine",
"phone_one": "1234567890"
},
"fields": {
"qid.model": "ABC-123"
},
"created_at": "2014-11-11T08:40:51.620Z",
"updated_at": "2015-04-45T11:23:39.593Z"
}
Ticket Assignment ¶
Set Ticket AssigneePUT/accounts/tickets/assign
Example URI
- assignee
string
(required)ID of new assignee. The new assignee MUST have read permission on the account. IF assignee is empty (
""
) ornull
then the present assignee is removed
Headers
Content-Type: application/json
Body
{
"assignee": "5226aa1516f2f72eef000003"
}
Remove Ticket AssigneeDELETE/accounts/tickets/assign
Removes the present assignee of the ticket
Example URI
Ticket Metrics ¶
Provides an aggregation of state changes for label
and status
for a ticket
Get metrics for a TicketGET/accounts/tickets/metrics
total_time
is in seconds
Example URI
200
Headers
Content-Type: application/json
Body
[
{
"type": "label",
"value": "Escalations",
"transitions": 2,
"total_time": 32382
}
]
Ticket Export ¶
Given a Handlebars template, returns that template populated with data from a ticket
Export a ticketPOST/accounts/tickets/export
Example URI
- template
string
(required)Handlebars template
- contentType
string
(optional) Example: text/csvUse this value for the response
Content-Type
header.- Default
string
(required) Example: text/plain
Headers
Content-Type: application/json
Body
{
"template": "{{id}}, {{status}}, {{description}}, {{labels}}"
}
200
Headers
Content-Type: text/plain
Ticket Enqueue ¶
Places ticket into the task queue for action by users assigned to the account. Ticket will sit in the task queue until it is claimed.
Enqueue ticketPOST/accounts/tickets/enqueue
Example URI
204
Ticket Comments Collection ¶
Comments enable users to document steps taken, provide additional information and foster collaboration around tickets. Comments support a subset of Markdown syntax for formatting beyond simple plain-text:
-
monospaced
by surrounding text with backticks `monospaced` -
italic by surrounding text with underscores _itatic_
-
bold by surrounding text with double-asterisks **bold**
-
strikeby surrounding text with double-tildes ~~strike~~ -
quote by prefixing the line with a greater than sign > quote
-
preformatted
by surrounding block of text with triple backticks ```preformatted``` -
Link text through link text in square brackets followed immediately by the url in parenthesis [Links](https://crmct.com)
List all Ticket CommentsGET/accounts/tickets/comments
List all comments for a given ticket
Example URI
- order
string
(optional)Sort order on
created_at
- Default
string
(required) Example: desc- Members
string
(required)-
asc
-
desc
-
200
Headers
Content-Type: application/json
Body
[
{
"id": "53a726484d616348cd130000",
"text": "Unable to access account",
"author": {
"id": "522cceab16f2f7ff92000005",
"display_name": "Agent One"
},
"created_at": "2013-12-20T04:45:30.574Z"
}
]
Create a Ticket CommentPOST/accounts/tickets/comments
Example URI
- text
string
(required)Markdown-flavored text of the comment
Headers
Content-Type: application/json
Body
{
"text": "I am *very* **very** important comment"
}
201
Headers
Content-Type: application/json
Location: https://api.completetrack.io/accounts/test-account/tickets/4567/comments/52b3ccbe4d61637653190000
Body
{
"id": "52b3ccbe4d61637653190000",
"text" : "I am *very* **very** important comment"
"author": {
"id": "522cceab16f2f7ff92000005",
"display_name": "Agent One"
},
"created_at": "2013-12-20T04:45:30.574Z"
}
Search ¶
About the Search API
The Search API is optimized to help you find the specific item you’re looking for (e.g., a specific ticket, a specific contact, etc.). Think of it the way you think of performing a search on Google. It’s designed to help you find the one result you’re looking for (or maybe the few results you’re looking for). Just like searching on Google, you sometimes want to see a few pages of search results so that you can find the item that best meets your needs. To satisfy that need, the Search API provides up to 1,000 results for each search.
Ranking search results
Unless another sort option is provided as a query parameter, results are sorted by best match, as indicated by the score
field for each item returned. This is a computed value representing the relevance of an item relative to the other items in the result set. Multiple factors are combined to boost the most relevant item to the top of the result list.
Contact Search ¶
Search ContactsGET/accounts/contacts/search
Example URI
- q
string
(required)The search keywords, as well as any qualifiers
- sort
string
(optional)The sort field. Can be any of the fields in a contact. Defaults to sort by best match.
- order
string
(optional)The sort order
- Default
string
(required) Example: desc- Members
string
(required)-
asc
-
desc
-
200
Headers
Content-Type: application/json
Body
{
"total_count": 14,
"contacts": [
{
"id": "52b3cc3f4d61637653100000",
"labels": [
"musical"
],
"first_name": "Gilbert",
"last_name": "Sullivan",
"phone_one": "3457890123",
"company": "Music & More",
"created_at": "2013-12-20T04:49:03.606Z",
"updated_at": "2014-11-12T01:12:41.101Z"
}
]
}
Ticket Search ¶
Search TicketsGET/accounts/tickets/search
Example URI
- q
string
(required)The search keywords, as well as any qualifiers
- sort
string
(optional)The sort field. Can be any of the fields in a ticket. Defaults to sort by best match.
- order
string
(optional)The sort order
- Default
string
(required) Example: desc- Members
string
(required)-
asc
-
desc
-
200
Headers
Content-Type: application/json
Body
{
"total_count": 42,
"tickets": [
{
"id": "1234",
"description": "Not able to login to access account",
"status": "open",
"labels": [ "referral" ],
"disposition": [ "Support", "Account" ],
"channel": "phone",
"contact" : {
"id": "5963c55acda6ce6f84cf20d3",
"first_name": "Mary",
"last_name": "Sunshine",
"phone_one": "1234567890"
},
"fields": {
"qid.model" : "ABC-123"
},
"created_at": "2014-11-11T08:40:51.620Z",
"updated_at": "2015-04-45T11:23:39.593Z"
}
}
Webhooks ¶
Webhooks allow you to build or set up external applications which subscribe to certain events on CompleteTrack. When one of those events is triggered, we’ll send a HTTP POST payload to the webhook’s configured URL.
Webhooks are installed at the account level. Once installed, they will be triggered each time one or more subscribed events occurs on that organization or repository.
Events
When configuring a webhook, you can choose which events you would like to receive payloads for. You can even opt-in to all current and future events. Only subscribing to the specific events you plan on handling is useful for limiting the number of HTTP requests to your server.
Each event corresponds to a certain set of actions that can happen to your tickets and/or contacts.
Name | Description |
---|---|
“*” | Any time any event is trigged (Wildcard) |
contact | Issued when a contact is created, edited or when its labels change |
ticket | Issued when a ticket is assigned, unassigned, created, edited or when its status, labels, or disposition change |
ticket_comment | Any time a comment on a ticket is created |
Wildcard Event
We also support a wildcard (*) that will match all supported events. When you add the wildcard event, we’ll replace any existing events you have configured with the wildcard event and send you payloads for all supported events. You’ll also automatically get any new events we might add in the future.
Payload
Each event type has a specific payload format with the relevant event information.
In addition to the fields documented for each event, webhook payloads include the actor who performed the event (sender) as well as the account which the event occurred on.
Delivery Headers
HTTP request made to your webhooks configured URL endpoint will contain several special headers:
Header | Description |
---|---|
X-CT-Event | Name of the event which triggered this delivery |
X-CT-Delivery | Unique ID for this delivery |
Ping Event
When you create a new webhook, we’ll send you a simple ping event to let you know you’ve set up the webhook correctly.
Key | Value |
---|---|
entropy | Random string to ensure no one ping looks like the next |
webhook_id | The ID of the webhook that triggered the ping |
webhook | The webhook configuration |
ContactEvent
Triggered when a contact is created, edited or when its labels change
Payload
Key | Type | Description |
---|---|---|
action | string | The action that was performed: created , edited , labeled , unlabeled |
contact | object | The contact itself |
changes | object | The changes to contact if the action was edited |
label | object | The optional label that was added or removed from the contact |
TicketEvent
Triggered when a ticket is assigned, unassigned, created, edited or when its status, labels, or disposition change
Payload
Key | Type | Description |
---|---|---|
action | string | The action that was performed: assigned , unassigned , created , edited , status , labeled , unlabeled , disposition |
ticket | object | The ticket itself |
changes | object | The changes to ticket if the action was edited , status , disposition |
assignee | object | The optional user who was assigned or unassigned |
label | object | The optional label that was added or removed from the contact |
TicketCommentEvent
Triggered when a ticket comment is created
Payload
Key | Type | Description |
---|---|---|
action | string | The action that was performed: created |
comment | object | The comment itself |