a. Go to Settings > Invoicing > Tax Zones. Create zones for each jurisdiction where you operate by clicking Add Tax Zone. Enter a name, set the tax rate, and assign zip codes to map locations to the correct zone.
b. Assign tax rates to each zone. Tax is calculated automatically based on the service location's address and mapped tax zone. After creating all zones, click Set Tax Zones to apply the mappings to your customer locations.
⚠︎ You must click "Set Tax Zones" after creating or editing zones — changes do not apply automatically. Locations without a mapped zone will not have tax calculated.
⚠︎ If you export to QuickBooks or Intacct, your ServiceTitan tax zone names must match your accounting software's tax item names exactly. Mismatches cause export failures or incorrect tax reporting.
a. Go to Settings > Integrations > Avalara. Enter your Avalara account number, license key, company code, and select a cutoff date. Click Test Connection to verify, then click Save.
⚠︎ Avalara requires account configuration by ServiceTitan. Contact Technical Support to enable the integration before attempting setup.
b. Once connected, Avalara calculates tax rates automatically based on the exact service address — no manual tax zone mapping needed. You must also assign Avalara tax codes to your pricebook items (at the item, subcategory, or category level) for tax to calculate correctly.
⚠︎ If pricebook items do not have Avalara tax codes assigned (at any level), Avalara returns $0 tax. Check item, subcategory, and category levels.
⚠︎ Manual tax zone overrides can cause double-taxation on recurring service visits. Best practice: create non-taxable visit SKUs instead of overriding zones.
a. Create a "Permit Fee" material item in your pricebook for each permit type your business commonly pulls (e.g., "Permit — Mechanical," "Permit — Electrical," "Permit — Plumbing"). Set the cost to your average permit cost and the sell price to whatever you pass through to customers. Assign the items to a dedicated "Permits & Fees" category.
b. Bundle permit fees into Item Groups for common jobs. For example, create a "Water Heater Installation Package" Item Group that includes the labor service, equipment, expansion tank, and permit fee. The customer sees one total price — no line-item vetoing on the permit charge — while the system retains the individual components for job costing and reporting.
⚠︎ If you use membership discounts, be careful with "All Services" discount rules — they will discount permit fees too. Best practice: use Category-Based discounts so you discount Repairs but not the Permits & Fees category.
⚠︎ For QuickBooks Desktop/Online integrations, permit fee item names are limited to 31 characters. Use abbreviated naming (e.g., "Permit-Mech-Residential").
a. Create custom fields on the Job or Project scope to capture permit data. Go to Settings > Operations > Custom Fields. Recommended fields: Permit Number (Text) — the jurisdiction-issued permit ID; Permit Status (Dropdown) — values like "Not Required," "Application Submitted," "Approved," "Inspection Scheduled," "Inspection Passed," "Inspection Failed"; Permit Jurisdiction (Text or Dropdown) — the issuing authority (city, county); Inspection Date (Date) — when the inspection is scheduled.
b. Create tags for quick dispatch-board visibility. Suggested tags: Permit Required — applied at booking when the CSR identifies a permit need; Permit Pulled — applied when the office confirms the permit is in hand; Inspection Pending — applied after work is complete, awaiting inspector; Inspection Passed — final state, clears the job for closeout. Tags are visible on the dispatch board and in the technician's mobile view, so dispatchers and techs know at a glance whether a job is cleared to proceed.
⚠︎ Permit status must be managed manually through custom fields and tags. There is no automatic gate that prevents a technician from starting work on a job without a permit — enforcement comes from process (forms) or dispatcher vigilance (tags).
a. Create a "Permit & Inspection Readiness" form in Settings > Operations > Forms. Include fields such as: "Is a permit required for this job?" (Radio: Yes / No), "Has the permit been pulled?" (Radio: Yes / No), "Permit number" (Text — confirms the permit is in hand), and "Photo of posted permit" (Photo — proof for your records and the inspector).
b. Set the form trigger to fire on the relevant Job Types (e.g., Install, Replacement, Panel Upgrade). Choose the trigger event based on your enforcement strategy: "On Arrival" — the tech sees the form immediately and must confirm permit status before proceeding (best for residential installs); or "Required for Job Completion" — the tech can start work but cannot close the job until the form is submitted (best for multi-day projects where the permit may arrive mid-job).
c. Add conditional logic and auto-tagging to the form: IF "Is a permit required?" = Yes AND "Has the permit been pulled?" = No → auto-apply the Permit Required tag to the Job and show a warning section: "STOP — Do not begin work until the permit is confirmed. Contact the office." IF "Has the permit been pulled?" = Yes → auto-apply the Permit Pulled tag to the Job.
⚠︎ Never mark a form field as "Required" if its section can be hidden by conditional logic. This causes the form to freeze and the technician cannot submit it.
a. Create a "Completed Form" alert filtered to your Permit & Inspection Readiness form. Route this to the Office Manager or Permit Coordinator so they are notified the moment a technician submits permit data from the field.
b. Create a "Task Used" alert for your Permit Fee pricebook items. When a technician adds a permit fee to an invoice, the alert notifies the office that a permit-related job is in progress and may need inspection scheduling.
c. (Optional) If your jurisdiction requires specific materials to be documented (e.g., solar panel installs requiring AHJ approval), create an additional "Task Used" alert for those specific pricebook items to flag jobs that will need regulatory sign-off.
⚠︎ Alert logic uses strict AND matching — all conditions must be met. Start broad (just the form or task trigger) and narrow down only if alert volume is too high. Over-filtering causes missed notifications.
a. Create specific pricebook material items for each refrigerant type your technicians handle (e.g., "R-410A — per lb," "R-22 — per lb," "R-454B — per lb"). Set accurate costs and assign them to a dedicated "Refrigerants" subcategory. A generic "Refrigerant" SKU won't satisfy EPA Section 608 reporting, which requires tracking by type.
b. When technicians add refrigerant to an invoice in the field, they enter the quantity (pounds) used. To track cylinder serial numbers — required for full EPA chain-of-custody documentation — use one of two approaches: Custom fields on the material item — add a "Cylinder Serial #" custom field to your refrigerant pricebook items (techs enter the serial number at the point of use); or Form-based capture (recommended) — create a "Refrigerant Usage Log" form with fields for refrigerant type (dropdown), quantity (number), cylinder serial number (text), and a photo of the cylinder label, then trigger the form on Job Types where refrigerant use is expected (e.g., "HVAC Repair," "System Charge"). This creates a richer audit trail than custom fields alone.
c. Set up a "Task Used" alert for your refrigerant pricebook items — especially R-22, which is phased out under EPA regulations and commands premium pricing. Route the alert to your Safety Officer or Operations Manager.
d. To generate EPA-ready usage reports, go to Reports > Create Report, select the Invoice Items template, and filter by your Refrigerant subcategory. Include these columns: Item Name, Quantity, Customer Name, Location Address, Job Date, and Technician.
⚠︎ ServiceTitan does not have a dedicated EPA refrigerant tracking module or a push-button EPA compliance report. You must build a custom Invoice Items report filtered by refrigerant SKU codes.
⚠︎ If you use the form-based approach, ensure the form is assigned to Jobs (not just Locations) — forms assigned only to Locations do not appear in the Form Submissions report, which breaks your audit trail.
⚠︎ For HVAC companies handling R-22 recovery, consider creating separate "R-22 Recovery" and "R-22 Charge" SKUs to distinguish between refrigerant added and refrigerant removed. EPA reporting requires both directions.
a. Set up custom fields on the Technician entity to store certification data. Go to Settings > Operations > Custom Fields. Create fields for each license type relevant to your trade: License Number (Text) — the state or jurisdiction-issued ID; License Type (Dropdown) — e.g., "Journeyman Electrician," "Master Plumber," "EPA 608 Universal," "NATE Certified"; Issue Date (Date) — when the license was issued; Expiration Date (Date) — when the license expires; Issuing Authority (Text) — the licensing body or state board.
b. Build a proactive expiration monitoring report. Go to Reports > Create Report, select the Technician report template, and include your custom certification fields. Create three saved versions: Expiring in 30 days — your "act now" list (schedule weekly); Expiring in 60 days — your planning horizon for renewal paperwork; Expiring in 90 days — your early warning for certifications that require classes or testing (schedule monthly).
c. Use Technician Skills (a Core dispatch feature) to reflect certification status in dispatch. Map certifications to skills — for example, create a "Backflow Certified" skill and assign it to qualified techs. Then configure job types that require backflow work to require that skill. The dispatch system will only suggest or assign backflow jobs to techs with the matching skill, preventing compliance violations at the scheduling level.
⚠︎ ServiceTitan does not have a native certification tracking module with built-in expiration alerts. There is no automatic notification when a certification is about to expire. The scheduled report is the only proactive mechanism — if you don't build and schedule it, expirations will be missed.
⚠︎ If a technician's certification expires, removing their corresponding Skill in the dispatch system is a manual step. There is no automatic sync between custom field expiration dates and technician skill assignments. Your Operations Manager must update both.
a. Verify the service location has a valid, Google-verified address with a mapped tax zone. Go to Settings > Invoicing > Tax Zones and confirm the location's zip code is included in a zone. If you recently created or edited zones, confirm you clicked Set Tax Zones to apply changes.
b. If using Avalara, confirm the integration is active at Settings > Integrations > Avalara and verify pricebook items have Avalara tax codes assigned. If using manual tax zones, verify the rate is set correctly for the location's zone and that the pricebook item is marked as Taxable.
⚠︎ A common cause: the pricebook item's "Taxable" checkbox is not selected. Even with correct tax zones, non-taxable items will show $0 tax.
⚠︎ Tax zone "drift" — if dispatchers or office staff manually override the tax zone on individual invoices instead of fixing the Location's master data, the error repeats on every future job at that address. Fix the Location, not the invoice.
a. Confirm that your permit-related tags (e.g., "Permit Required," "Permit Pulled") are created and active. Tags must be applied to the Job entity (not Customer or Location) to appear on the dispatch board next to the job.
b. If you're using form-based auto-tagging, verify that the conditional logic rules are configured correctly: the IF condition matches the expected form answer, and the THEN action applies the tag to the correct target (Job, not Location). Test by submitting the form on a test job and checking whether the tag appears.
⚠︎ Auto-tags applied by conditional logic are permanent once the form is submitted. If a permit status changes (e.g., from "Required" to "Pulled"), the old tag must be manually removed and the new tag applied — forms do not remove previously applied tags.
a. Verify that technicians are using the correct, specific refrigerant SKUs (e.g., "R-410A — per lb") rather than a generic "Refrigerant" item or a miscellaneous charge. Generic items won't appear when you filter by refrigerant category.
b. If using the form-based cylinder tracking approach, confirm the Refrigerant Usage Log form is assigned to Jobs (not just Locations) and that the form trigger is set to fire on the correct Job Types. Forms assigned only to Locations do not appear in the Form Submissions report.
a. Confirm that custom fields are created at the correct scope (Technician entity) and that data has been entered for each technician. Custom fields with blank values won't appear in filtered reports.
b. Verify you are using the Technician report template (not the Employee template). Include all relevant custom field columns and check that your date filter range is correct — filtering for "next 30 days" from today's date.
⚠︎ If the report returns zero results, it likely means no expiration dates fall within your filter range — not that the report is broken. Widen the date range to confirm data exists.