1.  Last updated
    
    Mar 31, 2023
    
2.  [Save as PDF](https://developer.connectwise.com/@api/deki/pages/1291/pdf/PSA%2bAPI%2bRequests.pdf "Export page as a PDF")

## HTTP Methods

-   POST
    -   Create an entity or any non-CRUD action
-   GET
    -   Return entity or list of entities
-   PUT
    -   Replace all fields on an entity with supplied fields
-   PATCH
    -   Update specific fields on an entity
-   DELETE
    -   Remove entity

## HTTP Response Statuses

-   201 Created
    -   The response will be the record that was created as well as the path to it.
-   204 NoContent
    -   Will be returned by successful delete requests
-   400 Bad Request
    -   The request could not be understood by the server due to malformed syntax. The client SHOULD NOT repeat the request without modifications
-   401 Unauthorized
    -   The supplied authentication is incorrect
-   403 Forbidden
    -   Improper security role settings for the supplied authentication
-   404 Not Found
    -   Resource URL not found, this could mean the record was deleted or moved
-   405 Method Not Allowed
    -   This will occur if you try to use an HTTP method that is not supported by the URL specified
-   409 Conflict
    -   Record possibly in use or another conflict with the record
-   415 Unsupported Media Type
    -   This can occur when using the documents API if you are sending the file as a JSON object
-   429 Too Many Requests
    -   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) 
-   500 Server Error
    -   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
    -   These errors should follow the retry logic we recommend and if it appears to be an undefined error, should be reported

> 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/. 

## Formatting Each Method

### Get

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.

```
https://api-na.myconnectwise.net/v4_6_release/apis/3.0/service/tickets/5000
```

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.

```
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
```

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.

#### URL Max Length

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.  **With that in mind, the safe max length of a URL would be around 1745 characters.**  

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.

#### Query String Parameters

