Add Autotask Child Entity
Use this skill when
- •Adding a new child resource under an existing parent entity in the Autotask node
- •Implementing a new query-only or CRUD child entity
- •You need the full change set, including docs updates in
README.mdandCHANGELOG.md
End-to-end workflow
- •Verify API capabilities first (Swagger/docs)
- •Add entity metadata in
nodes/Autotask/constants/entities.ts - •Add resource definition in
nodes/Autotask/resources/definitions.ts(strict alphabetical order) - •Create resource files under
nodes/Autotask/resources/<resourceDir>/:- •
description.ts - •
execute.ts - •
index.ts
- •
- •Wire the resource in
nodes/Autotask/Autotask.node.ts:- •execute import
- •fields import
- •
addOperationsToResource(...)inproperties - •
switchcase inexecute()
- •Wire the resource in
nodes/Autotask/resources/tool/execute.ts(shared executor backbone):- •execute import
- •
RESOURCE_EXECUTORSmap entry (key = node resource value fromdefinitions.ts)
- •Verify AI Tools exposure via
resourceKey+ operation mapping - •Update docs:
- •Add entry under current version in
CHANGELOG.md - •Add resource row in README supported resources table
- •Add entry under current version in
- •Run validation:
- •
npx tsc --noEmit - •run lint checks for changed files
- •
Implementation details
1) Entity metadata (entities.ts)
Add an entity object in AUTOTASK_ENTITIES with:
- •
name: singular PascalCase internal identifier - •
resourceKey: required whenlowerCamelCase(name)does not match API path/resource identifier - •
childOf: parent entity internal name - •
subname: exact API child URL segment - •
parentIdField: parent FK field - •
operations: only operations the API supports
Example for query-only child:
{
name: 'TicketCategoryFieldDefault',
resourceKey: 'ticketCategoryFieldDefaults',
childOf: 'TicketCategory',
subname: 'FieldDefaults',
parentIdField: 'ticketCategoryID',
operations: {
[OperationType.QUERY]: 'self',
[OperationType.COUNT]: 'self',
},
}
2) Resource definition (definitions.ts)
- •Add a new entry in strict alphabetical order by
name - •Keep
valuealigned with node resource key used inAutotask.node.ts
Example:
{
name: 'Ticket Category Field Default',
value: 'ticketCategoryFieldDefault',
description: 'Query default field values for ticket categories, which define default settings for ticket fields based on category',
}
3) Resource files
description.ts
- •Include only supported operations (for query-only:
get,getMany,count) - •Define
idforget - •Define
fieldsToMapforgetManyandcount - •Export base fields (advanced/entity-info operations are injected by
addOperationsToResource)
execute.ts
- •Set
ENTITY_TYPEto lowerCamelCase internal entity name - •Include switch cases for:
- •
get - •
getMany - •
getManyAdvanced - •
count - •
getEntityInfo - •
getFieldInfo
- •
- •Keep
continueOnFailbehaviour aligned with existing resources - •Reuse base operations (
GetOperation,GetManyOperation,CountOperation, etc.)
index.ts
export * from './description'; export * from './execute';
4) Main node wiring (Autotask.node.ts)
Add:
- •execute import from new resource
execute.ts - •fields import from new resource
description.ts - •properties entry:
- •
...addOperationsToResource(newFields, { resourceName: 'newResourceValue' })
- •
- •switch case:
- •
case 'newResourceValue': return executeNewResourceOperation.call(this);
- •
5) Shared executor wiring (resources/tool/execute.ts)
This step is critical and separate from the main node wiring.
tool/execute.ts contains the RESOURCE_EXECUTORS map — the shared execution backbone used by:
- •AutotaskAiTools node (
AutotaskAiTools.node.ts) — the new structured AI tools node, which callsexecuteToolOperationviaai-tools/tool-executor.ts - •Legacy Tool resource (the
toolresource withinAutotask.node.ts) — being decommissioned in a future release
Without an entry in RESOURCE_EXECUTORS, the new resource will be invisible to the AI tools node even though the main Autotask node works fine.
Decommissioning note: The
toolresource andaiHelperresource withinAutotask.node.tsare legacy and will be removed in a future release. TheAutotaskAiTools.node.tsis the replacement. However,tool/execute.tsitself is not legacy — it is the shared executor that the new AI tools node depends on.
Add:
- •Import the execute function from the new resource module
- •Entry in the
RESOURCE_EXECUTORSmap using the node resource value (fromdefinitions.ts) as the key
Example:
// Import (add near other ticket-related imports)
import { executeTicketSecondaryResourceOperation } from '../ticketSecondaryResources/execute';
// RESOURCE_EXECUTORS entry (add in alphabetical position among ticket-related entries)
ticketSecondaryResource: executeTicketSecondaryResourceOperation,
The map key must match the value field from definitions.ts (the node resource key), not the entity resourceKey from entities.ts. These can differ when resourceKey is explicitly set (e.g. entity resourceKey: 'ticketSecondaryResources' plural vs node value ticketSecondaryResource singular).
6) AI Tools mapping check
The AI tools architecture auto-derives available resources and operations from entity metadata. The flow is:
AUTOTASK_ENTITIES (entities.ts)
↓
buildResourceOperationsMap() in resource-operations.ts
↓
RESOURCE_OPERATIONS_MAP
↓
AutotaskAiTools.node.ts (loadOptions + tool generation)
↓
ai-tools/tool-executor.ts → executeToolOperation() → RESOURCE_EXECUTORS
nodes/Autotask/constants/resource-operations.ts resolves key as:
const resourceKey = entity.resourceKey ?? lowerCamelCase(entity.name);
Validation checklist:
- •Entity is not excluded by
isAttachment/ excluded name patterns - •
resourceKeyresolves to expected map key - •Operation mapping is correct for supported operation types
- •Alias generation handles default key vs explicit key mismatch
- •
tool-surface.tscallsgetResourceOperations(entity.name)which normalises via aliases — confirm the alias chain resolves to the correctRESOURCE_OPERATIONS_MAPkey
Adding special/custom operations? Standard CRUD operations (get, getMany, create, update, delete, count) are auto-derived and need no manual AI tools wiring. But if you're adding a custom operation (e.g.
slaHealthCheck,searchByDomain) to a resource, there are 10+ additional mandatory touchpoints in the AI tools layer. Use theadd-autotask-special-operationskill and follow the full checklist at.docs/autotask/change-guidelines/ai-tools-special-operation-checklist.md. The most critical step is adding anormaliseOperation()case inai-tools/tool-executor.ts— without it, the operation silently fails at runtime.
7) README and CHANGELOG updates
CHANGELOG.md
- •Under the current version, add an
Addedbullet for the new resource - •Mention operation scope clearly (for query-only: Get/Get Many/Count)
- •Mention parent/child context where useful
README.md
- •Add the resource in the supported resources table
- •Keep resource table ordering consistent (alphabetical within the section)
- •Use concise, user-facing description
8) RESOURCE_ALIASES entry (when needed)
When the entity name in entities.ts is plural (e.g. ServiceLevelAgreementResults) but the node resource value in definitions.ts is singular (e.g. serviceLevelAgreementResult), the AI Tools mapping cannot resolve the resource automatically. Add a manual alias in constants/resource-operations.ts:
// In RESOURCE_ALIASES initialiser object servicelevelagreementresult: 'serviceLevelAgreementResults',
This is separate from the auto-generated aliases derived from resourceKey mismatches. Check whether normaliseResourceName(nodeResourceValue) resolves to the correct RESOURCE_OPERATIONS_MAP key; if not, add the alias.
Dual-scope entities (root + child endpoints)
Some entities can be accessed via both root endpoints and child endpoints (e.g. ServiceLevelAgreementResults has both /ServiceLevelAgreementResults/* and /ServiceLevelAgreements/{id}/Results/*).
When to use
- •The Autotask API exposes both root and child endpoints for the same entity
- •The parent entity may or may not be registered in
entities.ts
Rules
- •Never add an "Endpoint Scope" selector to the UI. Make the parent ID field optional and detect scope automatically.
- •If the parent entity is not in
entities.ts, do NOT usechildOf. Register the entity standalone and handle child routing inexecute.ts. - •In
execute.ts, determine scope with:typescriptconst parentId = getParentId(this, i); const isChildScope = parentId !== undefined;
- •Root scope → use base operation classes. Child scope → build URLs manually with
buildChildBasePath(). - •Add manual
executeChildEntityInfoOperationandexecuteChildFieldInfoOperationhelpers for child-scoped entity/field info.
Reference implementations
- •Without
childOf:nodes/Autotask/resources/serviceLevelAgreementResults/ - •With
childOf:nodes/Autotask/resources/ticketChangeRequestApprovals/
Quality gates
- • API operations match Swagger/docs (no unsupported operations)
- •
resourceKeyset when required - •
RESOURCE_ALIASESentry added if entity name plural/singular mismatch exists - •
definitions.tsordering remains correct - •
Autotask.node.tsimports/properties/switch all wired - •
tool/execute.tsimport andRESOURCE_EXECUTORSentry added - • AI Tools mapping produces expected operations (verify
RESOURCE_OPERATIONS_MAPkey resolves) - • No "Endpoint Scope" selector in description.ts — scope is auto-detected from parent ID
- •
README.mdandCHANGELOG.mdupdated - •
npx tsc --noEmitpasses
Known hazards
normaliseOperation() in ai-tools/tool-executor.ts
When adding any special/custom operation with a camelCase name, it must have an explicit case in normaliseOperation(). This function lowercases all input and selectively restores casing for known operations. If a new operation is not handled, it stays lowercase and silently fails every downstream comparison — no compiler or linter catches it.
See .docs/autotask/change-guidelines/ai-tools-special-operation-checklist.md for the full AI tools wiring checklist.
filtersFromTool parameter and getNodeParameter throws
The shared buildFiltersFromResourceMapper() helper in helpers/filter.ts accesses a filtersFromTool parameter that is only injected at runtime by the AI tool executor (tool/execute.ts). It does not exist in the node's property schema.
In newer n8n versions, getNodeParameter(name, index, fallback) throws "Could not get parameter" even when a fallback is supplied, if the parameter name is absent from the node schema. This was fixed by wrapping the access in try/catch in filter.ts.
Rule: Any shared helper code that reads parameters only available in the AI tool execution context must use try/catch, not rely on a fallback value. This affects all resources globally, not just new ones.
Notes
- •Prefer exact API naming for endpoint segments (
subnameand endpoint-specific keys) - •Keep changes minimal and aligned with established patterns in existing resources
- •Follow existing indentation style in this repo for touched files
- •The
tool/execute.tswiring is a separate concern fromAutotask.node.ts— both must be updated independently. Missing the executor entry means the main node works but the AI tools node silently fails to route to the resource. - •
tool/execute.tsis the shared executor backbone, not a legacy file. Do not confuse it with the legacytoolresource (which routes through it) or the legacyaiHelperresource — both of those resources are being decommissioned, buttool/execute.tsitself persists as the execution layer forAutotaskAiTools.node.ts. - •When implementing dual-scope entities, the
ServiceLevelAgreementResultsresource is the canonical reference for the pattern withoutchildOf, andTicketChangeRequestApprovalsis the reference for dual-scope withchildOf.