README
Autotask REST API NodeJS Connector
This connector simplifies interaction with the Autotask PSA REST API for developers using NodeJS.
Please insure you are using a LTS version of NodeJS, or at least a version that supports ES6 promises.
Connecting to Autotask
const {AutotaskRestApi} = require('@apigrate/autotask-rest');
const autotask = new AutotaskRestApi(
process.env.AUTOTASK_USER, // make sure it's an API User
process.env.AUTOTASK_SECRET,
process.env.AUTOTASK_INTEGRATION_CODE
);
The .api() method returns a convenience object that has all available entities as well as API methods you can use on each entity. This provides a simple and readable syntax for interacting with the API.
The Autotask REST API has endpoints ("zones") distributed around the world. The connector automatically determines the correct endpoint when you invoke the
.api()method, remembering the zone url for subsequent API calls.
let api = await autotask.api();
let company = await api.Companies.get(0);//Get the root company
Methods Available on Each Entity
The following sections list the methods on each available entity on the connector.
Not all methods may be applicable for an entity. For example, most entities do not support delete; therefore, expect an error if you attempt to use a method in an inappropriate context.
count
Counts entities. Use Autotask query filter syntax to provide criteria for the count.
// Count companies with a CompanyName beginning with "B"
result = await api.Companies.count({
filter:[
{
"op": "beginsWith",
"field": "CompanyName",
"value": "B"
}
]
});
// result = {queryCount: 7}
// Count all the contacts in Autotask
result = await api.Contacts.count({
filter:[
{
"op": "gte",
"field": "Id",
"value": 0
}
]
});
// result = {queryCount: 1209}
related Autotask documentation
get
Get a single entity by id.
let product = await api.Products.get(232486923);
// product = { item: { id: 232486923, ...product object properties... } }
Note, filter expressions using the
getmethod are not supported. Use thequerymethod instead.
related Autotask documentation
Special case: To retrieve attachment base64-encoded data, you must use an attachment-specific parent-child GET request. For: 'ConfigurationItemAttachments', 'ConfigurationItemNoteAttachments', 'OpportunityAttachments', 'TaskAttachments', 'TaskNoteAttachments', 'TicketAttachments', 'TicketNoteAttachments', 'TimeEntryAttachments', you must use the following
getsyntax:
Get a entity attachment data by id
// TicketID 129873
// AttachmentID 232486923
let ticketAttachment = await api.TicketAttachments.get(129873, 232486923);
// ticketAttachment = { items: { id: 232486923, ..., data: "iVBORw0KGgoAAAANSUhEUgAAAV8AAAC (...the rest of the base64 ecoded data)..." } }
query
Query for entities matching a filter expression.
//Find a company by name
let result = await api.Companies.query({
filter:[
{
"op": "eq",
"field": "CompanyName",
"value": "Sirius Cybernetics Corporation "
}
]
});
Query results take the following form (example shows the Company returned from the above query)
{
"items": [
{
"id": 29683616,
"additionalAddressInformation": "",
"address1": null,
"address2": null,
"alternatePhone1": "",
...
"surveyCompanyRating": null,
"taxID": "",
"taxRegionID": null,
"territoryID": null,
"webAddress": null,
"userDefinedFields": []
}
],
"pageDetails": {
"count": 1,
"requestCount": 500,
"prevPageUrl": null,
"nextPageUrl": null
}
}
Limiting fields returned on a query.
//Find a company by name
let result = await api.Companies.query({
filter:[
{
"op": "eq",
"field": "CompanyName",
"value": "Sirius Cybernetics Corporation "
}
],
includeFields:[
"Id",
"companyName",
"city",
"state"
]
});
Running the above query yields a response:
{
"items": [
{
"id": 29683616,
"city": "",
"companyName": "Sirius Cybernetics Corporation",
"state": "",
"userDefinedFields": []
}
],
"pageDetails": {
"count": 1,
"requestCount": 500,
"prevPageUrl": null,
"nextPageUrl": null
}
}
Note: when using creating filters and specifying field include conditions, field names are not case sensitive.
Querying User Defined Fields
It is possible to query user-defined fields by including a "udf": true to UDF field expressions in filter conditions. In the example below, a Company-level UDF named "Number of Employees" exists. We can query to see which companies have more than 0 employees like this:
result = await api.Companies.query({
filter:[
{
"op": "gt",
"field": "Number of Employees",
"value": 0,
"udf": true
}
]
});
related Autotask documentation
create
Creates an entity.
The following creates Company using the Companies api.
let myCompany = {
CompanyName: "Sirius Cybernetics Corporation",
CompanyType: 3,
Phone: '8005551212',
OwnerResourceID: 29683995
};;
result = await api.Companies.create(myCompany);
..which yields the result:
{
"itemId": 29683664
}
Note some entities in the Autotask REST API are child entities of other entities. This does NOT affect how you query or retrieve them, but it does require you to provide the parent entity id when using the
create(),update(),replace(), ordelete()methods.
To illustrate the child record relationship, the following example will create a ToDo for a Company using the CompanyToDos api.
let myToDo = {
ActionType: 3,
AssignedToResourceID: 29683995,
CompanyID: 0,
ActivityDescription: "Learn more about the Autotask REST API",
StartDateTime: '2020-06-15',
EndDateTime: '2020-06-16',
};
result = await api.CompanyToDos.create(0, myToDo);
Note the use of the parent id (company id = 0) as the first argument of the create method. The parent id is required as the first parameter of the method.
It yields the result:
{
"itemId": 29684378
}
related Autotask documentation
update
Updates an entity. This updates ONLY the fields you specify, leaving other fields on it unchanged.
The following example updates a Company phone number.
let updateResult = await api.Company.update({"id":45701237, phone: "1112223344"});
As mentioned in the create() documentation above, child record relationships require a slight change in syntax when invoking updates on sub-entities. Here is another example of the child record relationship, using the Contacts entity. Since Contacts are children of Companies, we must also provide the CompanyID of the Contact before we can update it.
// Here we are using the api.Contacts handle. Queries don't require knowledge of parent-child structure.
let queryResult = await api.Contacts.query({filter:[{field:'firstName', op:FilterOperators.eq, value:'Zaphod'}]});
let companyID = queryResult.items[0].companyID;
// However, here we are using the api.CompanyContacts handle because of the structure required by the Autotask REST API. The parent entity is provided as the first argument of the update.
let updateResult = await api.CompanyContacts.update(companyID, {"id":30684047, middleName: "Hortensius"});
Note some entities in the Autotask REST API are child entities of other entities. This doesn't affect how you query or retrieve them, but it does require you to provide the parent entity id when using the
create(),update(),replace(), ordelete()methods.
related Autotask documentation
replace
Replaces an entity. This replaces the entire entity, obliterating its prior contents (except for readonly fields) and replacing it with the data you provide.
Note some entities in the Autotask REST API are child entities of other entities. This doesn't affect how you query or retrieve them, but it does require you to provide the parent entity id when using the
create(),update(),replace(), ordelete()methods.
related Autotask documentation
delete
Deletes an entity by id.
Note some entities in the Autotask REST API are child entities of other entities. This doesn't affect how you query or retrieve them, but it does require you to provide the parent entity id when using the
create(),update(),replace(), ordelete()methods.
related Autotask documentation
info
related Autotask documentation
fieldInfo
Get metadata about a given entity's fields. This includes information about the data type; whether the field is required, read-only etc; and any valid-values that should be used. related Autotask documentation
result = await api.AccountToDo.fieldInfo();
This will yield a result:
{
"fields": [
{
"name": "ActionType",
"dataType": "integer",
"length": 0,
"isRequired": true,
"isReadOnly": false,
"isQueryable": true,
"isReference": false,
"referenceEntityType": "",
"isPickList": true,
"picklistValues": [
{
"value": "0",
"label": "Opportunity Update",
"isDefaultValue": false,
"sortOrder": 0,
"parentValue": "",
"isActive": true,
"isSystem": true
},
{
"value": "1",
"label": "Phone Call",
"isDefaultValue": false,
"sortOrder": 0,
"parentValue": "",
"isActive": true,
"isSystem": true
},
...
],
"picklistParentValueField": "",
"isSupportedWebhookField": false
},
{
"name": "ActivityDescription",
"dataType": "string",
"length": 32000,
"isRequired": false,
"isReadOnly": false,
"isQueryable": true,
"isReference": false,
"referenceEntityType": "",
"isPickList": false,
"picklistValues": null,
"picklistParentValueField": "",
"isSupportedWebhookField": false
},
...
]
}
related Autotask documentation
udfInfo
related Autotask documentation
Available Entities
The following is a list of all Autotask entities supported by the connector:
- ActionTypes
- AdditionalInvoiceFieldValues
- Appointments
- AttachmentInfo
- ProjectCharges
- BillingCodes
- BillingItems
- BillingItemApprovalLevels
- ChangeOrderCharges
- ChangeRequestLinks
- ChecklistLibraries
- ClassificationIcons
- ClientPortalUsers
- ComanagedAssociations
- Companies
- CompanyWebhooks
- ConfigurationItems
- ConfigurationItemCategories
- ConfigurationItemTypes
- Contacts
- ContactGroups
- ContactWebhooks
- Contracts
- ContractExclusionSets
- Countries
- Currencies
- Departments
- Expenses
- ExpenseReports
- HolidaySets
- InternalLocations
- InternalLocationWithBusinessHours
- InventoryItems
- InventoryLocations
- InventoryTransfers
- Invoices
- InvoiceTemplates
- NotificationHistory
- Opportunities
- OrganizationalLevel1
- OrganizationalLevel2
- OrganizationalLevelAssociations
- PaymentTerms
- PriceListMaterialCodes
- PriceListProducts
- PriceListProductTiers
- PriceListRoles
- PriceListServices
- PriceListServiceBundles
- PriceListWorkTypeModifiers
- Products
- Projects
- PurchaseApprovals
- PurchaseOrders
- Quotes
- QuoteLocations
- QuoteTemplates
- Resources
- ResourceRoles
- Roles
- Services
- ServiceBundles
- ServiceCalls
- ShippingTypes
- Skills
- Subscriptions
- Surveys
- SurveyResults
- Taxes
- TaxCategories
- TaxRegions
- ThresholdInformation
- Tickets
- TicketCategories
- TicketHistory
- TimeEntries
- UserDefinedFieldDefinitions
- WebhookEventErrorLogs
- WorkTypeModifiers
- ZoneInformation
The REST API introduces a parent-child relationship among some Autotask entities. The connector uses a shorthand name to make working with the entities more intuitive. The following child-entities are also supported by the connector:
- ChecklistLibraryChecklistItems → ChecklistLibraries/ChecklistItems
- CompanyAlerts → Companies/Alerts
- CompanyAttachments → Companies/Attachments
- CompanyContacts → Companies/Contacts
- CompanyLocations → Companies/Locations
- CompanyNotes → Companies/Notes
- CompanySiteConfigurations → Companies/SiteConfigurations
- CompanyTeams → Companies/Teams
- CompanyToDos → Companies/ToDos
- CompanyWebhookExcludedResources → CompanyWebhooks/ExcludedResources
- CompanyWebhookFields → CompanyWebhooks/Fields
- CompanyWebhookUdfFields → CompanyWebhoosk/UdfFields
- ConfigurationItemAttachments → ConfigurationItem/Attachments
- ConfigurationItemBillingProductAssociations → ConfigurationItems/BillingProductAssociations
- ConfigurationItemCategoryUdfAssociations → ConfigurationItemCategories/UdfAssociations
- ConfigurationItemNotes → ConfigurationItems/Notes
- ConfigurationItemNoteAttachments → ConfigurationItemNotes/Attachments
- ContactBillingProductAssociations → Contacts/BillingProductAssociationis
- ContactGroupContacts → ContactGroups/Contacts
- ContactWebhookExcludedResources → ContactWebhooks/ExcludedResources
- ContactWebhookFields → ContactWebhooks/Fields
- ContactWebhookUdfFields → ContactWebhooks/UdfFields
- ContractBillingRules → Contracts/BillingRules
- ContractBlocks → Contracts/Blocks
- ContractBlockHourFactors → Contracts/BlockHourFactors
- ContractCharges → Contracts/Charges
- ContractExclusionBillingCodes → Contracts/ExclusionBillingCodes
- ContractExclusionRoles → Contracts/ExclusionRoles
- ContractExclusionSetExcludedRoles → ContractExclusionSets/ExcludedRoles
- ContractExclusionSetExcludedWorkTypes → ContractExclusionSets/ExcludedWorkTypes
- ContractMilestones → Contracts/Milestones
- ContractNotes → Contracts/Notes
- ContractRates → Contracts/Rates
- ContractRetainers → Contracts/Retainers
- ContractRoleCosts → Contracts/RoleCosts
- ContractServices → Contracts/Services
- ContractServiceAdjustments → Contracts/ServiceAdjustments
- ContractServiceBundles → Contracts/ServiceBundles
- ContractServiceBundleAdjustments → Contracts/ServiceBundleAdjustments
- ContractServiceBundleUnits → Contracts/ServiceBundleUnits
- ContractServiceUnits → Contracts/ServiceUnits
- ContractTicketPurchases → Contracts/TicketPurchases
- ExpenseItems → Expenses/Items
- Holidays → HolidaySets/Holidays
- InventoryItemSerialNumbers → InventoryItems/SerialNumbers
- OpportunityAttachments → Opportunities/Attachments
- OrganizatonalResources → OrganizationalLevelAssociations/Resources
- Phases → Projects/Phases
- ProductNotes → Products/Notes
- ProductTiers → Products/Tiers
- ProductVendors → Products/Vendors
- ProjectAttachments → Projects/Attachments
- ProjectCharges → Projects/Charges
- ProjectNotes → Projects/Notes
- PurchaseOrderItems → PurchaseOrders/Items
- PurchaseOrderItemReceiving → PurchaseOrderItems/Receiving
- QuoteItems → Quotes/Items
- ResourceRoleDepartments → Resources/RoleDepartments
- ResourceRoleQueues → Resources/RoleQueues
- ResourceServiceDeskRoles → Resources/ServiceDeskRoles
- ResourceSkills → Resources/Skills
- SalesOrders → Opportunities/SalesOrders
- ServiceBundleServices → ServiceBundles/Services
- ServiceCallTasks → ServiceCalls/Tasks
- ServiceCallTaskResource → ServiceCallTasks/Resources
- ServiceCallTickets → ServiceCalls/Tickets
- ServiceCallTicketResource → ServiceCallTickets/Resources
- ServiceLevelAgreementResults → ServiceLevelAgreements/Results
- SubscriptionPeriods → Subscriptions/Periods
- Tasks → Projects/Tasks
- TaskAttachments → Tasks/Attachments
- TaskNotes → Tasks/Notes
- TaskNoteAttachments → TaskNotes/Attachments
- TaskPredecessors → Tasks/Predecessors
- TaskSecondaryResources → Tasks/SecondaryResources
- TicketAdditionalConfigurationItems → Tickets/AdditionalConfigurationItems
- TicketAdditionalContacts → Tickets/AdditionalContacts
- TicketAttachments → Tickets/Attachments
- TicketCategoryFieldDefaults → TicketCategories/FieldDefaults
- TicketChangeRequestApprovals → Tickets/ChangeRequestApprovals
- TicketCharges → Tickets/Charges
- TicketChecklistItems → Tickets/ChecklistItems
- TicketChecklistLibraries → Tickets/ChecklistLibraries
- TicketNotes → Tickets/Notes
- TicketNoteAttachments → TicketNotes/Attachments
- TicketRmaCredits → Tickets/RmaCredits
- TicketSecondaryResources → Tickets/SecondaryResources
- TimeEntryAttachments → TimeEntries/Attachments
- UserDefinedFieldListItems → UserDefinedFields/ListItems
Debugging
Support for debugging is provided via the debug library. Two levels of debugging are supported:
- debug include
autotask:restapiin yourDEBUGenvironment variable - verbose include
autotask:restapi:verboseor simplyautotask:restapi*in your DEBUG environment variable.