Autotask Time Entries — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited Autotask Time Entries (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
Time entries are the foundation of MSP billing and resource utilization tracking. Every hour logged against tickets, projects, and contracts flows through the time entry system. This skill covers comprehensive time management including billing calculations, approval workflows, budget validation, and utilization analytics.
autotask-ticket-notes-attachments for ticket charges.
autotask-expenses.autotask-billing.
autotask-contracts.
Based on the Autotask API, these are the time entry approval statuses:
| Status ID | Name | Description | Business Logic |
|---|---|---|---|
| 0 | DRAFT | Entry created but not submitted | Editable by resource |
| 1 | SUBMITTED | Submitted for approval | Locked, awaiting manager review |
| 2 | APPROVED | Manager approved entry | Included in billing cycle |
| 3 | REJECTED | Manager rejected entry | Returned for correction |
DRAFT (0) ────────────────> SUBMITTED (1)
│
┌───────────┴───────────┐
▼ ▼
APPROVED (2) REJECTED (3)
│ │
▼ ▼
Billing Cycle Back to DRAFTWorkflow Rules:
The fields you touch on nearly every call:
| Group | Key fields |
|---|---|
| Core | id, resourceID, ticketID, projectID, taskID, contractID |
| Time | dateWorked (YYYY-MM-DD), hoursWorked, startDateTime, endDateTime |
| Billing | isBillable, billingCodeID, contractID |
| Rate | hourlyRate, roleID, internalBillingCodeID |
| Approval | approveAndPostDate, approvalStatus |
| Description | summaryNotes (client-visible), internalNotes |
A time entry requires either a ticketID or a projectID — never neither, and never both.
See references/fields.md for the complete field reference.
Billing rates are determined in this order:
The first match wins; a contract rate silently overrides a resource's own rate, which is a common source of "wrong invoice amount" reports.
See references/examples.md for the rate-resolution, billing-amount, and billability-determination implementations.
Certain conditions automatically require manager approval:
| Condition | Requires Approval | Reason |
|---|---|---|
| Billable time | Yes | Financial impact |
| Hours > 8 | Yes | Overtime review |
| Weekend work | Yes | Policy compliance |
| Holiday work | Yes | Policy compliance |
| Exceeds budget | Yes | Cost control |
See references/examples.md for the requiresApproval implementation.
Before posting time, check both the project's hour budget and the contract's block-hour or retainer limit — they are tracked separately and either can be exceeded independently. Crossing 90% of a project budget flips the entry into requiring manager approval.
See references/examples.md for the project-budget and contract-limit check implementations.
| Metric | Target | Good | Excellent |
|---|---|---|---|
| Utilization Rate | 65% | 70-75% | 80%+ |
| Average Daily Hours | 6.5h | 7h | 7.5h |
| Approval Turnaround | 24h | 8h | 4h |
| Entry Accuracy | 95% | 98% | 99%+ |
See references/examples.md for the utilization-rate calculation.
| Purpose | Call |
|---|---|
| Create entry | POST /TimeEntries |
| Query entries | POST /TimeEntries/query with a filter array |
| Submit for approval | PATCH /TimeEntries/{id} setting the approval field |
| Approve / reject | PATCH /TimeEntries/{id} (approver credentials required) |
See references/api.md for the full create/query request bodies and the submit, approve, and reject patterns.
Standard MSP practice is to round time to the nearest quarter hour:
function roundToQuarterHour(hours) {
return Math.round(hours * 4) / 4;
}
// Examples:
// 1.12 → 1.0
// 1.13 → 1.25
// 1.38 → 1.5
// 1.63 → 1.75
// 1.88 → 2.0| Work Type | Minimum | Rationale |
|---|---|---|
| Remote Support | 0.25h (15 min) | Quick remote fixes |
| Phone Call | 0.25h (15 min) | Brief calls |
| On-Site Visit | 1.0h (60 min) | Travel overhead |
| Emergency/After Hours | 1.0h (60 min) | Premium rate |
If no date is provided, default to the current date:
function setDefaultDate(timeEntry) {
if (!timeEntry.dateWorked) {
timeEntry.dateWorked = new Date().toISOString().split('T')[0];
}
return timeEntry;
}// Get all draft entries for the week
const weekEntries = await queryTimeEntries({
filter: [
{field: 'resourceID', op: 'eq', value: currentResourceId},
{field: 'dateWorked', op: 'between', value: [weekStart, weekEnd]},
{field: 'approvalStatus', op: 'eq', value: 0}
]
});
// Submit all for approval
for (const entry of weekEntries) {
await updateTimeEntry(entry.id, { approvalStatus: 1 });
}// Get pending approvals for my team
const pendingApprovals = await queryTimeEntries({
filter: [
{field: 'approvalStatus', op: 'eq', value: 1},
{field: 'dateWorked', op: 'gte', value: lastWeekStart}
],
includeFields: ['Resource.firstName', 'Resource.lastName', 'Ticket.title']
});| Code | Message | Resolution |
|---|---|---|
| 400 | TicketID or ProjectID required | Provide either ticket or project |
| 400 | Invalid hours value | Hours must be positive decimal |
| 400 | Future date not allowed | Date cannot be in future |
| 401 | Unauthorized | Verify API credentials |
| 403 | Cannot modify approved entry | Entry is locked after approval |
| 409 | Entry already submitted | Cannot edit while pending |
| Error | Cause | Fix |
|---|---|---|
| ResourceID required | Missing technician | Add resourceID field |
| Invalid dateWorked | Date format wrong | Use YYYY-MM-DD format |
| Hours exceed 24 | Too many hours | Check hour calculation |
| Missing summary | No description | Add summaryNotes |
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.