# Work tracking

> Raise Jira tickets from incidents, requests, drift findings and attention signals, read their status, and manage tracker connections

Source: https://www.apitraffic.io/docs/api-reference/work-items

The work tracking API is what the **Create Jira issue** button uses. See [Work tracking](https://www.apitraffic.io/docs/work-tracking) for how it behaves. Every path is scoped to an account, and an account can only reach its own records.

**People, not tokens.** A ticket is created with the caller's own connected Jira account, so these endpoints need a signed-in person or an MCP token tied to one. An account API token that isn't a person gets `403 WORK_ITEM_NEEDS_USER` when it tries to raise a ticket.

**Permissions.** Any member can raise, read and unlink tickets and connect their own tracker account. Changing a destination's settings, listing everyone's tracker accounts and revoking another member's are for owners and admins. Scoped tokens need `integrations:write` and `traffic:read` to raise tickets, and `integrations:read` to read them.

**Subjects.** `subjectType` is `incident`, `request`, `drift_finding` or `attention_signal`; `subjectSid` is its sid.

All examples use `Authorization: Bearer `.

## Destinations

`GET https://api.apitraffic.io/v1/accounts/{accountSid}/workItems/destinations`

The ticket destinations (Jira channels) the account has, with their one-click settings and whether the caller's own Jira account is connected to each.

- **bucketSid (query, string)**:
  Answer the one-click default for this bucket in `defaultChannelSid`

- **lastUsed (query, boolean)**:
  Also answer `lastUsed`

- **records (object[])**:
  `sid`, `name`, `type`, `status`, `deployment` (`cloud` or `datacenter`), `site`, `projectKey`, `issueType`, `settings` and `connected`

- **defaultChannelSid (string)**:
  The destination one click uses, or null when the caller must choose

- **lastUsed (object)**:
  With `lastUsed=true`: the `channelSid` and `projectKey` of the newest ticket the caller created in this bucket (unlinked ones included, failed ones not; `projectKey` is null when it used the destination's own), or null. The review dialog starts there.

`PATCH https://api.apitraffic.io/v1/accounts/{accountSid}/workItems/destinations/{channelSid}`

Change a destination's one-click settings. Owners and admins only.

- **oneClick (body, boolean)**:
  Whether one-click tickets may use it

- **defaultFor (body, string | string[] | null)**:
  `"account"`, a list of bucket sids, or null

- **issueTypeBySubject (body, object)**:
  An issue type name per subject type, for example `{"incident": "Bug"}`

- **shareLinks (body, object)**:
  `enabled` (boolean), `expiresIn` (`7d`, `30d`, `90d` or `never`) and `includeBodies` (boolean, false for metadata-only links)

`GET https://api.apitraffic.io/v1/accounts/{accountSid}/workItems/destinations/{channelSid}/schema`

The projects, issue types, priorities and required fields of a destination, as the caller's own Jira account sees them.

- **projectKey (query, string)**:
  Default: the destination's project

- **issueTypeId (query, string)**:
  Whose required fields to return. Default: the destination's issue type

- **subjectType (query, string)**:
  `incident`, `request`, `drift_finding` or `attention_signal`. Without `issueTypeId`, start on the issue type the destination settings give this kind of subject

## Tickets

`POST https://api.apitraffic.io/v1/accounts/{accountSid}/workItems/preview`

The ticket as it would be created, open tickets for the same problem (`recurring`), the tickets already linked (`existing`), and whether the caller is connected.

- **subjectType (body, string, required)**:

- **subjectSid (body, string, required)**:

- **channelSid (body, string)**:
  Default: the one-click destination for the subject's bucket

`POST https://api.apitraffic.io/v1/accounts/{accountSid}/workItems`

Raise a ticket, or add the subject to an open ticket with `appendTo`. Repeating the same request answers the existing link instead of creating another ticket.

- **subjectType (body, string, required)**:

- **subjectSid (body, string, required)**:

- **channelSid (body, string)**:
  Default: the one-click destination for the subject's bucket

- **appendTo (body, string)**:
  The sid of an open ticket link (from `recurring` in the preview) to add this subject to as a comment

- **overrides (body, object)**:
  `title`, `projectKey`, `issueType` or `issueTypeId`, `priority`, `assignee` (a Jira account id), `labels`, `components` and `fields` (custom fields by `customfield_` id)

- **includeShare (body, boolean)**:
  False leaves out the share link

- **nonce (body, string)**:
  A new value raises another ticket for a subject that already has one

| Status | Meaning |
|---|---|
| `201` | Created (`outcome: created`) or added (`outcome: appended`) |
| `200` | Already linked (`outcome: existing`) |
| `202` | Still being created or checked. Poll `GET /workItems/{sid}`: its `outcome` may become `found` when an earlier attempt turned out to have reached Jira |
| `403 TRACKER_PERMISSION_DENIED` | Jira refused this issue for the caller's account |
| `403 WORK_ITEM_NEEDS_USER` | The caller is not a person |
| `404 TRACKER_ITEM_NOT_FOUND` | The `appendTo` issue is not visible to the caller's Jira account |
| `409 TRACKER_ACCOUNT_REQUIRED` / `TRACKER_ACCOUNT_EXPIRED` | Connect or reconnect the caller's Jira account |
| `422 TRACKER_FIELD_ERRORS` | Jira asked for fields; `data.fieldErrors` names them |

`GET https://api.apitraffic.io/v1/accounts/{accountSid}/workItems`

The tickets linked to a subject.

- **subjectType (query, string, required)**:

- **subjectSid (query, string, required)**:

`GET https://api.apitraffic.io/v1/accounts/{accountSid}/workItems/{workItemSid}`

One ticket link. Its status is read from Jira again when it is more than 5 minutes old.

- **refresh (query, boolean)**:
  Read the status now

A link has `sid`, `status` (`creating`, `checking`, `linked`, `failed` or `unlinked`), `kind` (`created` or `appended`), `externalId` (the issue key), `url`, `externalStatus`, `statusCategory` (`todo`, `in_progress` or `done`), `statusUnknown`, `duplicates`, `failedReason`, `shareSid` and timestamps.

`DELETE https://api.apitraffic.io/v1/accounts/{accountSid}/workItems/{workItemSid}`

Unlink a ticket from its subject. The Jira issue is left alone.

## Tracker accounts

`GET https://api.apitraffic.io/v1/accounts/{accountSid}/me/trackerAccounts`

The caller's own connected Jira accounts. Tokens are never returned.

`POST https://api.apitraffic.io/v1/accounts/{accountSid}/me/trackerAccounts`

Connect the caller's Jira account for a destination. For Jira Cloud the answer is `{"connected": false, "authorizeUrl": "…"}`: open the URL in a browser to sign in to Atlassian, then finish with `complete` below. For Jira Data Center, send the caller's personal access token in `token`; it is checked with Jira first.

- **channelSid (body, string, required)**:

- **token (body, string)**:
  Jira Data Center personal access token

`POST https://api.apitraffic.io/v1/accounts/{accountSid}/me/trackerAccounts/complete`

Finish a Jira Cloud connection. After the Atlassian sign-in, the browser lands on ApiTraffic with a one-time `code`, and the app sends it here in the signed-in member's own session. Only the member who started the connection can finish it, within 10 minutes; a sign-in link forwarded to someone else can't attach their Atlassian account to yours.

- **code (body, string, required)**:

`DELETE https://api.apitraffic.io/v1/accounts/{accountSid}/me/trackerAccounts/{trackerAccountSid}`

Disconnect one of the caller's accounts. Its tokens are deleted at once.

`GET https://api.apitraffic.io/v1/accounts/{accountSid}/trackerAccounts`

Every member's connected accounts, each with the member's `memberName` and `memberEmail` (null when that user no longer exists). Owners and admins only.

`DELETE https://api.apitraffic.io/v1/accounts/{accountSid}/trackerAccounts/{trackerAccountSid}`

Revoke a member's account. Owners and admins only. Its tokens are deleted at once.
