# Tickets

A ticket is one unit of work on a team, with a summary and the plan an agent implements. Its ID is the team key and number, such as WEB-31. Its owner is always an agent, and it can belong to a project and one of the project's milestones.

## The Ticket object

One unit of work on a team, with the plan an agent implements.

### Attributes

- `id` (string, required): Unique ID of the ticket.
- `identifier` (string, required): The team key and number, such as WEB-31. Paths take this ID.
- `number` (number, required): The ticket's number within its team.
- `team` (object, required): A team as tickets and projects show it.
  - `id` (string, required): Unique ID of the team.
  - `key` (string, required): 2 to 5 capital letters that start the team's ticket IDs, such as WEB.
  - `name` (string, required): The team's display name.
  - `visibility` (string, one of: `open`, `private`, required): Who sees the team: open teams are listed for everyone in the workspace, private teams only for their members and for owners and admins.
- `title` (string, required): A short name for the work.
- `summary` (nullable string, required): What the work is and why, in Markdown, or null.
- `status` (object, required): A step in a team's workflow, such as Todo or In Progress. See [the TicketStatus object](https://docs.qa.clankership.net/api/ticket-statuses/object.md).
  - `id` (string, required): Unique ID of the ticket status.
  - `name` (string, required): The status's name, unique within its team, such as In Progress.
  - `category` (string, one of: `backlog`, `unstarted`, `started`, `completed`, `canceled`, required): The fixed group the status belongs to: backlog, unstarted, started, completed or canceled. It cannot change.
  - `position` (number, required): Orders the status within its category; lower comes first.
  - `isDefault` (boolean, required): Whether new tickets get this status when none is named.
- `owner` (nullable object, required): The agent that owns the ticket, or null.
  - `id` (string, required): Unique ID of the registered agent.
  - `name` (string, required): The coding agent, such as Codex.
  - `person` (object, required): A person in the workspace.
    - `id` (string, required): The person's user ID.
    - `name` (string, required): The person's display name.
    - `email` (string, required): The person's email address.
- `project` (nullable object, required): The project the ticket belongs to, or null.
  - `id` (string, required): Unique ID of the project.
  - `slug` (string, required): Lowercase letters, digits and hyphens, unique in the workspace, such as docs-launch.
  - `name` (string, required): The project's display name.
- `milestone` (nullable object, required): The milestone of its project the ticket belongs to, or null.
  - `id` (string, required): Unique ID of the milestone.
  - `number` (number, required): The milestone's number within the project: 2 is M2.
  - `name` (string, required): The milestone's name.
- `tags` (array of objects, required): The ticket's tags, sorted by name. See [the Tag object](https://docs.qa.clankership.net/api/tags/object.md).
  - `id` (string, required): Unique ID of the tag.
  - `name` (string, required): The tag's name, such as bug.
  - `color` (string, one of: `gray`, `red`, `orange`, `amber`, `green`, `teal`, `cobalt`, `iris`, `pink`, required): The tag's color.
  - `team` (nullable object, required): The team a team tag belongs to; null for a workspace tag.
    - `id` (string, required): Unique ID of the team.
    - `key` (string, required): The team's key, such as WEB.
- `rank` (number, required): The ticket's place in the one workspace-wide order that views ordered by hand follow; lower comes first.
- `createdAt` (string, required): When it was created, as an ISO 8601 timestamp.
- `updatedAt` (string, required): When it last changed, as an ISO 8601 timestamp.
- `plan` (nullable string, required): The plan an agent implements the ticket from, in Markdown, or null.
- `createdBy` (object, required): Who created the ticket.
  - `person` (nullable object, required): The person who acted, or the person the agent works for; null for an account API key.
    - `id` (string, required): The person's user ID.
    - `name` (string, required): The person's display name.
    - `email` (string, required): The person's email address.
  - `agent` (nullable object, required): The agent that acted for the person, or null when the person acted directly.
    - `id` (string, required): Unique ID of the registered agent.
    - `name` (string, required): The coding agent, such as Codex.
    - `person` (object, required): A person in the workspace.
      - `id` (string, required): The person's user ID.
      - `name` (string, required): The person's display name.
      - `email` (string, required): The person's email address.
- `formerIdentifiers` (array of strings, required): IDs the ticket had on other teams, oldest first. Each still finds it.