|**Parameter**|**Description**|**Example**|
|---|---|---|
|[conditions](https://developer.connectwise.com/Best_Practices/PSA_API_Requests?mt-learningpath=manage#Conditions "Manage API Requests")|Search results based on the fields returned in a GET|board/name="Integration"
summary="xyz"
board/id in (3, 2, 4)
lastUpdated > \[2016-08-20T18:04:26Z\]
Only fields returned in a GET request can be used|\=, !=, <, <=, >, >=, contains, like, in, not|
|childConditions|Allows searching arrays on endpoints that list childConditions under parameters|/company/contacts?childconditions=communicationItems/value like "[john@Outlook.com](mailto:%john@Outlook.com% "mailto:%john@Outlook.com%")" AND communicationItems/communicationType="Email"|\=, !=, <, <=, >, >=, contains, like, not|
|[customFieldConditions](https://developer.connectwise.com/Products/ConnectWise_PSA/Developer_Guide#Custom_Fields "Developer Guide")|Allows searching custom fields when customFieldConditions is listed in the parameters|/company/contacts?customFieldConditions=caption="TomNumber" AND value !=null|\=, !=, <, <=, >, >=, contains, like, not|
|orderBy|Choose which field to sort the results by|contact/name asc|asc or desc|
|[fields](https://developer.connectwise.com/Products/ConnectWise_PSA/Developer_Guide#Partial_Responses "Developer Guide")|Limits which information is returned in the response|company/companies?fields=id,name,status/id|Not available on the reporting endpoints|
|[columns](https://developer.connectwise.com/Products/ConnectWise_PSA/Developer_Guide#Partial_Responses "Developer Guide")|Limits which information is returned in the response|system/reports/service?columns=id,summary,name|Only used for the Reporting Endpoints|
|[page](https://developer.connectwise.com/Products/ConnectWise_PSA/Developer_Guide#Pagination "Developer Guide")|Used in pagination to cycle through results|
|[pageSize](https://developer.connectwise.com/Products/ConnectWise_PSA/Developer_Guide#Pagination "Developer Guide")|Number of results returned per page (Defaults to 25)|Max Size = 1,000\*|
|\*Max page size was increased to 1,000 in 2016.2.|

#### Conditions

|Strings|Must be surrounded by quotes|Summary = "This is my string" (Accepts \*'s for Wild Cards)|
|---|---|---|
|Integers|No formatting required|Board/Id = 123|
|Boolean|No formatting is required but must be True or False|ClosedFlag = True|
|Datetimes|Must be surrounded by square brackets|LastUpdated = \[2016-08-20T18:04:26Z\]|
|Operators|<, <=, =, !=, >, >=, contains, like, in, not|Summary Not Contains "Low Priority"|
|Logic Operators|Supported operators include:
-   AND
-   OR|board/name="integration" and summary="xyz"
board/name="integration" or board/name="professional services"|
|Reference\*|Must have a / followed by the field under the reference you would like to use|manufacturer/name|

#### Using the /Search endpoints

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.

```
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'"
}
```

> Successful get requests will return a 200 status response and a content body of the record(s).

### Patch

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.

```
https://api-na.myconnectwise.net/v4_6_release/apis/3.0/service/tickets/5000
```

```
[
  {
    "op": "string",
    "path": "string",
    "value": "string"
  }
]
```

|op|The update operation used in the request|add|
|---|---|---|
|path|Pathway for the updated field (Case Sensitive)|summary
company|
|value|The new value if doing a replace
Refer to [escaping characters](https://developer.connectwise.com/Products/ConnectWise_PSA/Developer_Guide#Escaping_Characters "Developer Guide")
When working with custom fields, you must pass the entire array of custom fields.|String: "Here is my Summary"
Object: { "identifier": "connectwise" }|

|`01`|`[`|
|---|---|

|`02`|`{`|
|---|---|

|`03`|`"op"``:` `"replace"``,`|
|---|---|

|`04`|`"path"``:` `"summary"``,`|
|---|---|

|`05`|`"value"``:` `"New Summary"`|
|---|---|

|`06`|`},`|
|---|---|

|`07`|`{`|
|---|---|

|`08`|`"op"``:` `"replace"``,`|
|---|---|

|`09`|`"path"``:` `"company"``,`|
|---|---|

|`10`|`"value"``: {`|
|---|---|

|`11`|`"identifier"``:` `"New Company"`|
|---|---|

|`12`|`}`|
|---|---|

|`13`|`},`|
|---|---|

|`14`|`{`|
|---|---|

|`15`|`"op"``:` `"replace"``,`|
|---|---|

|`16`|`"path"``:` `"customFields"``,`|
|---|---|

|`17`|`"value"``: [`|
|---|---|

|`18`|`{`|
|---|---|

|`19`|`"id"``: 5,`|
|---|---|

|`20`|`"caption"``:` `"CloudPlus"``,`|
|---|---|

|`21`|`"type"``:` `"Checkbox"``,`|
|---|---|

|`22`|`"entryMethod"``:` `"EntryField"``,`|
|---|---|

|`23`|`"numberOfDecimals"``: 0,`|
|---|---|

|`24`|`"value"``:` `false`|
|---|---|

|`25`|`},`|
|---|---|

|`26`|`{`|
|---|---|

|`27`|`"id"``: 28,`|
|---|---|

|`28`|`"caption"``:` `"test"``,`|
|---|---|

|`29`|`"type"``:` `"Text"``,`|
|---|---|

|`30`|`"entryMethod"``:` `"List"``,`|
|---|---|

|`31`|`"numberOfDecimals"``: 0,`|
|---|---|

|`32`|`"value"``:` `"test"`|
|---|---|

|`33`|`}`|
|---|---|

|`34`|`]`|
|---|---|

|`35`|`}`|
|---|---|

|`36`|`]`|
|---|---|

> 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.
> 
> Successful patch requests will return a 200 status response for success

### Delete

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.

```
https://api-na.myconnectwise.net/v4_6_release/apis/3.0/service/tickets/5000
```

> Successful delete requests will return a 204 status response for No Content.  204 is a success response.

### Post

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.

### Put

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.

### Escaping Characters

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:

|Character|Escaped|Displayed in the UI|
|---|---|---|
|Double Quotes|\\"|"|
|Backslash|\\\\|\\|
|Tab|\\t|Tabbed space equal to four spaces|
|Backspace (Not Supported)|\\b|An invisible character that doesn't take up any space|
|Carriage Return (Not Supported)|\\r|Single space which is returned as a space in the API instead of an escaped character|
|Newline (Not Supported)|\\n|Single space which is returned as a space in the API instead of an escaped character|
|Form Feed (Not Supported)|\\f|An invisible character that doesn't take up any space|
|**Applies to JSON Bodies Only:** 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.|

 URL Encoding is required when using conditions and other URL parameters that have symbols that would denote new query parameters or strings.

|Character|Formatting|
|---|---|
|&|%26|
|"|%22|
|'|%27|
|\*|%2A|
|%|%25|
|+|%2B|
|\[string\]|\[\[\]string\]|
|**This applies to URL Parameters Only**|

### Partial Responses

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.

|Fields|company/companies?fields=company/id,company/name,phoneNumber|
|---|---|
|Columns (Reporting API only)|system/reports/service?columns=id,summary,company/name|

### Custom Fields

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.

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.

> Refer to the [GET](https://developer.connectwise.com/Products/ConnectWise_PSA/Developer_Guide#Get "Developer Guide") section on how to search custom fields.  Searching custom fields uses customFieldConditions instead of conditions.

In order to access the custom fields via the thick client, navigate to System > Setup Tables > Custom fields,

#### Field Options and Parameters

![Custom Fields.png](https://developer.connectwise.com/@api/deki/files/379/Custom_Fields.png?revision=1&size=bestfit&width=844&height=269)

|**Field**|**Description**|
|---|---|
|Field Caption|Enter a custom field caption for this required field; you are limited to 12 characters.|
|Help Text|The text entered in this field will be displayed when you hover over the help button next to the custom field on the screen.  
**Note:** This has a limit of 1000 characters, however only 512 characters will display on the opportunity screen.|
|Field Type|Select one of the following options:
-   **Button** This field allows you to add a hyperlink in the **Button URL** field.  There is a character limit of 1000.
-   **Checkbox** This field is used for simple "Yes/No" or "On/Off" answers.  This will display as a checkbox. 
-   **Date** This field displays a standard date picker field.
-   **Hyperlink** This field displays a text entry field to enter a URL and will be accompanied by a button to visit the hyperlink.
-   **Number** 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.  
-   **Percent** 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.
-   **Text** This field displays alpha-numeric values. There is a character limit of 100.
-   **Text** **Area** This field displays alpha-numeric values. There is a character limit of 1000. The **List** and **Dropdown** method of entry is unavailable for this option.
    
    **Note:** If you change a **Date** field to a **Text** or **Text Area** field, the date entered will save as plain text.
    
    If you change a **Text** or **Text Area** field to a **Date** 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.|
|Number of Decimals|This required field is only available for the Number and Percent Field Type.  You can add up to 5 decimal places.|
|Method of Entry|Select one of the following options:
-   **Entry Field** This field is available for all field types.
-   **List (Drop-down)** 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. 
-   **Option (Radio)** 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.|
|Sequence #|Enter a sequence number.  This value must be between 1 and 50.|
|Required Field?|Select this checkbox if you would like to make this a required custom field.  This will display as a blue asterisk.|
|Display on Screen?|Select this checkbox if you would like this to display on the Opportunities screen.  This is selected by default.|
|Read Only?|This field is used for the API.  The **Required Field** checkbox cannot be marked for this field.|
|Include on List View?|Select this checkbox if you would like to include this custom field in the My Opportunities list view screen.
**Note:** 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.|
|Button URL|Enter the URL if you are using the Field Type Button. The field only appends URLs, no other form of entry will generate content.|
|Select the Locations that will use this Custom Field|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.|
|Select the Departments that will use this Custom Field|This is not a required field. Opportunities that have the specified department(s) will display this custom field.|