Associate a Contract and Service to an Autotask Ticket
This tutorial walks through associating a contract and service to an Autotask ticket created by Email2AT. This is optional, but useful if your Autotask instance requires or benefits from tickets being linked to a specific contract and service for billing or time tracking.
Overview
Autotask uses three related entities for contract/service association:
| Entity | What it is |
|---|---|
| Contract | A billing agreement with a customer (for example, a Managed Services contract) |
| Service | A type of work (for example, "Help Desk" or "Hardware - Desktop") |
| ContractService | The join record that links a specific Service to a specific Contract. This is what the ticket actually references. |
When you manually create a ticket in the Autotask UI and select a contract, then select a service, Autotask resolves the ContractService join record behind the scenes. When creating tickets via the API, you must resolve it yourself.
The workflow to resolve the ContractService ID is:
- Find the Account
- Find the Contract on that Account
- Find the Service by name
- Find the ContractService record that links the Contract to the Service
- Create the ticket with the Account ID, Contract ID, and ContractService ID
Related pages:
When to Use This
Use this pattern when:
- Your Autotask instance requires a contract and service on tickets for billing
- You want time entries on tickets to automatically apply to the correct contract
- You have standardized contract structures across your customers (for example, every customer has a "Managed Service" contract with a "Help Desk" service)
If your Autotask instance does not use contract/service associations on tickets, you do not need this.
Step-by-Step Workflow
This tutorial assumes you already have a rule that creates tickets (for example, from the Create Your First Mailbox tutorial). The steps below are inserted before the ticket creation step.
Action 1: Query for the Account
If your workflow already has the Account ID (for example, from the Create Autotask Ticket workflow action), you can skip this step.
- Click Add New Action, select API: Query for One Object, click OK
- Name the step
Find Account - Set Entity Type to
Account - Add query conditions as appropriate (for example, by account name or by contact lookup)
- In Store results in variable, enter
account
Action 2: Query for the Contract
- Click Add New Action, select API: Query for One Object, click OK
- Name the step
Find Contract - Set Entity Type to
Contract - Set Only perform this action if:
custom.account.idis not empty - Add query conditions:
AccountIDequals{{custom.account.id}}StatusequalsActive(or1, depending on your Autotask)- Optionally filter by contract category (for example,
ContractCategoryequalsManaged Service)
- In Store results in variable, enter
contract
Action 3: Query for the Service
- Click Add New Action, select API: Query for One Object, click OK
- Name the step
Find Service - Set Entity Type to
Service - Set Only perform this action if:
custom.contract.idis not empty - Add query conditions:
ServiceNameequals the name of the service you want (for example,Help Desk)
- In Store results in variable, enter
service
If you always use the same service, you can skip this query and hard-code the service ID directly in the next step. Query the service by name if it varies by customer or if you want the workflow to adapt automatically.
Action 4: Query for the ContractService
This is the join record that links the Contract to the Service.
- Click Add New Action, select API: Query for One Object, click OK
- Name the step
Find ContractService - Set Entity Type to
ContractService - Set Only perform this action if:
custom.service.idis not empty - Add query conditions:
ContractIDequals{{custom.contract.id}}ServiceIDequals{{custom.service.id}}
- In Store results in variable, enter
contractService
Action 5: Create the Ticket
- Click Add New Action, select API: Create an Object, click OK
- Name the step
Create Ticket with Contract - Set Entity Type to
Ticket - Set Only perform this action if:
custom.contractService.idis not empty - Configure the required ticket fields, plus:
| Field | Value |
|---|---|
| AccountID | {{custom.account.id}} (unlock the field) |
| ContractID | {{custom.contract.id}} (unlock the field) |
| ContractServiceID | {{custom.contractService.id}} (unlock the field) |
| Status | New |
| Priority | Set as appropriate |
| QueueID | Your support queue |
| Title | {{email.subject}} |
| Description | {{email.body}} |
Autotask rejects ticket creation if the Contract ID does not belong to the Account on the ticket. The query chain above ensures this by filtering the Contract by Account ID.
Handling Missing Data
If any step in the chain returns no result (no contract, no service, or no ContractService), the subsequent steps are skipped because of the "only perform if" conditions. Add a fallback action that creates the ticket without contract association:
- Add another API: Create an Object (Ticket) step after the contract-associated version
- Set Only perform this action if:
custom.contractService.idis empty ANDcustom.account.idis not empty - Configure the same ticket fields but omit ContractID and ContractServiceID
This ensures a ticket is always created, with or without contract association.
Key Takeaways
- ContractService is the join record: the ticket references ContractService, not Service directly
- Four queries to resolve the chain: Account → Contract → Service → ContractService
- Guard every step: if any query returns empty, skip downstream steps and fall back to a ticket without contract
- Contract must match the account: Autotask rejects tickets where the contract does not belong to the ticket's account
- This is optional: only use this pattern if your Autotask instance requires or benefits from contract/service on tickets
Related Documentation
- API: Query for One Object: querying Autotask for a single result
- API: Create an Object: creating any Autotask entity
- Core Concepts: how rules, actions, and variables work together
- Create Your First Mailbox: the starting point for a basic ticket workflow