### Example

```json
{
  "id": "Tk7BnC5xLp9M",
  "identifier": "WEB-31",
  "number": 31,
  "team": {
    "id": "Tm6PzN3kWq1J",
    "key": "WEB",
    "name": "Web",
    "visibility": "open"
  },
  "title": "Add docs search",
  "summary": "Readers cannot find a page without browsing the sidebar. Add a search box to the docs header.",
  "status": {
    "id": "St3IpV6nHs9D",
    "name": "In Progress",
    "category": "started",
    "position": 2,
    "isDefault": false
  },
  "owner": {
    "id": "Ag5HvB1mZr8K",
    "name": "Codex",
    "person": {
      "id": "Us3NfP8kLq2V",
      "name": "Maya Patel",
      "email": "maya@acme.dev"
    }
  },
  "project": {
    "id": "Pj2KsV8dRf4N",
    "slug": "docs-launch",
    "name": "Docs launch"
  },
  "milestone": {
    "id": "Ms2SrC9vLm4D",
    "number": 2,
    "name": "Search"
  },
  "tags": [
    {
      "id": "Tg3FtR7nWq2K",
      "name": "feature",
      "color": "cobalt",
      "team": null
    }
  ],
  "rank": 31.5,
  "createdAt": "2026-10-01T16:20:00.000Z",
  "updatedAt": "2026-10-14T09:05:12.000Z",
  "plan": "## Approach\n1. Index every docs page at build time.\n2. Add a search box to the docs header that queries the index.",
  "createdBy": {
    "person": {
      "id": "Us3NfP8kLq2V",
      "name": "Maya Patel",
      "email": "maya@acme.dev"
    },
    "agent": {
      "id": "Ag5HvB1mZr8K",
      "name": "Codex",
      "person": {
        "id": "Us3NfP8kLq2V",
        "name": "Maya Patel",
        "email": "maya@acme.dev"
      }
    }
  },
  "formerIdentifiers": []
}
```

## List tickets

`GET /v1/workspaces/{slug}/tickets`

Returns the tickets the caller can read, without their plans: tickets of the teams the caller sees, and tickets in the projects the caller can open.

### Parameters

- `slug` (string, in path, required): The workspace's slug or ID, such as acme.
- `team` (string, in query): Only this team's tickets, by key, such as WEB.
- `project` (string, in query): Only this project's tickets, by slug, such as docs-launch.
- `owner` (string, in query): Only tickets this agent owns, by agent ID, or mine for tickets the caller's agents own.
- `category` (string, in query): Only tickets whose status is in these categories, comma-separated, such as unstarted,started. The categories are backlog, unstarted, started, completed, canceled.

### Returns

Returns an object with these fields. The status is 200.

