Skip to main content

Async Python client for the Autotask REST API

Project description

autotask-client

Async Python client for the Autotask REST API. Handles zone discovery, authentication, rate limiting, pagination, and all 211 entity types out of the box.

Install

pip install autotask-client

Quick Start

import asyncio
from autotask import AutotaskClient, AutotaskConfig, EntityManager
from autotask.models import Ticket, Company
from autotask.query import Q

async def main():
    config = AutotaskConfig(
        username="user@example.com",
        secret="your-api-secret",
        integration_code="your-integration-code",
    )
    async with AutotaskClient(config) as client:
        em = EntityManager(client)

        # Query tickets by status
        tickets = await em.query(Ticket, Q(status=8))

        # Get a single company
        company = await em.get(Company, 12345)

        # Create a ticket
        ticket = Ticket(
            title="Server down",
            companyID=12345,
            status=1,
            priority=1,
        )
        created = await em.create(ticket)

        # Update with PATCH (only specified fields change)
        updated = await em.update(Ticket(id=created.id, status=5))

        # Query any of the 211 entity types by name
        items = await em.query("ConfigurationItems", Q(isActive=True))

asyncio.run(main())

Configuration

Environment Variables

export AUTOTASK_USERNAME="user@example.com"
export AUTOTASK_SECRET="your-secret"
export AUTOTASK_INTEGRATION_CODE="your-code"

# Optional
export AUTOTASK_API_URL="https://webservicesX.autotask.net/atservicesrest"
export AUTOTASK_RESOURCE_ID="12345"
config = AutotaskConfig.from_env()

AUTOTASK_SECRET_B64 is also supported for platforms that mangle special characters (base64-encoded secret).

If AUTOTASK_API_URL is not set, the client automatically discovers your zone via the Autotask zone information endpoint and caches it to ~/.cache/autotask/zone.json.

Query DSL

Django-inspired filter syntax:

from autotask.query import Q

Q(status=1)                        # eq (default)
Q(id__gt=100)                      # greater than
Q(title__contains="server")        # contains
Q(status__in=[1, 5, 8])            # in list
Q(priority__gte=2, status__noteq=5)  # multiple filters (AND)

# UDF (User Defined Field) filters — one per query (API limitation)
Q.udf(myCustomField__contains="value")

# Combine with &
filters = Q(status=1) & Q(companyID=123)

Supported operators: eq, noteq, gt, gte, lt, lte, beginsWith, endsWith, contains, exist, notExist, in, notIn

Entity Models

Hand-crafted Pydantic models for common entities with typed fields and validation:

Model API Entity
Ticket Tickets
Company Companies
Project Projects
Task Tasks (child of Project)
Resource Resources
TimeEntry TimeEntries
TicketNote TicketNotes (child of Ticket)
ProjectNote ProjectNotes (child of Project)
TaskNote TaskNotes (child of Task)

All models use extra="allow" to preserve unmodeled fields during round-trips.

For entity types without a hand-crafted model, pass the entity name as a string — the manager returns raw dicts:

items = await em.query("Contacts", Q(isActive=True))

CLI

Output is JSON by default (designed for scripting/AI consumption). Use --table for human-readable output.

Entity Commands

Full CRUD for the core entity types:

# Tickets
autotask tickets list --status 8 --limit 10
autotask tickets get 12345
autotask tickets create --title "Fix printer" --company-id 123
autotask tickets update 12345 --status 5 --priority 1
autotask tickets delete 12345

# Companies
autotask companies list --limit 10
autotask companies get 12345
autotask companies create --name "Acme Corp"
autotask companies update 12345 --name "Acme Inc"

# Projects
autotask projects list --limit 10
autotask projects get 12345

# Tasks (queried via projectID filter, not a child entity)
autotask tasks list --project 12345
autotask tasks get 67890
autotask tasks create --project-id 12345 --title "Migrate database"
autotask tasks update 67890 --status 5

# Time entries
autotask time-entries list --limit 10
autotask time-entries create --resource-id 456 --ticket-id 12345 --hours 1.5
autotask time-entries update 67890 --hours 2.0

# Resources (read-only)
autotask resources list --limit 10
autotask resources get 12345

Notes (Child Entities)

Notes are children of their parent entity — the parent ID is required:

# Ticket notes
autotask ticket-notes list 12345          # notes on ticket 12345
autotask ticket-notes get 12345 67890     # note 67890 on ticket 12345
autotask ticket-notes create 12345 --title "Update" --description "Fixed the issue"

# Project notes
autotask project-notes list 12345
autotask project-notes create 12345 --title "Status" --description "On track"

# Task notes
autotask task-notes list 67890
autotask task-notes create 67890 --title "Progress" --description "50% done"

Generic Commands

Work with any of the 211 Autotask entity types:

# Query any entity
autotask query ConfigurationItems isActive=true --limit 20
autotask query Contacts firstName=John --limit 10

