Skip to main content
Every ticket has at most one assignee: a single user or a single user group. Assignment decides who can take transitions permitted to ticket.assignee or ticket.assignee_group_member, and who receives notifications addressed to the assignee role. Set these before running the examples:
Every request sends Authorization: Bearer $TOKEN and ORG-ID: $ORG_ID. Successful responses use the envelope {"ok": 1, "data": {...}}.

Assignment

User vs group

The two are mutually exclusive:
  • Send exactly one of them. Sending both (or neither, on /assign) returns 400 “exactly one of assigned_user_id or assigned_group_id is required”.
  • Assigning a user clears assigned_group_id. Assigning a group clears assigned_to.

Assign when you create a ticket

Add assigned_user_id or assigned_group_id to the create body. The ticket is created and assigned in one step.
Creating with an assignee raises both Ticket Created and Ticket Assigned notifications.

Assign and unassign an existing ticket

Both return {"ok": 1, "data": {"ok": true}}.
Repeating an assignment that is already in place, or unassigning a target that is already empty, succeeds without changing anything and sends no notification.
The Console has no assign or unassign control. Its Assign users option on the create form adds user tags to the ticket; it does not set assigned_to. See Console.

Group members claiming a ticket

There is no separate claim endpoint. A member claims a group ticket by assigning it to themselves:
  1. Assign the ticket to a group (for example, a maintenance shift).
  2. A member of that group calls /assign with their own user ID as assigned_user_id.
  3. The ticket moves from the group to that user: assigned_to is set and assigned_group_id is cleared.
Any Project member can call /assign, so the platform does not check that the claimer belongs to the group. In Slack, Microsoft Teams, and Telegram, notification cards for Ticket Created, Ticket Transitioned, and Ticket Unassigned include an Assign to me button. It assigns the ticket to the Golain user linked to the chat identity who clicked, and requires that user to be a member of the Organization and Project.

How assignment affects permits

Transitions declare who may fire them with permit. These permits read assignment:
Claiming a group ticket clears assigned_group_id. After a claim, ticket.assignee_group_member matches nobody and only the claimer matches ticket.assignee. If other group members still need to move the ticket, also permit ticket.assignee or a project permission such as project.member on those transitions.
A workflow where any member of the assigned group can start and finish work:
See Workflows for the full permit list.

List tickets by assignee

Filter GET /projects/{project_id}/tickets with: Combine with other filters such as system_class or labels.
Tickets a group member has claimed no longer match assigned_group_id. To find them, filter by assigned_to.

Notifications for tickets

Ticket notifications use notification subscriptions. A subscription selects events, a channel (email, Slack, Microsoft Teams, Telegram, Twilio SMS, or Twilio WhatsApp), and who receives each message.

Ticket event types

Ticket deletion is not a notifiable event. Ticket Due Soon and Ticket Due fire only for tickets with a top-level due_at on a workflow that defines due_policy. See Automation. To list every notifiable event with its roles, call the registry:
data.events[] items include key, display_name, description, card_fields, default_actions, and recipient_roles.

What a notification includes

Where subscriptions live

Each scope supports GET (list), POST (create), PATCH /{id}, DELETE /{id}, and POST /{id}/test. The delivery log and single-subscription GET are on the organization path: GET /organizations/notification-subscriptions/{id} and /{id}/deliveries. They work for subscriptions of any scope.

Subscription fields

On PATCH, omitted fields stay unchanged. workflow_def_ids: [] clears the workflow filter, and recipient_roles: [] returns to a fixed-destination subscription.

Recipient roles

Rules enforced when you save:
  • Every role you list must be declared by every subscribed event. For example, assignee with Ticket Unassigned returns 400 “role “assignee” is not declared by ticket.ticket.unassigned.v1”.
  • recipient_roles works only with channel_ref.kind: "email".
  • An email subscription with no to and no recipient_roles is rejected.
  • $-placeholders in to (such as $assignee_email) are no longer supported and are rejected.
Each resolved person gets their own message. A person already listed in to is not mailed twice.
The assignee role reads only assigned_to and assigned_group_id. Users added through user tags (including the Console’s Assign users option) are not notified as assignees. Use the /assign route if those people must receive assignee notifications.

Create a subscription for ticket events

1

Pick the workflow

Find the workflow_def_id of the workflow you want, for example maintenance-request, from GET /projects/{project_id}/ticket-workflows.
2

Create the subscription

This project subscription emails the assignee when a ticket is assigned or changes state, but not the person who made the change:
The API returns 201 with the subscription in data:
3

Add a fixed list for closures (optional)

A second subscription can email a fixed address whenever a ticket closes:
In the Console, you create fixed-destination subscriptions from each channel’s integration page with Add subscription. Recipient roles, notify_actor, group_assignee_mode, and workflow_def_ids are API-only today.

Group assignments and claims

Pair Ticket Assigned with Ticket Transitioned on an assignee subscription:
  1. While the ticket is assigned to a group, each transition notifies every group member except the one who moved it (with notify_actor: false).
  2. When a member claims the ticket, Ticket Assigned names them as the assignee. They are also the actor, so they are not notified of their own claim.
  3. From then on, assignee resolves to that person only. The rest of the group stops receiving updates for the ticket.
With group_assignee_mode: none, a group assignment notifies nobody and writes one suppressed row to the delivery log.

Delivery log and suppression

Each row has event_key, event_id, status, attempt_count, error_detail, recipient_user_id, recipient_role, recipient_display, recipient_via_group_id, recipient_via_group_name, and timestamps. Fixed-destination rows have recipient_user_id: null. Email addresses are never returned: recipient_contact is null and addresses in error_detail are redacted. status is pending, delivered, retrying, failed, or suppressed. A suppressed row is a normal outcome, not a failure. error_detail gives the reason, for example: Only users with manage integrations on the subscription’s Organization or Project see delivery rows. Others get an empty list. In the Console, open a subscription’s Delivery log from the subscription list.

Test sends

POST …/notification-subscriptions/{id}/test sends a test message and waits up to 10 seconds for the result. Success returns {"ok": 1, "data": {"delivered": true}}.
A test needs a fixed destination. Role recipients resolve from a real ticket event, so testing a role-only email subscription returns 400 “test send needs a fixed channel_ref.to”. Add an address to channel_ref.to to test it. Disabled or suspended subscriptions also return 400.

Next steps