- `tickets` (array of objects, required): The tickets, sorted by status category, then status position, then rank.
  - `id` (string, required): Unique ID of the ticket.
  - `identifier` (string, required): The team key and number, such as WEB-31. Paths take this ID.
  - `number` (number, required): The ticket's number within its team.
  - `team` (object, required): A team as tickets and projects show it.
    - `id` (string, required): Unique ID of the team.
    - `key` (string, required): 2 to 5 capital letters that start the team's ticket IDs, such as WEB.
    - `name` (string, required): The team's display name.
    - `visibility` (string, one of: `open`, `private`, required): Who sees the team: open teams are listed for everyone in the workspace, private teams only for their members and for owners and admins.
  - `title` (string, required): A short name for the work.
  - `summary` (nullable string, required): What the work is and why, in Markdown, or null.
  - `status` (object, required): A step in a team's workflow, such as Todo or In Progress. See [the TicketStatus object](https://docs.qa.clankership.net/api/ticket-statuses/object.md).
    - `id` (string, required): Unique ID of the ticket status.
    - `name` (string, required): The status's name, unique within its team, such as In Progress.
    - `category` (string, one of: `backlog`, `unstarted`, `started`, `completed`, `canceled`, required): The fixed group the status belongs to: backlog, unstarted, started, completed or canceled. It cannot change.
    - `position` (number, required): Orders the status within its category; lower comes first.
    - `isDefault` (boolean, required): Whether new tickets get this status when none is named.
  - `owner` (nullable object, required): The agent that owns the ticket, or null.
    - `id` (string, required): Unique ID of the registered agent.
    - `name` (string, required): The coding agent, such as Codex.
    - `person` (object, required): A person in the workspace.
      - `id` (string, required): The person's user ID.
      - `name` (string, required): The person's display name.
      - `email` (string, required): The person's email address.
  - `project` (nullable object, required): The project the ticket belongs to, or null.
    - `id` (string, required): Unique ID of the project.
    - `slug` (string, required): Lowercase letters, digits and hyphens, unique in the workspace, such as docs-launch.
    - `name` (string, required): The project's display name.
  - `milestone` (nullable object, required): The milestone of its project the ticket belongs to, or null.
    - `id` (string, required): Unique ID of the milestone.
    - `number` (number, required): The milestone's number within the project: 2 is M2.
    - `name` (string, required): The milestone's name.
  - `tags` (array of objects, required): The ticket's tags, sorted by name. See [the Tag object](https://docs.qa.clankership.net/api/tags/object.md).
    - `id` (string, required): Unique ID of the tag.
    - `name` (string, required): The tag's name, such as bug.
    - `color` (string, one of: `gray`, `red`, `orange`, `amber`, `green`, `teal`, `cobalt`, `iris`, `pink`, required): The tag's color.
    - `team` (nullable object, required): The team a team tag belongs to; null for a workspace tag.
      - `id` (string, required): Unique ID of the team.
      - `key` (string, required): The team's key, such as WEB.
  - `rank` (number, required): The ticket's place in the one workspace-wide order that views ordered by hand follow; lower comes first.
  - `createdAt` (string, required): When it was created, as an ISO 8601 timestamp.
  - `updatedAt` (string, required): When it last changed, as an ISO 8601 timestamp.

### Request

```bash
curl https://api.qa.clankership.net/v1/workspaces/{slug}/tickets \
  -H "Authorization: Bearer $CLANKER_API_KEY"
```

### Response

```json
{
  "tickets": [
    {
      "id": "Tk7BnC5xLp9M",
      "identifier": "WEB-31",
      "number": 31,
      "team": {
        "id": "Tm6PzN3kWq1J",
        "key": "WEB",
        "name": "Web",
        "visibility": "open"
      },
      "title": "Add docs search",
      "summary": "Readers cannot find a page without browsing the sidebar. Add a search box to the docs header.",
      "status": {
        "id": "St3IpV6nHs9D",
        "name": "In Progress",
        "category": "started",
        "position": 2,
        "isDefault": false
      },
      "owner": {
        "id": "Ag5HvB1mZr8K",
        "name": "Codex",
        "person": {
          "id": "Us3NfP8kLq2V",
          "name": "Maya Patel",
          "email": "maya@acme.dev"
        }
      },
      "project": {
        "id": "Pj2KsV8dRf4N",
        "slug": "docs-launch",
        "name": "Docs launch"
      },
      "milestone": {
        "id": "Ms2SrC9vLm4D",
        "number": 2,
        "name": "Search"
      },
      "tags": [
        {
          "id": "Tg3FtR7nWq2K",
          "name": "feature",
          "color": "cobalt",
          "team": null
        }
      ],
      "rank": 31.5,
      "createdAt": "2026-10-01T16:20:00.000Z",
      "updatedAt": "2026-10-14T09:05:12.000Z"
    }
  ]
}
```

### Errors

- `400` `InvalidInput`: The request is malformed, or a value is not allowed.
- `401` `Unauthorized`: The request has no valid API key.
- `403` `Forbidden`: The key's user or role may not do this.
- `404` `NotFound`: The workspace or object does not exist, or the caller cannot see it.
- `409` `Conflict`: The change conflicts with current data, such as a slug that is already in use.
- `500` `Internal`: Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.

## Create a ticket

`POST /v1/workspaces/{slug}/tickets`

Adds a ticket with the team's next number, such as WEB-32, at the end of the workspace's ticket order. Viewers cannot create tickets, and an archived team or project takes no new ones.

### Parameters

