Skip to content

Working with tasks and tickets

Tasks represent planned work. Tickets represent inbound requests and reactive work. The public API lets integrations read and update both while preserving the permissions and state rules used by AgencyTitan.

Start with the API Quickstart for authentication, envelopes, pagination, errors, and rate limits. The examples below assume:

Terminal window
BASE_URL="https://api.agencytitan.com"

GET /v1/tasks returns task-grain rows. Several row fields, including status, assigned_to, due_date, priority_level, and start_date, describe the current stage.

Use first-class query parameters for common filters:

Terminal window
curl "$BASE_URL/v1/tasks?status_scope=active&client_ids=66666666-6666-4666-8666-666666666666&sort=due_date&order=asc&limit=50" \
--header "Authorization: Bearer $AGENCYTITAN_API_KEY" \
--header "Accept: application/json"

Useful filters include:

  • status_scope, statuses, assigned_to, due_date_from, and due_date_to for the current stage
  • process_status_scope, process_statuses, process_assigned_to, and process_due_date_from for the parent task
  • client_ids, process_definition_id, priority_level, and tags for task-level selection
  • filter_group for supported custom-field and nested conditions

Values within one array filter are combined with OR. Different filters are combined with AND. Resolve status, priority, and tag values with GET /v1/tasks/options instead of guessing tenant-configured values.

For assigned work at stage grain, use GET /v1/task-stages and filter by assigned_to.

Update current-stage status, assignment, or due date

Section titled “Update current-stage status, assignment, or due date”

POST /v1/tasks/manage is an action-enum composite for three same-risk updates. The required action selects one of:

  • update_status, with status
  • assign, with an assigned_to array that replaces the current-stage assignment
  • set_due_date, with an ISO 8601 due_date or null to clear it

For example:

Terminal window
curl --request POST "$BASE_URL/v1/tasks/manage" \
--header "Authorization: Bearer $AGENCYTITAN_API_KEY" \
--header "Content-Type: application/json" \
--data '{
"action": "set_due_date",
"task_id": "11111111-1111-4111-8111-111111111111",
"due_date": "2026-08-15T17:00:00Z"
}'

Use the status values returned by GET /v1/tasks/options for update_status.

POST /v1/tasks/update-fields patches custom fields by registered field key:

Terminal window
curl --request POST "$BASE_URL/v1/tasks/update-fields" \
--header "Authorization: Bearer $AGENCYTITAN_API_KEY" \
--header "Content-Type: application/json" \
--data '{
"task_id": "11111111-1111-4111-8111-111111111111",
"field_values": {
"campaign_url": "https://example.com/campaign",
"estimated_hours": 8
}
}'

The operation rejects system task fields. Use the dedicated task or stage operation for status, assignment, and dates. Valid custom fields are attempted independently, and the response reports each field as applied or rejected; inspect every result instead of treating HTTP 200 as proof that every field changed.

POST /v1/tasks/transition-stage moves a task only along a declared transition from its current stage:

Terminal window
curl --request POST "$BASE_URL/v1/tasks/transition-stage" \
--header "Authorization: Bearer $AGENCYTITAN_API_KEY" \
--header "Content-Type: application/json" \
--data '{
"task_id": "11111111-1111-4111-8111-111111111111",
"target_stage_id": "22222222-2222-4222-8222-222222222222",
"reason": "Client approved the deliverable"
}'

An undeclared target, unmet dependency, or missing required field returns a conflict without changing the task. The optional reason is invocation context returned to the caller; it is not stored on the task.

GET /v1/tickets supports search, resource-specific sorting, and filters for status, client, assignee, department, inbox, priority, tags, SLA state, and creation time.

Create a ticket with POST /v1/tickets. subject is required; description, client_id, assigned_to, and priority are optional.

Use PATCH /v1/tickets/{id} to replace provided fields only. It can change status, priority, client link, and the full assignee set. An empty assigned_to array or null clears assignment.

The composite POST /v1/tickets/manage can create or update a ticket and can add a safe internal note to an existing ticket. Its comment field never queues an outbound reply.

POST /v1/tickets/{id}/assign supports two actions:

  • manual replaces the full assignee set. An empty array unassigns the ticket. You can also provide target_inbox_id to move and assign atomically and reason for audit context.
  • smart runs AgencyTitan’s live assignment scorer. Do not send manual-assignment fields with this action.
Terminal window
curl --request POST "$BASE_URL/v1/tickets/99999999-9999-4999-8999-999999999999/assign" \
--header "Authorization: Bearer $AGENCYTITAN_API_KEY" \
--header "Content-Type: application/json" \
--data '{
"action": "manual",
"assigned_to": ["33333333-3333-4333-8333-333333333333"],
"reason": "Route to the web support team"
}'

GET /v1/ticket-messages requires ticket_id and returns inbound and outbound messages plus internal notes. The default order is chronological. Use is_internal_note as the stable discriminator.

Terminal window
curl "$BASE_URL/v1/ticket-messages?ticket_id=99999999-9999-4999-8999-999999999999&order=asc" \
--header "Authorization: Bearer $AGENCYTITAN_API_KEY" \
--header "Accept: application/json"

Attachment references are metadata only. Follow Files and attachments to obtain a download URL.

GET /v1/ticket-messages/{id} also requires the parent ticket_id query parameter because conversation-item reads are ticket-scoped.

These capabilities are not yet fully exposed by the current OpenAPI document:

  • Task creation. The existing tasks.manage operation intentionally omits creation. Live task creation can apply billing and deferred-creation rules and can optionally advance a stage, so the planned operation is approval-gated instead of being treated as a simple insert.
  • Outbound ticket sending. Conversation reads, internal notes, and reply drafts are available now: POST /v1/ticket-drafts/save creates or updates a draft, and the ticket-drafts tag includes read and review-queue operations. A saved draft always keeps draft delivery status; the operation that actually sends an outbound message is still rolling out.
  • Linking tasks to tickets. Ticket and task records can be managed independently, but no public link or unlink operation is in the current reference.

Do not guess route names or request bodies for rolling-out operations. Wait until an operation appears in the generated API reference and the current OpenAPI document before calling it.