Autotask Integration
This integration syncs Autotask PSA data into Resplendent Data through the Autotask REST API.
It is a read-only, poll-based integration: Resplendent queries Autotask on a schedule and does not register or rely on webhooks.
What you can sync:
- Customer context: Companies, Contacts, Resources, ConfigurationItems
- Service desk: Tickets, ServiceCalls, ServiceCallTasks, ServiceCallTaskResources, ServiceCallTickets, ServiceCallTicketResources, Time Entries
- Projects: Projects and Tasks
- Contracts and billing: Contracts, ContractMilestones, ContractRates, ContractServiceBundles, ContractServices, ContractServiceUnits, Services, Products, Invoices
- Sales: Opportunities
Supported datasets in the current integration:
- Companies
- ConfigurationItems
- Contacts
- ContractMilestones
- ContractRates
- ContractServiceBundles
- ContractServices
- ContractServiceUnits
- Contracts
- Invoices
- Opportunities
- Products
- Projects
- Resources
- ServiceCalls
- ServiceCallTaskResources
- ServiceCallTasks
- ServiceCallTicketResources
- ServiceCallTickets
- Services
- Tasks
- Tickets
- Time Entries
How datasets relate
Section titled “How datasets relate”Most Autotask reporting starts from a small set of numeric ID join paths. Use the fields below as your default links in the app.
| Start dataset | Join column | Related dataset | Related column | Typical use |
|---|---|---|---|---|
| Companies | id |
Contacts | companyID |
Contacts by customer |
| Companies | id |
Contracts | companyID |
Contracts by customer |
| Companies | id |
Projects | companyID |
Projects by customer |
| Companies | id |
Tickets | companyID |
Ticket volume by customer |
| Companies | id |
ServiceCalls | companyID |
Service calls by customer |
| Companies | id |
ConfigurationItems | companyID |
Configuration items by customer |
| Companies | id |
Invoices | companyID |
Invoices by customer |
| Companies | id |
Opportunities | companyID |
Sales pipeline by customer |
| Companies | id |
Opportunities | companyID |
Sales pipeline by customer |
| Contacts | id |
Opportunities | contactID |
Opportunities tied to a contact |
| Contacts | id |
Opportunities | contactID |
Opportunities tied to a contact |
| Contracts | id |
ContractMilestones | contractID |
Milestones billed against a contract |
| Contracts | id |
ContractRates | contractID |
Hourly rates tied to a contract |
| Contracts | id |
ContractServiceBundles | contractID |
Service bundles attached to a contract |
| Contracts | id |
ContractServices | contractID |
Services attached to a contract |
| Contracts | id |
ContractServiceUnits | contractID |
Unit counts and pricing periods on a contract |
| Contracts | id |
Projects | contractID |
Projects tied to a contract |
| Contracts | id |
Tickets | contractID |
Tickets tied to a contract |
| ContractServices | id |
ContractServiceUnits | contractServiceID |
Quantity / units history for each contract service |
| Services | id |
ContractServices | serviceID |
Service metadata such as name or period type |
| Services | id |
ContractServiceUnits | serviceID |
Unit rows grouped by service |
| Projects | id |
Tasks | projectID |
Project workload and task completion |
| Projects | id |
Tickets | projectID |
Tickets associated with a project |
| Tasks | id |
Time Entries | taskID |
Time logged against tasks |
| Tickets | id |
Time Entries | ticketID |
Time logged against tickets |
| ServiceCalls | id |
ServiceCallTasks | serviceCallID |
Tasks linked to a service call |
| ServiceCalls | id |
ServiceCallTickets | serviceCallID |
Tickets linked to a service call |
| ServiceCallTasks | id |
ServiceCallTaskResources | serviceCallTaskID |
Resources assigned to service-call tasks |
| ServiceCallTickets | id |
ServiceCallTicketResources | serviceCallTicketID |
Resources assigned to service-call tickets |
| Resources | id |
Opportunities | ownerResourceID |
Opportunities owned by a resource |
| Resources | id |
Opportunities | ownerResourceID |
Opportunities owned by a resource |
| Resources | id |
Tickets | assignedResourceID |
Assigned technician on tickets |
| Resources | id |
ServiceCallTaskResources | resourceID |
Assignments on service-call tasks |
| Resources | id |
ServiceCallTicketResources | resourceID |
Assignments on service-call tickets |
| Resources | id |
Time Entries | resourceID |
Time by technician |
Common join patterns
Section titled “Common join patterns”- Contract service quantity: Join
ContractServices.id = ContractServiceUnits.contractServiceID. This is the clearest way to bring unit counts into reporting. - Contract service details:
ContractServicesalready hydratesserviceNameandservicePeriodType.ContractServiceUnitsalso hydratesunitPrice,serviceName, andservicePeriodType, so you often do not need an extra join toServicesjust to label unit rows. - Opportunities pipeline: Join
Opportunities.companyID = Companies.idto see pipeline by customer, orOpportunities.ownerResourceID = Resources.idto see pipeline by owner.OpportunitieshydratescompanyNameandownerResourceUserName, so simple reports may not need the extra join. - Service call assigned resources:
ServiceCallTaskResourcesis the cleanest assignment table. The integration hydratesserviceCallID,taskID, andresourceUserNameonto it, so you can usually join it directly toServiceCalls.idonserviceCallID. - Service call ticket assignments:
ServiceCallTicketResourceshydratesserviceCallID,ticketID, andresourceUserName, so it can usually join directly toServiceCalls.idorTickets.id. If you need the explicit bridge path, useServiceCalls.id = ServiceCallTickets.serviceCallIDandServiceCallTickets.id = ServiceCallTicketResources.serviceCallTicketID. - Time against contract work: Join
Time Entries.contractServiceID = ContractServices.id,Time Entries.contractServiceBundleID = ContractServiceBundles.id, orTime Entries.contractID = Contracts.iddepending on whether you want service-, bundle-, or contract-level reporting. - Project execution: Join
Projects.id = Tasks.projectID, thenTasks.id = Time Entries.taskIDto compare planned work to logged work. - Customer billing: Join
Invoices.companyID = Companies.idfor invoice totals by customer, orContracts.companyID = Companies.idfor agreement reporting. - Configuration items under agreements: Join
ConfigurationItems.companyID = Companies.idfor customer inventory andConfigurationItems.contractID = Contracts.idfor agreement-linked assets.
Hydrated helper columns
Section titled “Hydrated helper columns”ContractsaddscompanyNameandbillToCompanyName.OpportunitiesaddscompanyNameandownerResourceUserName.TicketsaddscompanyNameplus several*UserNamehelper columns such asassignedResourceUserName.Time EntriesaddsresourceUserName,creatorUserName,lastModifiedUserName, and other resource-name helpers.ContractServicesaddsserviceNameandservicePeriodType.ContractServiceUnitsaddsunitPrice,serviceName, andservicePeriodType.ServiceCallTasksaddsassignedResourceID,taskNumber,title, andassignedResourceUserName.ServiceCallTaskResourcesaddsserviceCallID,taskID, andresourceUserName.ServiceCallTicketsaddsassignedResourceID,ticketNumber,title, andassignedResourceUserName.ServiceCallTicketResourcesaddsserviceCallID,ticketID, andresourceUserName.InvoicesaddscompanyName,creatorResourceUserName, andvoidedByResourceUserName.
Picklists and join keys
Section titled “Picklists and join keys”- The integration resolves Autotask picklist values to labels during sync by calling Autotask’s
/entityInformation/fieldsendpoint. - Because of that, many reporting dimensions are already readable labels rather than foreign keys. Examples include
status,priority,queueID,ticketType, andserviceLevelAgreementID. - Some of those fields still end in
ID, but the synced value is already the label. Do not use those as join keys. - Use raw relationship fields such as
companyID,contractID,projectID,taskID,ticketID,serviceCallID,resourceID, andcontractServiceIDfor joins. ContractServiceUnitsis time-sliced. A singlecontractServiceIDcan have multiple rows across billing periods, so includestartDate/endDatewhen charting unit changes over time.
Part 1: Create a custom security level
Section titled “Part 1: Create a custom security level”Create a read-only security level for the API user. The integration only queries Autotask; it does not write back.
1. Navigate to Security Levels
Section titled “1. Navigate to Security Levels”- In Autotask, hover over the Admin icon
- Click Account Settings & Users
- Expand Resources/Users (HR)
- Click Security Levels
2. Copy an existing level
Section titled “2. Copy an existing level”- Find API User (system) (API-only)
- Right-click and select Copy
3. Configure general settings
Section titled “3. Configure general settings”- Name:
Resplendent Data API User - Active: Checked
4. Grant query permissions
Section titled “4. Grant query permissions”For this integration, the important requirement is API query access to the entities you want to sync.
- In Web Services API, enable View (Query) for each dataset you plan to sync.
- If you want the full integration, enable query access for all of the datasets listed earlier on this page.
- Make sure the security level can also see the same records in the corresponding Autotask modules. If a dataset preview fails in Resplendent with a permissions warning, that entity type is still missing access.
- If you want
ConfigurationItems, make sure the API user can query and view configuration items in Autotask. - Webhooks are not required for this integration.
5. Save
Section titled “5. Save”Click Save & Close.
Part 2: Create the API user
Section titled “Part 2: Create the API user”Now create the user account that uses the security level you just made.
1. Navigate to Resources
Section titled “1. Navigate to Resources”- Go to Admin > Resources/Users (HR) > Resources/Users
- Hover over the arrow next to New and select New API User
2. Fill in details
Section titled “2. Fill in details”- First Name: Resplendent
- Last Name: Data
- Security Level: Select
Resplendent Data API User
3. Generate credentials
Section titled “3. Generate credentials”- Username (Key): Click Generate Key. Save this immediately.
- Password (Secret): Click Generate Secret. Save this immediately.
4. Select integration vendor
Section titled “4. Select integration vendor”- If the API Tracking Identifier section is present, select Resplendent Data as the Integration Vendor.
5. Save
Section titled “5. Save”Click Save & Close.
Part 3: Connect to Resplendent Data
Section titled “Part 3: Connect to Resplendent Data”1. Find your zone number
Section titled “1. Find your zone number”Look at your Autotask URL. If it’s https://ww2.autotask.net, your zone number is 2.
2. Add the connection
Section titled “2. Add the connection”- Log in to Resplendent Data
- Click Integrations in the sidebar
- Find Autotask and click + Connect
- Fill in:
- API Username: The Key from Part 2
- API Password: The Secret from Part 2
- Zone Number: From your URL
- Connection Title: Something like “Autotask Production”
3. Finalize
Section titled “3. Finalize”- Click Save & Test
- Once verified, click Sync Dataset to start pulling data
Sync behavior
Section titled “Sync behavior”- The integration is poll-based. It does not use Autotask webhooks or callback pushes.
- Autotask limits responses to 500 rows per request, so large initial syncs and backfills are automatically paged.
- Incremental refresh is currently supported for
Companies,Contacts,ContractMilestones,Contracts,Opportunities,Products,Projects,ServiceCalls,Services,Tasks,Tickets,Time Entries,ConfigurationItems, andInvoices. ContractRates,ContractServiceBundles,ContractServices,ContractServiceUnits,Resources,ServiceCallTasks,ServiceCallTaskResources,ServiceCallTickets, andServiceCallTicketResourcesare currently treated as non-incremental tables.- Ticket deletions are tracked through Autotask
DeletedTicketLogs, so deleted tickets can be removed on refresh. Other datasets do not currently emit explicit delete events through this integration.
User-defined fields
Section titled “User-defined fields”Autotask user-defined fields (UDFs) are expanded into individual columns during sync. Each UDF becomes its own column with (UDF) appended to the name. Spaces in the original UDF name are replaced with underscores, so a UDF named Opportunity Type appears as Opportunity_Type(UDF).
UDFs are available on these datasets:
- Companies
- Contracts
- Opportunities
- Resources
- Tickets
- Time Entries
How UDF columns behave
Section titled “How UDF columns behave”- If you select specific UDF columns in a dataset configuration, the integration fetches all standard fields plus the UDFs. This happens because the Autotask API only returns
userDefinedFieldswhen no column filter is applied. - UDF string values are not truncated to 256 characters.
- If a UDF contains a list value, it is stored as a serialized JSON string in the column.
- Rows without a particular UDF show
NULLfor that column.