# Get/create/update/delete by entity type
autotask get Tickets 12345
autotask create Tickets --fields '{"title":"Test","companyID":123,"status":1,"priority":2}'
autotask update Tickets 12345 --fields '{"status":5,"priority":1}'
autotask delete Tickets 12345

# Child entities use --parent-id
autotask get TicketNotes 67890 --parent-id 12345

Metadata & Utilities

autotask info Tickets           # Entity capabilities (canCreate, canQuery, etc.)
autotask fields Tickets         # Field definitions, types, required flags
autotask picklist Tickets status  # Resolve picklist IDs to labels
autotask whoami                 # Authenticated user's resource record
autotask config                 # Show current configuration (no secrets)

# Table output
autotask --table tickets list --limit 5

MCP Server

The package includes an MCP server for LLM tool use. Install with the mcp extra:

pip install autotask-client[mcp]

Tools

Tool Description
autotask_query Query any entity with filters and pagination
autotask_get Get a single entity by ID
autotask_create Create an entity from field values
autotask_update PATCH update (only specified fields change)
autotask_delete Delete an entity by ID
autotask_entity_info Entity capabilities (canCreate, canQuery, etc.)
autotask_field_info Field definitions, types, picklist references
autotask_resolve_picklist Resolve picklist field to {id: label} mapping
autotask_whoami Authenticated user's resource record

Claude Desktop Configuration

Add to your claude_desktop_config.json:

{
  "mcpServers": {
    "autotask": {
      "command": "autotask-mcp",
      "env": {
        "AUTOTASK_USERNAME": "user@example.com",
        "AUTOTASK_SECRET": "your-api-secret",
        "AUTOTASK_INTEGRATION_CODE": "your-integration-code"
      }
    }
  }
}

Or if installed via pipx:

{
  "mcpServers": {
    "autotask": {
      "command": "pipx",
      "args": ["run", "--spec", "autotask-client[mcp]", "autotask-mcp"],
      "env": {
        "AUTOTASK_USERNAME": "user@example.com",
        "AUTOTASK_SECRET": "your-api-secret",
        "AUTOTASK_INTEGRATION_CODE": "your-integration-code"
      }
    }
  }
}

Claude Code Configuration

Add to your .mcp.json:

{
  "mcpServers": {
    "autotask": {
      "command": "autotask-mcp",
      "env": {
        "AUTOTASK_USERNAME": "user@example.com",
        "AUTOTASK_SECRET": "your-api-secret",
        "AUTOTASK_INTEGRATION_CODE": "your-integration-code"
      }
    }
  }
}

API Behavior

Things this library handles so you don't have to:

  • Zone discovery — Autotask routes tenants to different datacenters. The client discovers and caches the correct URL automatically.
  • Auth via headersUserName, Secret, ApiIntegrationCode on every request.
  • Rate limiting — Progressive throttling at 50% and 75% of the 10k req/hour shared limit. Reads usage from response headers.
  • Paginationquery_all() automatically paginates using id > last_id (max 500 per page).
  • Retry — Transient failures (connection errors, timeouts) retry with exponential backoff (3 attempts).
  • Concurrency — Semaphore limits to 3 concurrent requests per endpoint.
  • Error mapping — 401 and 500-with-auth-pattern both raise AutotaskAuthError. 404 raises AutotaskNotFoundError. The API returns {item: null} instead of 404 for missing entities — this is handled correctly.

Requirements

  • Python 3.12+
  • httpx, pydantic, click, tenacity

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

autotask_client-0.3.1.tar.gz (52.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

autotask_client-0.3.1-py3-none-any.whl (30.9 kB view details)

Uploaded Python 3

File details

Details for the file autotask_client-0.3.1.tar.gz.

File metadata

  • Download URL: autotask_client-0.3.1.tar.gz
  • Upload date:
  • Size: 52.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.3

File hashes

Hashes for autotask_client-0.3.1.tar.gz
Algorithm Hash digest
SHA256 ed5d2c8b613d320e58e4dae9460c9a01ae7d85f393b215980ed0a976cac183c1
MD5 0c046986924da39f17f3f5f7378bc593
BLAKE2b-256 2f2a3d79b847600d97c3ea4658668db32838c78d6a96f4892026c997abbdf9c5

See more details on using hashes here.

File details

Details for the file autotask_client-0.3.1-py3-none-any.whl.

File metadata

File hashes

Hashes for autotask_client-0.3.1-py3-none-any.whl
Algorithm Hash digest
SHA256 ec128a20aa685c6bed8b1c55dc8aa3663fed524ead5db1adc9d96cfd716e08ea
MD5 38dbfea8c116a228c52975788441da86
BLAKE2b-256 fcde93b21e7b8924ca7431150d3ed8d7a4d3ae0ade760db34df7314b7df09ddd

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page