3585 lines
214 KiB
HTML
3585 lines
214 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en" class="js csstransitions wf-proximanova-n7-active wf-proximanova-n4-active wf-proximanova-n3-active wf-proximanova-i7-active wf-proximanova-n6-active wf-proximanova-i4-active wf-active"><head prefix="og: http://ogp.me/ns# article: http://ogp.me/ns/article#">
|
|
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
|
|
|
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
<meta name="generator" content="MindTouch">
|
|
<meta name="robots" content="index,follow">
|
|
<meta property="og:title" content="Developer Guide">
|
|
<meta property="og:site_name" content="Developer Network">
|
|
<meta property="og:type" content="article">
|
|
<meta property="og:locale" content="en_US">
|
|
<meta property="og:url" content="https://developer.connectwise.com/Products/ConnectWise_PSA/Developer_Guide">
|
|
<meta property="og:image" content="https://a.mtstatic.com/@public/production/site_8263/1680273416-logo.png">
|
|
<meta property="og:description" content="">
|
|
<meta property="article:published_time" content="2016-01-22T19:40:49Z">
|
|
<meta property="article:modified_time" content="2025-04-08T15:54:36Z">
|
|
<meta name="twitter:card" content="summary">
|
|
<meta name="twitter:title" content="Developer Guide">
|
|
<meta name="twitter:description" content="">
|
|
<meta name="twitter:image" content="https://a.mtstatic.com/@public/production/site_8263/1680273416-logo.png">
|
|
<meta name="description" content="">
|
|
<link rel="canonical" href="https://developer.connectwise.com/Products/ConnectWise_PSA/Developer_Guide">
|
|
<link rel="search" type="application/opensearchdescription+xml" title="Developer Network Search" href="https://developer.connectwise.com/@api/deki/site/opensearch/description">
|
|
<link rel="apple-touch-icon" href="https://a.mtstatic.com/@public/production/site_8263/1680273491-apple-touch-icon.png">
|
|
<link rel="shortcut icon" href="https://a.mtstatic.com/@public/production/site_8263/1680273592-favicon.ico">
|
|
|
|
|
|
<title>Developer Guide - Developer Network</title>
|
|
|
|
|
|
<style type="text/css">/*<![CDATA[*/
|
|
h3 {
|
|
font-size: 22px !important;
|
|
}/*]]>*/</style><style type="text/css">/*<![CDATA[*/
|
|
#mt-toc-container {
|
|
display: block !important;
|
|
}/*]]>*/</style><style type="text/css">/*<![CDATA[*/
|
|
dt {
|
|
color: #1468b1;
|
|
cursor: pointer;
|
|
}
|
|
dd {
|
|
display: none;
|
|
}/*]]>*/</style><style type="text/css">/*<![CDATA[*/
|
|
table, tr, td, th
|
|
{
|
|
border: 1px solid black;
|
|
border-collapse:collapse;
|
|
}
|
|
tr.header
|
|
{
|
|
cursor:pointer;
|
|
}/*]]>*/</style><style type="text/css">/*<![CDATA[*/#related,
|
|
.widget {
|
|
display: none;
|
|
}
|
|
.guide-content.static {
|
|
max-width: 98.5%;
|
|
}/*]]>*/</style><style type="text/css">/*<![CDATA[*/
|
|
.cw-footer {
|
|
background: #5d5d5d;
|
|
width: 100%;
|
|
color: #00aeef;
|
|
font-size: 11px;
|
|
clear: both;
|
|
}
|
|
|
|
.footer-wrapper {
|
|
position: relative;
|
|
max-width: 1050px!important;
|
|
width: 90%;
|
|
margin: 0 auto;
|
|
padding: 40px 0 75px 0;
|
|
overflow: hidden;
|
|
}
|
|
|
|
.cw-footer ul {
|
|
position: relative;
|
|
overflow: hidden;
|
|
list-style-type: none;
|
|
margin: 0 0 5px 0;
|
|
padding: 0;
|
|
}
|
|
|
|
.cw-footer ul li {
|
|
float: left;
|
|
border-right: 1px solid #00aeef;
|
|
margin: 0 6px 0 0;
|
|
padding: 0 6px 0 0;
|
|
list-style-type: none;
|
|
font-size: 11px;
|
|
line-height: 11px;
|
|
text-transform: uppercase;
|
|
}
|
|
|
|
.cw-footer ul li:last-child {
|
|
border: 0;
|
|
}
|
|
|
|
.cw-footer .social-links {
|
|
position: absolute;
|
|
top: 40px;
|
|
right: 0;
|
|
}
|
|
|
|
@media screen and (max-width:650px) {
|
|
.cw-footer .social-links {
|
|
position: static;
|
|
}
|
|
}
|
|
|
|
.cw-footer .social-links li {
|
|
border: 0;
|
|
font-size: 28px;
|
|
padding: 0;
|
|
}
|
|
|
|
.cw-footer p {
|
|
color: #fff;
|
|
}
|
|
|
|
.cw-footer a,
|
|
.cw-footer a.link-https,
|
|
.cw-footer a.mt-self-link {
|
|
color: #fff!important;
|
|
}
|
|
|
|
.cw-footer span.white-text {
|
|
color: #fff!important;
|
|
}
|
|
|
|
|
|
.elm-footer {
|
|
bottom: 0!important;
|
|
}
|
|
|
|
.elm-footer-custom p:last-child {
|
|
display: none;
|
|
}/*]]>*/</style><style type="text/css">/*<![CDATA[*/
|
|
/* Header Styles */
|
|
|
|
.header-blue {
|
|
background: #004b71;
|
|
|
|
height: 85px;
|
|
width: 100%;
|
|
position: relative;
|
|
}
|
|
|
|
#Version1_5 {
|
|
display:none;
|
|
}
|
|
.cw-wrapper {
|
|
max-width: 1050px;
|
|
height: 100%;
|
|
position: relative;
|
|
margin: 0 auto;
|
|
overflow: hidden;
|
|
width: 90%;
|
|
}
|
|
|
|
.header-wrapper {
|
|
max-width: 1050px;
|
|
height: 100%;
|
|
position: relative;
|
|
margin: 0 auto;
|
|
width: 90%;
|
|
z-index:500;
|
|
}
|
|
|
|
a#cw-logo {
|
|
display: block;
|
|
float: left;
|
|
width: 200px;
|
|
position: relative;
|
|
top: 10px;
|
|
z-index: 99999999;
|
|
}
|
|
|
|
.mt-logo {
|
|
display: none;
|
|
}
|
|
|
|
.action-items {
|
|
height: 40px;
|
|
position: absolute;
|
|
top: 20px;
|
|
right: 0;
|
|
}
|
|
|
|
@media screen and (max-width: 1050px) {
|
|
.action-items {
|
|
display: none;
|
|
}
|
|
}
|
|
|
|
.action-items a {
|
|
display: inline-block;
|
|
color: #fff;
|
|
padding: 8px 12px;
|
|
margin: 4px;
|
|
font-size: 13px;
|
|
}
|
|
|
|
.action-items a:visited {
|
|
color: #fff!important;
|
|
}
|
|
|
|
.action-items a:nth-child(2) {
|
|
background: #F18021;
|
|
}
|
|
|
|
.action-items a:last-child {
|
|
background: #F18021;
|
|
}
|
|
|
|
button#toggleSearch {
|
|
background: transparent;
|
|
border: 0;
|
|
outline: 0;
|
|
border-radius: 0;
|
|
padding: 0 .8em;
|
|
}
|
|
|
|
button#toggleSearch:focus,
|
|
button#toggleSearch:active:focus,
|
|
button#toggleSearch:active {
|
|
background: transparent!important;
|
|
outline: none!important;
|
|
outline-color: transparent!important;
|
|
outline-style: none!important;
|
|
box-shadow: none!important;
|
|
border-radius: 0!important;
|
|
padding: 0 .8em!important;
|
|
}
|
|
|
|
#toggleSearch i.fa-search {
|
|
color: white;
|
|
font-size: 17px;
|
|
position: relative;
|
|
top: 2px;
|
|
}
|
|
|
|
#search-cw {
|
|
max-width: 1050px;
|
|
margin: 0px auto;
|
|
position: relative;
|
|
display: block;
|
|
z-index:9999;
|
|
}
|
|
|
|
#search-cw form {
|
|
position: absolute;
|
|
width: 250px;
|
|
bottom: -40px;
|
|
right: 22px;
|
|
z-index: 99;
|
|
}
|
|
|
|
#search-cw input.mt-text {
|
|
border-radius: 0;
|
|
padding: 10px 10px 11px 10px;
|
|
border-color: #e7e7e8;
|
|
}
|
|
|
|
#search-cw button.mt-button {
|
|
position: absolute;
|
|
top: 0;
|
|
right: -21px;
|
|
background: #3fa85f;
|
|
border-radius: 0;
|
|
padding: 12px 10px 11px 11px;
|
|
color: #fff;
|
|
}
|
|
|
|
/* Mobile Nav */
|
|
.dl-menuwrapper {
|
|
width: 100%;
|
|
position: relative;
|
|
top: 20px;
|
|
-webkit-perspective: 1000px;
|
|
perspective: 1000px;
|
|
-webkit-perspective-origin: 50% 200%;
|
|
perspective-origin: 50% 200%;
|
|
}
|
|
|
|
.dl-menuwrapper:first-child {
|
|
margin-right: 100px;
|
|
}
|
|
|
|
.dl-menuwrapper button {
|
|
background: #1468b1;
|
|
border: none;
|
|
width: 48px;
|
|
height: 45px;
|
|
text-indent: -900em;
|
|
overflow: hidden;
|
|
position: absolute;
|
|
cursor: pointer;
|
|
outline: none;
|
|
top: 0;
|
|
right: 0;
|
|
visibility: hidden;
|
|
}
|
|
|
|
@media screen and (max-width: 1050px) {
|
|
.dl-menuwrapper button {
|
|
visibility: visible;
|
|
}
|
|
}
|
|
|
|
.dl-menuwrapper button:hover,
|
|
.dl-menuwrapper button.dl-active,
|
|
.dl-menuwrapper ul {
|
|
background: #1468b1;
|
|
}
|
|
|
|
.dl-menuwrapper button:after {
|
|
content: '';
|
|
position: absolute;
|
|
width: 68%;
|
|
height: 5px;
|
|
background: #fff;
|
|
top: 10px;
|
|
left: 16%;
|
|
box-shadow:
|
|
0 10px 0 #fff,
|
|
0 20px 0 #fff;
|
|
}
|
|
|
|
.dl-menuwrapper ul {
|
|
padding: 0;
|
|
list-style: none;
|
|
-webkit-transform-style: preserve-3d;
|
|
transform-style: preserve-3d;
|
|
}
|
|
|
|
.dl-menuwrapper li {
|
|
position: relative;
|
|
text-align: center;
|
|
border-bottom: 1px solid #007ac6;
|
|
}
|
|
|
|
.dl-menuwrapper li:last-child {
|
|
border-bottom: 0;
|
|
}
|
|
|
|
.dl-menuwrapper li a {
|
|
display: block;
|
|
position: relative;
|
|
padding: 15px 20px;
|
|
font-size: 16px;
|
|
line-height: 20px;
|
|
font-weight: 300;
|
|
color: #fff;
|
|
outline: none;
|
|
}
|
|
|
|
.no-touch .dl-menuwrapper li a:hover {
|
|
opacity: 0.8;
|
|
}
|
|
|
|
.dl-menuwrapper li.dl-back > a {
|
|
padding-left: 30px;
|
|
background: rgba(0,0,0,0.1);
|
|
}
|
|
|
|
.dl-menuwrapper li.dl-back:after,
|
|
.dl-menuwrapper li > a:not(:only-child):after {
|
|
position: absolute;
|
|
top: 0;
|
|
line-height: 50px;
|
|
font-family: 'icomoon';
|
|
speak: none;
|
|
-webkit-font-smoothing: antialiased;
|
|
content: "\e000";
|
|
}
|
|
|
|
.dl-menuwrapper li.dl-back:after {
|
|
left: 10px;
|
|
color: rgba(212,204,198,0.3);
|
|
-webkit-transform: rotate(180deg);
|
|
transform: rotate(180deg);
|
|
}
|
|
|
|
.dl-menuwrapper li > a:after {
|
|
right: 10px;
|
|
color: rgba(0,0,0,0.15);
|
|
}
|
|
|
|
.dl-menuwrapper .dl-menu {
|
|
margin: 5px 0 0 0;
|
|
position: absolute;
|
|
top: 60px;
|
|
width: 100%;
|
|
opacity: 0;
|
|
pointer-events: none;
|
|
-webkit-transform: translateY(10px);
|
|
transform: translateY(10px);
|
|
-webkit-backface-visibility: hidden;
|
|
backface-visibility: hidden;
|
|
}
|
|
|
|
.dl-menuwrapper .dl-menu.dl-menu-toggle {
|
|
transition: all 0.3s ease;
|
|
}
|
|
|
|
.dl-menuwrapper .dl-menu.dl-menuopen {
|
|
opacity: 1;
|
|
pointer-events: auto;
|
|
-webkit-transform: translateY(0px);
|
|
transform: translateY(0px);
|
|
}
|
|
|
|
/* Hide the inner submenus */
|
|
.dl-menuwrapper li .dl-submenu {
|
|
display: none;
|
|
}
|
|
|
|
/*
|
|
When a submenu is openend, we will hide all li siblings.
|
|
For that we give a class to the parent menu called "dl-subview".
|
|
We also hide the submenu link.
|
|
The opened submenu will get the class "dl-subviewopen".
|
|
All this is done for any sub-level being entered.
|
|
*/
|
|
.dl-menu.dl-subview li,
|
|
.dl-menu.dl-subview li.dl-subviewopen > a,
|
|
.dl-menu.dl-subview li.dl-subview > a {
|
|
display: none;
|
|
}
|
|
|
|
.dl-menu.dl-subview li.dl-subview,
|
|
.dl-menu.dl-subview li.dl-subview .dl-submenu,
|
|
.dl-menu.dl-subview li.dl-subviewopen,
|
|
.dl-menu.dl-subview li.dl-subviewopen > .dl-submenu,
|
|
.dl-menu.dl-subview li.dl-subviewopen > .dl-submenu > li {
|
|
display: block;
|
|
}
|
|
|
|
/* Dynamically added submenu outside of the menu context */
|
|
.dl-menuwrapper > .dl-submenu {
|
|
position: absolute;
|
|
width: 100%;
|
|
top: 50px;
|
|
left: 0;
|
|
margin: 0;
|
|
}
|
|
|
|
/* Animation classes for moving out and in */
|
|
|
|
.dl-menu.dl-animate-out-1 {
|
|
-webkit-animation: MenuAnimOut1 0.4s;
|
|
animation: MenuAnimOut1 0.4s;
|
|
}
|
|
|
|
.dl-menu.dl-animate-out-2 {
|
|
-webkit-animation: MenuAnimOut2 0.3s ease-in-out;
|
|
animation: MenuAnimOut2 0.3s ease-in-out;
|
|
}
|
|
|
|
.dl-menu.dl-animate-out-3 {
|
|
-webkit-animation: MenuAnimOut3 0.4s ease;
|
|
animation: MenuAnimOut3 0.4s ease;
|
|
}
|
|
|
|
.dl-menu.dl-animate-out-4 {
|
|
-webkit-animation: MenuAnimOut4 0.4s ease;
|
|
animation: MenuAnimOut4 0.4s ease;
|
|
}
|
|
|
|
.dl-menu.dl-animate-out-5 {
|
|
-webkit-animation: MenuAnimOut5 0.4s ease;
|
|
animation: MenuAnimOut5 0.4s ease;
|
|
}
|
|
|
|
@-webkit-keyframes MenuAnimOut1 {
|
|
0% { }
|
|
50% {
|
|
-webkit-transform: translateZ(-250px) rotateY(30deg);
|
|
}
|
|
75% {
|
|
-webkit-transform: translateZ(-372.5px) rotateY(15deg);
|
|
opacity: .5;
|
|
}
|
|
100% {
|
|
-webkit-transform: translateZ(-500px) rotateY(0deg);
|
|
opacity: 0;
|
|
}
|
|
}
|
|
|
|
@-webkit-keyframes MenuAnimOut2 {
|
|
0% { }
|
|
100% {
|
|
-webkit-transform: translateX(-100%);
|
|
opacity: 0;
|
|
}
|
|
}
|
|
|
|
@-webkit-keyframes MenuAnimOut3 {
|
|
0% { }
|
|
100% {
|
|
-webkit-transform: translateZ(300px);
|
|
opacity: 0;
|
|
}
|
|
}
|
|
|
|
@-webkit-keyframes MenuAnimOut4 {
|
|
0% { }
|
|
100% {
|
|
-webkit-transform: translateZ(-300px);
|
|
opacity: 0;
|
|
}
|
|
}
|
|
|
|
@-webkit-keyframes MenuAnimOut5 {
|
|
0% { }
|
|
100% {
|
|
-webkit-transform: translateY(40%);
|
|
opacity: 0;
|
|
}
|
|
}
|
|
|
|
@keyframes MenuAnimOut1 {
|
|
0% { }
|
|
50% {
|
|
-webkit-transform: translateZ(-250px) rotateY(30deg);
|
|
transform: translateZ(-250px) rotateY(30deg);
|
|
}
|
|
75% {
|
|
-webkit-transform: translateZ(-372.5px) rotateY(15deg);
|
|
transform: translateZ(-372.5px) rotateY(15deg);
|
|
opacity: .5;
|
|
}
|
|
100% {
|
|
-webkit-transform: translateZ(-500px) rotateY(0deg);
|
|
transform: translateZ(-500px) rotateY(0deg);
|
|
opacity: 0;
|
|
}
|
|
}
|
|
|
|
@keyframes MenuAnimOut2 {
|
|
0% { }
|
|
100% {
|
|
-webkit-transform: translateX(-100%);
|
|
transform: translateX(-100%);
|
|
opacity: 0;
|
|
}
|
|
}
|
|
|
|
@keyframes MenuAnimOut3 {
|
|
0% { }
|
|
100% {
|
|
-webkit-transform: translateZ(300px);
|
|
transform: translateZ(300px);
|
|
opacity: 0;
|
|
}
|
|
}
|
|
|
|
@keyframes MenuAnimOut4 {
|
|
0% { }
|
|
100% {
|
|
-webkit-transform: translateZ(-300px);
|
|
transform: translateZ(-300px);
|
|
opacity: 0;
|
|
}
|
|
}
|
|
|
|
@keyframes MenuAnimOut5 {
|
|
0% { }
|
|
100% {
|
|
-webkit-transform: translateY(40%);
|
|
transform: translateY(40%);
|
|
opacity: 0;
|
|
}
|
|
}
|
|
|
|
.dl-menu.dl-animate-in-1 {
|
|
-webkit-animation: MenuAnimIn1 0.3s;
|
|
animation: MenuAnimIn1 0.3s;
|
|
}
|
|
|
|
.dl-menu.dl-animate-in-2 {
|
|
-webkit-animation: MenuAnimIn2 0.3s ease-in-out;
|
|
animation: MenuAnimIn2 0.3s ease-in-out;
|
|
}
|
|
|
|
.dl-menu.dl-animate-in-3 {
|
|
-webkit-animation: MenuAnimIn3 0.4s ease;
|
|
animation: MenuAnimIn3 0.4s ease;
|
|
}
|
|
|
|
.dl-menu.dl-animate-in-4 {
|
|
-webkit-animation: MenuAnimIn4 0.4s ease;
|
|
animation: MenuAnimIn4 0.4s ease;
|
|
}
|
|
|
|
.dl-menu.dl-animate-in-5 {
|
|
-webkit-animation: MenuAnimIn5 0.4s ease;
|
|
animation: MenuAnimIn5 0.4s ease;
|
|
}
|
|
|
|
@-webkit-keyframes MenuAnimIn1 {
|
|
0% {
|
|
-webkit-transform: translateZ(-500px) rotateY(0deg);
|
|
opacity: 0;
|
|
}
|
|
20% {
|
|
-webkit-transform: translateZ(-250px) rotateY(30deg);
|
|
opacity: 0.5;
|
|
}
|
|
100% {
|
|
-webkit-transform: translateZ(0px) rotateY(0deg);
|
|
opacity: 1;
|
|
}
|
|
}
|
|
|
|
@-webkit-keyframes MenuAnimIn2 {
|
|
0% {
|
|
-webkit-transform: translateX(-100%);
|
|
opacity: 0;
|
|
}
|
|
100% {
|
|
-webkit-transform: translateX(0px);
|
|
opacity: 1;
|
|
}
|
|
}
|
|
|
|
@-webkit-keyframes MenuAnimIn3 {
|
|
0% {
|
|
-webkit-transform: translateZ(300px);
|
|
opacity: 0;
|
|
}
|
|
100% {
|
|
-webkit-transform: translateZ(0px);
|
|
opacity: 1;
|
|
}
|
|
}
|
|
|
|
@-webkit-keyframes MenuAnimIn4 {
|
|
0% {
|
|
-webkit-transform: translateZ(-300px);
|
|
opacity: 0;
|
|
}
|
|
100% {
|
|
-webkit-transform: translateZ(0px);
|
|
opacity: 1;
|
|
}
|
|
}
|
|
|
|
@-webkit-keyframes MenuAnimIn5 {
|
|
0% {
|
|
-webkit-transform: translateY(40%);
|
|
opacity: 0;
|
|
}
|
|
100% {
|
|
-webkit-transform: translateY(0);
|
|
opacity: 1;
|
|
}
|
|
}
|
|
|
|
@keyframes MenuAnimIn1 {
|
|
0% {
|
|
-webkit-transform: translateZ(-500px) rotateY(0deg);
|
|
transform: translateZ(-500px) rotateY(0deg);
|
|
opacity: 0;
|
|
}
|
|
20% {
|
|
-webkit-transform: translateZ(-250px) rotateY(30deg);
|
|
transform: translateZ(-250px) rotateY(30deg);
|
|
opacity: 0.5;
|
|
}
|
|
100% {
|
|
-webkit-transform: translateZ(0px) rotateY(0deg);
|
|
transform: translateZ(0px) rotateY(0deg);
|
|
opacity: 1;
|
|
}
|
|
}
|
|
|
|
@keyframes MenuAnimIn2 {
|
|
0% {
|
|
-webkit-transform: translateX(-100%);
|
|
transform: translateX(-100%);
|
|
opacity: 0;
|
|
}
|
|
100% {
|
|
-webkit-transform: translateX(0px);
|
|
transform: translateX(0px);
|
|
opacity: 1;
|
|
}
|
|
}
|
|
|
|
@keyframes MenuAnimIn3 {
|
|
0% {
|
|
-webkit-transform: translateZ(300px);
|
|
transform: translateZ(300px);
|
|
opacity: 0;
|
|
}
|
|
100% {
|
|
-webkit-transform: translateZ(0px);
|
|
transform: translateZ(0px);
|
|
opacity: 1;
|
|
}
|
|
}
|
|
|
|
@keyframes MenuAnimIn4 {
|
|
0% {
|
|
-webkit-transform: translateZ(-300px);
|
|
transform: translateZ(-300px);
|
|
opacity: 0;
|
|
}
|
|
100% {
|
|
-webkit-transform: translateZ(0px);
|
|
transform: translateZ(0px);
|
|
opacity: 1;
|
|
}
|
|
}
|
|
|
|
@keyframes MenuAnimIn5 {
|
|
0% {
|
|
-webkit-transform: translateY(40%);
|
|
transform: translateY(40%);
|
|
opacity: 0;
|
|
}
|
|
100% {
|
|
-webkit-transform: translateY(0);
|
|
transform: translateY(0);
|
|
opacity: 1;
|
|
}
|
|
}
|
|
|
|
.dl-menuwrapper > .dl-submenu.dl-animate-in-1 {
|
|
-webkit-animation: SubMenuAnimIn1 0.4s ease;
|
|
animation: SubMenuAnimIn1 0.4s ease;
|
|
}
|
|
|
|
.dl-menuwrapper > .dl-submenu.dl-animate-in-2 {
|
|
-webkit-animation: SubMenuAnimIn2 0.3s ease-in-out;
|
|
animation: SubMenuAnimIn2 0.3s ease-in-out;
|
|
}
|
|
|
|
.dl-menuwrapper > .dl-submenu.dl-animate-in-3 {
|
|
-webkit-animation: SubMenuAnimIn3 0.4s ease;
|
|
animation: SubMenuAnimIn3 0.4s ease;
|
|
}
|
|
|
|
.dl-menuwrapper > .dl-submenu.dl-animate-in-4 {
|
|
-webkit-animation: SubMenuAnimIn4 0.4s ease;
|
|
animation: SubMenuAnimIn4 0.4s ease;
|
|
}
|
|
|
|
.dl-menuwrapper > .dl-submenu.dl-animate-in-5 {
|
|
-webkit-animation: SubMenuAnimIn5 0.4s ease;
|
|
animation: SubMenuAnimIn5 0.4s ease;
|
|
}
|
|
|
|
|
|
@-webkit-keyframes SubMenuAnimIn1 {
|
|
0% {
|
|
-webkit-transform: translateX(50%);
|
|
opacity: 0;
|
|
}
|
|
100% {
|
|
-webkit-transform: translateX(0px);
|
|
opacity: 1;
|
|
}
|
|
}
|
|
|
|
@-webkit-keyframes SubMenuAnimIn2 {
|
|
0% {
|
|
-webkit-transform: translateX(100%);
|
|
opacity: 0;
|
|
}
|
|
100% {
|
|
-webkit-transform: translateX(0px);
|
|
opacity: 1;
|
|
}
|
|
}
|
|
|
|
@-webkit-keyframes SubMenuAnimIn3 {
|
|
0% {
|
|
-webkit-transform: translateZ(-300px);
|
|
opacity: 0;
|
|
}
|
|
100% {
|
|
-webkit-transform: translateZ(0px);
|
|
opacity: 1;
|
|
}
|
|
}
|
|
|
|
@-webkit-keyframes SubMenuAnimIn4 {
|
|
0% {
|
|
-webkit-transform: translateZ(300px);
|
|
opacity: 0;
|
|
}
|
|
100% {
|
|
-webkit-transform: translateZ(0px);
|
|
opacity: 1;
|
|
}
|
|
}
|
|
|
|
@-webkit-keyframes SubMenuAnimIn5 {
|
|
0% {
|
|
-webkit-transform: translateZ(-200px);
|
|
opacity: 0;
|
|
}
|
|
100% {
|
|
-webkit-transform: translateZ(0);
|
|
opacity: 1;
|
|
}
|
|
}
|
|
|
|
@keyframes SubMenuAnimIn1 {
|
|
0% {
|
|
-webkit-transform: translateX(50%);
|
|
transform: translateX(50%);
|
|
opacity: 0;
|
|
}
|
|
100% {
|
|
-webkit-transform: translateX(0px);
|
|
transform: translateX(0px);
|
|
opacity: 1;
|
|
}
|
|
}
|
|
|
|
@keyframes SubMenuAnimIn2 {
|
|
0% {
|
|
-webkit-transform: translateX(100%);
|
|
transform: translateX(100%);
|
|
opacity: 0;
|
|
}
|
|
100% {
|
|
-webkit-transform: translateX(0px);
|
|
transform: translateX(0px);
|
|
opacity: 1;
|
|
}
|
|
}
|
|
|
|
@keyframes SubMenuAnimIn3 {
|
|
0% {
|
|
-webkit-transform: translateZ(-300px);
|
|
transform: translateZ(-300px);
|
|
opacity: 0;
|
|
}
|
|
100% {
|
|
-webkit-transform: translateZ(0px);
|
|
transform: translateZ(0px);
|
|
opacity: 1;
|
|
}
|
|
}
|
|
|
|
|
|
@keyframes SubMenuAnimIn4 {
|
|
0% {
|
|
-webkit-transform: translateZ(300px);
|
|
transform: translateZ(300px);
|
|
opacity: 0;
|
|
}
|
|
100% {
|
|
-webkit-transform: translateZ(0px);
|
|
transform: translateZ(0px);
|
|
opacity: 1;
|
|
}
|
|
}
|
|
|
|
@keyframes SubMenuAnimIn5 {
|
|
0% {
|
|
-webkit-transform: translateZ(-200px);
|
|
transform: translateZ(-200px);
|
|
opacity: 0;
|
|
}
|
|
100% {
|
|
-webkit-transform: translateZ(0);
|
|
transform: translateZ(0);
|
|
opacity: 1;
|
|
}
|
|
}
|
|
|
|
.dl-menuwrapper > .dl-submenu.dl-animate-out-1 {
|
|
-webkit-animation: SubMenuAnimOut1 0.4s ease;
|
|
animation: SubMenuAnimOut1 0.4s ease;
|
|
}
|
|
|
|
.dl-menuwrapper > .dl-submenu.dl-animate-out-2 {
|
|
-webkit-animation: SubMenuAnimOut2 0.3s ease-in-out;
|
|
animation: SubMenuAnimOut2 0.3s ease-in-out;
|
|
}
|
|
|
|
.dl-menuwrapper > .dl-submenu.dl-animate-out-3 {
|
|
-webkit-animation: SubMenuAnimOut3 0.4s ease;
|
|
animation: SubMenuAnimOut3 0.4s ease;
|
|
}
|
|
|
|
.dl-menuwrapper > .dl-submenu.dl-animate-out-4 {
|
|
-webkit-animation: SubMenuAnimOut4 0.4s ease;
|
|
animation: SubMenuAnimOut4 0.4s ease;
|
|
}
|
|
|
|
.dl-menuwrapper > .dl-submenu.dl-animate-out-5 {
|
|
-webkit-animation: SubMenuAnimOut5 0.4s ease;
|
|
animation: SubMenuAnimOut5 0.4s ease;
|
|
}
|
|
|
|
@-webkit-keyframes SubMenuAnimOut1 {
|
|
0% {
|
|
-webkit-transform: translateX(0%);
|
|
opacity: 1;
|
|
}
|
|
100% {
|
|
-webkit-transform: translateX(50%);
|
|
opacity: 0;
|
|
}
|
|
}
|
|
|
|
@-webkit-keyframes SubMenuAnimOut2 {
|
|
0% {
|
|
-webkit-transform: translateX(0%);
|
|
opacity: 1;
|
|
}
|
|
100% {
|
|
-webkit-transform: translateX(100%);
|
|
opacity: 0;
|
|
}
|
|
}
|
|
|
|
@-webkit-keyframes SubMenuAnimOut3 {
|
|
0% {
|
|
-webkit-transform: translateZ(0px);
|
|
opacity: 1;
|
|
}
|
|
100% {
|
|
-webkit-transform: translateZ(-300px);
|
|
opacity: 0;
|
|
}
|
|
}
|
|
|
|
@-webkit-keyframes SubMenuAnimOut4 {
|
|
0% {
|
|
-webkit-transform: translateZ(0px);
|
|
opacity: 1;
|
|
}
|
|
100% {
|
|
-webkit-transform: translateZ(300px);
|
|
opacity: 0;
|
|
}
|
|
}
|
|
|
|
@-webkit-keyframes SubMenuAnimOut5 {
|
|
0% {
|
|
-webkit-transform: translateZ(0);
|
|
opacity: 1;
|
|
}
|
|
100% {
|
|
-webkit-transform: translateZ(-200px);
|
|
opacity: 0;
|
|
}
|
|
}
|
|
|
|
@keyframes SubMenuAnimOut1 {
|
|
0% {
|
|
-webkit-transform: translateX(0%);
|
|
transform: translateX(0%);
|
|
opacity: 1;
|
|
}
|
|
100% {
|
|
-webkit-transform: translateX(50%);
|
|
transform: translateX(50%);
|
|
opacity: 0;
|
|
}
|
|
}
|
|
|
|
@keyframes SubMenuAnimOut2 {
|
|
0% {
|
|
-webkit-transform: translateX(0%);
|
|
transform: translateX(0%);
|
|
opacity: 1;
|
|
}
|
|
100% {
|
|
-webkit-transform: translateX(100%);
|
|
transform: translateX(100%);
|
|
opacity: 0;
|
|
}
|
|
}
|
|
|
|
@keyframes SubMenuAnimOut3 {
|
|
0% {
|
|
-webkit-transform: translateZ(0px);
|
|
transform: translateZ(0px);
|
|
opacity: 1;
|
|
}
|
|
100% {
|
|
-webkit-transform: translateZ(-300px);
|
|
transform: translateZ(-300px);
|
|
opacity: 0;
|
|
}
|
|
}
|
|
|
|
|
|
@keyframes SubMenuAnimOut4 {
|
|
0% {
|
|
-webkit-transform: translateZ(0px);
|
|
transform: translateZ(0px);
|
|
opacity: 1;
|
|
}
|
|
100% {
|
|
-webkit-transform: translateZ(300px);
|
|
transform: translateZ(300px);
|
|
opacity: 0;
|
|
}
|
|
}
|
|
|
|
@keyframes SubMenuAnimOut5 {
|
|
0% {
|
|
-webkit-transform: translateZ(0);
|
|
transform: translateZ(0);
|
|
opacity: 1;
|
|
}
|
|
100% {
|
|
-webkit-transform: translateZ(-200px);
|
|
transform: translateZ(-200px);
|
|
opacity: 0;
|
|
}
|
|
}
|
|
|
|
|
|
/* No JS Fallback */
|
|
.no-js .dl-menuwrapper .dl-menu {
|
|
position: relative;
|
|
opacity: 1;
|
|
-webkit-transform: none;
|
|
transform: none;
|
|
}
|
|
|
|
.no-js .dl-menuwrapper li .dl-submenu {
|
|
display: block;
|
|
}
|
|
|
|
.no-js .dl-menuwrapper li.dl-back {
|
|
display: none;
|
|
}
|
|
|
|
.no-js .dl-menuwrapper li > a:not(:only-child) {
|
|
background: rgba(0,0,0,0.1);
|
|
}
|
|
|
|
.no-js .dl-menuwrapper li > a:not(:only-child):after {
|
|
content: '';
|
|
}
|
|
|
|
|
|
/* Main Nav */
|
|
|
|
nav#main-nav {
|
|
display: block;
|
|
position: absolute;
|
|
top: 20px;
|
|
right: 205px;
|
|
}
|
|
|
|
@media screen and (max-width:1050px) {
|
|
nav#main-nav {
|
|
display: none;
|
|
}
|
|
}
|
|
|
|
nav#main-nav ul {
|
|
list-style: none;
|
|
}
|
|
|
|
nav#main-nav ul li {
|
|
float: left;
|
|
margin: 0 0 0 25px;
|
|
}
|
|
|
|
nav#main-nav ul li a {
|
|
color: white;
|
|
font-weight: bold;
|
|
text-transform: uppercase;
|
|
font-size: 13px;
|
|
}
|
|
|
|
body.elm-user-anonymous .show-loggedin {
|
|
display: none;
|
|
}
|
|
|
|
body.elm-user-pro-member .show-public {
|
|
display: none;
|
|
}
|
|
nav#elm-header-user-nav {
|
|
z-index:1000;
|
|
}/*]]>*/</style>
|
|
|
|
<link media="screen" type="text/css" rel="stylesheet" href="Developer%20Guide%20-%20Developer%20Network_files/viewer.css" id="mt-screen-css">
|
|
|
|
|
|
<link media="print" type="text/css" rel="stylesheet" href="Developer%20Guide%20-%20Developer%20Network_files/print.css" id="mt-print-css">
|
|
|
|
|
|
<script type="text/javascript" async="" src="Developer%20Guide%20-%20Developer%20Network_files/js" nonce=""></script><script type="text/javascript" async="" src="Developer%20Guide%20-%20Developer%20Network_files/js_002" nonce=""></script><script async="" src="Developer%20Guide%20-%20Developer%20Network_files/analytics.js"></script><script type="application/json" nonce="" id="mt-localizations-draft">
|
|
{"Draft.JS.alert.cancel.button":"OK","Draft.JS.alert.cancel.message":"You can not cancel a draft when the live page is unpublished.","Draft.JS.alert.cancel.title":"This draft cannot be canceled","Draft.JS.alert.publish.button":"OK","Draft.JS.alert.publish.message":"You can not publish a draft of a page with an unpublished parent","Draft.JS.alert.publish.title":"This draft cannot be published","Draft.JS.alert.unpublish.button":"OK","Draft.JS.alert.unpublish.message":"You can not unpublish a page when published subpages are present.","Draft.JS.alert.unpublish.title":"This page cannot be unpublished","Draft.JS.success.cancel":"The draft was successfully deleted.","Draft.JS.success.schedule.publish":"Publication schedule successfully created.","Draft.JS.success.publish":"The draft was successfully published.","Draft.JS.success.unpublish":"The page was successfully unpublished.","Draft.JS.success.unpublish.inherits-schedule\n Draft.JS.success.unpublish.scheduled-to-publish":"[MISSING: draft.js.success.unpublish.inherits-schedule\n draft.js.success.unpublish.scheduled-to-publish]","Draft.JS.success.update.schedule.publish":"Publication schedule successfully updated.","Draft.JS.success.update.schedule.unpublish":"[MISSING: draft.js.success.update.schedule.unpublish]","Draft.JS.success.delete.schedule\n Draft.JS.success.delete.schedule.with.subpages\n Draft.error.cancel":"[MISSING: draft.js.success.delete.schedule\n draft.js.success.delete.schedule.with.subpages\n draft.error.cancel]","Draft.error.publish":"There was an error publishing the draft.","Draft.error.unpublish":"There was an error unpublishing the page.","Draft.message.at":"at","Dialog.ConfirmSave.StrictIdf.title":"Oops!","Dialog.ConfirmSave.StrictIdf.error.missing-template-reference":"This article type requires a template reference widget. Not having one may negatively impact your site and SEO. Please contact NiCE Knowledge Management support.","Dialog.ConfirmSave.StrictIdf.label.continue":"Proceed anyway","Dialog.ConfirmSave.StrictIdf.label.cancel":"Cancel","Dialog.ConfirmSave.StrictIdf.label.missing-template-reference-help-link":"Learn more about required references","Dialog.ConfirmSave.StrictIdf.error.invalid-idf":"This type of article should not exist at the requested location in the site hierarchy. Proceeding with the requested move may negatively impact site navigation and SEO.","Dialog.ConfirmSave.StrictIdf.label.invalid-idf-help-link":"Learn more about IDF structure","Dialog.EditDraft.page-title":"Create draft","Dialog.Scheduler.Common.label.am":"{0} AM","Dialog.Scheduler.Common.label.pm":"{0} PM","Dialog.Scheduler.Publish.alert-create-draft":"Create","Dialog.Scheduler.Publish.alert-existing-publication-scheduled":"This location has an existing publication schedule applied. The new page will inherit this new schedule.","Dialog.Scheduler.Publish.alert-modify-message":"This draft is scheduled to be published {0} at {1}. A schedule cannot be modified or deleted less than 15 minutes from its start time.","Dialog.Scheduler.Publish.alert-modify-title":"This schedule cannot be modified","Dialog.Scheduler.Publish.button-close":"Close","Dialog.Scheduler.Publish.button-save":"Save publish schedule","Dialog.Scheduler.Publish.button-go-to-parent":"Go to parent","Dialog.Scheduler.Publish.do-not-have-permission-message":"This page will be published {0} with another page scheduled by {1}. You do not have permission to view this page. Please see {1} to resolve scheduling conflicts.","Dialog.Scheduler.Publish.go-to-parent-message":"This draft will be published {0}, scheduled by {1}. A schedule can only be modified where it was created.","Dialog.Scheduler.Publish.label.f1-link":"Learn about scheduled publishing","Dialog.Scheduler.Publish.page-title":"Publish","Dialog.Scheduler.Unpublish.button-save":"Save unpublish schedule","Dialog.Scheduler.Unpublish.alert-modify-message":"This page is scheduled to be unpublished {0} at {1}. A schedule cannot be modified or deleted less than 15 minutes from its start time.","Dialog.Scheduler.Unpublish.do-not-have-permission-message":"This page will be unpublished {0} with another page scheduled by {1}. You do not have permission to view this page. Please see {1} to resolve scheduling conflicts.","Dialog.Scheduler.Unpublish.go-to-parent-message":"This page will be unpublished {0}, scheduled by {1}. A schedule can only be modified where it was created.","Dialog.Scheduler.Unpublish.page-title":"Unpublish","Page.Dashboard.page-title":"Dashboard"} </script> <script type="application/json" nonce="" id="mt-localizations-editor">
|
|
{"Article.Attach.file.upload.toobig":"The file \"{1}\" is too large. The maximum allowed file size is {0}.","Article.Attach.file.upload.notAllowed":"The selected file can not be uploaded because you do not have permission to upload files of that type.","Article.Attach.file.upload.fileExtension":"You picked a file with an unsupported extension. Please try again with a valid file.","Article.Common.page-is-restricted-login":"You do not have permission to view this page - please try signing in.","Article.Common.page-save-conflict":"You may have overwritten a concurrent editor's changes. Use this page's <a title=\"Revision History\" target=\"_blank\" href=\"{0}\" >Revision History<\/a> to review.","Article.Error.page-couldnt-be-loaded":"The requested page's contents could not be loaded.","Article.Error.page-save-conflict":"A page already exists at {0}. Navigate to the existing page and edit the page if you wish to modify its contents.","Article.Error.page-save-forbidden":"Your session has expired or you do not have permission to edit this page.","Article.Error.page-title-required":"A page title is required.","Article.edit.summary":"Edit summary","Article.edit.summary-reason":"Why are you making this edit?","Article.edit.enter-reason":"Enter reason (viewable in Site History Report)","Component.YoutubeSearch.error.key-invalid":"Your YouTube API Key was improperly configured. Please review the article at the","Component.YoutubeSearch.error.key-missing":"Your NiCE Knowledge Management deployment needs to update your YouTube API Key. Details on how to update can be found at the","Component.YoutubeSearch.error.search-failed":"Search failed","Component.YoutubeSearch.info.not-found":"No videos found","Component.YoutubeSearch.label.video-url":"Video URL","Component.YoutubeSearch.placeholder.query":"Video URL or YouTube search query","Dialog.ConfirmCancel.button.continue-editing":"Continue editing","Dialog.ConfirmCancel.button.discard-changes":"Discard changes","Dialog.ConfirmCancel.message.changes-not-saved":"Your changes have not been saved to MindTouch.","Dialog.ConfirmCancel.title":"Discard changes?","Dialog.ConfirmDeleteRedirects.label.delete-redirects-help-link":"Learn more about deleting redirects","Dialog.ConfirmSave.error.redirect":"A redirect exists at this location and will be deleted if you continue. This may negatively impact your site and SEO. Please contact NiCE Knowledge Management support.","Dialog.ConfirmSave.label.cancel":"Cancel","Dialog.ConfirmSave.label.continue":"Continue","Dialog.ConfirmSave.title":"Delete redirect?","Dialog.ConfirmSave.StrictIdf.error.invalid-idf":"This type of article should not exist at the requested location in the site hierarchy. Proceeding with the requested move may negatively impact site navigation and SEO.","Dialog.ConfirmSave.StrictIdf.error.missing-template-reference-insert":"You've removed the template reference, which is required for this page. Click Insert to reinsert the template reference.","Dialog.ConfirmSave.StrictIdf.label.cancel":"Cancel","Dialog.ConfirmSave.StrictIdf.label.continue":"Proceed anyway","Dialog.ConfirmSave.StrictIdf.label.insert":"Insert","Dialog.ConfirmSave.StrictIdf.label.missing-template-reference-help-link":"Learn more about required references","Dialog.ConfirmSave.StrictIdf.label.invalid-idf-help-link":"Learn more about IDF structure","Dialog.ConfirmSave.StrictIdf.title":"Oops!","Dialog.JS.wikibits-edit-section":"Edit section","Dialog.SaveRequired.button.cancel":"Cancel","Dialog.SaveRequired.button.save":"Save and continue","Dialog.SaveRequired.label.change-title-start":"This page needs a different title than","Dialog.SaveRequired.label.change-title-end":"Please make the correction and try again.","Dialog.SaveRequired.label.new-page-alert":"This operation can not be performed on a page that has not yet been created. In order to do that, we need to quickly save what you have.","Dialog.SaveRequired.title":"Save required","Draft.error.save-unpublished":"You cannot save an unpublished draft at {0}. A published page already exists at that location.","GUI.Editor.alert-changes-made-without-saving":"You have made changes to the content without saving your changes. Are you sure you want to exit this page?","GUI.Editor.error.copy-hint":"To avoid losing your work, copy the page contents to a new file and retry saving again.","GUI.Editor.error.server-error":"A server error has occurred.","GUI.Editor.error.unable-to-save":"We are unable to save this page","Redist.CKE.mt-save.save-to-file-link":"Save the page content to a file","Redist.CKE.mt-autosave.contents-autosaved":"The page contents were autosaved to the browser's local storage {0}","System.API.Error.invalid-redirect":"Cannot create a redirect on a page with sub-pages.","System.API.Error.invalid-redirect-target":"The redirect does not point at a valid page."} </script> <script type="application/json" nonce="" id="mt-localizations-file-uploader">
|
|
{"Dialog.Attach.allowed-types":"Allowed file types:","Dialog.Attach.button.upload":"Upload","Dialog.Attach.choose-files-dad":"Choose files to upload or drag and drop files into this window.","Dialog.Attach.max-size":"Maximum upload file size: {0}"} </script> <script type="application/json" nonce="" id="mt-localizations-grid-widget">
|
|
{"Article.Common.page-is-restricted-login":"You do not have permission to view this page - please try signing in.","MindTouch.Help.Page.search-unavailable":"Sorry, search is currently unavailable.","MindTouch.Reports.data.empty-grid-text":"No Data Available.","Page.StructuredTags.error-update":"An unknown error occurred."} </script> <script type="application/json" nonce="" id="mt-localizations-tree-widget">
|
|
{"Skin.Common.home":"Home","Dialog.Common.error.path-not-found":"The requested page or section could not be loaded. Please update the link.","Dialog.JS.loading":"Loading...","Dialog.JS.loading.copy":"Copying page(s)...","Dialog.JS.loading.insertImage":"Inserting image...","Dialog.JS.loading.move":"Moving page(s)...","Dialog.JS.loading.moveFile":"Moving file...","Dialog.JS.loading.search":"Searching...","MindTouch.Help.Page.in":"in","MindTouch.Help.Page.no-search-results":"Sorry, we can't find what you are looking for.","MindTouch.Help.Page.no-search-try":"Try searching for something else, selecting a category, or try creating a ticket.","MindTouch.Help.Page.retrysearch":"Click here to search the whole site.","MindTouch.Help.Page.search-error-try":"Please try again later.","MindTouch.Help.Page.search-unavailable":"Sorry, search is currently unavailable."} </script> <script type="application/json" nonce="" id="mt-localizations-dialog">
|
|
{"Dialog.Common.button.cancel":"Cancel","Dialog.Common.button.ok":"OK","Dialog.Common.label.home":"Home"} </script>
|
|
<script type="text/javascript" data-mindtouch-module="true" nonce="" src="Developer%20Guide%20-%20Developer%20Network_files/globals.jqueryv2.2.4.js"></script><script type="application/json" id="mt-global-settings">{}</script><script type="text/javascript" data-mindtouch-module="true" nonce="" src="Developer%20Guide%20-%20Developer%20Network_files/deki.legacy.js"></script><script type="text/javascript" data-mindtouch-module="true" nonce="" src="Developer%20Guide%20-%20Developer%20Network_files/community.js"></script><script type="text/javascript" data-mindtouch-module="true" nonce="" src="Developer%20Guide%20-%20Developer%20Network_files/skin_elm.js"></script><script type="text/javascript" data-mindtouch-module="true" nonce="" src="Developer%20Guide%20-%20Developer%20Network_files/pageBootstrap.js"></script>
|
|
|
|
|
|
<link type="text/css" rel="stylesheet" href="Developer%20Guide%20-%20Developer%20Network_files/shCore.min.css"><link type="text/css" rel="stylesheet" href="Developer%20Guide%20-%20Developer%20Network_files/shThemeCedar.min.css"><script type="text/javascript" src="Developer%20Guide%20-%20Developer%20Network_files/shCore.min.js"></script><script type="text/javascript" src="Developer%20Guide%20-%20Developer%20Network_files/shBrushCss.min.js"></script><script type="text/javascript">/*<![CDATA[*/SyntaxHighlighter.all();/*]]>*/</script><script type="text/javascript" src="Developer%20Guide%20-%20Developer%20Network_files/shBrushJScript.min.js"></script><script type="text/javascript" src="Developer%20Guide%20-%20Developer%20Network_files/shBrushCSharp.min.js"></script><script type="text/javascript" src="Developer%20Guide%20-%20Developer%20Network_files/modernizr.js"></script><link href="Developer%20Guide%20-%20Developer%20Network_files/font-awesome.min.css" rel="stylesheet"><style type="text/css">.tk-proxima-nova{font-family:"proxima-nova",sans-serif;}</style><style type="text/css">@font-face{font-family:proxima-nova;src:url(https://use.typekit.net/af/7d485b/00000000000000003b9ad1b1/27/l?subset_id=2&fvd=n7&v=3) format("woff2"),url(https://use.typekit.net/af/7d485b/00000000000000003b9ad1b1/27/d?subset_id=2&fvd=n7&v=3) format("woff"),url(https://use.typekit.net/af/7d485b/00000000000000003b9ad1b1/27/a?subset_id=2&fvd=n7&v=3) format("opentype");font-weight:700;font-style:normal;font-stretch:normal;font-display:auto;}@font-face{font-family:proxima-nova;src:url(https://use.typekit.net/af/347aea/00000000000000003b9ad1b2/27/l?subset_id=2&fvd=i7&v=3) format("woff2"),url(https://use.typekit.net/af/347aea/00000000000000003b9ad1b2/27/d?subset_id=2&fvd=i7&v=3) format("woff"),url(https://use.typekit.net/af/347aea/00000000000000003b9ad1b2/27/a?subset_id=2&fvd=i7&v=3) format("opentype");font-weight:700;font-style:italic;font-stretch:normal;font-display:auto;}@font-face{font-family:proxima-nova;src:url(https://use.typekit.net/af/04b81b/00000000000000003b9ad1bb/27/l?subset_id=2&fvd=n6&v=3) format("woff2"),url(https://use.typekit.net/af/04b81b/00000000000000003b9ad1bb/27/d?subset_id=2&fvd=n6&v=3) format("woff"),url(https://use.typekit.net/af/04b81b/00000000000000003b9ad1bb/27/a?subset_id=2&fvd=n6&v=3) format("opentype");font-weight:600;font-style:normal;font-stretch:normal;font-display:auto;}@font-face{font-family:proxima-nova;src:url(https://use.typekit.net/af/c9cde8/00000000000000003b9ad1b9/27/l?subset_id=2&fvd=n4&v=3) format("woff2"),url(https://use.typekit.net/af/c9cde8/00000000000000003b9ad1b9/27/d?subset_id=2&fvd=n4&v=3) format("woff"),url(https://use.typekit.net/af/c9cde8/00000000000000003b9ad1b9/27/a?subset_id=2&fvd=n4&v=3) format("opentype");font-weight:400;font-style:normal;font-stretch:normal;font-display:auto;}@font-face{font-family:proxima-nova;src:url(https://use.typekit.net/af/4ba64f/00000000000000003b9ad1ba/27/l?subset_id=2&fvd=i4&v=3) format("woff2"),url(https://use.typekit.net/af/4ba64f/00000000000000003b9ad1ba/27/d?subset_id=2&fvd=i4&v=3) format("woff"),url(https://use.typekit.net/af/4ba64f/00000000000000003b9ad1ba/27/a?subset_id=2&fvd=i4&v=3) format("opentype");font-weight:400;font-style:italic;font-stretch:normal;font-display:auto;}@font-face{font-family:proxima-nova;src:url(https://use.typekit.net/af/3333ef/00000000000000003b9ad1b5/27/l?subset_id=2&fvd=n3&v=3) format("woff2"),url(https://use.typekit.net/af/3333ef/00000000000000003b9ad1b5/27/d?subset_id=2&fvd=n3&v=3) format("woff"),url(https://use.typekit.net/af/3333ef/00000000000000003b9ad1b5/27/a?subset_id=2&fvd=n3&v=3) format("opentype");font-weight:300;font-style:normal;font-stretch:normal;font-display:auto;}</style><script src="Developer%20Guide%20-%20Developer%20Network_files/puk4twq.js"></script><script>/*<![CDATA[*/try{Typekit.load();}catch(e){}/*]]>*/</script><script type="text/javascript" src="Developer%20Guide%20-%20Developer%20Network_files/jquery.cookie.js"></script><script type="text/javascript" src="Developer%20Guide%20-%20Developer%20Network_files/devnet.js"></script><script type="text/javascript" src="Developer%20Guide%20-%20Developer%20Network_files/responsive-tables.js"></script><script type="text/javascript" src="Developer%20Guide%20-%20Developer%20Network_files/jquery.dlmenu.js"></script>
|
|
|
|
<script type="text/javascript" nonce="">(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)})(window,document,'script','//www.google-analytics.com/analytics.js','ga');ga('create','UA-3249818-20','developer.connectwise.com',{allowLinker:true});ga('send','pageview');ga('create','UA-65721316-4','auto',{name:'mtTracker',allowLinker:true});ga('mtTracker.require','linker');ga('mtTracker.set', 'anonymizeIp', true);ga('mtTracker.send','pageview');document.addEventListener('mindtouch-web-widget:f1:loaded',function(e){var t=e.data||{},d=t.widget;d&&''!==t.embedId&&document.addEventListener('mindtouch-web-widget:f1:clicked',function(e){var t=(e.data||{}).href;if(t){var n=document.createElement('a');n.setAttribute('href',t),'expert-help.nice.com'===n.hostname&&(e.preventDefault(),ga('linker:decorate',n),d.open(n.href))}})});</script>
|
|
<style id="mt-fixed-header-styles"></style></head>
|
|
<body class="elm-user-community columbia-page-main columbia-article-topic-guide columbia-browser-firefox columbia-platform-windows columbia-breadcrumb-home-products-connectwisepsa-developerguide columbia-live no-touch columbia-lang-en-us columbia-skin-elm columbia-group-developer columbia-group-connectwise-developer" style="margin-top: 40px;">
|
|
<a class="elm-skip-link" href="#elm-main-content" title="Press enter to skip to the main content">Skip to main content</a><main class="elm-skin-container" data-ga-category="Community | page">
|
|
<header class="elm-header">
|
|
<div class="elm-header-custom"><div class="header-blue"><div class="header-wrapper"><a id="cw-logo" href="https://developer.connectwise.com/" rel="internal"><img class="internal" alt="CWLogo-R-Reg_Horz-White.png" loading="lazy" src="Developer%20Guide%20-%20Developer%20Network_files/CWLogo-R-Reg_Horz-White.png"></a><div id="dl-menu" class="dl-menuwrapper"><button class="dl-trigger">Open Menu</button><ul class="dl-menu"><li><a href="https://developer.connectwise.com/Best_Practices/Getting_Started" rel="internal">Get Started</a></li><li><a href="https://developer.connectwise.com/Products" rel="internal">Documentation</a></li><li class="show-loggedin"><a href="https://developer.connectwise.com/Special:ClientId" rel="internal">ClientId</a></li><li class="show-public"><a href="https://virtualcommunity.connectwise.com/community-home?CommunityKey=b91ec22c-a6ca-4ae3-bedb-018a5199538b" target="_blank" rel="external noopener nofollow" class="link-https">Developer Community</a></li><li class="show-loggedin"><a href="https://developer.connectwise.com/Special:faq" rel="internal">FAQ</a></li><li><a href="https://marketplace.connectwise.com/" target="_blank" rel="external noopener nofollow" class="link-https">Marketplace</a></li><li class="show-public"><a href="https://developer.connectwise.com/Special:Userlogin" rel="internal">Login</a></li><li class="show-public"><a href="https://register.developer.connectwise.com/" target="_blank" rel="external noopener nofollow" class="link-https">Register</a></li><li class="show-loggedin"><a href="https://developer.connectwise.com/Special:Preferences" rel="internal">Preferences</a></li><li class="show-loggedin"><a href="https://developer.connectwise.com/Special:Userlogout" rel="internal">Logout</a></li></ul></div><nav id="main-nav"><ul><li><a href="https://developer.connectwise.com/Best_Practices/Getting_Started" rel="internal">Get Started</a></li><li><a href="https://developer.connectwise.com/Products" rel="internal">Documentation</a></li><li class="show-loggedin"><a href="https://developer.connectwise.com/ClientID" rel="internal">ClientId</a></li><li><a href="https://virtualcommunity.connectwise.com/community-home?CommunityKey=b91ec22c-a6ca-4ae3-bedb-018a5199538b" target="_blank" rel="external noopener nofollow" class="link-https">Developer Community</a></li><li><a href="https://marketplace.connectwise.com/" target="_blank" rel="external noopener nofollow" class="link-https">Marketplace</a></li></ul></nav><div class="action-items anonymous-user"><button id="toggleSearch"><i class="fa fa-search"></i></button><a href="https://developer.connectwise.com/Special:Userlogin" rel="internal">Login</a><a href="https://register.developer.connectwise.com/" target="_blank" rel="external noopener nofollow" class="link-https">Register</a></div><div class="action-items confirmed-user"><button id="toggleSearch"><i class="fa fa-search"></i></button><a href="https://developer.connectwise.com/Special:Preferences" rel="internal">Preferences</a><a href="https://developer.connectwise.com/Special:Userlogout" rel="internal">Logout</a></div></div></div><div id="search-cw" style="display:none;"><form action="/Special:Search"><input name="qid" id="mt-qid-skin" type="hidden" value=""><input name="fpid" id="mt-search-filter-id" type="hidden" value=""><input name="fpth" id="mt-search-filter-path" type="hidden"><input name="path" id="mt-search-path" type="hidden" value=""><input class="mt-text mt-search search-field" name="search" id="mt-site-search-input" placeholder="Search..." tabindex="1" type="search"><button class="mt-button ui-button-icon mt-icon-site-search-button search-button" tabindex="2" type="submit">Search</button></form></div><div class="style-wrap" style="display: none;"><div id="mt-useremail">user@example.invalid</div></div>
|
|
|
|
|
|
|
|
<script type="text/javascript">/*<![CDATA[*/
|
|
$(document).ready(function(){
|
|
$("button#toggleSearch").click(function(){
|
|
$("#search-cw").toggle();
|
|
});
|
|
$( '#dl-menu' ).dlmenu();
|
|
});
|
|
$(document).ready(function(){
|
|
$('li:contains("API Version 1.5")').remove();
|
|
});/*]]>*/</script>
|
|
|
|
|
|
|
|
<div class="style-wrap"><input id="mt-manage" type="hidden" value="1"></div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
</div>
|
|
<div class="elm-nav mt-translate-module" hidden="true">
|
|
<div class="elm-nav-container mt-translate-container"></div>
|
|
</div>
|
|
<div class="elm-header-logo-container">
|
|
<a href="https://developer.connectwise.com/" title="Developer Network" aria-label="Link to home"><img src="Developer%20Guide%20-%20Developer%20Network_files/1680273416-logo.png" alt="Developer Network"></a>
|
|
</div>
|
|
|
|
<nav class="elm-header-user-nav elm-nav" role="navigation">
|
|
<div class="elm-nav-container">
|
|
<ol>
|
|
<li class="elm-global-search" data-ga-action="Header search"><a class="mt-icon-site-search mt-toggle-form" href="#" title="Search site">Search site</a>
|
|
<div class="mt-quick-search-container mt-toggle-form-container">
|
|
<form action="/Special:Search">
|
|
<input name="qid" id="mt-qid-skin" type="hidden" value="">
|
|
<input name="fpid" id="mt-search-filter-id" type="hidden" value="230">
|
|
<input name="fpth" id="mt-search-filter-path" type="hidden">
|
|
<input name="path" id="mt-search-path" type="hidden" value="">
|
|
|
|
<label class="mt-label" for="mt-site-search-input">
|
|
Search
|
|
</label>
|
|
<input class="mt-text mt-search search-field" name="q" id="mt-site-search-input" placeholder="How can we help you?" type="search">
|
|
<button class="mt-button ui-button-icon mt-icon-site-search-button search-button" type="submit">
|
|
Search
|
|
</button>
|
|
</form>
|
|
</div>
|
|
<div class="elm-search-back"><a class="mt-icon-browser-back" data-ga-label="Browse back" href="#" id="mt-browser-back" title="Go back to previous article">Go back to previous article</a></div>
|
|
</li>
|
|
<li class="elm-user-menu"><ol class="mt-user-menu">
|
|
<li class="mt-user-menu-user">
|
|
<a class="mt-icon-user-menu mt-dropdown-link" href="#" title="">redacted-hub-copy</a>
|
|
<ol class="mt-user-menu-container mt-dropdown" style="">
|
|
<li class="mt-user-menu-preferences">
|
|
<a class="mt-icon-user-preferences" href="https://developer.connectwise.com/Special:Preferences" title="Click to change your user preferences">My preferences</a>
|
|
</li>
|
|
<li class="mt-user-menu-signout">
|
|
<a class="mt-icon-user-sign-out" href="https://developer.connectwise.com/Special:UserLogout?returntotitle=Products%2FConnectWise_PSA%2FDeveloper_Guide" title="Click to sign out of this site">Sign out</a>
|
|
</li>
|
|
</ol>
|
|
</li>
|
|
</ol></li>
|
|
</ol>
|
|
</div>
|
|
</nav>
|
|
<nav class="elm-header-global-nav elm-nav elm-fixed-header" data-ga-action="Elm Navigation" style="top: 0px;">
|
|
<div class="elm-nav-container">
|
|
<button class="elm-hierarchy-trigger mt-hierarchy-trigger ui-button-icon mt-icon-hierarchy-trigger-closed" title="Expand/collapse global hierarchy" data-ga-label="Hierarchy Toggle - Tree View">
|
|
Expand/collapse global hierarchy
|
|
</button>
|
|
<ol class="mt-breadcrumbs" data-ga-action="Breadcrumbs">
|
|
<li>
|
|
<a href="https://developer.connectwise.com/" data-ga-label="Breadcrumb category">
|
|
<span class="mt-icon-article-category mt-icon-article-home"></span>
|
|
Home
|
|
</a>
|
|
</li>
|
|
<li>
|
|
<a href="https://developer.connectwise.com/Products" data-ga-label="Breadcrumb category">
|
|
<span class="mt-icon-article-category"></span>
|
|
Products
|
|
</a>
|
|
</li>
|
|
<li>
|
|
<a href="https://developer.connectwise.com/Products/ConnectWise_PSA" data-ga-label="Breadcrumb category">
|
|
<span class="mt-icon-article-category"></span>
|
|
ConnectWise PSA
|
|
</a>
|
|
</li>
|
|
<li class="mt-breadcrumbs-current-page">
|
|
<span class="mt-icon-article-guide"></span>
|
|
Developer Guide
|
|
</li>
|
|
</ol>
|
|
<button class="mt-icon-hierarchy-mobile-view-trigger ui-button-icon mt-icon-hierarchy-mobile-trigger-closed" title="Expand/collapse global location" data-ga-label="Hierarchy Toggle - Breadcrumb Expand/Collapse">
|
|
Expand/collapse global location
|
|
</button>
|
|
</div>
|
|
</nav>
|
|
<nav class="elm-nav elm-header-hierarchy">
|
|
<div class="elm-nav-container">
|
|
<div class="elm-hierarchy mt-hierarchy"></div>
|
|
</div>
|
|
</nav> <div class="elm-nav mt-review-banner" hidden="true"></div>
|
|
</header>
|
|
<article class="elm-content-container" id="elm-main-content" tabindex="-1">
|
|
<header>
|
|
<div id="flash-messages"><div class="dekiFlash"></div></div>
|
|
|
|
|
|
<h1 id="title" data-title-editor-available="false">
|
|
Developer Guide
|
|
</h1>
|
|
|
|
|
|
|
|
|
|
<ol class="elm-meta-data elm-meta-top" data-ga-action="Page actions">
|
|
<li class="elm-last-modified"><dl class="mt-last-updated-container">
|
|
<dt class="mt-last-updated-label">Last updated</dt>
|
|
<dd>
|
|
<span class="mt-last-updated" data-timestamp="2025-04-08T15:54:36Z">Apr 8, 2025</span>
|
|
</dd>
|
|
</dl>
|
|
</li>
|
|
<li class="elm-pdf-export"><a data-ga-label="PDF" href="https://developer.connectwise.com/@api/deki/pages/901/pdf/Developer%2bGuide.pdf" rel="nofollow" target="_blank" title="Export page as a PDF">
|
|
<span class="mt-icon-article-pdf"></span>Save as PDF
|
|
</a></li>
|
|
<li class="elm-social-share"></li>
|
|
</ol>
|
|
|
|
|
|
</header>
|
|
<header class="mt-content-header"></header>
|
|
<aside class="mt-content-side"></aside>
|
|
<aside id="mt-toc-container" data-title="Table of contents" data-collapsed="false" class="mt-toggle-container"><button class="mt-toggle mt-summary-toggle ui-button-icon mt-toggle-collapse" type="button">Table of contents</button>
|
|
<nav class="mt-toc-content mt-collapsible-section">
|
|
<ol><li><a href="#ClientIds" rel="internal">ClientIds</a><ol><li><a href="#What_is_a_clientId.3F" rel="internal">What is a clientId?</a></li><li><a href="#Asked_for_a_clientId.3F" rel="internal">Asked for a clientId? </a></li><li><a href="#Follow_this_link_to_obtain_a_clientId" rel="internal">Follow this link to obtain a clientId</a></li></ol></li><li><a href="#Versioning" rel="internal">Versioning</a></li><li><a href="#What_is_a_breaking_change.3F" rel="internal">What is a breaking change?</a><ol><li><a href="#Examples_of_breaking_changes:" rel="internal">Examples of breaking changes:</a></li><li><a href="#NOT_a_breaking_change:" rel="internal">NOT a breaking change:</a></li></ol></li><li><a href="#Formatting_Version_Header" rel="internal">Formatting Version Header</a></li><li><a href="#Per_Endpoint" rel="internal">Per Endpoint</a></li><li><a href="#Authentication" rel="internal">Authentication</a><ol><li><a href="#Postman_Example" rel="internal">Postman Example</a></li><li><a href="#Obtaining_your_Keys" rel="internal">Obtaining your Keys</a></li></ol></li><li><a href="#Rate_Limiting" rel="internal">Rate Limiting</a></li><li><a href="#Security" rel="internal">Security</a></li><li><a href="#HTTP_Methods" rel="internal">HTTP Methods</a></li><li><a href="#HTTP_Response_Statuses" rel="internal">HTTP Response Statuses</a></li><li><a href="#Formatting_Each_Method" rel="internal">Formatting Each Method</a><ol><li><a href="#Get" rel="internal">Get</a><ol><li><a href="#URL_Max_Length" rel="internal">URL Max Length</a></li><li><a href="#Query_String_Parameters" rel="internal">Query String Parameters</a></li><li><a href="#Conditions" rel="internal">Conditions</a></li><li><a href="#Using_the_.2FSearch_endpoints" rel="internal">Using the /Search endpoints</a></li></ol></li><li><a href="#Patch" rel="internal">Patch</a></li><li><a href="#Delete" rel="internal">Delete</a></li><li><a href="#Post" rel="internal">Post</a></li><li><a href="#Put" rel="internal">Put</a></li><li><a href="#Escaping_Characters" rel="internal">Escaping Characters</a></li><li><a href="#Partial_Responses" rel="internal">Partial Responses</a></li><li><a href="#Custom_Fields" rel="internal">Custom Fields</a><ol><li><a href="#Field_Options_and_Parameters" rel="internal">Field Options and Parameters</a></li></ol></li><li><a href="#Pagination" rel="internal">Pagination</a><ol><li><a href="#Navigable" rel="internal">Navigable</a></li><li><a href="#Forward-Only" rel="internal">Forward-Only</a></li></ol></li></ol></li><li><a href="#Callbacks_(Webhooks)" rel="internal">Callbacks (Webhooks)</a><ol><li><a href="#Levels_and_Types" rel="internal">Levels and Types</a></li><li><a href="#Configuring_the_Callbacks" rel="internal">Configuring the Callbacks</a></li><li><a href="#Testing_Callbacks" rel="internal">Testing Callbacks</a><ol><li><a href="#Webhook.Site" rel="internal">Webhook.Site</a></li></ol></li><li><a href="#When_Callbacks_Fail_to_POST_to_Target_Host" rel="internal">When Callbacks Fail to POST to Target Host</a></li><li><a href="#Verifying_the_Callback_Source" rel="internal">Verifying the Callback Source</a></li><li><a href="#Callback_Changelog" rel="internal">Callback Changelog </a></li></ol></li><li><a href="#Troubleshooting" rel="internal">Troubleshooting</a><ol><li><a href="#Reading_Logs" rel="internal">Reading Logs</a></li><li><a href="#Telerik's_Fiddler" rel="internal">Telerik's Fiddler</a></li><li><a href="#Error_Handling" rel="internal">Error Handling</a><ol><li><a href="#Retry_Policy" rel="internal">Retry Policy</a></li><li><a href="#500_Server_Errors" rel="internal">500 Server Errors</a></li><li><a href="#400_Client_Errors" rel="internal">400 Client Errors</a></li></ol></li></ol></li><li><a href="#REST_SDK_Downloads" rel="internal">REST SDK Downloads</a></li><li><a href="#Document_API" rel="internal">Document API</a></li><li><a href="#Calling_Company_Info" rel="internal">Calling Company Info</a><ol><li><a href="#Response" rel="internal">Response</a></li></ol></li><li><a href="#API_Request_URL_Format" rel="internal">API Request URL Format</a></li><li><a href="#Cloud_vs_Premise" rel="internal">Cloud vs Premise</a></li><li><a href="#Cloud_URLs" rel="internal">Cloud URLs</a></li></ol>
|
|
</nav>
|
|
</aside>
|
|
<section class="mt-content-container">
|
|
|
|
|
|
<div class="mt-contentreuse-widget" data-page="AddTOC" data-section="" data-show="">
|
|
<div class="mt-include" id="s1121">
|
|
</div>
|
|
</div>
|
|
|
|
<div mt-section-origin="Products/ConnectWise_PSA/Developer_Guide" class="mt-section" id="section_1"><span id="ClientIds"></span><h3 class="editable">ClientIds</h3>
|
|
|
|
<div mt-section-origin="Products/ConnectWise_PSA/Developer_Guide" class="mt-section" id="section_2"><span id="What_is_a_clientId.3F"></span><h4 class="editable"><span class="mt-color-000000">What is a clientId?</span></h4>
|
|
|
|
<p><span class="mt-color-000000">A clientId is a unique GUID or Globally
|
|
Unique Identifier assigned to each integration. This clientId is
|
|
required for all API calls made by your integration. This will be used
|
|
to monitor integration performance and systems' health.</span></p>
|
|
|
|
</div><div mt-section-origin="Products/ConnectWise_PSA/Developer_Guide" class="mt-section" id="section_3"><span id="Asked_for_a_clientId.3F"></span><h4 class="editable"><span class="mt-color-000000">Asked for a clientId? </span></h4>
|
|
|
|
<p><span class="mt-color-000000">You should never share your clientId,
|
|
doing so may result in issues relating to integrations in your
|
|
environments. A clientId is unique to your company and is used to
|
|
say that API traffic is coming from your source. It should be
|
|
treated as a sort of password and identifier for your company. We
|
|
may disable any clientId that looks to have been compromised if we
|
|
suspect any abuse. <strong><strong>If anyone asks you to provide a clientId value, do not do so.</strong></strong>
|
|
The only exception to this rule would be integrations where you
|
|
yourself are creating it. For instance, if you use Zapier and use
|
|
the Zapier Code function and add your own API call, not in the
|
|
ConnectWise PSA package. If a tool requires that you enter in the
|
|
API full path, the body, and request, map it to different things or
|
|
otherwise is a custom tool that the vendor is not actually developing
|
|
the calls, you may have to enter your clientId. Do not provide
|
|
clientId values to integrations that are designed "out-of-the-box" and
|
|
apply to all users. An example would be the Automate to
|
|
ConnectWise PSA integration. That is an integration that is the
|
|
same for every user and the clientId would be set up by the third-party
|
|
integration. Automate controls the Ids around that integration
|
|
themselves.</span></p>
|
|
|
|
<blockquote>
|
|
<div mt-section-origin="Products/ConnectWise_PSA/Developer_Guide" class="mt-section"><span id="Follow_this_link_to_obtain_a_clientId"></span><h4 class="editable"><a title="ClientID" href="https://developer.connectwise.com/ClientID" rel="internal"><span class="mt-color-000000">Follow this link to obtain a clientId</span></a></h4>
|
|
</div></blockquote>
|
|
|
|
</div></div><div mt-section-origin="Products/ConnectWise_PSA/Developer_Guide" class="mt-section" id="section_4"><span id="Versioning"></span><h3 class="editable">Versioning</h3>
|
|
|
|
<div class="mt-contentreuse-widget" data-page="Manage/API_Versioning" data-section="" data-show="">
|
|
<div class="mt-include" id="s1118"><p><span class="mt-color-000000">Starting
|
|
with 2019.1 the API is now tied to the ConnectWise PSA release
|
|
cycle. Previously the API was versioned as it's own entity and
|
|
followed a format such as 3.0.1. To provide clarity around the API
|
|
Versioning and to make it easier for consumers, we have replaced 3.0.0
|
|
with the specific ConnectWise PSA version that the API model was
|
|
released on.</span></p>
|
|
|
|
<p><span class="mt-color-000000">If you develope your API against 2019.1
|
|
and pass in the version 2019.1, you will continue to get the models for
|
|
2019.1 even if we change them in 2019.2. What this means is that
|
|
each time we release a breaking change, you have a period of time to
|
|
switch over to the new version. We do not release new models every
|
|
release, however you can still target a version that did not have any
|
|
changes. For instance, lets say in 2019.1 we have a specific
|
|
ticket model called A. In 2019.4 we update tickets to have model
|
|
B. If you pass 2019.1, 2019.2 or 2019.3, you will get model A,
|
|
which is 2019.1.</span></p>
|
|
|
|
<p><span class="mt-color-000000">By default all requests will receive
|
|
the latest version of our API endpoint. As breaking changes are
|
|
released, each individual API endpoint, may receive an updated version.
|
|
In order to prevent your integration from breaking, we encourage
|
|
you to request a specific version using an Accept header. For all
|
|
production level integrations we recommend using this Accept header
|
|
concept and for all development and testing work, we recommend using the
|
|
latest version of the API. We will regularly deprecate old
|
|
models of the API.</span></p>
|
|
|
|
<div mt-section-origin="Best_Practices/PSA_Versioning" class="mt-section" id="section_1"><span id="What_is_a_breaking_change.3F"></span><h3 id="What_is_a_breaking_change.3F-1118">What is a breaking change?</h3>
|
|
|
|
<p><span class="mt-color-000000">Breaking changes are defined as any
|
|
change to the APIs that could result in an error being returned by the
|
|
SDK. The SDK is a JSON interpreter and as long as you develop your
|
|
code the way a modern JSON interpreter would, you shouldn't have any
|
|
issues. If you hard code every field, you will have issues that we
|
|
don't consider breaking.</span></p>
|
|
|
|
<div mt-section-origin="Best_Practices/PSA_Versioning" class="mt-section" id="section_2"><span id="Examples_of_breaking_changes:"></span><h4 id="Examples_of_breaking_changes:-1118"><span class="mt-color-000000"><strong><span class="mt-font-Helvetica,sans-serif"><span class="mt-font-size-11.5pt">Examples of breaking changes:</span></span></strong></span></h4>
|
|
|
|
<ul>
|
|
<li>
|
|
<p><span class="mt-color-000000">Renaming a field (fixing a typo)</span></p>
|
|
</li>
|
|
<li>
|
|
<p><span class="mt-color-000000"><span class="mt-font-Helvetica,sans-serif"><span class="mt-font-size-11.5pt">Changing a field's data type (such as from an int to a decimal, or from editable to read only)</span></span></span></p>
|
|
</li>
|
|
<li>
|
|
<p><span class="mt-color-000000"><span class="mt-font-Helvetica,sans-serif"><span class="mt-font-size-11.5pt">Changing the response type (such as from an object to an array of objects)</span></span></span></p>
|
|
</li>
|
|
<li>
|
|
<p><span class="mt-color-000000"><span class="mt-font-Helvetica,sans-serif"><span class="mt-font-size-11.5pt">Validation changes (fields now required that previously were not)</span></span></span></p>
|
|
</li>
|
|
</ul>
|
|
|
|
</div><div mt-section-origin="Best_Practices/PSA_Versioning" class="mt-section" id="section_3"><span id="NOT_a_breaking_change:"></span><h4 id="NOT_a_breaking_change:-1118"><span class="mt-color-000000"><strong><span class="mt-font-Helvetica,sans-serif"><span class="mt-font-size-11.5pt">NOT a breaking change:</span></span></strong></span></h4>
|
|
|
|
<ul>
|
|
<li>
|
|
<p><span class="mt-color-000000">Adding new fields</span></p>
|
|
</li>
|
|
<li>
|
|
<p><span class="mt-color-000000"><span class="mt-font-Helvetica,sans-serif"><span class="mt-font-size-11.5pt">Adding new endpoints</span></span></span></p>
|
|
</li>
|
|
<li>
|
|
<p><span class="mt-color-000000"><span class="mt-font-Helvetica,sans-serif"><span class="mt-font-size-11.5pt">Making a read only field editable</span></span></span></p>
|
|
</li>
|
|
<li>
|
|
<p><span class="mt-color-000000"><span class="mt-font-Helvetica,sans-serif"><span class="mt-font-size-11.5pt">Making a field no longer required if it was previously required</span></span></span></p>
|
|
</li>
|
|
</ul>
|
|
|
|
<blockquote>
|
|
<p>As we release breaking changes the individual endpoint will be
|
|
versioned when applicable. The previous version will be immediately be
|
|
considered deprecated but supported for 12 months. Please note
|
|
that some endpoints cannot be versioned.</p>
|
|
</blockquote>
|
|
|
|
</div></div><div mt-section-origin="Best_Practices/PSA_Versioning" class="mt-section" id="section_4"><span id="Formatting_Version_Header"></span><h3 id="Formatting_Version_Header-1118">Formatting Version Header</h3>
|
|
|
|
<p><span class="mt-color-000000">We try to make it as simple as possible
|
|
to format your version header. We use an accept header that lists
|
|
our JSON schema as well as the version following. Accept headers
|
|
tell the server what type of information you are expecting to get
|
|
back. This makes it a perfect fit to add our version to as this
|
|
tells the server that you want xyz version back.</span></p>
|
|
|
|
<div id="highlighter_859561" class="syntaxhighlighter "><div class="bar"><div class="toolbar"><a href="#viewSource" title="view source" style="width: 16px; height: 16px;" class="item viewSource">view source</a><a href="#printSource" title="print" style="width: 16px; height: 16px;" class="item printSource">print</a><a href="#about" title="?" style="width: 16px; height: 16px;" class="item about">?</a></div></div><div class="lines"><div class="line alt1"><table><tbody><tr><td class="number"><code>1</code></td><td class="content"><code class="plain">Accept: application/vnd.connectwise.com+json; version=</code><code class="value">2019.1</code></td></tr></tbody></table></div></div></div>
|
|
|
|
</div><div mt-section-origin="Best_Practices/PSA_Versioning" class="mt-section" id="section_5"><span id="Per_Endpoint"></span><h3 id="Per_Endpoint-1118">Per Endpoint</h3>
|
|
|
|
<p><span class="mt-color-000000">If you are not ready to update to the
|
|
latest API Models for your entire integration, you can change your
|
|
accept header to be on an endpoint by endpoint basis. We recommend
|
|
that you keep a singular version across your integration, but will
|
|
support it either way. Anytime you test your integration and
|
|
validate it against a version, update your version header even if we are
|
|
not deprecating the version you are on. We may do so without
|
|
warning, or give you very little time to make changes.</span></p>
|
|
</div></div>
|
|
</div>
|
|
|
|
</div><div mt-section-origin="Products/ConnectWise_PSA/Developer_Guide" class="mt-section" id="section_5"><span id="Authentication"></span><h3 class="editable">Authentication</h3>
|
|
|
|
<div class="mt-contentreuse-widget" data-page="Manage/REST/Permissions_(REST)" data-section="" data-show="">
|
|
<div class="mt-include" id="s342"><p>REST based integrations have three
|
|
methods of authentication. The recommended method, is using an API
|
|
Member account to create API Keys specific to the integration.
|
|
The second method is to use impersonation. Impersonation
|
|
uses either an Integrator Login (Legacy) or another Member to create API
|
|
Keys programmatically for other members. The third method which
|
|
is only support for internal integrations, uses username and passwords
|
|
for individual members. Due to this method requiring a user to
|
|
enter their ConnectWise PSA username and password into another
|
|
application, we do not support vendors utilizing this method.</p>
|
|
|
|
<p>ConnectWise PSA <span class="mt-font-Segoe UI,sans-serif"><span class="mt-font-size-10.0pt">utilizes the "Basic Auth" standard with Public and Private keys and the authorization header that are unique to </span></span> ConnectWise PSA <span class="mt-font-Segoe UI,sans-serif"><span class="mt-font-size-10.0pt">members. This means you can use the benefits of </span></span> ConnectWise PSA <span class="mt-font-Segoe UI,sans-serif"><span class="mt-font-size-10.0pt">security roles and give granular access to the APIs.</span></span></p>
|
|
|
|
<p><span class="mt-font-size-16" style="line-height:1.4;">Your header must be </span>base64<span class="mt-font-size-16" style="line-height:1.4;"> encoded and has to include a username:password. The username will always begin with </span>CompanyId<span class="mt-font-size-16" style="line-height:1.4;">+ and then use either the public key, integrator username or </span>MemberId<span class="mt-font-size-16" style="line-height:1.4;">. The password will be the private key, integrator password or member hash.</span></p>
|
|
|
|
<pre class="mt-indent-1">Method 1 - API Keys - Member Authentication
|
|
It is recommended to create API Members versus using API Keys tied to a specific member.
|
|
Authorization: Basic base64(companyid+publickey:privatekey)
|
|
(Authorization: Basic Y29tcGFueWlkK3B1YmxpY2tleTpwcml2YXRla2V5)
|
|
|
|
Method 2 - Integrator Login - Impersonation
|
|
This method should only be used for legacy integrations in a transition period.
|
|
Authorization: Basic base64(companyid+integratorlogin:integratorpassword)
|
|
(Authorization: Basic Y29tcGFueWlkK2ludGVncmF0b3Jsb2dpbjppbnRlZ3JhdG9ycGFzc3dvcmQ=)
|
|
|
|
Method 3 - Member ID and Password - Cookie Authentication (<span class="mt-color-ff0000">Not intended for 3rd party products unless using Hosted API</span>)
|
|
This method uses 3 cookie headers.
|
|
Cookie: companyName=YourLoginCompany
|
|
Cookie: memberHash=Generated by POST to login.aspx or via Hosted API
|
|
Cookie: memberId=YourUsername
|
|
Cookie: memberContext=web
|
|
</pre>
|
|
|
|
<p><strong>Important Note: </strong>SSL is required on production
|
|
PSA servers when accessing the API. Any calls received via regular HTTP
|
|
will be denied on production systems.</p>
|
|
|
|
<p>Are you connecting to the Cloud or Staging? If so you must
|
|
include API- in front of the ConnectWise PSA site. If you are using a
|
|
training environment that normally uses sandbox- in front of the Site,
|
|
you will not include sandbox- and should still follow these same
|
|
guidelines. </p>
|
|
|
|
<pre class="mt-indent-1">api-au.myconnectwise.net
|
|
api-eu.myconnectwise.net
|
|
api-na.myconnectwise.net
|
|
api-staging.connectwisedev.com
|
|
</pre>
|
|
|
|
<p>Otherwise you will run into this error:</p>
|
|
|
|
<pre class="mt-indent-1">{
|
|
"code": "Security",
|
|
"message": "SSL is required.",
|
|
"errors": null
|
|
}</pre>
|
|
|
|
<p> </p>
|
|
|
|
<div mt-section-origin="Products/ConnectWise_PSA/Developer_Guide/Authentication" class="mt-section" id="section_1"><span id="Postman_Example"></span><h4 id="Postman_Example-342">Postman Example</h4>
|
|
|
|
<p><img class="internal" style="width: 1030px; height: 293px;" width="1030px" height="293px" alt="clipboard_e3fce13499f91853cf4c9c60c4c88b774.png" loading="lazy" src="Developer%20Guide%20-%20Developer%20Network_files/clipboard_e3fce13499f91853cf4c9c60c4c88b774.png"> </p>
|
|
|
|
<script type="text/javascript">/*<![CDATA[*/
|
|
$(function() {
|
|
$('dl').find('dt').on('click', function() {
|
|
$(this).next().toggle('350');
|
|
});
|
|
});/*]]>*/</script>
|
|
|
|
</div><div mt-section-origin="Products/ConnectWise_PSA/Developer_Guide/Authentication" class="mt-section" id="section_2"><span id="Obtaining_your_Keys"></span><h4 id="Obtaining_your_Keys-342">Obtaining your Keys</h4>
|
|
|
|
<p>We only support API Member and My Account based authentication for
|
|
Integration Vendors. Impersonation and Cookie Authentication are
|
|
for internal only based integrations. In rare cases impersonation
|
|
may be the route to go.</p>
|
|
|
|
|
|
|
|
<dl>
|
|
<dt style="font-size:large">API Member Only *Recommended for 3rd parties</dt>
|
|
<dd>
|
|
<p>Using the same setup screen as creating a Member an API
|
|
Member allows granular control over what type of information an
|
|
integration has access to. A global user allows integrations to be
|
|
turned on and off easily without requiring the person who initially
|
|
setup the integration.</p>
|
|
API Members are the recommended route for most integrations.
|
|
|
|
<blockquote>
|
|
<p>The Members screen can by found by going to the System Module and
|
|
opening the Members page. After accessing the Members page, click
|
|
on the API Members tab. Here you can create a new user and
|
|
generate API Keys for them.</p>
|
|
|
|
<p>API Members do not require a user license.</p>
|
|
</blockquote>
|
|
|
|
<p><img alt="CW_Snag_-_0641.png" class="internal default" style="width: 1089px; height: 836px;" width="1089px" height="836px" loading="lazy" src="Developer%20Guide%20-%20Developer%20Network_files/CW_Snag_-_0641.png"></p>
|
|
|
|
<p><img alt="CW_Snag_-_0642.png" class="internal default" style="width: 1089px; height: 836px;" width="1089px" height="836px" loading="lazy" src="Developer%20Guide%20-%20Developer%20Network_files/CW_Snag_-_0642.png"></p>
|
|
|
|
<p> </p>
|
|
</dd>
|
|
</dl>
|
|
|
|
<dl>
|
|
<dt style="font-size:large">Member Impersonation</dt>
|
|
<dd>Member impersonation works by using an integrator login with
|
|
access to the Member API through the integrator login setup tables. You
|
|
can then use the integrator login credentials to make a call to the
|
|
Member API under REST in order to generate a temporary (4 hours)
|
|
API Key for that member. Once you have the generated API Keys, you
|
|
will need to use the returned API Keys for that member to make
|
|
additional API Calls.
|
|
<pre>Post Request:
|
|
https://YourConnectWiseSite/v4_6_release/apis/3.0/system/members/{memberIdentifier}/tokens
|
|
|
|
Headers:
|
|
-API Member:
|
|
Authentication Basic base64(companyid+publickey:privatekey)
|
|
x-cw-usertype: member
|
|
|
|
-Integrator Login:
|
|
Authentication Basic base64(companyid+integratorlogin:integratorpassword)
|
|
(example: Y29tcGFueWlkK2ludGVncmF0b3Jsb2dpbjppbnRlZ3JhdG9ycGFzc3dvcmQ=)
|
|
x-cw-usertype: integrator
|
|
|
|
Body:
|
|
{
|
|
"memberIdentifier":"The member indentifier"
|
|
}
|
|
|
|
Response:
|
|
{
|
|
"publicKey": "yCdymjwp082t9uqp",
|
|
"privateKey": "zhqz7g3ne71jV4Jn",
|
|
"expiration": "2015-06-12T22:20:38Z"
|
|
}
|
|
</pre>
|
|
</dd>
|
|
</dl>
|
|
|
|
<dl>
|
|
<dt style="font-size:large">My Account</dt>
|
|
<dd>
|
|
<p><img alt="CW_Snag_-_0560.png" class="internal default" style="width: 1063px; height: 815px;" width="1063px" height="815px" loading="lazy" src="Developer%20Guide%20-%20Developer%20Network_files/CW_Snag_-_0560.png"></p>
|
|
|
|
<p><img alt="CW_Snag_-_0561.png" class="internal default" style="width: 1063px; height: 815px;" width="1063px" height="815px" loading="lazy" src="Developer%20Guide%20-%20Developer%20Network_files/CW_Snag_-_0561.png"></p>
|
|
|
|
<p><img alt="CW_Snag_-_0562.png" class="internal default" style="width: 1063px; height: 815px;" width="1063px" height="815px" loading="lazy" src="Developer%20Guide%20-%20Developer%20Network_files/CW_Snag_-_0562.png"></p>
|
|
|
|
<p><img alt="CW_Snag_-_0563.png" class="internal default" style="width: 1063px; height: 815px;" width="1063px" height="815px" loading="lazy" src="Developer%20Guide%20-%20Developer%20Network_files/CW_Snag_-_0563.png"></p>
|
|
</dd>
|
|
</dl>
|
|
|
|
<dl>
|
|
<dt style="font-size:large">Cookie Authentication</dt>
|
|
<dd>
|
|
<blockquote>
|
|
<p><strong>Warning</strong>:<em> If a partner activates SAML based
|
|
authentication, you will not be able to generate a member hash using the
|
|
Login.aspx page. The Hosted API will still return a hash that can
|
|
be used by the APIs, but all other methods of hash generation will no
|
|
longer work.</em></p>
|
|
</blockquote>
|
|
|
|
<p><span class="mt-color-ff0000">Vendor integrations should ignore cookie authentication and instead use API Members.</span></p>
|
|
|
|
<p>Cookie Authentication uses the ConnectWise PSA member credentials
|
|
for making API Requests. This method is subject to change with
|
|
the integration of additional two factor
|
|
authentications (2fa). By Passing the following
|
|
Form Request data, you will impersonate the member using your
|
|
integration.</p>
|
|
|
|
<p><img alt="cookieauth1.png" class="internal default" style="width: 927px; height: 411px;" width="927px" height="411px" loading="lazy" src="Developer%20Guide%20-%20Developer%20Network_files/cookieauth1.png"></p>
|
|
|
|
<p>In order to obtain the MemberHash you have to call to our Login
|
|
module. Once you have done that you will recieve a unique hash
|
|
that expires every 8 hours. This is the max amount of time a
|
|
ConnectWise PSA session can remain active.</p>
|
|
|
|
<p><img alt="cookieauth2.png" class="internal default" style="width: 943px; height: 721px;" width="943px" height="721px" loading="lazy" src="Developer%20Guide%20-%20Developer%20Network_files/cookieauth2.png"></p>
|
|
</dd>
|
|
</dl>
|
|
</div></div>
|
|
</div>
|
|
|
|
</div><div mt-section-origin="Products/ConnectWise_PSA/Developer_Guide" class="mt-section" id="section_6"><span id="Rate_Limiting"></span><h3 class="editable">Rate Limiting</h3>
|
|
|
|
<p>To strengthen the stability, security, and performance of our APIs,
|
|
reasonable rate limits are enforced. This measure safeguards our system
|
|
against excessive or unintended high-volume requests, ensuring a
|
|
consistent and reliable experience for all users. The service monitors
|
|
resource usage in real time. If your request volume approaches capacity
|
|
limits, you may receive HTTP 429 (Too Many Requests) responses,
|
|
indicating temporary throttling. These responses include a Retry-After
|
|
header specifying the number of seconds to wait before re-attempting
|
|
your request. If your integration currently sends over 1,000 requests
|
|
per minute, it will likely experience rate limiting. </p>
|
|
|
|
<p>To avoid rate limits, we suggest that you optimize your integration
|
|
by minimizing unnecessary API calls and using proper filtering, limiting
|
|
the number of parallel requests, <a title="Best_Practices/Bundled_Requests" href="https://developer.connectwise.com/Best_Practices/Bundled_Requests" rel="internal">using bundled requests</a>, as well as implementing intelligent retry mechanisms with exponential backoff, respecting the Retry-After header values.</p>
|
|
|
|
<p>Example response body:</p>
|
|
|
|
<div class="style-wrap">
|
|
<pre> {
|
|
"error": "ConnectWiseAPI",
|
|
"message": "Too many requests. Please try again in 30 seconds."
|
|
}
|
|
</pre>
|
|
|
|
<p>Example code for handling 429 response:</p>
|
|
|
|
<pre>def make_request_with_backoff(url, headers=None, max_retries=5):
|
|
retry_count = 0
|
|
wait_time = 30 # Start with default 30 second wait time
|
|
while retry_count < max_retries:
|
|
response = requests.get(url, headers=headers)
|
|
if response.status_code == 429: # Too Many Requests
|
|
retry_after = int(response.headers.get("Retry-After", wait_time)) # Use Retry-After if provided
|
|
print(f"Rate limit exceeded. Retrying in {retry_after} seconds...")
|
|
time.sleep(retry_after) # Wait before retrying
|
|
else:
|
|
return response # Return successful response or other errors
|
|
retry_count += 1
|
|
wait_time *= 2 # Exponential backoff (30, 60, 120, ...)
|
|
print("Max retries reached. Request failed.")
|
|
return None # Return None if all retries fail
|
|
</pre>
|
|
|
|
<p> </p>
|
|
</div>
|
|
|
|
</div><div mt-section-origin="Products/ConnectWise_PSA/Developer_Guide" class="mt-section" id="section_7"><span id="Security"></span><h3 class="editable">Security</h3>
|
|
|
|
<p>When working with the ConnectWise PSA REST API, security is based on
|
|
the Security Roles table within Manage. This table determines each
|
|
type of entity and the level of access associated. We do not
|
|
recommend requesting Admin access for an integration. Instead,
|
|
integrators are highly encouraged to only enable the security roles for
|
|
access that they need.</p>
|
|
|
|
<p><a title="Security_Roles_Matrix_11132017.xlsx" rel="internal" class="iconitext-16 ext-xlsx" href="https://developer.connectwise.com/@api/deki/files/422/Security_Roles_Matrix_11132017.xlsx?revision=1">Click here to view our Security Role Matrix</a></p>
|
|
|
|
<p>When looking at the REST API documentation, you may notice that some
|
|
items are considered a Setup Table value. These are denoted with
|
|
the lock icon. These endpoints will return an inquiry level of
|
|
access without access to the table. This matches the UI
|
|
functionality in that you can create listings of available statuses and
|
|
boards without having access to the setup table associated with those
|
|
values.</p>
|
|
|
|
<div class="mt-contentreuse-widget" data-page="Best_Practices/Manage_API_Requests" data-section="" data-show="false">
|
|
<div class="mt-include" id="s1291"><div class="mt-contentreuse-widget" data-page="AddTOC" data-section="" data-show="false">
|
|
<div class="mt-include" id="s1121">
|
|
</div>
|
|
</div>
|
|
|
|
<p> </p>
|
|
|
|
<div class="mt-contentreuse-widget" data-page="Best_Practices/HTTP_Verbs_and_Error_Codes" data-section="" data-show="false">
|
|
<div class="mt-include" id="s873"><div mt-section-origin="Best_Practices/HTTP_Verbs_and_Error_Codes" class="mt-section" id="section_1"><span id="HTTP_Methods"></span><h2 id="HTTP_Methods-873">HTTP Methods</h2>
|
|
|
|
<ul>
|
|
<li>POST
|
|
<ul>
|
|
<li>Create an entity or any non-CRUD action</li>
|
|
</ul>
|
|
</li>
|
|
<li>GET
|
|
<ul>
|
|
<li>Return entity or list of entities</li>
|
|
</ul>
|
|
</li>
|
|
<li>PUT
|
|
<ul>
|
|
<li>Replace all fields on an entity with supplied fields</li>
|
|
</ul>
|
|
</li>
|
|
<li>PATCH
|
|
<ul>
|
|
<li>Update specific fields on an entity</li>
|
|
</ul>
|
|
</li>
|
|
<li>DELETE
|
|
<ul>
|
|
<li>Remove entity</li>
|
|
</ul>
|
|
</li>
|
|
</ul>
|
|
|
|
</div><div mt-section-origin="Best_Practices/HTTP_Verbs_and_Error_Codes" class="mt-section" id="section_2"><span id="HTTP_Response_Statuses"></span><h2 id="HTTP_Response_Statuses-873">HTTP Response Statuses</h2>
|
|
|
|
<ul>
|
|
<li>201 Created
|
|
<ul>
|
|
<li>The response will be the record that was created as well as the path to it.</li>
|
|
</ul>
|
|
</li>
|
|
<li>204 NoContent
|
|
<ul>
|
|
<li>Will be returned by successful delete requests</li>
|
|
</ul>
|
|
</li>
|
|
<li>400 Bad Request
|
|
<ul>
|
|
<li>The request could not be understood by the server due to
|
|
malformed syntax. The client SHOULD NOT repeat the request without
|
|
modifications</li>
|
|
</ul>
|
|
</li>
|
|
<li>401 Unauthorized
|
|
<ul>
|
|
<li>The supplied authentication is incorrect</li>
|
|
</ul>
|
|
</li>
|
|
<li>403 Forbidden
|
|
<ul>
|
|
<li>Improper security role settings for the supplied authentication</li>
|
|
</ul>
|
|
</li>
|
|
<li>404 Not Found
|
|
<ul>
|
|
<li>Resource URL not found, this could mean the record was deleted or moved</li>
|
|
</ul>
|
|
</li>
|
|
<li>405 Method Not Allowed
|
|
<ul>
|
|
<li>This will occur if you try to use an HTTP method that is not supported by the URL specified</li>
|
|
</ul>
|
|
</li>
|
|
<li><span class="mt-font-arial" style="line-height:1.5;">409 </span><span class="mt-font-arial" style="line-height:1.5;">Conflict</span>
|
|
<ul>
|
|
<li>Record possibly in use or another conflict with the record</li>
|
|
</ul>
|
|
</li>
|
|
<li>415 Unsupported Media Type
|
|
<ul>
|
|
<li>This can occur when using the documents API if you are sending the file as a JSON object</li>
|
|
</ul>
|
|
</li>
|
|
<li>429 Too Many Requests
|
|
<ul>
|
|
<li>This will occur if request volume exceeds capacity limits
|
|
and will include a Retry-After header with a numeric value that
|
|
indicates the number of seconds to wait before retrying (see Retry
|
|
Policy below) </li>
|
|
</ul>
|
|
</li>
|
|
<li>500 Server Error
|
|
<ul>
|
|
<li>Server errors can occur oftentimes due to a network fault or
|
|
other non-application-related error, however, In some cases, a 500
|
|
error may occur when another error message has not been defined for an
|
|
error</li>
|
|
<li>These errors should follow the retry logic we recommend and if it appears to be an undefined error, should be reported</li>
|
|
</ul>
|
|
</li>
|
|
</ul>
|
|
|
|
<blockquote>
|
|
<p>PSA Specific - Are you getting a 404 error or "Could not get any
|
|
response" on cloud? You may have incorrect authentication instead
|
|
of the resource not being found. To confirm, change your base URL
|
|
from v4_6_release to your ConnectWise PSA version /201x_x/. </p>
|
|
</blockquote>
|
|
</div></div>
|
|
</div>
|
|
|
|
<div mt-section-origin="Best_Practices/PSA_API_Requests" class="mt-section" id="section_1"><span id="Formatting_Each_Method"></span><h2 id="Formatting_Each_Method-1291">Formatting Each Method</h2>
|
|
|
|
<div mt-section-origin="Best_Practices/PSA_API_Requests" class="mt-section" id="section_2"><span id="Get"></span><h3 id="Get-1291">Get</h3>
|
|
|
|
<p>Get requests are used for finding both individual records or a
|
|
listing of records. In order to grab an individual entity you must
|
|
specify an id within the request URL.</p>
|
|
|
|
<pre>https://api-na.myconnectwise.net/v4_6_release/apis/3.0/service/tickets/5000
|
|
</pre>
|
|
|
|
<p>When requesting a grouping of records, do not include an id record.
|
|
Optionally include parameters at the end of the URL to instead
|
|
grab a specific set of records.</p>
|
|
|
|
<pre>https://api-na.myconnectwise.net/v4_6_release/apis/3.0/service/tickets?conditions=board/name="Integration"%20and%20status/name="new"&page=1&pageSize=10</pre>
|
|
|
|
<p>When looking at an endpoint, the parameters section will tell you
|
|
which fields can be used to filter the request. In addition to the
|
|
below parameters, you can use the Fields and Columns to manipulate the
|
|
response dataset.</p>
|
|
|
|
<div mt-section-origin="Best_Practices/PSA_API_Requests" class="mt-section" id="section_3"><span id="URL_Max_Length"></span><h4 id="URL_Max_Length-1291">URL Max Length</h4>
|
|
|
|
<p>The HTTP standards document does not impost a max URL length.
|
|
However various browsers, as well as applications, have
|
|
different limits in place. In addition search engines favor URLs
|
|
that are around 2000 characters. As a URL grows in length it no
|
|
longer remains user-friendly and becomes unusable or readable by users.
|
|
This causes issues with troubleshooting and leads to the overall
|
|
confusion. We recommend keeping the URL length of each request to a
|
|
maximum of 2000 characters. This will ensure there are no
|
|
compatibility issues with various servers and configurations.
|
|
Please keep in mind that the max length of a domain name can reach
|
|
255 characters. <strong>With that in mind, the safe max length of a URL would be around 1745 characters. </strong></p>
|
|
|
|
<p>This can vary based on environment configurations. There will
|
|
often be times when the URL could be significantly longer. There
|
|
may also be one of the server configurations based on premise that
|
|
restricts the URL to a lower length. However, it is recommended to
|
|
keep the URL length to a max of 2000 characters including the domain
|
|
name.</p>
|
|
|
|
</div><div mt-section-origin="Best_Practices/PSA_API_Requests" class="mt-section" id="section_4"><span id="Query_String_Parameters"></span><h4 id="Query_String_Parameters-1291">Query String Parameters</h4>
|
|
|
|
<table border="1" cellpadding="1" cellspacing="1" style="width: 100%; table-layout: fixed;">
|
|
<tbody>
|
|
<tr>
|
|
<td style="width:105px;background-color:rgb(0, 102, 204);"><span class="mt-color-ffffff"><strong>Parameter</strong></span></td>
|
|
<td style="width:200px;background-color:rgb(0, 102, 204);"><span class="mt-color-ffffff"><strong>Description</strong></span></td>
|
|
<td style="width:383px;background-color:rgb(0, 102, 204);"><span class="mt-color-ffffff"><strong>Example</strong></span></td>
|
|
<td style="background-color:rgb(0, 102, 204);"><span class="mt-color-ffffff"><strong> </strong></span></td>
|
|
</tr>
|
|
<tr>
|
|
<td style="width:105px;"><a title="Manage API Requests" href="#Conditions-1291" rel="internal">conditions</a></td>
|
|
<td style="width:200px;">Search results based on the fields returned in a GET</td>
|
|
<td style="width:383px;">board/name="Integration"<br>
|
|
summary="xyz"<br>
|
|
board/id in (3, 2, 4)<br>
|
|
lastUpdated > [2016-08-20T18:04:26Z]<br>
|
|
Only fields returned in a GET request can be used</td>
|
|
<td>=, !=, <, <=, >, >=, contains, like, in, not</td>
|
|
</tr>
|
|
<tr>
|
|
<td style="width:105px;">childConditions</td>
|
|
<td style="width:200px;">Allows searching arrays on endpoints that list childConditions under parameters</td>
|
|
<td style="width:383px;">/company/contacts?childconditions=communicationItems/value like "<a title="mailto:%john@Outlook.com%" href="mailto:%john@Outlook.com%" target="_blank" rel="external noopener nofollow" class="link-mailto">john@Outlook.com</a>" AND communicationItems/communicationType="Email"</td>
|
|
<td>=, !=, <, <=, >, >=, contains, like, not</td>
|
|
</tr>
|
|
<tr>
|
|
<td style="width:105px;"><a title="Developer Guide" href="#Custom_Fields" rel="internal">customFieldConditions</a></td>
|
|
<td style="width:200px;">Allows searching custom fields when customFieldConditions is listed in the parameters</td>
|
|
<td style="width:383px;">/company/contacts?customFieldConditions=caption="TomNumber" AND value !=null</td>
|
|
<td>=, !=, <, <=, >, >=, contains, like, not</td>
|
|
</tr>
|
|
<tr>
|
|
<td style="width:105px;">orderBy</td>
|
|
<td style="width:200px;">Choose which field to sort the results by</td>
|
|
<td style="width:383px;">contact/name asc</td>
|
|
<td>asc or desc</td>
|
|
</tr>
|
|
<tr>
|
|
<td style="width:105px;"><a title="Developer Guide" href="#Partial_Responses" rel="internal">fields</a></td>
|
|
<td style="width:200px;">Limits which information is returned in the response</td>
|
|
<td style="width:383px;">company/companies?fields=id,name,status/id</td>
|
|
<td>Not available on the reporting endpoints</td>
|
|
</tr>
|
|
<tr>
|
|
<td style="width:105px;"><a title="Developer Guide" href="#Partial_Responses" rel="internal">columns</a></td>
|
|
<td style="width:200px;">Limits which information is returned in the response</td>
|
|
<td style="width:383px;">system/reports/service?columns=id,summary,name</td>
|
|
<td>Only used for the Reporting Endpoints</td>
|
|
</tr>
|
|
<tr>
|
|
<td style="width:105px;"><a title="Developer Guide" href="#Pagination" rel="internal">page</a></td>
|
|
<td colspan="3" rowspan="1" style="width:973px;">Used in pagination to cycle through results</td>
|
|
</tr>
|
|
<tr>
|
|
<td style="width:105px;"><a title="Developer Guide" href="#Pagination" rel="internal">pageSize</a></td>
|
|
<td colspan="2" rowspan="1" style="width:585px;">Number of results returned per page (Defaults to 25)</td>
|
|
<td rowspan="1" style="width:223px;">Max Size = 1,000*</td>
|
|
</tr>
|
|
<tr>
|
|
<td colspan="4" style="width:79px;">*Max page size was increased to 1,000 in 2016.2.</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
|
|
</div><div mt-section-origin="Best_Practices/PSA_API_Requests" class="mt-section" id="section_5"><span id="Conditions"></span><h4 id="Conditions-1291">Conditions</h4>
|
|
|
|
<table border="1" cellpadding="1" cellspacing="1" class="mt-responsive-table">
|
|
<tbody>
|
|
<tr>
|
|
<td class="mt-noheading">Strings</td>
|
|
<td class="mt-noheading">Must be surrounded by quotes</td>
|
|
<td class="mt-noheading">Summary = "This is my string" (Accepts *'s for Wild Cards)</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="mt-noheading">Integers</td>
|
|
<td class="mt-noheading">No formatting required</td>
|
|
<td class="mt-noheading">Board/Id = 123</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="mt-noheading">Boolean</td>
|
|
<td class="mt-noheading">No formatting is required but must be True or False</td>
|
|
<td class="mt-noheading">ClosedFlag = True</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="mt-noheading">Datetimes</td>
|
|
<td class="mt-noheading">Must be surrounded by square brackets</td>
|
|
<td class="mt-noheading">LastUpdated = [2016-08-20T18:04:26Z]</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="mt-noheading">Operators</td>
|
|
<td class="mt-noheading"><, <=, =, !=, >, >=, contains, like, in, not</td>
|
|
<td class="mt-noheading">Summary Not Contains "Low Priority"</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="mt-noheading">Logic Operators</td>
|
|
<td class="mt-noheading">Supported operators include:
|
|
<ul>
|
|
<li>AND</li>
|
|
<li>OR</li>
|
|
</ul>
|
|
</td>
|
|
<td class="mt-noheading">
|
|
<p>board/name="integration" and summary="xyz"<br>
|
|
board/name="integration" or board/name="professional services"</p>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="mt-noheading">Reference*</td>
|
|
<td class="mt-noheading">Must have a / followed by the field under the reference you would like to use</td>
|
|
<td class="mt-noheading">manufacturer/name</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
|
|
</div><div mt-section-origin="Best_Practices/PSA_API_Requests" class="mt-section" id="section_6"><span id="Using_the_.2FSearch_endpoints"></span><h4 id="Using_the_.2FSearch_endpoints-1291">Using the /Search endpoints</h4>
|
|
|
|
<p>If your request URL is going to be over 10,000 characters long you
|
|
can instead use the /Search path for certain endpoints. This
|
|
allows you to enter the conditions in the body of the request.</p>
|
|
|
|
<pre>POST /v4_6_release/apis/3.0/service/tickets/search HTTP/1.1
|
|
Host: YOURCONNECTWISESITE
|
|
Authorization: Basic AUTHKEY=
|
|
Content-Type: application/json
|
|
|
|
Body:
|
|
{
|
|
"conditions": "summary like 'test'"
|
|
}</pre>
|
|
|
|
<blockquote>
|
|
<p>Successful get requests will return a 200 status response and a content body of the record(s).</p>
|
|
</blockquote>
|
|
|
|
</div></div><div mt-section-origin="Best_Practices/PSA_API_Requests" class="mt-section" id="section_7"><span id="Patch"></span><h3 id="Patch-1291">Patch</h3>
|
|
|
|
<p>Patch requests enable the ability to update individual fields on an
|
|
entity. When formatting the request you can specify multiple
|
|
fields to be updated. When working with a patch, the entire object
|
|
is part of an array and must be surrounded by square brackets as per
|
|
the example below. If you do not have the square brackets, you
|
|
will run into errors. In addition, when you are updating a
|
|
reference, you can only update it through the use of unique
|
|
values. Many times Name is not considered unique.</p>
|
|
|
|
<pre>https://api-na.myconnectwise.net/v4_6_release/apis/3.0/service/tickets/5000</pre>
|
|
|
|
<pre>[
|
|
{
|
|
"op": "string",
|
|
"path": "string",
|
|
"value": "string"
|
|
}
|
|
]
|
|
<span class="rangySelectionBoundary" id="selectionBoundary_1454443517692_5980667155236006" style="line-height:0;display:none;"></span></pre>
|
|
|
|
<table border="1" cellpadding="1" cellspacing="1" style="width: 100%; table-layout: fixed;">
|
|
<tbody>
|
|
<tr>
|
|
<td style="width:64px;">op</td>
|
|
<td style="width:277px;">The update operation used in the request</td>
|
|
<td style="width:293px;">add | replace | remove</td>
|
|
</tr>
|
|
<tr>
|
|
<td style="width:64px;">path</td>
|
|
<td style="width:277px;">Pathway for the updated field (Case Sensitive)</td>
|
|
<td style="width:293px;">summary<br>
|
|
company</td>
|
|
</tr>
|
|
<tr>
|
|
<td style="width:64px;">value</td>
|
|
<td style="width:277px;">The new value if doing a replace<br>
|
|
Refer to <a title="Developer Guide" href="#Escaping_Characters" rel="internal">escaping characters</a><br>
|
|
When working with custom fields, you must pass the entire array of custom fields.</td>
|
|
<td style="width:293px;">String: "Here is my Summary"<br>
|
|
Object: { "identifier": "connectwise" }</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
|
|
<div id="highlighter_51494" class="syntaxhighlighter "><div class="bar "><div class="toolbar"><a href="#viewSource" title="view source" style="width: 16px; height: 16px;" class="item viewSource">view source</a><a href="#printSource" title="print" style="width: 16px; height: 16px;" class="item printSource">print</a><a href="#about" title="?" style="width: 16px; height: 16px;" class="item about">?</a></div></div><div class="lines"><div class="line alt1"><table><tbody><tr><td class="number"><code>01</code></td><td class="content"><code class="plain">[</code></td></tr></tbody></table></div><div class="line alt2"><table><tbody><tr><td class="number"><code>02</code></td><td class="content"><code class="spaces"> </code><code class="plain">{</code></td></tr></tbody></table></div><div class="line alt1"><table><tbody><tr><td class="number"><code>03</code></td><td class="content"><code class="spaces"> </code><code class="string">"op"</code><code class="plain">: </code><code class="string">"replace"</code><code class="plain">,</code></td></tr></tbody></table></div><div class="line alt2"><table><tbody><tr><td class="number"><code>04</code></td><td class="content"><code class="spaces"> </code><code class="string">"path"</code><code class="plain">: </code><code class="string">"summary"</code><code class="plain">,</code></td></tr></tbody></table></div><div class="line alt1"><table><tbody><tr><td class="number"><code>05</code></td><td class="content"><code class="spaces"> </code><code class="string">"value"</code><code class="plain">: </code><code class="string">"New Summary"</code></td></tr></tbody></table></div><div class="line alt2"><table><tbody><tr><td class="number"><code>06</code></td><td class="content"><code class="spaces"> </code><code class="plain">},</code></td></tr></tbody></table></div><div class="line alt1"><table><tbody><tr><td class="number"><code>07</code></td><td class="content"><code class="spaces"> </code><code class="plain">{</code></td></tr></tbody></table></div><div class="line alt2"><table><tbody><tr><td class="number"><code>08</code></td><td class="content"><code class="spaces"> </code><code class="string">"op"</code><code class="plain">: </code><code class="string">"replace"</code><code class="plain">,</code></td></tr></tbody></table></div><div class="line alt1"><table><tbody><tr><td class="number"><code>09</code></td><td class="content"><code class="spaces"> </code><code class="string">"path"</code><code class="plain">: </code><code class="string">"company"</code><code class="plain">,</code></td></tr></tbody></table></div><div class="line alt2"><table><tbody><tr><td class="number"><code>10</code></td><td class="content"><code class="spaces"> </code><code class="string">"value"</code><code class="plain">: {</code></td></tr></tbody></table></div><div class="line alt1"><table><tbody><tr><td class="number"><code>11</code></td><td class="content"><code class="spaces"> </code><code class="string">"identifier"</code><code class="plain">: </code><code class="string">"New Company"</code></td></tr></tbody></table></div><div class="line alt2"><table><tbody><tr><td class="number"><code>12</code></td><td class="content"><code class="spaces"> </code><code class="plain">}</code></td></tr></tbody></table></div><div class="line alt1"><table><tbody><tr><td class="number"><code>13</code></td><td class="content"><code class="spaces"> </code><code class="plain">},</code></td></tr></tbody></table></div><div class="line alt2"><table><tbody><tr><td class="number"><code>14</code></td><td class="content"><code class="spaces"> </code><code class="plain">{</code></td></tr></tbody></table></div><div class="line alt1"><table><tbody><tr><td class="number"><code>15</code></td><td class="content"><code class="spaces"> </code><code class="string">"op"</code><code class="plain">: </code><code class="string">"replace"</code><code class="plain">,</code></td></tr></tbody></table></div><div class="line alt2"><table><tbody><tr><td class="number"><code>16</code></td><td class="content"><code class="spaces"> </code><code class="string">"path"</code><code class="plain">: </code><code class="string">"customFields"</code><code class="plain">,</code></td></tr></tbody></table></div><div class="line alt1"><table><tbody><tr><td class="number"><code>17</code></td><td class="content"><code class="spaces"> </code><code class="string">"value"</code><code class="plain">: [</code></td></tr></tbody></table></div><div class="line alt2"><table><tbody><tr><td class="number"><code>18</code></td><td class="content"><code class="spaces"> </code><code class="plain">{</code></td></tr></tbody></table></div><div class="line alt1"><table><tbody><tr><td class="number"><code>19</code></td><td class="content"><code class="spaces"> </code><code class="string">"id"</code><code class="plain">: 5,</code></td></tr></tbody></table></div><div class="line alt2"><table><tbody><tr><td class="number"><code>20</code></td><td class="content"><code class="spaces"> </code><code class="string">"caption"</code><code class="plain">: </code><code class="string">"CloudPlus"</code><code class="plain">,</code></td></tr></tbody></table></div><div class="line alt1"><table><tbody><tr><td class="number"><code>21</code></td><td class="content"><code class="spaces"> </code><code class="string">"type"</code><code class="plain">: </code><code class="string">"Checkbox"</code><code class="plain">,</code></td></tr></tbody></table></div><div class="line alt2"><table><tbody><tr><td class="number"><code>22</code></td><td class="content"><code class="spaces"> </code><code class="string">"entryMethod"</code><code class="plain">: </code><code class="string">"EntryField"</code><code class="plain">,</code></td></tr></tbody></table></div><div class="line alt1"><table><tbody><tr><td class="number"><code>23</code></td><td class="content"><code class="spaces"> </code><code class="string">"numberOfDecimals"</code><code class="plain">: 0,</code></td></tr></tbody></table></div><div class="line alt2"><table><tbody><tr><td class="number"><code>24</code></td><td class="content"><code class="spaces"> </code><code class="string">"value"</code><code class="plain">: </code><code class="keyword">false</code></td></tr></tbody></table></div><div class="line alt1"><table><tbody><tr><td class="number"><code>25</code></td><td class="content"><code class="spaces"> </code><code class="plain">},</code></td></tr></tbody></table></div><div class="line alt2"><table><tbody><tr><td class="number"><code>26</code></td><td class="content"><code class="spaces"> </code><code class="plain">{ </code></td></tr></tbody></table></div><div class="line alt1"><table><tbody><tr><td class="number"><code>27</code></td><td class="content"><code class="spaces"> </code><code class="string">"id"</code><code class="plain">: 28,</code></td></tr></tbody></table></div><div class="line alt2"><table><tbody><tr><td class="number"><code>28</code></td><td class="content"><code class="spaces"> </code><code class="string">"caption"</code><code class="plain">: </code><code class="string">"test"</code><code class="plain">,</code></td></tr></tbody></table></div><div class="line alt1"><table><tbody><tr><td class="number"><code>29</code></td><td class="content"><code class="spaces"> </code><code class="string">"type"</code><code class="plain">: </code><code class="string">"Text"</code><code class="plain">,</code></td></tr></tbody></table></div><div class="line alt2"><table><tbody><tr><td class="number"><code>30</code></td><td class="content"><code class="spaces"> </code><code class="string">"entryMethod"</code><code class="plain">: </code><code class="string">"List"</code><code class="plain">,</code></td></tr></tbody></table></div><div class="line alt1"><table><tbody><tr><td class="number"><code>31</code></td><td class="content"><code class="spaces"> </code><code class="string">"numberOfDecimals"</code><code class="plain">: 0,</code></td></tr></tbody></table></div><div class="line alt2"><table><tbody><tr><td class="number"><code>32</code></td><td class="content"><code class="spaces"> </code><code class="string">"value"</code><code class="plain">: </code><code class="string">"test"</code></td></tr></tbody></table></div><div class="line alt1"><table><tbody><tr><td class="number"><code>33</code></td><td class="content"><code class="spaces"> </code><code class="plain">}</code></td></tr></tbody></table></div><div class="line alt2"><table><tbody><tr><td class="number"><code>34</code></td><td class="content"><code class="spaces"> </code><code class="plain">]</code></td></tr></tbody></table></div><div class="line alt1"><table><tbody><tr><td class="number"><code>35</code></td><td class="content"><code class="spaces"> </code><code class="plain">}</code></td></tr></tbody></table></div><div class="line alt2"><table><tbody><tr><td class="number"><code>36</code></td><td class="content"><code class="plain">]</code></td></tr></tbody></table></div></div></div>
|
|
|
|
<blockquote>
|
|
<p>When updating an Object such as Company, you cannot specify a
|
|
location inside of the object. You have to replace the whole
|
|
object like the example above. (Do not
|
|
use "path":"company/identifier") If you try to update the
|
|
Object incorrectly, you may receive a false 200 message.</p>
|
|
|
|
<p>Successful patch requests will return a 200 status response for success</p>
|
|
</blockquote>
|
|
|
|
</div><div mt-section-origin="Best_Practices/PSA_API_Requests" class="mt-section" id="section_8"><span id="Delete"></span><h3 id="Delete-1291">Delete</h3>
|
|
|
|
<p>Delete requests are used for removing records from the ConnectWise
|
|
PSA system. Please take care when removing items as they cannot be
|
|
recovered. The id for the record to be deleted needs to be
|
|
included in the request URL.</p>
|
|
|
|
<pre>https://api-na.myconnectwise.net/v4_6_release/apis/3.0/service/tickets/5000
|
|
</pre>
|
|
|
|
<blockquote>
|
|
<p>Successful delete requests will return a 204 status response for No Content. 204 is a success response.</p>
|
|
</blockquote>
|
|
|
|
</div><div mt-section-origin="Best_Practices/PSA_API_Requests" class="mt-section" id="section_9"><span id="Post"></span><h3 id="Post-1291">Post</h3>
|
|
|
|
<p>Post is used when creating new records. The body of the request
|
|
must be sent in JSON format. When sending a Post the response
|
|
body will include the newly created record id as well as a Get request
|
|
for the record. If you pass a post request without filling out
|
|
every possible value, the system will attempt to default all required
|
|
information, and anything that does not require a value will be set to
|
|
Null.</p>
|
|
|
|
</div><div mt-section-origin="Best_Practices/PSA_API_Requests" class="mt-section" id="section_10"><span id="Put"></span><h3 id="Put-1291">Put</h3>
|
|
|
|
<p>Put requests are designed to completely replace an entity. They
|
|
work the in the same manner as a Post request with the exception that
|
|
you must specify an already created entity in your URL. When you
|
|
use Put to update a record, any field that has not been specified will
|
|
be overridden with the system defaults or set to Null.</p>
|
|
|
|
</div><div mt-section-origin="Best_Practices/PSA_API_Requests" class="mt-section" id="section_11"><span id="Escaping_Characters"></span><h3 id="Escaping_Characters-1291">Escaping Characters</h3>
|
|
|
|
<p>When working with JSON, you may find that you need to use characters
|
|
that require escaping. This comes into play primarily when quotes
|
|
are involved as we do not support many of the characters that require
|
|
escaping. Refer to the chart below:</p>
|
|
|
|
<table class="mt-responsive-table">
|
|
<tbody>
|
|
</tbody>
|
|
<tbody>
|
|
<tr>
|
|
<th>Character</th>
|
|
<th class="mt-column-width-15">Escaped</th>
|
|
<th class="mt-column-width-50">Displayed in the UI</th>
|
|
</tr>
|
|
<tr>
|
|
<td data-th="Character">Double Quotes</td>
|
|
<td class="mt-column-width-15" data-th="Escaped">\"</td>
|
|
<td class="mt-column-width-50" data-th="Displayed in the UI">"</td>
|
|
</tr>
|
|
<tr>
|
|
<td data-th="Character">Backslash</td>
|
|
<td class="mt-column-width-15" data-th="Escaped">\\</td>
|
|
<td class="mt-column-width-50" data-th="Displayed in the UI">\</td>
|
|
</tr>
|
|
<tr>
|
|
<td data-th="Character">Tab</td>
|
|
<td class="mt-column-width-15" data-th="Escaped">\t</td>
|
|
<td class="mt-column-width-50" data-th="Displayed in the UI">Tabbed space equal to four spaces</td>
|
|
</tr>
|
|
<tr>
|
|
<td data-th="Character">Backspace (Not Supported)</td>
|
|
<td class="mt-column-width-15" data-th="Escaped">\b</td>
|
|
<td class="mt-column-width-50" data-th="Displayed in the UI">An invisible character that doesn't take up any space</td>
|
|
</tr>
|
|
<tr>
|
|
<td data-th="Character">Carriage Return (Not Supported)</td>
|
|
<td class="mt-column-width-15" data-th="Escaped">\r</td>
|
|
<td class="mt-column-width-50" data-th="Displayed in the UI">Single space which is returned as a space in the API instead of an escaped character</td>
|
|
</tr>
|
|
<tr>
|
|
<td data-th="Character">Newline (Not Supported)</td>
|
|
<td class="mt-column-width-15" data-th="Escaped">\n</td>
|
|
<td class="mt-column-width-50" data-th="Displayed in the UI">Single space which is returned as a space in the API instead of an escaped character</td>
|
|
</tr>
|
|
<tr>
|
|
<td data-th="Character">Form Feed (Not Supported)</td>
|
|
<td class="mt-column-width-15" data-th="Escaped">\f</td>
|
|
<td class="mt-column-width-50" data-th="Displayed in the UI">An invisible character that doesn't take up any space</td>
|
|
</tr>
|
|
<tr>
|
|
<td colspan="3" data-th="Displayed in the UI"><strong>Applies to JSON Bodies Only: </strong>Please
|
|
note that Single Quotes ', do not require escaping as they should not
|
|
be used as a container for your strings. If you are using single
|
|
contains around string values, you must switch to doubles. </td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
|
|
<p> URL Encoding is required when using conditions and other URL
|
|
parameters that have symbols that would denote new query parameters or
|
|
strings.</p>
|
|
|
|
<table class="mt-responsive-table">
|
|
<thead>
|
|
<tr>
|
|
<th scope="col">Character</th>
|
|
<th scope="col">Formatting</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td data-th="Character">&</td>
|
|
<td data-th="Formatting">%26</td>
|
|
</tr>
|
|
<tr>
|
|
<td data-th="Character">"</td>
|
|
<td data-th="Formatting">%22</td>
|
|
</tr>
|
|
<tr>
|
|
<td data-th="Character">'</td>
|
|
<td data-th="Formatting">%27</td>
|
|
</tr>
|
|
<tr>
|
|
<td data-th="Character">*</td>
|
|
<td data-th="Formatting">%2A</td>
|
|
</tr>
|
|
<tr>
|
|
<td data-th="Character">%</td>
|
|
<td data-th="Formatting">%25</td>
|
|
</tr>
|
|
<tr>
|
|
<td data-th="Character">+</td>
|
|
<td data-th="Formatting">%2B</td>
|
|
</tr>
|
|
<tr>
|
|
<td data-th="Character">[string]</td>
|
|
<td data-th="Formatting">[[]string]</td>
|
|
</tr>
|
|
<tr>
|
|
<td colspan="2" data-th="Formatting"><strong>This applies to URL Parameters Only</strong></td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
|
|
</div><div mt-section-origin="Best_Practices/PSA_API_Requests" class="mt-section" id="section_12"><span id="Partial_Responses"></span><h3 id="Partial_Responses-1291">Partial Responses</h3>
|
|
|
|
<p>The API allows you to specify which information you want to be
|
|
returned. You do this by listing the request fields or columns on
|
|
your endpoint URL. Partial responses work for both GET and POST
|
|
requests.</p>
|
|
|
|
<table border="1" cellpadding="1" cellspacing="1" style="width: 100%; table-layout: fixed;">
|
|
<tbody>
|
|
<tr>
|
|
<td style="width:159px;">Fields</td>
|
|
<td style="width:486px;">company/companies?fields=company/id,company/name,phoneNumber</td>
|
|
</tr>
|
|
<tr>
|
|
<td style="width:159px;">Columns (Reporting API only)</td>
|
|
<td style="width:486px;">system/reports/service?columns=id,summary,company/name</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
|
|
</div><div mt-section-origin="Best_Practices/PSA_API_Requests" class="mt-section" id="section_13"><span id="Custom_Fields"></span><h3 id="Custom_Fields-1291">Custom Fields</h3>
|
|
|
|
<p>Screens that have custom fields in the ConnectWise PSA UI will have
|
|
an array of fields on the respective endpoint. This array can be
|
|
both queried and updated via the API. When updating custom fields,
|
|
you must pass in the entire array object, which means that you cannot
|
|
patch a single custom field record. Wondering if an endpoint
|
|
supports custom fields? Supported endpoints will
|
|
have customFields(CustomFieldValue[]) listed at the end of the
|
|
documentation.</p>
|
|
|
|
<p>There are two methods of adding new custom fields to the ConnectWise
|
|
PSA environment. The first method will require access to the
|
|
ConnectWise PSA thick client and the second method is available in the
|
|
system/userDefinedFields endpoint within the REST API.</p>
|
|
|
|
<blockquote>
|
|
<p>Refer to the <a title="Developer Guide" href="#Get" rel="internal">GET </a>section on how to search custom fields. Searching custom fields uses customFieldConditions instead of conditions.</p>
|
|
</blockquote>
|
|
|
|
<p>In order to access the custom fields via the thick client, navigate to System > Setup Tables > Custom fields,</p>
|
|
|
|
<div mt-section-origin="Best_Practices/PSA_API_Requests" class="mt-section" id="section_14"><span id="Field_Options_and_Parameters"></span><h4 id="Field_Options_and_Parameters-1291">Field Options and Parameters</h4>
|
|
|
|
<p><img class="internal" style="width: 844px; height: 269px;" width="844px" height="269px" alt="Custom Fields.png" loading="lazy" src="Developer%20Guide%20-%20Developer%20Network_files/Custom%20Fields.png"></p>
|
|
|
|
<table class="mt-responsive-table">
|
|
<tbody>
|
|
<tr>
|
|
<td class="mt-noheading mt-column-width-15"><strong>Field</strong></td>
|
|
<td class="mt-noheading mt-column-width-55"><strong>Description</strong></td>
|
|
</tr>
|
|
<tr>
|
|
<td class="mt-noheading mt-column-width-15">Field Caption</td>
|
|
<td class="mt-noheading mt-column-width-55">Enter a custom field caption for this required field; you are limited to 12 characters.</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="mt-noheading mt-column-width-15">Help Text</td>
|
|
<td class="mt-noheading mt-column-width-55">
|
|
<p>The text entered in this field will be displayed when you
|
|
hover over the help button next to the custom field on the screen.
|
|
</p>
|
|
|
|
<p><strong>Note: </strong>This has a limit of 1000 characters, however only 512 characters will display on the opportunity screen.</p>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="mt-noheading mt-column-width-15">Field Type</td>
|
|
<td class="mt-noheading mt-column-width-55">
|
|
<p>Select one of the following options:</p>
|
|
|
|
<ul>
|
|
<li><strong>Button</strong> This field allows you to add a hyperlink in the <strong>Button URL</strong> field. There is a character limit of 1000.</li>
|
|
<li><strong>Checkbox</strong> This field is used for simple "Yes/No" or "On/Off" answers. This will display as a checkbox. </li>
|
|
<li><strong>Date </strong>This field displays a standard date picker field.</li>
|
|
<li><strong>Hyperlink </strong>This field displays a text entry field to enter a URL and will be accompanied by a button to visit the hyperlink.</li>
|
|
<li><strong>Number </strong>This field displays
|
|
numerical values only. You will be prompted with an error message
|
|
that displays 'Option value must be a number' if the text is entered.
|
|
</li>
|
|
<li><strong>Percent </strong>This field displays
|
|
numerical values only. You will be prompted with an error message that
|
|
displays 'Option value must be a number' if the text is entered.</li>
|
|
<li><strong>Text </strong>This field displays alpha-numeric values. There is a character limit of 100.</li>
|
|
<li><strong>Text </strong><strong>Area </strong>This field displays alpha-numeric values. There is a character limit of 1000. The <strong>List </strong>and <strong>Dropdown </strong>method of entry is unavailable for this option.
|
|
<p><strong>Note: </strong>If you change a <strong>Date</strong> field to a <strong>Text </strong>or <strong>Text Area</strong> field, the date entered will save as plain text.<br>
|
|
<br>
|
|
If you change a <strong>Text </strong>or <strong>Text Area</strong> field to a <strong>Date</strong> field,
|
|
the system may not automatically save the date. If this occurs, and it
|
|
is a required field, the page-level validation will alert the user to
|
|
enter a date in the field.</p>
|
|
</li>
|
|
</ul>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="mt-noheading mt-column-width-15">Number of Decimals</td>
|
|
<td class="mt-noheading mt-column-width-55">This required field is only available for the Number and Percent Field Type. You can add up to 5 decimal places. </td>
|
|
</tr>
|
|
<tr>
|
|
<td class="mt-noheading mt-column-width-15">Method of Entry</td>
|
|
<td class="mt-noheading mt-column-width-55">
|
|
<p>Select one of the following options:</p>
|
|
|
|
<ul>
|
|
<li><strong>Entry Field</strong> This field is available for all field types.</li>
|
|
<li><strong>List (Drop-down) </strong>This field is
|
|
available for the following field types: Number, Percent, and Text.
|
|
You are able to enter option values once this entry is
|
|
selected. </li>
|
|
<li><strong>Option (Radio) </strong>This field is
|
|
available for the following field types: Number, Percent, and Text.
|
|
You are able to enter option values once this entry is
|
|
selected. </li>
|
|
</ul>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="mt-noheading mt-column-width-15">Sequence #</td>
|
|
<td class="mt-noheading mt-column-width-55">Enter a sequence number. This value must be between 1 and 50. </td>
|
|
</tr>
|
|
<tr>
|
|
<td class="mt-noheading mt-column-width-15">Required Field? </td>
|
|
<td class="mt-noheading mt-column-width-55">Select this checkbox if you would like to make this a required custom field. This will display as a blue asterisk. </td>
|
|
</tr>
|
|
<tr>
|
|
<td class="mt-noheading mt-column-width-15">Display on Screen?</td>
|
|
<td class="mt-noheading mt-column-width-55">Select this checkbox if you would like this to display on the Opportunities screen. This is selected by default.</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="mt-noheading mt-column-width-15">Read Only?</td>
|
|
<td class="mt-noheading mt-column-width-55">This field is used for the API. The <strong>Required Field</strong> checkbox cannot be marked for this field.</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="mt-noheading mt-column-width-15">Include on List View?</td>
|
|
<td class="mt-noheading mt-column-width-55">
|
|
<p>Select this checkbox if you would like to include this custom field in the My Opportunities list view screen.</p>
|
|
|
|
<p><strong>Note: </strong>There is a limit of 10 fields
|
|
that can be displayed on the list view screen. You can have an
|
|
unlimited number of custom fields, but the check box will not display if
|
|
there are already 10 list items. You can unselect this check box at any
|
|
time.</p>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="mt-noheading mt-column-width-15">Button URL</td>
|
|
<td class="mt-noheading mt-column-width-55">Enter the URL if you are using the Field Type Button. The field only appends URLs, no other form of entry will generate content.</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="mt-noheading mt-column-width-15">Select the Locations that will use this Custom Field</td>
|
|
<td class="mt-noheading mt-column-width-55">This is a
|
|
required field. Opportunities that have the specified location(s)
|
|
will display this custom field. Select at least one location where
|
|
the custom field will be used. </td>
|
|
</tr>
|
|
<tr>
|
|
<td class="mt-noheading mt-column-width-15">Select the Departments that will use this Custom Field</td>
|
|
<td class="mt-noheading mt-column-width-55">This is not a required field. Opportunities that have the specified department(s) will display this custom field.</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
|
|
<p> </p>
|
|
</div></div></div></div>
|
|
</div>
|
|
|
|
</div><div mt-section-origin="Products/ConnectWise_PSA/Developer_Guide" class="mt-section" id="section_8"><span id="Pagination"></span><h3 class="editable">Pagination</h3>
|
|
|
|
<div mt-section-origin="Products/ConnectWise_PSA/Developer_Guide" class="mt-section" id="section_9"><span id="Navigable"></span><h4 class="editable">Navigable</h4>
|
|
|
|
<div class="mt-contentreuse-widget" data-page="Best_Practices/Manage_Pagination" data-section="Navigable Pagination" data-show="false">
|
|
<div class="mt-include" id="s1266">
|
|
|
|
<p>The ConnectWise PSA API provides a vast wealth of information for
|
|
developers to consume. Most of the time, you will find that there
|
|
is far more information than is needed for integration. In order
|
|
to ensure server availability, the API automatically sets the page size
|
|
to 25 results. The maximum page size for any request can be up to
|
|
1,000 records if properly specified in the request URL.</p>
|
|
|
|
<table class="mt-responsive-table">
|
|
<tbody>
|
|
<tr>
|
|
<td class="mt-noheading mt-column-width-15">pagesize</td>
|
|
<td class="mt-noheading mt-column-width-85">The number of
|
|
results returned by each call. Defaulted to 25 and has a maximum
|
|
of 1,000. These values cannot be changed.</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="mt-noheading mt-column-width-15">page</td>
|
|
<td class="mt-noheading mt-column-width-85">Starting with page 1, is the number of pages available based on the current pagesize.</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
|
|
<p>When using paging, the response will include a <a title="https://tools.ietf.org/html/rfc5988" href="https://tools.ietf.org/html/rfc5988" target="_blank" rel="external noopener nofollow" class="link-https">Link header</a> that looks like this:</p>
|
|
|
|
<div id="highlighter_165522" class="syntaxhighlighter "><div class="bar"><div class="toolbar"><a href="#viewSource" title="view source" style="width: 16px; height: 16px;" class="item viewSource">view source</a><a href="#printSource" title="print" style="width: 16px; height: 16px;" class="item printSource">print</a><a href="#about" title="?" style="width: 16px; height: 16px;" class="item about">?</a></div></div><div class="lines"><div class="line alt1"><table><tbody><tr><td class="number"><code>1</code></td><td class="content"><code class="plain">/v</code><code class="value">4</code><code class="plain">_</code><code class="value">6</code><code class="plain">_release/apis/</code><code class="value">3.0</code><code class="plain">/company/companies?pagesize=</code><code class="value">50</code><code class="plain">&page=</code><code class="value">1</code></td></tr></tbody></table></div><div class="line alt2"><table><tbody><tr><td class="number"><code>2</code></td><td class="content"><code class="plain">link <<a href="https://staging.connectwisedev.com/v">https://staging.connectwisedev.com/v</a></code><code class="value">2017</code><code class="plain">_</code><code class="value">3</code><code class="plain">/apis/</code><code class="value">3.0</code><code class="plain">/company/companies?pageSize=</code><code class="value">50</code><code class="plain">&page=</code><code class="value">2</code><code class="plain">>; rel=</code><code class="string">"next"</code><code class="plain">, <<a href="https://staging.connectwisedev.com/v">https://staging.connectwisedev.com/v</a></code><code class="value">2017</code><code class="plain">_</code><code class="value">3</code><code class="plain">/apis/</code><code class="value">3.0</code><code class="plain">/company/companies?pageSize=</code><code class="value">50</code><code class="plain">&page=</code><code class="value">4</code><code class="plain">>; rel=</code><code class="string">"last"</code></td></tr></tbody></table></div></div></div>
|
|
|
|
<p>If you notice, the header contains two separate URLs in this
|
|
instance. The first one is "next" and the second one is "last".
|
|
These refer to the next set of results and the final set of
|
|
results. If we navigate to the next page, we will get some
|
|
additional URLs in the response Link header.</p>
|
|
|
|
<div id="highlighter_609603" class="syntaxhighlighter "><div class="bar"><div class="toolbar"><a href="#viewSource" title="view source" style="width: 16px; height: 16px;" class="item viewSource">view source</a><a href="#printSource" title="print" style="width: 16px; height: 16px;" class="item printSource">print</a><a href="#about" title="?" style="width: 16px; height: 16px;" class="item about">?</a></div></div><div class="lines"><div class="line alt1"><table><tbody><tr><td class="number"><code>1</code></td><td class="content"><code class="plain">/v</code><code class="value">4</code><code class="plain">_</code><code class="value">6</code><code class="plain">_release/apis/</code><code class="value">3.0</code><code class="plain">/company/companies?pagesize=</code><code class="value">50</code><code class="plain">&page=</code><code class="value">2</code></td></tr></tbody></table></div><div class="line alt2"><table><tbody><tr><td class="number"><code>2</code></td><td class="content"><code class="plain">link <<a href="https://staging.connectwisedev.com/v">https://staging.connectwisedev.com/v</a></code><code class="value">2017</code><code class="plain">_</code><code class="value">3</code><code class="plain">/apis/</code><code class="value">3.0</code><code class="plain">/company/companies?pageSize=</code><code class="value">50</code><code class="plain">&page=</code><code class="value">3</code><code class="plain">>; rel=</code><code class="string">"next"</code><code class="plain">, <<a href="https://staging.connectwisedev.com/v">https://staging.connectwisedev.com/v</a></code><code class="value">2017</code><code class="plain">_</code><code class="value">3</code><code class="plain">/apis/</code><code class="value">3.0</code><code class="plain">/company/companies?pageSize=</code><code class="value">50</code><code class="plain">&page=</code><code class="value">1</code><code class="plain">>; rel=</code><code class="string">"prev"</code><code class="plain">, <<a href="https://staging.connectwisedev.com/v">https://staging.connectwisedev.com/v</a></code><code class="value">2017</code><code class="plain">_</code><code class="value">3</code><code class="plain">/apis/</code><code class="value">3.0</code><code class="plain">/company/companies?pageSize=</code><code class="value">50</code><code class="plain">&page=</code><code class="value">1</code><code class="plain">>; rel=</code><code class="string">"first"</code><code class="plain">, <<a href="https://staging.connectwisedev.com/v">https://staging.connectwisedev.com/v</a></code><code class="value">2017</code><code class="plain">_</code><code class="value">3</code><code class="plain">/apis/</code><code class="value">3.0</code><code class="plain">/company/companies?pageSize=</code><code class="value">50</code><code class="plain">&page=</code><code class="value">4</code><code class="plain">>; rel=</code><code class="string">"last"</code></td></tr></tbody></table></div></div></div>
|
|
|
|
<p>Now that we have navigated to the second page, we will find two
|
|
additional URLs. These are "prev" and "first" and in total we now
|
|
have four including the original "next" and "last".</p>
|
|
|
|
<table class="mt-responsive-table">
|
|
<tbody>
|
|
<tr>
|
|
<td class="mt-noheading mt-column-width-10">First</td>
|
|
<td class="mt-noheading mt-column-width-85">This link will display the first page available based on the current page size</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="mt-noheading mt-column-width-10">Prev*</td>
|
|
<td class="mt-noheading mt-column-width-85">This link will display the previous page based on the current page position and page size</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="mt-noheading mt-column-width-10">Next*</td>
|
|
<td class="mt-noheading mt-column-width-85">This link will display the next available page based on the current page position and page size</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="mt-noheading mt-column-width-10">Last</td>
|
|
<td class="mt-noheading mt-column-width-85">This link will always display the final page available based on the current page size</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
|
|
<p><span class="mt-color-e74c3c">*We will not return the next or prev links if there isn't a next or prev respectively.</span></p>
|
|
|
|
<p>In the above examples, we have four pages of results and depending on
|
|
the page size, that number can change. For instance, let's say we
|
|
switch to the default page size of 25. Instead of returning four
|
|
pages, we actually get back 7 pages as there are only 160 results.</p>
|
|
|
|
<p>The goal of pagination is not to pull every possible result, every
|
|
single time. Instead, it is designed to be in conjunction with a
|
|
UI component to create a set of navigation links.</p>
|
|
|
|
<p><img class="internal" style="width: 604px; height: 67px;" width="604px" height="67px" alt="clipboard_e29fb7e94d767bfdc2a4db21d834fef74.png" loading="lazy" src="Developer%20Guide%20-%20Developer%20Network_files/clipboard_e29fb7e94d767bfdc2a4db21d834fef74.png"></p>
|
|
|
|
<blockquote>
|
|
<p>Navigable Pagination closely follows <a title="https://tools.ietf.org/html/rfc5988" href="https://tools.ietf.org/html/rfc5988" target="_blank" rel="external noopener nofollow" class="link-https">RFC 5988</a>.</p>
|
|
</blockquote>
|
|
|
|
</div>
|
|
</div>
|
|
|
|
</div><div mt-section-origin="Products/ConnectWise_PSA/Developer_Guide" class="mt-section" id="section_10"><span id="Forward-Only"></span><h4 class="editable">Forward-Only</h4>
|
|
|
|
<div class="mt-contentreuse-widget" data-page="Best_Practices/Manage_Pagination" data-section="Forward-Only Pagination" data-show="false">
|
|
<div class="mt-include" id="s1266">
|
|
|
|
<p>Released in 2018.5</p>
|
|
|
|
<p>Unlike Navigable Pagination, forward-only requires that you pass
|
|
in a header to identify the type of pagination you would like to
|
|
use. For instance, we now accept a header called pagination-type,
|
|
and when you set that to forward-only you will get to utilize the new
|
|
features. In addition to the new header, there is a new query
|
|
parameter called pageId. The pageId is the record in which you
|
|
would like to begin with for paging.</p>
|
|
|
|
<ul>
|
|
<li>If you do not include the new header in your request, it will use the default paging method of navigable. </li>
|
|
<li>The Page query parameter will be ignored with forward-only paging as all results are technically page 1.</li>
|
|
<li>You cannot use an Order By query parameter with forward-only as it must be ordered by the ID.</li>
|
|
<li>There will always be a link header in the response for the next pageId.</li>
|
|
<li>The pageId query parameter is treated like an additional condition of Id > pageId.</li>
|
|
<li>The following pageId in the header will be the last Id you got in the request.</li>
|
|
</ul>
|
|
|
|
<p><img alt="clipboard_ebcad30cfa48ce47932d2c0b47108b933.png" class="internal" loading="lazy" src="Developer%20Guide%20-%20Developer%20Network_files/clipboard_ebcad30cfa48ce47932d2c0b47108b933.png"></p>
|
|
|
|
<p><img alt="clipboard_ef5cbb3427dc4eaba39453ea2dbcaf2c3.png" class="internal" loading="lazy" src="Developer%20Guide%20-%20Developer%20Network_files/clipboard_ef5cbb3427dc4eaba39453ea2dbcaf2c3.png"></p>
|
|
|
|
<p> </p>
|
|
|
|
<blockquote>
|
|
<p>Forward-Only pagination does not work with the Audit Trail endpoints at this time.</p>
|
|
</blockquote>
|
|
|
|
</div>
|
|
</div>
|
|
|
|
</div></div><div mt-section-origin="Products/ConnectWise_PSA/Developer_Guide" class="mt-section" id="section_11"><span id="Callbacks_(Webhooks)"></span><h2 class="editable">Callbacks (Webhooks)</h2>
|
|
|
|
<div class="mt-contentreuse-widget" data-page="Manage/Developer_Guide/Callbacks" data-section="" data-show="">
|
|
<div class="mt-include" id="s859"><p>ConnectWise PSA callbacks are
|
|
payloads of information that are similar to webhooks. When a
|
|
record is saved within PSA, a summarized payload is sent to a
|
|
specified location. </p>
|
|
|
|
<div mt-section-origin="Best_Practices/PSA_Callbacks" class="mt-section" id="section_1"><span id="Levels_and_Types"></span><h3 id="Levels_and_Types-859">Levels and Types</h3>
|
|
|
|
<p>The REST APIs allow a more granular approach to callbacks.
|
|
Levels and types open the ability to report on specific boards or
|
|
tickets without getting unnecessary results.</p>
|
|
|
|
<table border="1" cellpadding="1" cellspacing="1" style="width: 100%; table-layout: fixed;">
|
|
<tbody>
|
|
<tr>
|
|
<td style="width:103px;background-color:rgb(0, 102, 204);"><span class="mt-color-ffffff"><strong>Type</strong></span></td>
|
|
<td style="width:120px;background-color:rgb(0, 102, 204);"><span class="mt-color-ffffff"><strong>Level</strong></span></td>
|
|
<td style="width:503px;background-color:rgb(0, 102, 204);"><span class="mt-color-ffffff"><strong>Description</strong></span></td>
|
|
</tr>
|
|
</tbody>
|
|
<tbody>
|
|
<tr class="header">
|
|
<th colspan="3">Activities <span>+</span></th>
|
|
</tr>
|
|
<tr style="display: none;">
|
|
<td style="width:103px;">Activity</td>
|
|
<td style="width:120px;">Owner</td>
|
|
<td style="width:503px;">When set to owner, all ConnectWise PSA activities are returned.</td>
|
|
</tr>
|
|
<tr style="display: none;">
|
|
<td style="width:103px;">Activity</td>
|
|
<td style="width:120px;">Status</td>
|
|
<td style="width:503px;">Receive callbacks for activities in the specified status.</td>
|
|
</tr>
|
|
<tr style="display: none;">
|
|
<td style="width:103px;">Activity</td>
|
|
<td style="width:120px;">Type</td>
|
|
<td style="width:503px;">Receive callbacks for activities in the specified type.</td>
|
|
</tr>
|
|
<tr style="display: none;">
|
|
<td style="width:103px;">Activity</td>
|
|
<td style="width:120px;">Company</td>
|
|
<td style="width:503px;">Receive callbacks for activities under a specific company.</td>
|
|
</tr>
|
|
<tr style="display: none;">
|
|
<td style="width:103px;">Activity</td>
|
|
<td style="width:120px;">Activity</td>
|
|
<td style="width:503px;">Receive callbacks for specific activity.</td>
|
|
</tr>
|
|
<tr class="header">
|
|
<th colspan="3">Agreements <span>+</span></th>
|
|
</tr>
|
|
<tr style="display: none;">
|
|
<td style="width:103px;">Agreement</td>
|
|
<td style="width:120px;">Owner</td>
|
|
<td style="width:503px;">When set to owner, all ConnectWise PSA agreements are returned.</td>
|
|
</tr>
|
|
<tr style="display: none;">
|
|
<td style="width:103px;">Agreement</td>
|
|
<td style="width:120px;">Type</td>
|
|
<td style="width:503px;">Receive callbacks for agreements in the specified type.</td>
|
|
</tr>
|
|
<tr style="display: none;">
|
|
<td style="width:103px;">Agreement</td>
|
|
<td style="width:120px;">Company</td>
|
|
<td style="width:503px;">Receive callbacks for agreements under a specific company.</td>
|
|
</tr>
|
|
<tr style="display: none;">
|
|
<td style="width:103px;">Agreement</td>
|
|
<td style="width:120px;">Agreement</td>
|
|
<td style="width:503px;">Recieve callbacks for specific agreement.</td>
|
|
</tr>
|
|
<tr class="header">
|
|
<th colspan="3">Companies <span>+</span></th>
|
|
</tr>
|
|
<tr style="display: none;">
|
|
<td style="width:103px;">Company</td>
|
|
<td style="width:120px;">Owner</td>
|
|
<td style="width:503px;">When set to owner, all ConnectWise PSA companies are returned.</td>
|
|
</tr>
|
|
<tr style="display: none;">
|
|
<td style="width:103px;">Company</td>
|
|
<td style="width:120px;">Status</td>
|
|
<td style="width:503px;">Receive callbacks for companies in the specified status.</td>
|
|
</tr>
|
|
<tr style="display: none;">
|
|
<td style="width:103px;">Company</td>
|
|
<td style="width:120px;">Type</td>
|
|
<td style="width:503px;">Receive callbacks for companies in the specified type.</td>
|
|
</tr>
|
|
<tr style="display: none;">
|
|
<td style="width:103px;">Company</td>
|
|
<td style="width:120px;">Territory</td>
|
|
<td style="width:503px;">Receive callbacks for companies in the specified territory.</td>
|
|
</tr>
|
|
<tr style="display: none;">
|
|
<td style="width:103px;">Company</td>
|
|
<td style="width:120px;">Company</td>
|
|
<td style="width:503px;">Receive callbacks for specific company regardless of territory.</td>
|
|
</tr>
|
|
<tr style="display: none;">
|
|
<td style="width:103px;">Company</td>
|
|
<td style="width:120px;">IntegratorTag</td>
|
|
<td style="width:503px;">Tag companies to only get updates for that company with one callback record</td>
|
|
</tr>
|
|
<tr class="header">
|
|
<th colspan="3">Contacts <span>+</span></th>
|
|
</tr>
|
|
<tr style="display: none;">
|
|
<td style="width:103px;">Contact</td>
|
|
<td style="width:120px;">Owner</td>
|
|
<td style="width:503px;">When set to owner, all ConnectWise PSA contacts are returned.</td>
|
|
</tr>
|
|
<tr style="display: none;">
|
|
<td style="width:103px;">Contact</td>
|
|
<td style="width:120px;">Type</td>
|
|
<td style="width:503px;">Receive callbacks for contacts in the specified type.</td>
|
|
</tr>
|
|
<tr style="display: none;">
|
|
<td style="width:103px;">Contact</td>
|
|
<td style="width:120px;">Territory</td>
|
|
<td style="width:503px;">Receive callbacks for contacts in the specified territory.</td>
|
|
</tr>
|
|
<tr style="display: none;">
|
|
<td style="width:103px;">Contact</td>
|
|
<td style="width:120px;">Company</td>
|
|
<td style="width:503px;">Receive callbacks for contacts under a specific company.</td>
|
|
</tr>
|
|
<tr style="display: none;">
|
|
<td style="width:103px;">Contact</td>
|
|
<td style="width:120px;">Contact</td>
|
|
<td style="width:503px;">Receive callbacks for specific contact.</td>
|
|
</tr>
|
|
<tr class="header">
|
|
<th colspan="3">Configurations <span>+</span></th>
|
|
</tr>
|
|
<tr style="display: none;">
|
|
<td style="width:103px;">Configuration</td>
|
|
<td style="width:120px;">Owner</td>
|
|
<td style="width:503px;">When set to owner, all ConnectWise PSA configurations are returned.</td>
|
|
</tr>
|
|
<tr style="display: none;">
|
|
<td style="width:103px;">Configuration</td>
|
|
<td style="width:120px;">Type</td>
|
|
<td style="width:503px;">Receive callbacks for configurations in the specified type.</td>
|
|
</tr>
|
|
<tr style="display: none;">
|
|
<td style="width:103px;">Configuration</td>
|
|
<td style="width:120px;">Status</td>
|
|
<td style="width:503px;">Receive callbacks for contacts in the specified status.</td>
|
|
</tr>
|
|
<tr style="display: none;">
|
|
<td style="width:103px;">Configuration</td>
|
|
<td style="width:120px;">Configuration</td>
|
|
<td style="width:503px;">Receive callbacks for a specific configuration.</td>
|
|
</tr>
|
|
<tr class="header">
|
|
<th colspan="3">Invoice <span>+</span></th>
|
|
</tr>
|
|
<tr style="display: none;">
|
|
<td style="width:103px;">Invoice</td>
|
|
<td style="width:120px;">Owner</td>
|
|
<td style="width:503px;">When set to owner, all ConnectWise PSA invoices are returned.</td>
|
|
</tr>
|
|
<tr style="display: none;">
|
|
<td style="width:103px;">Invoice</td>
|
|
<td style="width:120px;">Status</td>
|
|
<td style="width:503px;">Receive callbacks for invoices in the specified status.</td>
|
|
</tr>
|
|
<tr style="display: none;">
|
|
<td style="width:103px;">Invoice</td>
|
|
<td style="width:120px;">Company</td>
|
|
<td style="width:503px;">Receive callbacks for invoices under a specific company.</td>
|
|
</tr>
|
|
<tr style="display: none;">
|
|
<td style="width:103px;">Invoice</td>
|
|
<td style="width:120px;">Invoice</td>
|
|
<td style="width:503px;">Receive callbacks for specific invoice.</td>
|
|
</tr>
|
|
<tr class="header">
|
|
<th colspan="3">Expense <span>+</span></th>
|
|
</tr>
|
|
<tr style="display: none;">
|
|
<td style="width:103px;">Expense</td>
|
|
<td style="width:120px;">Owner</td>
|
|
<td style="width:503px;">When set to owner, all ConnectWise PSA expenses are returned.</td>
|
|
</tr>
|
|
<tr style="display: none;">
|
|
<td style="width:103px;">Expense</td>
|
|
<td style="width:120px;">ChargeToType</td>
|
|
<td style="width:503px;">Receive callbacks for expenses under the specified ChargeToType.</td>
|
|
</tr>
|
|
<tr style="display: none;">
|
|
<td style="width:103px;">Expense</td>
|
|
<td style="width:120px;">Type</td>
|
|
<td style="width:503px;">Receive callbacks for expenses under the specified Type.</td>
|
|
</tr>
|
|
<tr style="display: none;">
|
|
<td style="width:103px;">Expense</td>
|
|
<td style="width:120px;">Class</td>
|
|
<td style="width:503px;">Receive callbacks for expenses under the specified Class.</td>
|
|
</tr>
|
|
<tr style="display: none;">
|
|
<td style="width:103px;">Expense</td>
|
|
<td style="width:120px;">Company</td>
|
|
<td style="width:503px;">Receive callbacks for expenses under the specified Company.</td>
|
|
</tr>
|
|
<tr style="display: none;">
|
|
<td style="width:103px;">Expense</td>
|
|
<td style="width:120px;">Expense</td>
|
|
<td style="width:503px;">Receive calbacks for specific expense.</td>
|
|
</tr>
|
|
<tr class="header">
|
|
<th colspan="3">Member <span>+</span></th>
|
|
</tr>
|
|
<tr style="display: none;">
|
|
<td style="width:103px;">Member</td>
|
|
<td style="width:120px;">Owner</td>
|
|
<td style="width:503px;">When set to owner, changes to all ConnectWise PSA member records are returned.</td>
|
|
</tr>
|
|
<tr style="display: none;">
|
|
<td style="width:103px;">Member</td>
|
|
<td style="width:120px;">Location</td>
|
|
<td style="width:503px;">Receive callbacks for member records associated with the specified Location.</td>
|
|
</tr>
|
|
<tr style="display: none;">
|
|
<td style="width:103px;">Member</td>
|
|
<td style="width:120px;">SecurityRole</td>
|
|
<td style="width:503px;">Receive callbacks for member records associated with the specified Security Role.</td>
|
|
</tr>
|
|
<tr style="display: none;">
|
|
<td style="width:103px;">Member</td>
|
|
<td style="width:120px;">Member</td>
|
|
<td style="width:503px;">Receive callbacks for changes made to a specified member record.</td>
|
|
</tr>
|
|
<tr class="header">
|
|
<th colspan="3">Opportunities <span>+</span></th>
|
|
</tr>
|
|
<tr style="display: none;">
|
|
<td style="width:103px;">Opportunity</td>
|
|
<td style="width:120px;">Owner</td>
|
|
<td style="width:503px;">When set to owner, all ConnectWise PSA opportunities are returned.</td>
|
|
</tr>
|
|
<tr style="display: none;">
|
|
<td style="width:103px;">Opportunity</td>
|
|
<td style="width:120px;">StatusId</td>
|
|
<td style="width:503px;">Receive callbacks for opportunities in the specified status.</td>
|
|
</tr>
|
|
<tr style="display: none;">
|
|
<td style="width:103px;">Opportunity</td>
|
|
<td style="width:120px;">Company</td>
|
|
<td style="width:503px;">Receive callbacks for opportunities under a specific company.</td>
|
|
</tr>
|
|
<tr style="display: none;">
|
|
<td style="width:103px;">Opportunity</td>
|
|
<td style="width:120px;">Opportunity</td>
|
|
<td style="width:503px;">Receive callbacks for specific opportunity.</td>
|
|
</tr>
|
|
<tr class="header">
|
|
<th colspan="3">Product Catalog <span>+</span></th>
|
|
</tr>
|
|
<tr style="display: none;">
|
|
<td style="width:103px;"><span class="mt-font-size-12">ProductCatalog</span></td>
|
|
<td style="width:120px;">Owner</td>
|
|
<td style="width:503px;">When set to owner, all ConnectWise PSA product catalog items are returned.</td>
|
|
</tr>
|
|
<tr class="header">
|
|
<th colspan="3">Projects <span>+</span></th>
|
|
</tr>
|
|
<tr style="display: none;">
|
|
<td style="width:103px;">Project</td>
|
|
<td style="width:120px;">Owner</td>
|
|
<td style="width:503px;">When set to owner, all ConnectWise PSA projects are returned.</td>
|
|
</tr>
|
|
<tr style="display: none;">
|
|
<td style="width:103px;">Project</td>
|
|
<td style="width:120px;">Status</td>
|
|
<td style="width:503px;">Receive callbacks for projects in the specified status.</td>
|
|
</tr>
|
|
<tr style="display: none;">
|
|
<td style="width:103px;">Project</td>
|
|
<td style="width:120px;">Board</td>
|
|
<td style="width:503px;">Receive callbacks for projects on the specified board.</td>
|
|
</tr>
|
|
<tr style="display: none;">
|
|
<td style="width:103px;">Project</td>
|
|
<td style="width:120px;">Project</td>
|
|
<td style="width:503px;">Receive callbacks for specific project.</td>
|
|
</tr>
|
|
<tr class="header">
|
|
<th colspan="3">Purchase Orders <span>+</span></th>
|
|
</tr>
|
|
<tr style="display: none;">
|
|
<td style="width:103px;"><span class="mt-font-size-12">PurchaseOrder</span></td>
|
|
<td style="width:120px;">Owner</td>
|
|
<td style="width:503px;">When set to owner, all ConnectWise PSA purchase orders are returned.</td>
|
|
</tr>
|
|
<tr style="display: none;">
|
|
<td style="width:103px;"><span class="mt-font-size-12">PurchaseOrder</span></td>
|
|
<td style="width:120px;">Status</td>
|
|
<td style="width:503px;">Receive callbacks for purchase orders in the specified status.</td>
|
|
</tr>
|
|
<tr style="display: none;">
|
|
<td style="width:103px;"><span class="mt-font-size-12">PurchaseOrder</span></td>
|
|
<td style="width:120px;">Vendor</td>
|
|
<td style="width:503px;">Receive callbacks for purchase orders under the specified Vendor.</td>
|
|
</tr>
|
|
<tr style="display: none;">
|
|
<td style="width:103px;"><span class="mt-font-size-12">PurchaseOrder</span></td>
|
|
<td style="width:120px;">Company</td>
|
|
<td style="width:503px;">Receive callbacks for purchase orders under a specific company.</td>
|
|
</tr>
|
|
<tr style="display: none;">
|
|
<td style="width:103px;"><span class="mt-font-size-12">PurchaseOrder</span></td>
|
|
<td style="width:120px;"><span class="mt-font-size-12">PurchaseOrder</span></td>
|
|
<td style="width:503px;">Receive callbacks for specific purchase orders.</td>
|
|
</tr>
|
|
<tr class="header">
|
|
<th colspan="3">Schedule Entries <span>+</span></th>
|
|
</tr>
|
|
<tr style="display: none;">
|
|
<td style="width:103px;">Schedule</td>
|
|
<td style="width:120px;">Owner</td>
|
|
<td style="width:503px;">When set to owner, all ConnectWise PSA schedule entries are returned.</td>
|
|
</tr>
|
|
<tr style="display: none;">
|
|
<td style="width:103px;">Schedule</td>
|
|
<td style="width:120px;">Status</td>
|
|
<td style="width:503px;">Receive callbacks for schedule entries under a specific status.</td>
|
|
</tr>
|
|
<tr style="display: none;">
|
|
<td style="width:103px;">Schedule</td>
|
|
<td style="width:120px;">Type</td>
|
|
<td style="width:503px;">Receive callbacks for schedule entries under a specific type.</td>
|
|
</tr>
|
|
<tr style="display: none;">
|
|
<td style="width:103px;">Schedule</td>
|
|
<td style="width:120px;">Location</td>
|
|
<td style="width:503px;">Receive callbacks for schedule entries under a specific location.</td>
|
|
</tr>
|
|
<tr style="display: none;">
|
|
<td style="width:103px;">Schedule</td>
|
|
<td style="width:120px;">Member</td>
|
|
<td style="width:503px;">Receive callbacks for schedule entries under a specific member.</td>
|
|
</tr>
|
|
<tr style="display: none;">
|
|
<td style="width:103px;">Schedule</td>
|
|
<td style="width:120px;">Schedule</td>
|
|
<td style="width:503px;">Receive callbacks for specific schedule entries.</td>
|
|
</tr>
|
|
<tr class="header">
|
|
<th colspan="3">Sites <span>+</span></th>
|
|
</tr>
|
|
<tr style="display: none;">
|
|
<td style="width:103px;">Site</td>
|
|
<td style="width:120px;">Owner</td>
|
|
<td style="width:503px;">When set to owner, all ConnectWise PSA sites are returned.</td>
|
|
</tr>
|
|
<tr style="display: none;">
|
|
<td style="width:103px;">Site</td>
|
|
<td style="width:120px;">Territory</td>
|
|
<td style="width:503px;">Receive callbacks for sites in specified territory.</td>
|
|
</tr>
|
|
<tr style="display: none;">
|
|
<td style="width:103px;">Site</td>
|
|
<td style="width:120px;">Company</td>
|
|
<td style="width:503px;">Receive callbacks for sites associated with a specific company.</td>
|
|
</tr>
|
|
<tr style="display: none;">
|
|
<td style="width:103px;">Site</td>
|
|
<td style="width:120px;">Site</td>
|
|
<td style="width:503px;">Receive callbacks for specific site.</td>
|
|
</tr>
|
|
<tr class="header">
|
|
<th colspan="3">Tickets <span>+</span></th>
|
|
</tr>
|
|
<tr style="display: none;">
|
|
<td style="width:103px;">Ticket</td>
|
|
<td style="width:120px;">Owner</td>
|
|
<td style="width:503px;">When set to owner, all ConnectWise PSA tickets are returned.</td>
|
|
</tr>
|
|
<tr style="display: none;">
|
|
<td style="width:103px;">Ticket</td>
|
|
<td style="width:120px;">Board</td>
|
|
<td style="width:503px;">Receive callbacks for tickets on the specified board.</td>
|
|
</tr>
|
|
<tr style="display: none;">
|
|
<td style="width:103px;">Ticket</td>
|
|
<td style="width:120px;">Project</td>
|
|
<td style="width:503px;">Receive callbacks for tickets attached to a specific project.</td>
|
|
</tr>
|
|
<tr style="display: none;">
|
|
<td style="width:103px;">Ticket</td>
|
|
<td style="width:120px;">Phase</td>
|
|
<td style="width:503px;">Receive callbacks for tickets attached to a specific project phase.</td>
|
|
</tr>
|
|
<tr style="display: none;">
|
|
<td style="width:103px;">Ticket</td>
|
|
<td style="width:120px;">Status</td>
|
|
<td style="width:503px;">Receive callbacks for tickets in the specified status.</td>
|
|
</tr>
|
|
<tr style="display: none;">
|
|
<td style="width:103px;">Ticket</td>
|
|
<td style="width:120px;">Ticket</td>
|
|
<td style="width:503px;">Receive callbacks for specific tickets.</td>
|
|
</tr>
|
|
<tr style="display: none;">
|
|
<td style="width:103px;">Ticket</td>
|
|
<td style="width:120px;">IntegratorTag</td>
|
|
<td style="width:503px;">Tag tickets to only get updates for that ticket with one callback record</td>
|
|
</tr>
|
|
<tr class="header">
|
|
<th colspan="3">Time Entries <span>+</span></th>
|
|
</tr>
|
|
<tr style="display: none;">
|
|
<td style="width:103px;">Time</td>
|
|
<td style="width:120px;">Owner</td>
|
|
<td style="width:503px;">When set to owner, all ConnectWise PSA time entries are returned.</td>
|
|
</tr>
|
|
<tr style="display: none;">
|
|
<td style="width:103px;">Time</td>
|
|
<td style="width:120px;">Company</td>
|
|
<td style="width:503px;">Receive callbacks for tickets for the specified company.</td>
|
|
</tr>
|
|
<tr style="display: none;">
|
|
<td style="width:103px;">Time</td>
|
|
<td style="width:120px;">Time</td>
|
|
<td style="width:503px;">Receive callbacks for specific time entries.</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
|
|
|
|
|
|
<script type="text/javascript">/*<![CDATA[*/
|
|
$('.header').click(function(){
|
|
$(this).find('span').text(function(_, value){return value=='-'?'+':'-'});
|
|
$(this).nextUntil('tr.header').slideToggle(100, function(){
|
|
});
|
|
});/*]]>*/</script>
|
|
|
|
</div><div mt-section-origin="Best_Practices/PSA_Callbacks" class="mt-section" id="section_2"><span id="Configuring_the_Callbacks"></span><h3 id="Configuring_the_Callbacks-859">Configuring the Callbacks</h3>
|
|
|
|
<p>More information can be found within the REST API documentation <a title="https://developer.connectwise.com/Products/Manage/REST#/CallbackEntries" href="https://developer.connectwise.com/Products/ConnectWise_PSA/REST#/CallbackEntries" rel="internal">Here</a> with the endpoint system/callbacks.</p>
|
|
|
|
<table class="mt-responsive-table">
|
|
<tbody>
|
|
<tr>
|
|
<td class="mt-noheading mt-column-width-15" style="background-color:rgb(0, 102, 204);">
|
|
<p><span class="mt-color-ffffff"><strong>Fields</strong></span></p>
|
|
</td>
|
|
<td class="mt-noheading mt-column-width-85" style="background-color:rgb(0, 102, 204);">
|
|
<p><span class="mt-color-ffffff"><strong>Description</strong></span></p>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="mt-noheading mt-column-width-15">Id</td>
|
|
<td class="mt-noheading mt-column-width-85">The database record id of the callback; is automatically assigned.</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="mt-noheading mt-column-width-15">Description</td>
|
|
<td class="mt-noheading mt-column-width-85">This is used to label the callback's usage.</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="mt-noheading mt-column-width-15">URL</td>
|
|
<td class="mt-noheading mt-column-width-85">
|
|
<p>This is the URL PSA will send the POST payload to. </p>
|
|
|
|
<p><strong>Note</strong>: PSA appends the record id, and action is taken, to the specified callback URL.</p>
|
|
|
|
<p>For example, a callback on ticket 7601, turns the callback URL into: <a title="https://mycallbacksite.com/e355a80bc2c107e32" href="https://mycallbacksite.com/e355a80bc2c107e32" target="_blank" rel="external noopener nofollow" class="link-https">https://mycallbacksite.com/e355a80bc2c107e32</a><em>?7601&action=updated</em></p>
|
|
|
|
<p>Typically, this is not an issue. However, when it is
|
|
necessary to add custom parameters to your callback URL, this
|
|
can cause a problem. For this reason, it is recommended that partners
|
|
append <em>&recordId=</em> to the end of their callback URL, like: <a title="https://mycallbacksite.com/e355a80bc2c107e32" href="https://mycallbacksite.com/e355a80bc2c107e32" target="_blank" rel="external noopener nofollow" class="link-https">https://mycallbacksite.com/e355a80bc2c107e32</a><strong><em>&recordId=</em></strong>. This will ensure that the record id does not interfere with any custom parameters.</p>
|
|
|
|
<p>Example:<br>
|
|
Desired callback URL: <a data-auth="Verified" data-linkindex="0" href="https://nam02.safelinks.protection.outlook.com/?url=https%3A%2F%2Fapi.mycallbackendpoint.com%2F%3Fparam1%3D5%26param2%3D6&data=05%7C01%7CRBodford%40connectwise.com%7C3deeae87cf1245c0a98008db0301ab7e%7Cf2ddb62f83354cc99886175b834e4bf3%7C0%7C0%7C638107077950837811%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000%7C%7C%7C&sdata=6dopNZzGSRoM5HMUn%2BzhlV0UV3DeZizIxiwMajv5eXE%3D&reserved=0" originalsrc="https://api.mycallbackendpoint.com/?param1=5&param2=6" rel="noopener noreferrer" shash="XphkNj4he01l3/v29hfbZ8eZIY7Gk5Arvm5LxavTIgYyFi9wOqCQMQNaCxTRCHsP8rB4xhKpF0csWjxclSngJ4SjGIABApacOziMt6jS3uOO84L+8G2hUnk0AVEgciG7annuA3/syZM4r5SGQ7Ely2gdhuLffxMoFaZNBvzre8k=" target="_blank" title="Original URL: https://api.mycallbackendpoint.com/?param1=5&param2=6. Click or tap if you trust this link.">https://api.mycallbackendpoint.com?param1=5&param2=6</a></p>
|
|
|
|
<p>Currently, a callback on ticket number 2475 turns the callback URL into:</p>
|
|
|
|
<p><a data-auth="Verified" data-linkindex="1" href="https://nam02.safelinks.protection.outlook.com/?url=https%3A%2F%2Fapi.mycallbackendpoint.com%2F%3Fparam1%3D5%26param2%3D62475%26action%3Dupdated&data=05%7C01%7CRBodford%40connectwise.com%7C3deeae87cf1245c0a98008db0301ab7e%7Cf2ddb62f83354cc99886175b834e4bf3%7C0%7C0%7C638107077950837811%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000%7C%7C%7C&sdata=2BxWDta4VObPj81GAHDOWTxyrtYmj3AxTo8MYp3mxv4%3D&reserved=0" originalsrc="https://api.mycallbackendpoint.com/?param1=5&param2=62475&action=updated" rel="noopener noreferrer" shash="TlXW142oUsObxDnCgBTOBwfa+0pl9ziUSh2i4in6gxpSXHmEuiaKVSqotlvhpGUooil0AQzdlAWg3jx26M1r2bk/RW897bYOHzjTFNZ69UYmWfhS80dTtrHRwd6HrFW6A/JN2tY06Da8uIV/yFOKNjzBHt/1Rt1M1Brfy2G3ApQ=" target="_blank" title="Original URL: https://api.mycallbackendpoint.com/?param1=5&param2=62475&action=updated. Click or tap if you trust this link.">https://api.mycallbackendpoint.com?param1=5&param2=62475&action=updated</a></p>
|
|
|
|
<p>Notice the value of param2 is now changed from 6 to 62475 because the ticket number was appended.</p>
|
|
|
|
<p aria-hidden="true">To resolve this issue, change the desired callback URL to <a data-auth="Verified" data-linkindex="2" href="https://nam02.safelinks.protection.outlook.com/?url=https%3A%2F%2Fapi.mycallbackendpoint.com%2F%3Fparam1%3D5%26param2%3D6%26recordId%3D&data=05%7C01%7CRBodford%40connectwise.com%7C3deeae87cf1245c0a98008db0301ab7e%7Cf2ddb62f83354cc99886175b834e4bf3%7C0%7C0%7C638107077950837811%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000%7C%7C%7C&sdata=6zqQnRHSICdGqSor%2BzxHzG0xp%2F1sA%2FhPWiu7APbwl60%3D&reserved=0" originalsrc="https://api.mycallbackendpoint.com/?param1=5&param2=6&recordId=" rel="noopener noreferrer" shash="meoQPTm90K66Kg5zJdjgiyOdehUJ6XGbBnPp6+b5NphRVS3OAZBYII+cD6RG2p1wZE7BGetcEg+/4qI48Y/vbcmtnlNU2Jej9LzQiJaUu9cj79O8tQot0l5DDpoKmxENMF/nG0kxqaJUqp5uDOjQmLQ+27jjYdrkyxkm5qjHPZQ=" target="_blank" title="Original URL: https://api.mycallbackendpoint.com/?param1=5&param2=6&recordId=. Click or tap if you trust this link.">https://api.mycallbackendpoint.com?param1=5&param2=6&recordId=</a></p>
|
|
|
|
<p>This results in the following URL:</p>
|
|
|
|
<p><a data-auth="Verified" data-linkindex="3" href="https://nam02.safelinks.protection.outlook.com/?url=https%3A%2F%2Fapi.mycallbackendpoint.com%2F%3Fparam1%3D5%26param2%3D6%26recordId%3D2475%26action%3Dupdated&data=05%7C01%7CRBodford%40connectwise.com%7C3deeae87cf1245c0a98008db0301ab7e%7Cf2ddb62f83354cc99886175b834e4bf3%7C0%7C0%7C638107077950994009%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000%7C%7C%7C&sdata=GwH9Y77%2Be5wgOxXwy%2FD1HXx4XRII%2FgE8eFCu7pyLafw%3D&reserved=0" originalsrc="https://api.mycallbackendpoint.com/?param1=5&param2=6&recordId=2475&action=updated" rel="noopener noreferrer" shash="QlCHGMx45y/eoAsClXEKlmzxS0NiCau08OosJQ9AyBgU+XXeRPiozojW8/1pKs3JuutiG1Ftfyo+HWfJBi8KM6S1LlPtJ4cCrjO9TYRdjqs/gafQKcThyRESlJT4ARsanbCcCbXArFjBeIjtov8msKL5v6+9nmKytE6WCuakcXQ=" target="_blank" title="Original URL: https://api.mycallbackendpoint.com/?param1=5&param2=6&recordId=2475&action=updated. Click or tap if you trust this link.">https://api.mycallbackendpoint.com?param1=5&param2=6&recordId=2475&action=updated</a></p>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="mt-noheading mt-column-width-15">ObjectId</td>
|
|
<td class="mt-noheading mt-column-width-85">The
|
|
ObjectId should be the Id of whatever record you are subscribing
|
|
to. This should be set to 1 when using a level of Owner. </td>
|
|
</tr>
|
|
<tr>
|
|
<td class="mt-noheading mt-column-width-15">Type</td>
|
|
<td class="mt-noheading mt-column-width-85">This is the specific type of record such as Company, Ticket, Contact, etc... See the associated table for all values.</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="mt-noheading mt-column-width-15">Level</td>
|
|
<td class="mt-noheading mt-column-width-85">The level is used to determine how granular the callback subscription will be. See the associated table for all values.</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="mt-noheading mt-column-width-15">isSelfSuppressedFlag</td>
|
|
<td class="mt-noheading mt-column-width-85">If
|
|
isSelfSuppressedFlag = true AND the record (ticket/company/etc.) that is
|
|
triggering the callback was updated by the memberId associated with the
|
|
callback, then the callback does not fire. The logic being that the
|
|
member making the update does not need to be notified an
|
|
update was made.</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="mt-noheading mt-column-width-15">MemberId</td>
|
|
<td class="mt-noheading mt-column-width-85">This is a read-only value that shows who initially created the Callback.</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="mt-noheading mt-column-width-15">InactiveFlag</td>
|
|
<td class="mt-noheading mt-column-width-85">Used to determine if the callback is active and sending requests.</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="mt-noheading mt-column-width-15">_Info</td>
|
|
<td class="mt-noheading mt-column-width-85">This section has additional metadata about the record and is included on all API requests as read-only data.</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
|
|
<div id="highlighter_858562" class="syntaxhighlighter "><div class="bar"><div class="toolbar"><a href="#viewSource" title="view source" style="width: 16px; height: 16px;" class="item viewSource">view source</a><a href="#printSource" title="print" style="width: 16px; height: 16px;" class="item printSource">print</a><a href="#about" title="?" style="width: 16px; height: 16px;" class="item about">?</a></div></div><div class="lines"><div class="line alt1"><table><tbody><tr><td class="number"><code>01</code></td><td class="content"><code class="plain">POST /v4_6_release/apis/3.0/system/callbacks</code></td></tr></tbody></table></div><div class="line alt2"><table><tbody><tr><td class="number"><code>02</code></td><td class="content"><code class="plain">{</code></td></tr></tbody></table></div><div class="line alt1"><table><tbody><tr><td class="number"><code>03</code></td><td class="content"><code class="spaces"> </code><code class="string">"id"</code><code class="plain">: 0,</code></td></tr></tbody></table></div><div class="line alt2"><table><tbody><tr><td class="number"><code>04</code></td><td class="content"><code class="spaces"> </code><code class="string">"description"</code><code class="plain">: </code><code class="string">"maxLength = 100"</code><code class="plain">,</code></td></tr></tbody></table></div><div class="line alt1"><table><tbody><tr><td class="number"><code>05</code></td><td class="content"><code class="spaces"> </code><code class="string">"url"</code><code class="plain">: </code><code class="string">"Sample string"</code><code class="plain">,</code></td></tr></tbody></table></div><div class="line alt2"><table><tbody><tr><td class="number"><code>06</code></td><td class="content"><code class="spaces"> </code><code class="string">"objectId"</code><code class="plain">: 0,</code></td></tr></tbody></table></div><div class="line alt1"><table><tbody><tr><td class="number"><code>07</code></td><td class="content"><code class="spaces"> </code><code class="string">"type"</code><code class="plain">: </code><code class="string">"Sample string"</code><code class="plain">,</code></td></tr></tbody></table></div><div class="line alt2"><table><tbody><tr><td class="number"><code>08</code></td><td class="content"><code class="spaces"> </code><code class="string">"level"</code><code class="plain">: </code><code class="string">"Sample string"</code><code class="plain">,</code></td></tr></tbody></table></div><div class="line alt1"><table><tbody><tr><td class="number"><code>09</code></td><td class="content"><code class="spaces"> </code><code class="string">"memberId"</code><code class="plain">: 0,</code></td></tr></tbody></table></div><div class="line alt2"><table><tbody><tr><td class="number"><code>10</code></td><td class="content"><code class="spaces"> </code><code class="string">"inactiveFlag"</code><code class="plain">: </code><code class="string">"false"</code><code class="plain">,</code></td></tr></tbody></table></div><div class="line alt1"><table><tbody><tr><td class="number"><code>11</code></td><td class="content"><code class="spaces"> </code><code class="string">"_info "</code><code class="plain">: { </code><code class="string">"lastUpdated"</code><code class="plain">: </code><code class="string">""</code><code class="plain">, </code><code class="string">"updatedBy"</code><code class="plain">: </code><code class="string">""</code> <code class="plain">}</code></td></tr></tbody></table></div><div class="line alt2"><table><tbody><tr><td class="number"><code>12</code></td><td class="content"><code class="plain">}</code></td></tr></tbody></table></div></div></div>
|
|
|
|
</div><div mt-section-origin="Best_Practices/PSA_Callbacks" class="mt-section" id="section_3"><span id="Testing_Callbacks"></span><h3 id="Testing_Callbacks-859">Testing Callbacks</h3>
|
|
|
|
<div class="mt-contentreuse-widget" data-page="ConnectWise/Troubleshooting/Test_Applications" data-section="JSON Callback Tester:" data-show="">
|
|
|
|
</div>
|
|
|
|
<div mt-section-origin="Best_Practices/PSA_Callbacks" class="mt-section" id="section_4"><span id="Webhook.Site"></span><h4 id="Webhook.Site-859">Webhook.Site</h4>
|
|
|
|
<p>When testing the ConnectWise PSA callbacks there are a number of useful browser-based tools. One of note is <a title="https://webhook.site" href="https://webhook.site/" target="_blank" rel="external noopener nofollow" class="link-https">https://webhook.site</a>.</p>
|
|
|
|
<p>Simply use the New button to create a URL and then the Copy URL
|
|
button to save the URL generated to your clipboard and add
|
|
this as your ConnectWise PSA callback URL.</p>
|
|
|
|
<pre>https://webhook.site/xxxxxxx-xxxx-xxxx-af13-855ab85aebae
|
|
</pre>
|
|
|
|
</div></div><div mt-section-origin="Best_Practices/PSA_Callbacks" class="mt-section" id="section_5"><span id="When_Callbacks_Fail_to_POST_to_Target_Host"></span><h3 id="When_Callbacks_Fail_to_POST_to_Target_Host-859">When Callbacks Fail to POST to Target Host</h3>
|
|
|
|
<p>When a callback receives an error when attempting to POST the
|
|
callback payload to the host specified in the callback
|
|
URL, ConnectWise PSA will retry the POST for any 404, 409,
|
|
419, or 429 error responses. ConnectWise PSA retries twice, once
|
|
two seconds after the initial POST attempt and again four seconds after
|
|
the first retry attempt. Requests will timeout after five seconds.</p>
|
|
|
|
<p>The system counts how many consecutive days the callback fails, and
|
|
after three consecutive days of failed attempts, ConnectWise PSA
|
|
will disable the callback</p>
|
|
|
|
<p>Any 2xx response is considered successful.</p>
|
|
|
|
<p>For partners with an on-premise instance of ConnectWise PSA,
|
|
when troubleshooting why your callback POSTs are receiving error
|
|
response from the remote host, logs for the service are found on the
|
|
ConnectWise PSA frontend server at C:\Program
|
|
Files\ConnectWise\ApiCallbackService\logs\server.log</p>
|
|
|
|
<p>To enable verbose logging, change the minlevel value to
|
|
minlevel=”Info” in the C:\Program
|
|
Files\ConnectWise\ApiCallbackService\ApiCallbackService.exe.nlog</p>
|
|
|
|
</div><div mt-section-origin="Best_Practices/PSA_Callbacks" class="mt-section" id="section_6"><span id="Verifying_the_Callback_Source"></span><h3 id="Verifying_the_Callback_Source-859">Verifying the Callback Source</h3>
|
|
|
|
<p>Callbacks contain a key_url in the metadata section that can be
|
|
used to verify the source of the callback. The key_url returns the
|
|
signing key which then can be used in conjunction with the below code
|
|
sample and the x-content-signature.</p>
|
|
|
|
<div id="highlighter_904805" class="syntaxhighlighter "><div class="bar "><div class="toolbar"><a href="#viewSource" title="view source" style="width: 16px; height: 16px;" class="item viewSource">view source</a><a href="#printSource" title="print" style="width: 16px; height: 16px;" class="item printSource">print</a><a href="#about" title="?" style="width: 16px; height: 16px;" class="item about">?</a></div></div><div class="lines"><div class="line alt1"><table><tbody><tr><td class="number"><code>1</code></td><td class="content"><code class="keyword">using</code> <code class="plain">(var sha = </code><code class="keyword">new</code> <code class="plain">SHA256Managed())</code></td></tr></tbody></table></div><div class="line alt2"><table><tbody><tr><td class="number"><code>2</code></td><td class="content"><code class="spaces"> </code><code class="plain">{</code></td></tr></tbody></table></div><div class="line alt1"><table><tbody><tr><td class="number"><code>3</code></td><td class="content"><code class="spaces"> </code><code class="plain">var hash = sha.ComputeHash(Encoding.UTF8.GetBytes(sharedSecretKey));</code></td></tr></tbody></table></div><div class="line alt2"><table><tbody><tr><td class="number"><code>4</code></td><td class="content"><code class="spaces"> </code><code class="keyword">using</code> <code class="plain">(var hmac = </code><code class="keyword">new</code> <code class="plain">HMACSHA256(hash))</code></td></tr></tbody></table></div><div class="line alt1"><table><tbody><tr><td class="number"><code>5</code></td><td class="content"><code class="spaces"> </code><code class="plain">{</code></td></tr></tbody></table></div><div class="line alt2"><table><tbody><tr><td class="number"><code>6</code></td><td class="content"><code class="spaces"> </code><code class="keyword">return</code> <code class="plain">Convert.ToBase64String(hmac.ComputeHash(Encoding.UTF8.GetBytes(jsonPayload)));</code></td></tr></tbody></table></div><div class="line alt1"><table><tbody><tr><td class="number"><code>7</code></td><td class="content"><code class="spaces"> </code><code class="plain">}</code></td></tr></tbody></table></div><div class="line alt2"><table><tbody><tr><td class="number"><code>8</code></td><td class="content"><code class="spaces"> </code><code class="plain">}</code></td></tr></tbody></table></div></div></div>
|
|
|
|
</div><div mt-section-origin="Best_Practices/PSA_Callbacks" class="mt-section" id="section_7"><span id="Callback_Changelog"></span><h3 id="Callback_Changelog-859">Callback Changelog </h3>
|
|
|
|
<table border="1" cellpadding="1" cellspacing="1" style="width: 100%; table-layout: fixed;">
|
|
<tbody>
|
|
<tr>
|
|
<td style="width:136px;background-color:rgb(0, 102, 204);"><span class="mt-color-ffffff"><strong>Supported Version</strong></span></td>
|
|
<td style="width:509px;background-color:rgb(0, 102, 204);"><span class="mt-color-ffffff"><strong>Changes</strong></span></td>
|
|
</tr>
|
|
<tr>
|
|
<td style="width:136px;">ConnectWise PSA 2020.2</td>
|
|
<td style="width:509px;">Added callbacks for Configurations</td>
|
|
</tr>
|
|
<tr>
|
|
<td style="width:136px;">ConnectWise PSA 2016.6</td>
|
|
<td style="width:509px;">Added callbacks for Invoice<br>
|
|
Added callbacks for Projects<br>
|
|
Added callbacks for Activities</td>
|
|
</tr>
|
|
<tr>
|
|
<td style="width:136px;">ConnectWise PSA 2016.5</td>
|
|
<td style="width:509px;">Company Callbacks: Added Status and Type levels<br>
|
|
Contact Callbacks: Added Type level<br>
|
|
Ticket Callbacks: Added levels for tracking Project Tickets</td>
|
|
</tr>
|
|
<tr>
|
|
<td style="width:136px;">ConnectWise PSA 2016.4</td>
|
|
<td style="width:509px;">Added callbacks for Opportunities</td>
|
|
</tr>
|
|
<tr>
|
|
<td style="width:136px;">ConnectWise PSA 2016.3</td>
|
|
<td style="width:509px;">Added callbacks for Companies and Contacts</td>
|
|
</tr>
|
|
<tr>
|
|
<td style="width:136px;">ConnectWise PSA 2015.6</td>
|
|
<td style="width:509px;">Added callbacks for Tickets</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div></div>
|
|
</div>
|
|
|
|
</div><div mt-section-origin="Products/ConnectWise_PSA/Developer_Guide" class="mt-section" id="section_12"><span id="Troubleshooting"></span><h2 class="editable">Troubleshooting</h2>
|
|
|
|
<div class="mt-contentreuse-widget" data-page="Manage/Developer_Guide/Troubleshooting" data-section="" data-show="">
|
|
<div class="mt-include" id="s1176"><p>Troubleshooting with the REST API
|
|
requires login access to the ConnectWise PSA UI. Additionally the
|
|
account being used to login, must have access to information relating to
|
|
the account for integration. In the case of the integration using
|
|
API Members, the account accessing logs, must have the security roles
|
|
to view members enabled. This requirement has to do with the API
|
|
Keys used for integrations, being tied to a specific member.</p>
|
|
|
|
<p>Logging with the REST API must be specifically turned on and there is
|
|
a time limit of 1440 minutes or 24 hours that can be recorded in a
|
|
single session. During this time, all requests that are processed
|
|
by the server and are associated to the member you are running logs
|
|
from, will appear in the UI. If you are getting errors from the
|
|
API and logs are not appearing, it may be a server side issue.</p>
|
|
|
|
<p>To get started with logging, you will need to access the API Log tab
|
|
found on every ConnectWise PSA member. Open the UI and navigate to
|
|
either System > Members or My Account and after you select the
|
|
respective account, click on the API Logs tab.</p>
|
|
|
|
<p><img class="internal default" style="width: 670px; height: 245px;" width="670px" height="245px" alt="clipboard_e89a0f4557369e1913310d5ad38f55b88.png" loading="lazy" src="Developer%20Guide%20-%20Developer%20Network_files/clipboard_e89a0f4557369e1913310d5ad38f55b88.png"></p>
|
|
|
|
<p>Once you have found the API Logs tab, the next step will be to press
|
|
"Start Debug Mode" and from there, select the amount of time you would
|
|
like to record for.</p>
|
|
|
|
<p><img class="internal" style="width: 590px; height: 61px;" width="590px" height="61px" alt="clipboard_ef9f4d7b1792c1769f896add5d50d1b56.png" loading="lazy" src="Developer%20Guide%20-%20Developer%20Network_files/clipboard_ef9f4d7b1792c1769f896add5d50d1b56.png"></p>
|
|
|
|
<p>Debugging will only run for a maximum of 1440 minutes per queue.
|
|
You can restart the timer at anytime by hitting "Start Debug Mode"
|
|
again.</p>
|
|
|
|
<div mt-section-origin="Products/ConnectWise_PSA/Developer_Guide/Troubleshooting" class="mt-section" id="section_1"><span id="Reading_Logs"></span><h3 id="Reading_Logs-1176">Reading Logs</h3>
|
|
|
|
<p><img class="internal" style="width: 1317px; height: 525px;" width="1317px" height="525px" alt="clipboard_ea2140f5216f5ed663aa1b17823aafb9a.png" loading="lazy" src="Developer%20Guide%20-%20Developer%20Network_files/clipboard_ea2140f5216f5ed663aa1b17823aafb9a.png"></p>
|
|
|
|
<table class="mt-responsive-table">
|
|
<tbody>
|
|
<tr>
|
|
<td class="mt-noheading mt-column-width-25">Search</td>
|
|
<td class="mt-noheading mt-column-width-75">The search option will refresh the visible logs</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="mt-noheading mt-column-width-25">Start Debug Mode</td>
|
|
<td class="mt-noheading mt-column-width-75">This will kick off the recording process for the specified amount of time</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="mt-noheading mt-column-width-25">Download Logs</td>
|
|
<td class="mt-noheading mt-column-width-75">This will
|
|
provide a shareable document that contacts all of the requests that were
|
|
recorded since the last time the debug mode was started</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="mt-noheading mt-column-width-25">API Key Description</td>
|
|
<td class="mt-noheading mt-column-width-75">This is the public key that is associated to the logged API Call</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="mt-noheading mt-column-width-25">Start Time</td>
|
|
<td class="mt-noheading mt-column-width-75">This is the start time for the request which when clicked, will show you the request body details</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="mt-noheading mt-column-width-25">Duration (ms)</td>
|
|
<td class="mt-noheading mt-column-width-75">This is how long the request took to be completed in milliseconds</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="mt-noheading mt-column-width-25">Response</td>
|
|
<td class="mt-noheading mt-column-width-75">This will show
|
|
the HTTP response code returned, please note that any error messages or
|
|
underlined responses can be clicked in order to see further details</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="mt-noheading mt-column-width-25">Method</td>
|
|
<td class="mt-noheading mt-column-width-75">This is the HTTP Verb being used in the request</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="mt-noheading mt-column-width-25">URL</td>
|
|
<td class="mt-noheading mt-column-width-75">This is the full
|
|
request endpoint URL that is being used and it can be used to see any
|
|
conditions or extra fields not found in the request body</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
|
|
</div><div mt-section-origin="Products/ConnectWise_PSA/Developer_Guide/Troubleshooting" class="mt-section" id="section_2"><span id="Telerik's_Fiddler"></span><h3 id="Telerik's_Fiddler-1176">Telerik's Fiddler</h3>
|
|
|
|
<p>The built in logging capabilities of Manage are limited in that if
|
|
you want your request to show up, it must of first of been processed by
|
|
the server. What this means, is that if your request is timed out,
|
|
malformed or one of many other ways in which the server rejects
|
|
your request, you will not be able to use the built in tools for
|
|
diagnostics. There are other tools out there, besides our own
|
|
built in tools, that will provide information about your requests.
|
|
We have found that although there are many similar programs, Fiddler
|
|
has provided the easiest user experience and it is extremely accurate.</p>
|
|
|
|
<table class="mt-responsive-table">
|
|
<tbody>
|
|
<tr>
|
|
<td class="mt-noheading mt-column-width-15">Utility</td>
|
|
<td class="mt-noheading mt-column-width-25">Description</td>
|
|
<td class="mt-noheading mt-column-width-30">Download</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="mt-noheading mt-column-width-15">Fiddler by Telerik</td>
|
|
<td class="mt-noheading mt-column-width-25">Free Web Debugging Proxy</td>
|
|
<td class="mt-noheading mt-column-width-30"><a title="https://www.telerik.com/fiddler" href="https://www.telerik.com/fiddler" target="_blank" rel="external noopener nofollow" class="link-https">https://www.telerik.com/fiddler</a></td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
|
|
<p>Fiddler must be run from the machine that is making the outbound
|
|
requests. It cannot be run locally if the API requests are not
|
|
leaving your local machine from your control. Once you have
|
|
installed fiddler and have opened it for the first time you will see a
|
|
window like the below screenshot.</p>
|
|
|
|
<p><img alt="fiddler1.png" class="internal" loading="lazy" src="Developer%20Guide%20-%20Developer%20Network_files/fiddler1.png"></p>
|
|
|
|
<p>Once you have managed to open Fiddler, there are a few settings that need to be changed in order for Fiddler to capture SSL.</p>
|
|
|
|
<p><img alt="fiddler2.png" class="internal" loading="lazy" src="Developer%20Guide%20-%20Developer%20Network_files/fiddler2.png"></p>
|
|
|
|
<p>After you have setup fiddler to be able to capture your requests, you
|
|
simply need to send your API calls from your REST Client. The
|
|
calls will begin to show up in the left side of the screen and when you
|
|
click on them, various options will appear that let you manipulate the
|
|
records. If you are using Postman to send your requests, you will
|
|
also need to open Postman and go into the Settings section and turn off
|
|
SSL Certificate Verification.</p>
|
|
|
|
<p><img alt="Image Capture - 0075.png" class="internal" loading="lazy" src="Developer%20Guide%20-%20Developer%20Network_files/Image%20Capture%20-%200075.png"></p>
|
|
|
|
<p>If you do not turn off certificate verification, Postman will return
|
|
an error saying it couldn't get a response. Once you have
|
|
successfully made your request or successfully had an error occur, the
|
|
fiddler screen will display a list of URLs. Any that are marked in
|
|
red will be errors that Fiddler bas detected.</p>
|
|
|
|
<p><img alt="Image Capture - 0076.png" class="internal" loading="lazy" src="Developer%20Guide%20-%20Developer%20Network_files/Image%20Capture%20-%200076.png"></p>
|
|
|
|
<p>If you click on the red entry you can drill into the details about the request and see more information on the error.</p>
|
|
|
|
<p><img alt="Image Capture - 0077.png" class="internal" loading="lazy" src="Developer%20Guide%20-%20Developer%20Network_files/Image%20Capture%20-%200077.png"></p>
|
|
|
|
<p>In this case we can see that the problem with the request is that
|
|
company identifier is already in use. We can now right click on
|
|
the red item and unlock it for editing. what this does is we can
|
|
actually change the request right from within Fiddler. Once we
|
|
have then corrected the request we can right click on it again and this
|
|
time we can use replay. Replay will let you re-issue the command
|
|
right from within Fiddler, without having to go back to your REST
|
|
Client.</p>
|
|
|
|
<p><img alt="Image Capture - 0078.png" class="internal" loading="lazy" src="Developer%20Guide%20-%20Developer%20Network_files/Image%20Capture%20-%200078.png"></p>
|
|
|
|
</div><div mt-section-origin="Products/ConnectWise_PSA/Developer_Guide/Troubleshooting" class="mt-section" id="section_3"><span id="Error_Handling"></span><h3 id="Error_Handling-1176">Error Handling</h3>
|
|
|
|
<p>When working with the API, it is important to understand best
|
|
practices for handling errors. In the case of ever error, it
|
|
should be properly logged so it can be referenced later on. Server
|
|
errors are generally considered to be temporary errors and requests
|
|
should be repeated. If the request continues to occur, it should
|
|
be submitted for review. When it comes to Client errors, the
|
|
request should be stopped immediately and whoever setup the integration,
|
|
should be given the error message in order to troubleshoot.</p>
|
|
|
|
<div mt-section-origin="Products/ConnectWise_PSA/Developer_Guide/Troubleshooting" class="mt-section" id="section_4"><span id="Retry_Policy"></span><h4 id="Retry_Policy-1176">Retry Policy</h4>
|
|
|
|
<p><b>Overview</b></p>
|
|
|
|
<p>An application that communicates with elements running in the cloud
|
|
has to be resilient against transient faults that commonly occur in
|
|
distributed environments. These faults include momentary loss of network
|
|
connectivity, temporary service unavailability, timeouts when services
|
|
are busy, and rate limiting imposed by service providers.</p>
|
|
|
|
<p>These faults are typically self-correcting, and if the action that
|
|
triggered a fault is repeated with an appropriate delay strategy, it's
|
|
likely to succeed. For example, a database service processing a large
|
|
number of concurrent requests might implement throttling that
|
|
temporarily rejects further requests until its workload eases. An
|
|
application encountering this throttling will fail to connect initially
|
|
but may succeed after a well-designed retry attempt.</p>
|
|
|
|
<p><b>Design Principles</b></p>
|
|
|
|
<p>In cloud environments, transient faults are expected, and
|
|
applications should be designed to handle them elegantly and
|
|
transparently to minimize impacts on business operations. A modern retry
|
|
policy should incorporate the following principles:</p>
|
|
|
|
<ol class="mt-indent-1" start="1">
|
|
<li><b>Distinguish between retryable and non-retryable failures</b></li>
|
|
<li><b>Implement intelligent delay strategies</b></li>
|
|
<li><b>Respect service-provided backoff instructions</b></li>
|
|
<li><b>Apply appropriate limits to prevent excessive retries</b></li>
|
|
<li><b>Consider the operation context when configuring retry behavior</b></li>
|
|
</ol>
|
|
|
|
<p><b>Failure Handling Strategies</b></p>
|
|
|
|
<p>When an application detects a failure in communicating with a remote
|
|
service, it should handle the failure using one of these strategies:</p>
|
|
|
|
<p><b>1. Cancel</b></p>
|
|
|
|
<p>If the fault indicates that the failure isn't transient or is
|
|
unlikely to be successful if repeated, the application should cancel the
|
|
operation and report an exception. Examples include:</p>
|
|
|
|
<ul class="mt-indent-1" data-lf-anchor-id="8bc42d6fcf39849a2149c94757230663:0">
|
|
<li>Authentication failures (HTTP 401)</li>
|
|
<li>Authorization failures (HTTP 403)</li>
|
|
<li>Resource not found errors (HTTP 404)</li>
|
|
<li>Bad request or validation failures (HTTP 400)</li>
|
|
<li>Any other client errors (4xx range) except those explicitly identified as retryable</li>
|
|
</ul>
|
|
|
|
<p><b>2. Retry Immediately</b></p>
|
|
|
|
<p>If the specific fault reported is unusual or rare, it might have been
|
|
caused by exceptional circumstances such as a network packet becoming
|
|
corrupted during transmission. In these cases, an immediate retry might
|
|
be appropriate as the same failure is unlikely to be repeated.</p>
|
|
|
|
<p><b>3. Retry with Exponential Backoff</b></p>
|
|
|
|
<p>For common connectivity issues or busy services, implement exponential backoff:</p>
|
|
|
|
<ul class="mt-indent-1" style="list-style-type:disc;">
|
|
<li>Start with a base delay (e.g., 100ms)</li>
|
|
<li>For each subsequent retry, multiply the previous delay by a constant factor (typically 2)</li>
|
|
<li>Apply a maximum delay cap to prevent extremely long waits</li>
|
|
<li>Add jitter (randomization) to the calculated delay to prevent retry storms</li>
|
|
</ul>
|
|
|
|
<p><b>4. Retry with Service-Guided Backoff</b></p>
|
|
|
|
<p>When services provide explicit guidance on retry timing:</p>
|
|
|
|
<ul class="mt-indent-1" style="list-style-type:disc;">
|
|
<li>For HTTP 429 (Too Many Requests) responses, parse and respect the Retry-After header</li>
|
|
<li>Retry-After specifies seconds, so wait that duration before retrying</li>
|
|
<li>Fall back to exponential backoff if the service doesn't provide retry guidance</li>
|
|
</ul>
|
|
|
|
<p><b>Implementation Pattern</b></p>
|
|
|
|
<pre>Initialize retry policy with:
|
|
- Maximum retry attempts
|
|
- Base delay duration
|
|
- Backoff multiplier
|
|
- Maximum delay cap
|
|
- Jitter factor
|
|
|
|
For each operation:
|
|
retries = 0
|
|
DO
|
|
Try to execute the operation
|
|
IF operation succeeds
|
|
Return success
|
|
ELSE IF operation fails with HTTP 429 AND Retry-After header exists
|
|
delay = Parse Retry-After header value
|
|
ELSE IF operation fails with retryable error
|
|
delay = baseDelay * (backoffMultiplier^retries) * (1 ± jitterFactor)
|
|
delay = min(delay, maxDelay)
|
|
ELSE
|
|
Return failure (non-retryable error)
|
|
END IF
|
|
|
|
IF retries >= maxRetries
|
|
Return failure (retry limit exceeded)
|
|
END IF
|
|
|
|
Wait for calculated delay
|
|
retries = retries + 1
|
|
WHILE retries < maxRetries
|
|
</pre>
|
|
|
|
<p><b>Configuring Retry Policies</b></p>
|
|
|
|
<p>The retry policy should be tuned to match the business requirements of the application and the nature of the operation:</p>
|
|
|
|
<p><b>For Interactive Applications</b></p>
|
|
|
|
<ul style="list-style-type:disc;">
|
|
<li>Use fewer retry attempts (2-3 typically)</li>
|
|
<li>Use shorter base delays (50-100ms)</li>
|
|
<li>Set lower maximum delay caps (2-5 seconds)</li>
|
|
<li>Provide user feedback during retries for longer operations</li>
|
|
<li>Consider showing appropriate messages to users when retries are exhausted</li>
|
|
</ul>
|
|
|
|
<p><b>For Background Operations</b></p>
|
|
|
|
<ul style="list-style-type:disc;">
|
|
<li>Use more retry attempts (5-10 or more depending on criticality)</li>
|
|
<li>Use longer base delays (200-500ms)</li>
|
|
<li>Allow higher maximum delay caps (30-60 seconds)</li>
|
|
<li>Implement dead-letter queues or failure logging for operations that exhaust retries</li>
|
|
<li>Consider partial success handling for batch operations</li>
|
|
</ul>
|
|
|
|
<p><b>For Critical Operations</b></p>
|
|
|
|
<ul style="list-style-type:disc;">
|
|
<li>Combine retry policies with circuit breakers to prevent cascading failures</li>
|
|
<li>Implement fallback mechanisms when retries are exhausted</li>
|
|
<li>Consider retry budgets to limit the overall retry rate across your system</li>
|
|
</ul>
|
|
|
|
<blockquote>
|
|
<p>It's important to log all connectivity failures that cause a retry so
|
|
that underlying problems with the application, services, or resources
|
|
can be identified.</p>
|
|
</blockquote>
|
|
|
|
</div><div mt-section-origin="Products/ConnectWise_PSA/Developer_Guide/Troubleshooting" class="mt-section" id="section_5"><span id="500_Server_Errors"></span><h4 id="500_Server_Errors-1176">500 Server Errors</h4>
|
|
|
|
<p>Numerous components on a network, such as DNS servers, switches, load
|
|
balancers, and others can generate errors anywhere in the life of a
|
|
given request. The usual technique for dealing with these error
|
|
responses in a networked environment is to implement retries in the
|
|
client application. This technique increases the reliability of the
|
|
application and reduces operational costs for the developer.</p>
|
|
|
|
</div><div mt-section-origin="Products/ConnectWise_PSA/Developer_Guide/Troubleshooting" class="mt-section" id="section_6"><span id="400_Client_Errors"></span><h4 id="400_Client_Errors-1176">400 Client Errors</h4>
|
|
|
|
<p>A 400 error means that the request isn't valid. In the case of a
|
|
400 error you should stop the requests and analyze the results in order
|
|
to resolve the issue. Do not attempt to retry the request.</p>
|
|
</div></div></div>
|
|
</div>
|
|
|
|
</div><div mt-section-origin="Products/ConnectWise_PSA/Developer_Guide" class="mt-section" id="section_13"><span id="REST_SDK_Downloads"></span><h2 class="editable">REST SDK Downloads</h2>
|
|
|
|
<p>For more information please visit our <a title="SDK" href="#s686" rel="internal">SDK Section</a>.</p>
|
|
|
|
<div class="mt-contentreuse-widget" data-page="Manage/SDK" data-section="REST SDK" data-show="">
|
|
<div headingoffset="0" class="mt-include" id="s686"></div>
|
|
</div>
|
|
|
|
</div><div mt-section-origin="Products/ConnectWise_PSA/Developer_Guide" class="mt-section" id="section_14"><span id="Document_API"></span><h2 class="editable">Document API</h2>
|
|
|
|
<p>When working with the Document API, please use the uploaded sample provided with the following endpoint to proceed with testing.</p>
|
|
|
|
<p>GET <a title="https://ConnectWiseSite/v4_6_release/apis/3.0/system/documents/uploadsample" href="https://connectwisesite/v4_6_release/apis/3.0/system/documents/uploadsample" target="_blank" rel="external noopener nofollow" class="link-https">https://ConnectWiseSite/v4_6_release...s/uploadsample</a></p>
|
|
|
|
<p>The response is an HTML template that shows each of the settings that
|
|
can be selected. This form should help to design your own code
|
|
and mimic functionality.</p>
|
|
|
|
<p> <img class="internal" style="width: 415px; height: 325px;" width="415px" height="325px" alt="clipboard_e1d56cd4386ffef346995a6f8258a8ced" loading="lazy" src="Developer%20Guide%20-%20Developer%20Network_files/clipboard_e1d56cd4386ffef346995a6f8258a8ced.png"></p>
|
|
|
|
<div class="mt-contentreuse-widget" data-page="ConnectWise/Company_Info_(Cloud_Requests)" data-section="" data-show="">
|
|
<div class="mt-include" id="s959"><p>When making calls to the
|
|
ConnectWise PSA API, we have a URL that will give you the exact
|
|
codebase to target in place of v4_6_release. This is useful to see
|
|
if someone is on a cloud environment programmatically.
|
|
Additionally, the request can be routed directly to the correct
|
|
PSA version for the partner without it going through another
|
|
source.</p>
|
|
|
|
<div mt-section-origin="Best_Practices/PSA_Cloud_URL_Formatting" class="mt-section" id="section_1"><span id="Calling_Company_Info"></span><h2 id="Calling_Company_Info-959">Calling Company Info</h2>
|
|
|
|
<pre>"https://" + ConnectWiseSite + "/login/companyinfo/" + LoginCompanyId
|
|
https://na.myconnectwise.net/login/companyinfo/connectwise
|
|
</pre>
|
|
|
|
<div mt-section-origin="Best_Practices/PSA_Cloud_URL_Formatting" class="mt-section" id="section_2"><span id="Response"></span><h4 id="Response-959">Response</h4>
|
|
|
|
<pre>{
|
|
"CompanyName":"ConnectWise",
|
|
"Codebase":"v2017_3/",
|
|
"VersionCode":"v2017.3",
|
|
"VersionNumber":"v4.6.38842",
|
|
"CompanyID":"CW",
|
|
"IsCloud":"True" *<span class="mt-color-0000cd">Added in 2016.5</span>
|
|
}
|
|
</pre>
|
|
|
|
</div></div><div mt-section-origin="Best_Practices/PSA_Cloud_URL_Formatting" class="mt-section" id="section_3"><span id="API_Request_URL_Format"></span><h2 id="API_Request_URL_Format-959">API Request URL Format</h2>
|
|
|
|
<pre>"https://" + ConnectWiseSite + "/" + codebase + "apis/3.0/company/companies"
|
|
https://api-my.myconnectwise.net/v2017_3/apis/3.0/company/companies
|
|
</pre>
|
|
|
|
</div><div mt-section-origin="Best_Practices/PSA_Cloud_URL_Formatting" class="mt-section" id="section_4"><span id="Cloud_vs_Premise"></span><h2 id="Cloud_vs_Premise-959">Cloud vs Premise</h2>
|
|
|
|
<p>A cloud environment will return a codebase with the
|
|
PSA version. On-Premise does not use URL redirection and will
|
|
return v4_6_release/. If your returned codebase contains anything
|
|
other than v4_6_release/, you will need to ensure your request is
|
|
prefixed by API-</p>
|
|
|
|
</div><div mt-section-origin="Best_Practices/PSA_Cloud_URL_Formatting" class="mt-section" id="section_5"><span id="Cloud_URLs"></span><h2 id="Cloud_URLs-959">Cloud URLs</h2>
|
|
|
|
<p>These are the most commonly used URLs for the cloud.</p>
|
|
|
|
<pre>https://na.myconnectwise.net
|
|
https://eu.myconnectwise.net
|
|
https://au.myconnectwise.net
|
|
https://aus.myconnectwise.net
|
|
https://za.myconnectwise.net
|
|
https://staging.connectwisedev.com</pre>
|
|
</div></div>
|
|
</div>
|
|
|
|
<div id="mt-guide-tabs" class="noindex" data-ga-action="Guide tabs"></div><script type="application/json" id="mt-guide-tabs-json">/*<![CDATA[*/null/*]]>*/</script><script type="application/json" id="mt-localizations-guide-tabs">/*<![CDATA[*/{"MindTouch.IDF3.label.guide.tabscrollleft":"Scroll tabs left","MindTouch.IDF3.label.guide.tabscrollright":"Scroll tabs right"}/*]]>*/</script><script type="application/json" id="mt-localizations-guide-tabs-settings">/*<![CDATA[*/{"MindTouch.IDF3.label.guide.settings.classifications":"Classification settings","MindTouch.IDF3.label.guide.settings.learningpath":"Path settings","MindTouch.IDF3.label.overview.max.count":"{0} characters remaining.","MindTouch.IDF3.label.overview.max.count.over":"Warning. {0} characters will be truncated.","MindTouch.LearningPath.dialog.remove.cancel":"Cancel","MindTouch.LearningPath.dialog.remove.confirm":"OK","MindTouch.LearningPath.dialog.remove.header":"Remove path","MindTouch.LearningPath.dialog.remove.message":"You are about to remove this path from this guide."}/*]]>*/</script>
|
|
</div>
|
|
|
|
<footer class="mt-content-footer"></footer>
|
|
</section>
|
|
|
|
|
|
<footer class="elm-content-footer">
|
|
<ol class="elm-meta-data elm-meta-article-navigation">
|
|
<li class="elm-back-to-top"><a class="mt-icon-back-to-top" href="#title" id="mt-back-to-top" title="Jump back to top of this article">Back to top</a></li>
|
|
<li class="elm-article-pagination"><ul class="mt-article-pagination" data-ga-action="Article pagination bottom">
|
|
<li class="mt-pagination-previous">
|
|
|
|
<a class="mt-icon-previous-article" data-ga-label="Previous page" href="https://developer.connectwise.com/Products/ConnectWise_PSA/REST/CompanyTest" title="CompanyTest"><span>CompanyTest</span></a>
|
|
</li>
|
|
<li class="mt-pagination-next">
|
|
<a class="mt-icon-next-article" data-ga-label="Next page" href="https://developer.connectwise.com/Products/ConnectWise_PSA/Developer_Guide/Authentication" title="Authentication"><span>Authentication</span></a>
|
|
</li>
|
|
</ul>
|
|
</li>
|
|
</ol>
|
|
<div class="elm-article-feedback"><div class="mt-feedback-rating-container" data-ga-action="Page rating" data-page-revision="176" data-use-local-storage="false"><ul class="mt-feedback-rating-controls"><li class="mt-feedback-rating-message mt-feedback-rating-item">Was this article helpful?</li><li class="mt-rating-yes mt-feedback-rating-item"><button class="mt-rating-button-yes mt-feedback-rating-button ui-button-icon mt-icon-rating-yes" data-ga-label="Rate">Yes</button></li><li class="mt-rating-no mt-feedback-rating-item"><button class="mt-rating-button-no mt-feedback-rating-button ui-button-icon mt-icon-rating-no" data-ga-label="Rate">No</button></li><li class="mt-leave-feedback mt-feedback-rating-item"><button class="mt-feedback-button mt-feedback-rating-button ui-button-icon mt-icon-leave-feedback" data-ga-label="Feedback toggle">Leave feedback</button></li><li class="mt-last-rating-date mt-feedback-rating-item"></li></ul><div id="mt-feedback-flash-message"></div><div class="mt-feedback-form" data-path="Products/ConnectWise_PSA/Developer_Guide" data-user-email="user@example.invalid" data-page-title="Developer Guide" data-site-url="https://developer.connectwise.com/"><fieldset class="ui-dform-fieldset"><legend class="ui-dform-legend">Leave feedback</legend><div class="mt-field"><label class="mt-feedback-improve-label ui-dform-label" for="textarea-feedback">How can we improve this article?</label><textarea autocomplete="off" class="mt-feedback-improve-description ui-dform-textarea" id="textarea-feedback" spellcheck="false"></textarea></div><div class="mt-field"><input class="mt-feedback-consent-checkbox ui-dform-checkbox" data-ga-label="Feedback consent" id="mt-feedback-consent" type="checkbox"><label class="mt-feedback-consent-label mt-label-checkbox" data-ga-label="Feedback consent" for="mt-feedback-consent">Yes, you may contact me about this feedback.</label></div><div class="mt-field mt-submit"><button class="mt-feedback-submit mt-disabled ui-button ui-button-primary" data-ga-label="Submit feedback" id="deki-feedback-send">Submit feedback</button></div></fieldset></div></div><script type="application/json" id="mt-localizations-feedback-rating">/*<![CDATA[*/{"Page.FeedbackRating.label.last-rated":"-- You last rated this article on {0}","Page.FeedbackRating.message.contact.no":"No","Page.FeedbackRating.message.contact.yes":"Yes","Page.FeedbackRating.message.submit.error":"An error occurred while attempting to send your feedback. Please try again at a later time.","Page.FeedbackRating.message.submit.success":"Your feedback has been successfully submitted. You can submit more feedback at any time."}/*]]>*/</script></div>
|
|
<div class="elm-related-articles-container"><h2 class="mt-related-articles-header">Recommended articles</h2>
|
|
<ol class="mt-related-listings-container" data-ga-action="related">
|
|
<li class="mt-related-listing mt-related-listing-detailed"><a class="mt-related-listing-link" href="https://developer.connectwise.com/Products/ConnectWise_PSA/REST" title="REST" data-ga-label="related-link-detailed-1"><span class="mt-related-listing-link-icon mt-icon-article-topic-guide"></span><span class="mt-related-listing-link-text">REST</span></a><span class="mt-related-listing-link-overview">This
|
|
page will serve as the documentation hub for all Manage REST
|
|
docs. If you are having issues please report them to
|
|
Platform@ConnectWise.com and u...</span></li><li class="mt-related-listing mt-related-listing-detailed"><a class="mt-related-listing-link" href="https://developer.connectwise.com/Best_Practices/HTTP_Verbs_and_Error_Codes" title="HTTP Verbs and Error Codes" data-ga-label="related-link-detailed-2"><span class="mt-related-listing-link-icon mt-icon-article-topic-guide"></span><span class="mt-related-listing-link-text">HTTP Verbs and Error Codes</span></a></li><li class="mt-related-listing mt-related-listing-detailed"><a class="mt-related-listing-link" href="https://developer.connectwise.com/Products/ConnectWise_PSA/Developer_Guide/Batch_Requests" title="Batch Requests" data-ga-label="related-link-detailed-3"><span class="mt-related-listing-link-icon mt-icon-article-topic-category"></span><span class="mt-related-listing-link-text">Batch Requests</span></a></li><li class="mt-related-listing mt-related-listing-detailed"><a class="mt-related-listing-link" href="https://developer.connectwise.com/Products/ConnectWise_PSA/Developer_Guide/Troubleshooting" title="Troubleshooting" data-ga-label="related-link-detailed-4"><span class="mt-related-listing-link-icon mt-icon-article-topic-category"></span><span class="mt-related-listing-link-text">Troubleshooting</span></a></li><li class="mt-related-listing mt-related-listing-detailed"><a class="mt-related-listing-link" href="https://developer.connectwise.com/Products/ConnectWise_PSA/Developer_Guide/Markdown" title="Markdown" data-ga-label="related-link-detailed-5"><span class="mt-related-listing-link-icon mt-icon-article-topic-guide"></span><span class="mt-related-listing-link-text">Markdown</span></a></li></ol>
|
|
<script type="application/json" nonce="" id="mt-localizations-related-pages">
|
|
{"Skin.Columbia.label.no-recommended-articles":"There are no recommended articles."}</script></div>
|
|
<ol class="elm-meta-data elm-meta-bottom">
|
|
<li class="elm-classifications"> <dl class="mt-classification mt-classification-article-guide" data-ga-action="Tag navigation">
|
|
<dt class="mt-classification-label">Article type</dt>
|
|
<dd class="mt-classification-value"><a href="https://developer.connectwise.com/Special:Search?tags=article%3Atopic-guide" data-ga-label="Classification">Guide</a></dd>
|
|
</dl>
|
|
</li>
|
|
<li class="elm-tags"><dl class="mt-tags">
|
|
<dt class="mt-tag-label">Tags</dt>
|
|
<dd class="mt-tag-value">
|
|
<ol class="mt-tags-list" data-ga-action="Tag navigation">
|
|
<li class="mt-tag-link mt-tag-callbacks" rel="nofollow"><a href="https://developer.connectwise.com/Special:Search?tags=Callbacks" data-ga-label="Free tag"> Callbacks</a></li>
|
|
<li class="mt-tag-link mt-tag-codebase" rel="nofollow"><a href="https://developer.connectwise.com/Special:Search?tags=Codebase" data-ga-label="Free tag"> Codebase</a></li>
|
|
<li class="mt-tag-link mt-tag-conditions" rel="nofollow"><a href="https://developer.connectwise.com/Special:Search?tags=Conditions" data-ga-label="Free tag"> Conditions</a></li>
|
|
<li class="mt-tag-link mt-tag-custom-fields" rel="nofollow"><a href="https://developer.connectwise.com/Special:Search?tags=Custom+fields" data-ga-label="Free tag"> Custom fields</a></li>
|
|
<li class="mt-tag-link mt-tag-endpoints" rel="nofollow"><a href="https://developer.connectwise.com/Special:Search?tags=Endpoints" data-ga-label="Free tag"> Endpoints</a></li>
|
|
<li class="mt-tag-link mt-tag-formatting" rel="nofollow"><a href="https://developer.connectwise.com/Special:Search?tags=Formatting" data-ga-label="Free tag"> Formatting</a></li>
|
|
<li class="mt-tag-link mt-tag-get" rel="nofollow"><a href="https://developer.connectwise.com/Special:Search?tags=GET" data-ga-label="Free tag"> GET</a></li>
|
|
<li class="mt-tag-link mt-tag-headers" rel="nofollow"><a href="https://developer.connectwise.com/Special:Search?tags=Headers" data-ga-label="Free tag"> Headers</a></li>
|
|
<li class="mt-tag-link mt-tag-http-methods" rel="nofollow"><a href="https://developer.connectwise.com/Special:Search?tags=HTTP+Methods" data-ga-label="Free tag"> HTTP Methods</a></li>
|
|
<li class="mt-tag-link mt-tag-patch" rel="nofollow"><a href="https://developer.connectwise.com/Special:Search?tags=PATCH" data-ga-label="Free tag"> PATCH</a></li>
|
|
<li class="mt-tag-link mt-tag-post" rel="nofollow"><a href="https://developer.connectwise.com/Special:Search?tags=POST" data-ga-label="Free tag"> POST</a></li>
|
|
<li class="mt-tag-link mt-tag-rate-limiting" rel="nofollow"><a href="https://developer.connectwise.com/Special:Search?tags=Rate+Limiting" data-ga-label="Free tag"> Rate Limiting</a></li>
|
|
<li class="mt-tag-link mt-tag-rest" rel="nofollow"><a href="https://developer.connectwise.com/Special:Search?tags=rest" data-ga-label="Free tag"> rest</a></li>
|
|
<li class="mt-tag-link mt-tag-urls" rel="nofollow"><a href="https://developer.connectwise.com/Special:Search?tags=URLs" data-ga-label="Free tag"> URLs</a></li>
|
|
<li class="mt-tag-link mt-tag-versioning" rel="nofollow"><a href="https://developer.connectwise.com/Special:Search?tags=Versioning" data-ga-label="Free tag"> Versioning</a></li>
|
|
</ol>
|
|
</dd>
|
|
</dl></li>
|
|
</ol>
|
|
</footer>
|
|
|
|
</article>
|
|
<footer class="elm-footer">
|
|
<nav class="elm-footer-siteinfo-nav elm-nav">
|
|
<div class="elm-nav-container">
|
|
<ol>
|
|
<li class="elm-footer-copyright">© Copyright 2026 Developer Network</li>
|
|
<li class="elm-footer-powered-by"><a href="https://mindtouch.com/demo" class="mt-poweredby product " title="MindTouch" target="_blank">
|
|
Powered by NiCE Knowledge Management
|
|
<span class="mt-registered">®</span>
|
|
</a></li>
|
|
</ol>
|
|
</div>
|
|
</nav>
|
|
<div class="elm-footer-custom"><script>/*<![CDATA[*/ $('#spanYear').html(new Date().getFullYear());/*]]>*/</script>
|
|
|
|
|
|
<div class="cw-footer"><div class="footer-wrapper"><ul class="show-loggedin"><li><a href="https://developer.connectwise.com/" rel="internal">Home</a></li><li><a href="https://developer.connectwise.com/Products/ConnectWise_PSA" rel="internal">ConnectWise PSA</a></li><li><a href="https://developer.connectwise.com/Products/ConnectWise_Automate" rel="internal">ConnectWise Automate</a></li><li><a href="https://docs.connectwise.com/ConnectWise_Control_Documentation/Developers/Integration_guide" target="_blank" rel="external noopener nofollow" class="link-https">ConnectWise ScreenConnect</a></li><li><a href="https://developer.connectwise.com/Products/ConnectWise_CPQ" rel="internal">ConnectWise CPQ</a></li><li><a href="https://virtualcommunity.connectwise.com/community-home?CommunityKey=b91ec22c-a6ca-4ae3-bedb-018a5199538b" target="_blank" rel="external noopener nofollow" class="link-https">Developer Community</a></li><li><a href="https://developer.connectwise.com/faq" rel="internal">FAQ</a></li><li><a href="https://developer.connectwise.com/ClientID" rel="internal">Client ID</a></li></ul><p>© 2024 ConnectWise. All Rights Reserved.</p><div class="social-links"><ul><li class="facebook"><a href="https://www.facebook.com/ConnectWise?ref=ts" target="_blank" rel="external noopener nofollow" class="link-https"><i class="fa fa-facebook-square"></i></a></li><li class="linkedin"><a href="https://www.linkedin.com/company/connectwise" target="_blank" rel="external noopener nofollow" class="link-https"><i class="fa fa-linkedin-square"></i></a></li><li class="twitter"><a href="https://twitter.com/connectwise" target="_blank" rel="external noopener nofollow" class="link-https"><i class="fa fa-twitter-square"></i></a></li><li class="youtube"><a href="https://www.youtube.com/user/connectwise#grid/uploads" target="_blank" rel="external noopener nofollow" class="link-https"><i class="fa fa-youtube-square"></i></a></li></ul></div></div></div>
|
|
|
|
<div class="style-wrap">
|
|
<script type="text/javascript" src="Developer%20Guide%20-%20Developer%20Network_files/devnetcookie.js"></script>
|
|
</div>
|
|
</div>
|
|
</footer>
|
|
</main>
|
|
<div id="mt-modal-container"></div>
|
|
|
|
|
|
<script type="text/javascript" async="async" nonce="" src="Developer%20Guide%20-%20Developer%20Network_files/f1.js"></script>
|
|
|
|
<script type="text/javascript" data-mindtouch-module="true" src="Developer%20Guide%20-%20Developer%20Network_files/ui.guideTabsDisplay.js"></script><script type="text/javascript" data-mindtouch-module="true" nonce="" src="Developer%20Guide%20-%20Developer%20Network_files/serviceworker-unregister.js"></script><script type="text/javascript" data-mindtouch-module="true" nonce="" src="Developer%20Guide%20-%20Developer%20Network_files/pageLoaded.js"></script>
|
|
|
|
|
|
|
|
|
|
|
|
<script type="text/javascript" data-mindtouch-module="true" src="Developer%20Guide%20-%20Developer%20Network_files/f1.widget.js"></script><div id="hudu-eh-root"></div><div id="hudu-ch-root"></div><div id="hudu-pc-root"></div></body></html> |