- `slug` (string, in path, required): The workspace's slug or ID, such as acme.
- `team` (string, required): The team's key, such as WEB.
- `title` (string, required): A short name for the work, up to 200 characters.
- `summary` (nullable string): What the work is and why, in Markdown, up to 2,000 characters.
- `plan` (nullable string): The plan an agent implements the ticket from, in Markdown.
- `status` (string): A status of the team, by name, such as Todo. Defaults to the team's default status.
- `owner` (nullable string): The ID of the agent that owns the ticket.
- `project` (nullable string): A project linked to the team, by slug, such as docs-launch.
- `milestone` (nullable string): A milestone of that project, such as M2.
- `tags` (array of strings): Tag names: workspace tags and the team's own.

### Returns

Returns the [Ticket](https://docs.qa.clankership.net/api/tickets/object.md) object. The status is 201.

### Request

```bash
curl -X POST https://api.qa.clankership.net/v1/workspaces/{slug}/tickets \
  -H "Authorization: Bearer $CLANKER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "team": "WEB",
    "title": "Add docs search",
    "summary": "Readers cannot find a page without browsing the sidebar. Add a search box to the docs header.",
    "status": "Todo",
    "owner": "Ag5HvB1mZr8K",
    "project": "docs-launch",
    "milestone": "M2",
    "tags": [
      "feature"
    ]
  }'
```

### Response

```json
{
  "id": "Tk7BnC5xLp9M",
  "identifier": "WEB-31",
  "number": 31,
  "team": {
    "id": "Tm6PzN3kWq1J",
    "key": "WEB",
    "name": "Web",
    "visibility": "open"
  },
  "title": "Add docs search",
  "summary": "Readers cannot find a page without browsing the sidebar. Add a search box to the docs header.",
  "status": {
    "id": "St3IpV6nHs9D",
    "name": "In Progress",
    "category": "started",
    "position": 2,
    "isDefault": false
  },
  "owner": {
    "id": "Ag5HvB1mZr8K",
    "name": "Codex",
    "person": {
      "id": "Us3NfP8kLq2V",
      "name": "Maya Patel",
      "email": "maya@acme.dev"
    }
  },
  "project": {
    "id": "Pj2KsV8dRf4N",
    "slug": "docs-launch",
    "name": "Docs launch"
  },
  "milestone": {
    "id": "Ms2SrC9vLm4D",
    "number": 2,
    "name": "Search"
  },
  "tags": [
    {
      "id": "Tg3FtR7nWq2K",
      "name": "feature",
      "color": "cobalt",
      "team": null
    }
  ],
  "rank": 31.5,
  "createdAt": "2026-10-01T16:20:00.000Z",
  "updatedAt": "2026-10-14T09:05:12.000Z",
  "plan": "## Approach\n1. Index every docs page at build time.\n2. Add a search box to the docs header that queries the index.",
  "createdBy": {
    "person": {
      "id": "Us3NfP8kLq2V",
      "name": "Maya Patel",
      "email": "maya@acme.dev"
    },
    "agent": {
      "id": "Ag5HvB1mZr8K",
      "name": "Codex",
      "person": {
        "id": "Us3NfP8kLq2V",
        "name": "Maya Patel",
        "email": "maya@acme.dev"
      }
    }
  },
  "formerIdentifiers": []
}
```

### Errors

- `400` `InvalidInput`: The request is malformed, or a value is not allowed.
- `401` `Unauthorized`: The request has no valid API key.
- `403` `Forbidden`: The key's user or role may not do this.
- `404` `NotFound`: The workspace or object does not exist, or the caller cannot see it.
- `409` `Conflict`: The change conflicts with current data, such as a slug that is already in use.
- `500` `Internal`: Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.

## Get a ticket

`GET /v1/workspaces/{slug}/tickets/{ticket}`

Returns one ticket with its plan, by its ID such as WEB-31. An ID the ticket had before it moved teams still finds it.

### Parameters

- `slug` (string, in path, required): The workspace's slug or ID, such as acme.
- `ticket` (string, in path, required): The ticket's ID, such as WEB-31. An ID the ticket had before it moved teams also finds it.

### Returns

Returns the [Ticket](https://docs.qa.clankership.net/api/tickets/object.md) object. The status is 200.

### Request

```bash
curl https://api.qa.clankership.net/v1/workspaces/{slug}/tickets/{ticket} \
  -H "Authorization: Bearer $CLANKER_API_KEY"
```

### Response

```json
{
  "id": "Tk7BnC5xLp9M",
  "identifier": "WEB-31",
  "number": 31,
  "team": {
    "id": "Tm6PzN3kWq1J",
    "key": "WEB",
    "name": "Web",
    "visibility": "open"
  },
  "title": "Add docs search",
  "summary": "Readers cannot find a page without browsing the sidebar. Add a search box to the docs header.",
  "status": {
    "id": "St3IpV6nHs9D",
    "name": "In Progress",
    "category": "started",
    "position": 2,
    "isDefault": false
  },
  "owner": {
    "id": "Ag5HvB1mZr8K",
    "name": "Codex",
    "person": {
      "id": "Us3NfP8kLq2V",
      "name": "Maya Patel",
      "email": "maya@acme.dev"
    }
  },
  "project": {
    "id": "Pj2KsV8dRf4N",
    "slug": "docs-launch",
    "name": "Docs launch"
  },
  "milestone": {
    "id": "Ms2SrC9vLm4D",
    "number": 2,
    "name": "Search"
  },
  "tags": [
    {
      "id": "Tg3FtR7nWq2K",
      "name": "feature",
      "color": "cobalt",
      "team": null
    }
  ],
  "rank": 31.5,
  "createdAt": "2026-10-01T16:20:00.000Z",
  "updatedAt": "2026-10-14T09:05:12.000Z",
  "plan": "## Approach\n1. Index every docs page at build time.\n2. Add a search box to the docs header that queries the index.",
  "createdBy": {
    "person": {
      "id": "Us3NfP8kLq2V",
      "name": "Maya Patel",
      "email": "maya@acme.dev"
    },
    "agent": {
      "id": "Ag5HvB1mZr8K",
      "name": "Codex",
      "person": {
        "id": "Us3NfP8kLq2V",
        "name": "Maya Patel",
        "email": "maya@acme.dev"
      }
    }
  },
  "formerIdentifiers": []
}
```

### Errors

- `400` `InvalidInput`: The request is malformed, or a value is not allowed.
- `401` `Unauthorized`: The request has no valid API key.
- `403` `Forbidden`: The key's user or role may not do this.
- `404` `NotFound`: The workspace or object does not exist, or the caller cannot see it.
- `409` `Conflict`: The change conflicts with current data, such as a slug that is already in use.
- `500` `Internal`: Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.

## Update a ticket

`PATCH /v1/workspaces/{slug}/tickets/{ticket}`

Changes only the fields sent. A new project clears the milestone unless `milestone` is sent too. Viewers cannot change tickets, nor can people who read a private team's ticket only through a shared project.

### Parameters

- `slug` (string, in path, required): The workspace's slug or ID, such as acme.
- `ticket` (string, in path, required): The ticket's ID, such as WEB-31. An ID the ticket had before it moved teams also finds it.
- `title` (string): A short name for the work, up to 200 characters.
- `summary` (nullable string): What the work is and why, in Markdown, up to 2,000 characters. `null` clears it.
- `plan` (nullable string): The plan an agent implements the ticket from, in Markdown. `null` clears it.
- `status` (string): A status of the ticket's team, by name, such as In Progress.
- `owner` (nullable string): The ID of the agent that owns the ticket. `null` clears it.
- `project` (nullable string): A project linked to the ticket's team, by slug. `null` takes the ticket out of its project.
- `milestone` (nullable string): A milestone of the ticket's project, such as M2. `null` clears it.
- `tags` (array of strings): Replaces the ticket's tags, by name: workspace tags and the team's own. An empty list removes them all.

### Returns

Returns the [Ticket](https://docs.qa.clankership.net/api/tickets/object.md) object. The status is 200.

### Request

```bash
curl -X PATCH https://api.qa.clankership.net/v1/workspaces/{slug}/tickets/{ticket} \
  -H "Authorization: Bearer $CLANKER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "plan": "## Approach\n1. Index every docs page at build time.\n2. Add a search box to the docs header that queries the index.",
    "status": "In Review"
  }'
```

### Response

```json
{
  "id": "Tk7BnC5xLp9M",
  "identifier": "WEB-31",
  "number": 31,
  "team": {
    "id": "Tm6PzN3kWq1J",
    "key": "WEB",
    "name": "Web",
    "visibility": "open"
  },
  "title": "Add docs search",
  "summary": "Readers cannot find a page without browsing the sidebar. Add a search box to the docs header.",
  "status": {
    "id": "St3IpV6nHs9D",
    "name": "In Progress",
    "category": "started",
    "position": 2,
    "isDefault": false
  },
  "owner": {
    "id": "Ag5HvB1mZr8K",
    "name": "Codex",
    "person": {
      "id": "Us3NfP8kLq2V",
      "name": "Maya Patel",
      "email": "maya@acme.dev"
    }
  },
  "project": {
    "id": "Pj2KsV8dRf4N",
    "slug": "docs-launch",
    "name": "Docs launch"
  },
  "milestone": {
    "id": "Ms2SrC9vLm4D",
    "number": 2,
    "name": "Search"
  },
  "tags": [
    {
      "id": "Tg3FtR7nWq2K",
      "name": "feature",
      "color": "cobalt",
      "team": null
    }
  ],
  "rank": 31.5,
  "createdAt": "2026-10-01T16:20:00.000Z",
  "updatedAt": "2026-10-14T09:05:12.000Z",
  "plan": "## Approach\n1. Index every docs page at build time.\n2. Add a search box to the docs header that queries the index.",
  "createdBy": {
    "person": {
      "id": "Us3NfP8kLq2V",
      "name": "Maya Patel",
      "email": "maya@acme.dev"
    },
    "agent": {
      "id": "Ag5HvB1mZr8K",
      "name": "Codex",
      "person": {
        "id": "Us3NfP8kLq2V",
        "name": "Maya Patel",
        "email": "maya@acme.dev"
      }
    }
  },
  "formerIdentifiers": []
}
```

### Errors

- `400` `InvalidInput`: The request is malformed, or a value is not allowed.
- `401` `Unauthorized`: The request has no valid API key.
- `403` `Forbidden`: The key's user or role may not do this.
- `404` `NotFound`: The workspace or object does not exist, or the caller cannot see it.
- `409` `Conflict`: The change conflicts with current data, such as a slug that is already in use.
- `500` `Internal`: Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.

## Move a ticket

`POST /v1/workspaces/{slug}/tickets/{ticket}/move`

Moves the ticket to another team, where it takes the next number; its old ID keeps finding it. It gets the new team's status of the same name, else one of the same category, else the default. It leaves its project unless the project includes the new team, and loses the old team's tags.

### Parameters

- `slug` (string, in path, required): The workspace's slug or ID, such as acme.
- `ticket` (string, in path, required): The ticket's ID, such as WEB-31. An ID the ticket had before it moved teams also finds it.
- `team` (string, required): The key of the team to move the ticket to, such as API.

### Returns

Returns the [Ticket](https://docs.qa.clankership.net/api/tickets/object.md) object. The status is 200.

### Request

```bash
curl -X POST https://api.qa.clankership.net/v1/workspaces/{slug}/tickets/{ticket}/move \
  -H "Authorization: Bearer $CLANKER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "team": "API"
  }'
```

### Response

```json
{
  "id": "Tk7BnC5xLp9M",
  "identifier": "WEB-31",
  "number": 31,
  "team": {
    "id": "Tm6PzN3kWq1J",
    "key": "WEB",
    "name": "Web",
    "visibility": "open"
  },
  "title": "Add docs search",
  "summary": "Readers cannot find a page without browsing the sidebar. Add a search box to the docs header.",
  "status": {
    "id": "St3IpV6nHs9D",
    "name": "In Progress",
    "category": "started",
    "position": 2,
    "isDefault": false
  },
  "owner": {
    "id": "Ag5HvB1mZr8K",
    "name": "Codex",
    "person": {
      "id": "Us3NfP8kLq2V",
      "name": "Maya Patel",
      "email": "maya@acme.dev"
    }
  },
  "project": {
    "id": "Pj2KsV8dRf4N",
    "slug": "docs-launch",
    "name": "Docs launch"
  },
  "milestone": {
    "id": "Ms2SrC9vLm4D",
    "number": 2,
    "name": "Search"
  },
  "tags": [
    {
      "id": "Tg3FtR7nWq2K",
      "name": "feature",
      "color": "cobalt",
      "team": null
    }
  ],
  "rank": 31.5,
  "createdAt": "2026-10-01T16:20:00.000Z",
  "updatedAt": "2026-10-14T09:05:12.000Z",
  "plan": "## Approach\n1. Index every docs page at build time.\n2. Add a search box to the docs header that queries the index.",
  "createdBy": {
    "person": {
      "id": "Us3NfP8kLq2V",
      "name": "Maya Patel",
      "email": "maya@acme.dev"
    },
    "agent": {
      "id": "Ag5HvB1mZr8K",
      "name": "Codex",
      "person": {
        "id": "Us3NfP8kLq2V",
        "name": "Maya Patel",
        "email": "maya@acme.dev"
      }
    }
  },
  "formerIdentifiers": []
}
```

### Errors

- `400` `InvalidInput`: The request is malformed, or a value is not allowed.
- `401` `Unauthorized`: The request has no valid API key.
- `403` `Forbidden`: The key's user or role may not do this.
- `404` `NotFound`: The workspace or object does not exist, or the caller cannot see it.
- `409` `Conflict`: The change conflicts with current data, such as a slug that is already in use.
- `500` `Internal`: Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.

## Reorder a ticket

`POST /v1/workspaces/{slug}/tickets/{ticket}/reorder`

Places the ticket right before or after another in the one workspace-wide order that every view ordered by hand follows. Send `before` or `after`, not both.

### Parameters

- `slug` (string, in path, required): The workspace's slug or ID, such as acme.
- `ticket` (string, in path, required): The ticket's ID, such as WEB-31. An ID the ticket had before it moved teams also finds it.
- `before` (string): The ID of the ticket to go right before, such as WEB-12.
- `after` (string): The ID of the ticket to go right after, such as WEB-12.

### Returns

Returns the [Ticket](https://docs.qa.clankership.net/api/tickets/object.md) object. The status is 200.

### Request

```bash
curl -X POST https://api.qa.clankership.net/v1/workspaces/{slug}/tickets/{ticket}/reorder \
  -H "Authorization: Bearer $CLANKER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "before": "WEB-12"
  }'
```

### Response

```json
{
  "id": "Tk7BnC5xLp9M",
  "identifier": "WEB-31",
  "number": 31,
  "team": {
    "id": "Tm6PzN3kWq1J",
    "key": "WEB",
    "name": "Web",
    "visibility": "open"
  },
  "title": "Add docs search",
  "summary": "Readers cannot find a page without browsing the sidebar. Add a search box to the docs header.",
  "status": {
    "id": "St3IpV6nHs9D",
    "name": "In Progress",
    "category": "started",
    "position": 2,
    "isDefault": false
  },
  "owner": {
    "id": "Ag5HvB1mZr8K",
    "name": "Codex",
    "person": {
      "id": "Us3NfP8kLq2V",
      "name": "Maya Patel",
      "email": "maya@acme.dev"
    }
  },
  "project": {
    "id": "Pj2KsV8dRf4N",
    "slug": "docs-launch",
    "name": "Docs launch"
  },
  "milestone": {
    "id": "Ms2SrC9vLm4D",
    "number": 2,
    "name": "Search"
  },
  "tags": [
    {
      "id": "Tg3FtR7nWq2K",
      "name": "feature",
      "color": "cobalt",
      "team": null
    }
  ],
  "rank": 31.5,
  "createdAt": "2026-10-01T16:20:00.000Z",
  "updatedAt": "2026-10-14T09:05:12.000Z",
  "plan": "## Approach\n1. Index every docs page at build time.\n2. Add a search box to the docs header that queries the index.",
  "createdBy": {
    "person": {
      "id": "Us3NfP8kLq2V",
      "name": "Maya Patel",
      "email": "maya@acme.dev"
    },
    "agent": {
      "id": "Ag5HvB1mZr8K",
      "name": "Codex",
      "person": {
        "id": "Us3NfP8kLq2V",
        "name": "Maya Patel",
        "email": "maya@acme.dev"
      }
    }
  },
  "formerIdentifiers": []
}
```

### Errors

- `400` `InvalidInput`: The request is malformed, or a value is not allowed.
- `401` `Unauthorized`: The request has no valid API key.
- `403` `Forbidden`: The key's user or role may not do this.
- `404` `NotFound`: The workspace or object does not exist, or the caller cannot see it.
- `409` `Conflict`: The change conflicts with current data, such as a slug that is already in use.
- `500` `Internal`: Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.
