Skip to main content

Associate a Contract and Service to an Autotask Ticket

Tickets without the right contract and service can require billing cleanup or send time entries to the wrong place. If your Autotask process depends on those associations, Email2AT can find them before it creates the ticket.

This tutorial adds that optional lookup chain to an existing ticket rule.


Overview​

Autotask uses three related entities for contract/service association:

EntityWhat it is
ContractA billing agreement with a customer (for example, a Managed Services contract)
ServiceA type of work (for example, "Help Desk" or "Hardware - Desktop")
ContractServiceThe 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:

  1. Find the Account
  2. Find the Contract on that Account
  3. Find the Service by name
  4. Find the ContractService record that links the Contract to the Service
  5. 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.

  1. Click Add New Action, select API: Query for One Object, click OK
  2. Name the step Find Account
  3. Set Entity Type to Account
  4. Add query conditions as appropriate (for example, by account name or by contact lookup). See Identify the Customer for account-name, UDF, and fallback choices.
  5. In Store results in variable, enter account

Action 2: Query for the Contract​

  1. Click Add New Action, select API: Query for One Object, click OK
  2. Name the step Find Contract
  3. Set Entity Type to Contract
  4. Set Only perform this action if: custom.account.id is not empty
  5. Add query conditions:
    • AccountID equals {{custom.account.id}}
    • Status equals Active (or 1, depending on your Autotask)
    • Optionally filter by contract category (for example, ContractCategory equals Managed Service)
  6. In Store results in variable, enter contract

Type { in a query value field to open the variable picker and select a value such as {{custom.account.id}}.

Action 3: Query for the Service​

  1. Click Add New Action, select API: Query for One Object, click OK
  2. Name the step Find Service
  3. Set Entity Type to Service
  4. Set Only perform this action if: custom.contract.id is not empty
  5. Add query conditions:
    • ServiceName equals the name of the service you want (for example, Help Desk)
  6. In Store results in variable, enter service
Hard-coding vs. querying

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.

  1. Click Add New Action, select API: Query for One Object, click OK
  2. Name the step Find ContractService
  3. Set Entity Type to ContractService
  4. Set Only perform this action if: custom.service.id is not empty
  5. Add query conditions:
    • ContractID equals {{custom.contract.id}}
    • ServiceID equals {{custom.service.id}}
  6. In Store results in variable, enter contractService

Action 5: Create the Ticket​

  1. Click Add New Action, select API: Create an Object, click OK
  2. Name the step Create Ticket with Contract
  3. Set Entity Type to Ticket
  4. Set Only perform this action if: custom.contractService.id is not empty
  5. Configure the required ticket fields, plus:
FieldValue
AccountID{{custom.account.id}} (unlock the field)
ContractID{{custom.contract.id}} (unlock the field)
ContractServiceID{{custom.contractService.id}} (unlock the field)
StatusNew
PrioritySet as appropriate
QueueIDYour support queue
Title{{email.subject}}
Description{{email.body}}

The ID fields start as picklists for fixed Autotask records. Unlock them so you can enter variables and use the Account, Contract, and ContractService found by the earlier actions.

The contract must belong to the account

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.

What happens now​

  1. The automation finds the customer Account.
  2. It finds an active Contract on that Account and the Service you selected.
  3. It finds the ContractService that connects them.
  4. It creates the ticket with all three IDs, so Autotask associates the correct contract and service from the start.

Handling Missing Data​

First decide how your team wants to handle missing data:

Missing dataChoiceTradeoff
AccountStop with an exception, or create on a dedicated default account or the zero AccountStopping avoids a ticket on the wrong customer but requires someone to fix and replay the email. A fallback account keeps email moving but requires manual reassignment.
Contract, Service, or ContractServiceStop with an exception, or create the ticket without contract associationStopping protects billing requirements but delays the ticket. Creating without the association avoids delay but may require billing cleanup.

To use a fallback Account, leave the first lookup's no-results exception disabled. Add a second Account lookup that finds your dedicated default account or zero Account, stores it in account, and has Only perform this action if set to custom.account.id is empty.

To stop, enable Generate an exception if no results on each lookup that your process requires. To create the ticket without contract association, keep the lookup exceptions disabled and add this fallback action:

  1. Add another API: Create an Object (Ticket) step after the contract-associated version
  2. Set Only perform this action if: custom.contractService.id is empty AND custom.account.id is not empty
  3. Configure the same ticket fields but omit ContractID and ContractServiceID

This version creates a ticket whenever it finds the Account, even when it cannot complete the 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