Vetrix Docs

Issues

Reference for the issue-tracker endpoints: issues and their lifecycle, comments, description-edit history, parent/child hierarchy, labels, milestones, and the issue-type catalog and per-repository scheme.

Resource overview

Most issue endpoints are scoped to a repository and live under:

/api/v1/repos/{owner}/{repo}/...

This page covers the following sub-resources:

Sub-resource Base path
Issues /api/v1/repos/{owner}/{repo}/issues
Issue search /api/v1/repos/{owner}/{repo}/issues/search
Comments /api/v1/repos/{owner}/{repo}/issues/{number}/comments
Description history /api/v1/repos/{owner}/{repo}/issues/{number}/description-history
Parent / children /api/v1/repos/{owner}/{repo}/issues/{number}/parent, /children
Labels /api/v1/repos/{owner}/{repo}/labels
Milestones /api/v1/repos/{owner}/{repo}/milestones
Issue-type scheme /api/v1/repos/{owner}/{repo}/issue-type-scheme

The issue-type catalog is instance-wide, not per repository, so it sits at the top level:

Sub-resource Base path
Issue types (read) /api/v1/issue-types
Issue types (administer) /api/v1/admin/issue-types

The {number} segment accepts either the bare issue number (70) or the project-key form (ABC-70) when the repository has an issue-key prefix configured; a mismatched prefix returns 404.

Issue responses also carry component, version, and workflow-state fields. Those collections are read-only on this page; they are managed through their own endpoints.

Auth & scopes

See conventions.md for the accepted credential types and how scopes are enforced. The operations on this page require:

Operation OAuth2 scope PAT scope
Read issues, comments, history, children, labels, the issue-type scheme read:issue issue:read
Create or update issues and comments; manage labels write:issue issue:write
Read milestones read:repo repo:read
Create, update, or delete milestones write:repo repo:write
Delete an issue or a description-history entry admin:repo repo:admin
Manage a repository's issue-type scheme admin:repo repo:admin
Create, update, or delete a global issue type admin:system

Reading the global issue-type catalog (GET /api/v1/issue-types) requires only an authenticated caller; no resource scope applies.

Read vs. write authorization. Reads enforce the repository's visibility tier: a private repository is readable only by its members, an internal repository by any authenticated caller, and a public repository by anyone. Writes additionally require the issue author or the relevant write/admin permission — for example, the issue author or a caller with issue-write permission may update, close, or comment on an issue, while only the repository owner or an instance admin may delete one. A caller who cannot read a private repository receives 404, not 403; see errors.md.

The issue API takes a flat issue_type_id on write but returns a nested issue_type object on read; see issues-type-write-read-asymmetry.md.

The issue object

Issue reads (GET, list items, search hits, and the 201/200 bodies of create and update) return the same object:

{
  "id": "<uuid>",
  "repo_id": "<uuid>",
  "number": 70,
  "author_id": "<uuid>",
  "author": { "id": "<uuid>", "username": "alice", "...": "..." },
  "title": "Login button is misaligned",
  "description": "Markdown body of the issue.",
  "state": "open",
  "locked": false,
  "closed_at": null,
  "created_at": "2026-01-02T15:04:05Z",
  "updated_at": "2026-01-02T15:04:05Z",
  "issue_type": {
    "id": "00000000-0000-0000-0000-000000000005",
    "name": "bug",
    "display_name": "Bug",
    "description": "A defect or unexpected behaviour",
    "color": "ef4444",
    "icon": "bug",
    "is_subtask": false,
    "position": 6
  },
  "priority": "medium",
  "parent_id": null,
  "parent": null,
  "children_count": 0,
  "comments_count": 2,
  "due_date": null,
  "components": [],
  "fix_versions": [],
  "affects_versions": [],
  "story_points": null,
  "input_tokens": null,
  "output_tokens": null,
  "assumptions": null,
  "acceptance_criteria": null,
  "links_count": 0,
  "blocked_by": [],
  "watching": false,
  "watchers_count": 1,
  "issue_status": "queued",
  "labels": [],
  "assignees": [],
  "milestone": null
}
Field Type Notes
number integer Per-repository issue number; stable identifier in paths.
state string open or closed.
issue_status string Workflow status, independent of state: queued, in_progress, blocked, completed, canceled.
priority string none, low, medium, high, or critical.
issue_type object Nested type descriptor; null when no type is assigned. Set on write with the flat issue_type_id.
parent object { id, number, title }, or null when the issue has no parent. Always present.
assumptions string Markdown; null when unset.
acceptance_criteria string Markdown; null when unset.
input_tokens / output_tokens integer Non-negative estimates; rendered as explicit null when unset.
labels / assignees array Empty arrays when none are attached.
milestone object { id, title, due_date, state }, or null.

links_count, blocked_by, watching, and watchers_count are populated on a single-issue GET and are zero/empty on list and search responses.

Endpoints

Method Path Summary
GET /api/v1/repos/{owner}/{repo}/issues List issues (paginated, filterable)
GET /api/v1/repos/{owner}/{repo}/issues/{number} Fetch a single issue
POST /api/v1/repos/{owner}/{repo}/issues Create an issue
PATCH /api/v1/repos/{owner}/{repo}/issues/{number} Update an issue
POST /api/v1/repos/{owner}/{repo}/issues/{number}/close Close an issue
POST /api/v1/repos/{owner}/{repo}/issues/{number}/reopen Reopen an issue
DELETE /api/v1/repos/{owner}/{repo}/issues/{number} Delete an issue
GET /api/v1/repos/{owner}/{repo}/issues/search Ranked full-text issue search
GET /api/v1/repos/{owner}/{repo}/issues/{number}/comments List comments
POST /api/v1/repos/{owner}/{repo}/issues/{number}/comments Add a comment
PATCH /api/v1/repos/{owner}/{repo}/issues/{number}/comments/{cid} Edit a comment
DELETE /api/v1/repos/{owner}/{repo}/issues/{number}/comments/{cid} Delete a comment
GET /api/v1/repos/{owner}/{repo}/issues/{number}/description-history List description edits
DELETE /api/v1/repos/{owner}/{repo}/issues/{number}/description-history/{id} Delete a history entry
GET /api/v1/repos/{owner}/{repo}/issues/{number}/children List child issues
PUT /api/v1/repos/{owner}/{repo}/issues/{number}/parent Set or change the parent
DELETE /api/v1/repos/{owner}/{repo}/issues/{number}/parent Clear the parent
GET /api/v1/repos/{owner}/{repo}/labels List labels
POST /api/v1/repos/{owner}/{repo}/labels Create a label
GET /api/v1/repos/{owner}/{repo}/labels/{id} Fetch a label
PATCH /api/v1/repos/{owner}/{repo}/labels/{id} Update a label
DELETE /api/v1/repos/{owner}/{repo}/labels/{id} Delete a label
GET /api/v1/repos/{owner}/{repo}/milestones List milestones
POST /api/v1/repos/{owner}/{repo}/milestones Create a milestone
GET /api/v1/repos/{owner}/{repo}/milestones/{id} Fetch a milestone
PATCH /api/v1/repos/{owner}/{repo}/milestones/{id} Update a milestone
DELETE /api/v1/repos/{owner}/{repo}/milestones/{id} Delete a milestone
GET /api/v1/issue-types List global issue types
GET /api/v1/issue-types/{id} Fetch a global issue type
POST /api/v1/admin/issue-types Create an issue type
PATCH /api/v1/admin/issue-types/{id} Update an issue type
DELETE /api/v1/admin/issue-types/{id} Delete an issue type
GET /api/v1/repos/{owner}/{repo}/issue-type-scheme Read the repository's scheme
PUT /api/v1/repos/{owner}/{repo}/issue-type-scheme Replace the repository's scheme

GET /api/v1/repos/{owner}/{repo}/issues

List a repository's issues. Returns the page envelope described in Pagination.

Query parameters

Name Type Default Description
page integer 1 See Pagination.
per_page integer 25 See Pagination.
state string all One of open, closed, all. An unrecognized value returns 400.
status string Filter by workflow status (queued, in_progress, blocked, completed, canceled). An unrecognized value returns 400.
type string Filter by issue-type name (for example bug).
priority string Filter by priority.
label string Filter by label name.
milestone_id uuid Filter by milestone. A malformed UUID returns 400.
has_parent boolean true returns only issues that have a parent.
component / fix_version / affects_version string Filter by associated component or version name.
q string Case-insensitive title and full-text match, combined with the other filters.

A due_before / due_after pair (each YYYY-MM-DD), overdue, story_points_min / story_points_max, unestimated, and the token-budget filters (tokens_min, tokens_max, untokenized, output_tokens_min, output_tokens_max, no_output_tokens) are also accepted.

Response

{
  "items": [ { "...": "the issue object" } ],
  "total": 137,
  "page": 1,
  "per_page": 25
}

Status codes

Status When
200 OK Issues returned.
400 Bad Request Invalid state, status, or milestone_id.
404 Not Found Repository missing, or private and not readable — see Errors.

Example

curl -H "Authorization: Bearer <token>" \
  "https://api.gitvetrix.com/api/v1/repos/{owner}/{repo}/issues?state=open&label=bug&per_page=50"

GET /api/v1/repos/{owner}/{repo}/issues/{number}

Fetch one issue, fully hydrated.

Path parameters

Name Type Description
number string Issue number (70) or project key (ABC-70).

Responsethe issue object.

Status codes

Status When
200 OK Issue returned.
404 Not Found Issue or repository missing, or private and not readable.

Example

curl -H "Authorization: Bearer <token>" \
  https://api.gitvetrix.com/api/v1/repos/{owner}/{repo}/issues/70

POST /api/v1/repos/{owner}/{repo}/issues

Create an issue. The request is strictly decoded: an unknown field — including the read-shaped issue_type object — is rejected with 400.

Request body

{
  "title": "Login button is misaligned",
  "description": "Markdown body.",
  "issue_type_id": "00000000-0000-0000-0000-000000000005",
  "priority": "medium",
  "milestone_id": "<uuid>",
  "label_ids": ["<uuid>"],
  "assignee_ids": ["<uuid>"],
  "story_points": 3,
  "acceptance_criteria": "Given/when/then.",
  "assumptions": "None."
}
Field Required Notes
title yes Non-empty.
issue_type_id yes UUID of an existing issue type. Set the type with this flat scalar, never the nested issue_type.
description no Markdown body.
priority no One of the priority values; defaults to none.
milestone_id no UUID.
label_ids no UUIDs of existing labels.
inline_labels no [{ "name", "color" }] to create-or-reuse labels by name; requires label-create permission.
assignee_ids no UUIDs.
parent_id no UUID of an existing issue in the same repository to set as the parent at create time. A malformed, missing, or cross-repository value returns 400.
due_date no YYYY-MM-DD.
story_points no Non-negative integer.
input_tokens / output_tokens no Non-negative integers.
issue_status no Workflow status; defaults to queued.
assumptions / acceptance_criteria no Markdown; empty string stores no value.
component_ids / fix_version_ids / affects_version_ids no UUIDs of existing associations.

Set the parent at create time with parent_id (the parent issue's UUID). To re-parent an existing issue afterward, use PUT .../issues/{number}/parent with the integer parent_number instead; parent_id is rejected on PATCH (update).

Response201 Created with the issue object.

Status codes

Status When
201 Created Issue created.
400 Bad Request Missing title or issue_type_id, an invalid value, or an unknown/read-shaped field.
403 Forbidden inline_labels supplied without label-create permission.
404 Not Found Repository missing or not readable.

Example

curl -X POST -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{"title":"Login button is misaligned","issue_type_id":"00000000-0000-0000-0000-000000000005"}' \
  https://api.gitvetrix.com/api/v1/repos/{owner}/{repo}/issues

PATCH /api/v1/repos/{owner}/{repo}/issues/{number}

Update an issue. Use PATCH for every field change, including state-adjacent fields such as issue_status; PUT is not defined for this path and returns 405 Method Not Allowed. Only the fields present in the body change. The body is strictly decoded — parent_id and the read-shaped issue_type are rejected with 400.

Path parameters

Name Type Description
number string Issue number or project key.

Request body — any subset of:

{
  "title": "New title",
  "description": "New body.",
  "issue_type_id": "<uuid>",
  "priority": "high",
  "issue_status": "in_progress",
  "milestone_id": null,
  "locked": true,
  "label_ids": ["<uuid>"],
  "assignee_ids": ["<uuid>"],
  "story_points": null,
  "acceptance_criteria": "...",
  "assumptions": "..."
}

For the nullable fields, the three states are distinct: omit the key to leave it unchanged, send null to clear it, and send a value to set it. This applies to milestone_id, story_points, input_tokens, and output_tokens. A present label_ids or assignee_ids array (including an empty array) replaces the current set.

Response200 OK with the issue object.

Status codes

Status When
200 OK Issue updated.
400 Bad Request Empty title, an invalid value, or an unknown/disallowed field.
403 Forbidden Caller is neither the author nor holds issue-write permission.
404 Not Found Issue or repository missing or not readable.
405 Method Not Allowed PUT was used instead of PATCH.

Example

curl -X PATCH -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{"issue_status":"in_progress","priority":"high"}' \
  https://api.gitvetrix.com/api/v1/repos/{owner}/{repo}/issues/70

POST /api/v1/repos/{owner}/{repo}/issues/{number}/close

Close an issue. The author or a caller with issue-write permission may close it.

Status codes

Status When
204 No Content Issue closed.
403 Forbidden Caller may not modify the issue.
404 Not Found Issue or repository missing or not readable.

Example

curl -X POST -H "Authorization: Bearer <token>" \
  https://api.gitvetrix.com/api/v1/repos/{owner}/{repo}/issues/70/close

POST /api/v1/repos/{owner}/{repo}/issues/{number}/reopen

Reopen a closed issue. Same authorization and status codes as close, returning 204 No Content on success.

DELETE /api/v1/repos/{owner}/{repo}/issues/{number}

Permanently delete an issue and its dependent rows (comments, labels, assignees, links, history, watchers, and associations). Only the repository owner or an instance admin may delete an issue.

Status codes

Status When
204 No Content Issue deleted.
403 Forbidden Caller lacks delete permission.
404 Not Found Issue or repository missing or not readable.

Example

curl -X DELETE -H "Authorization: Bearer <token>" \
  https://api.gitvetrix.com/api/v1/repos/{owner}/{repo}/issues/70

GET /api/v1/repos/{owner}/{repo}/issues/search

Ranked full-text issue search. Returns a bare JSON array of issue objects, each with an added rank, ordered by relevance. This complements the list endpoint's q filter, which returns the standard page envelope in list order.

Query parameters

Name Type Default Description
q string Search query. Required.
limit integer 25 Maximum hits to return.
facets boolean false When true, returns aggregations alongside hits where the search backend supports them.

Response

[
  { "...": "the issue object", "rank": 0.41 }
]

Status codes

Status When
200 OK Hits returned (possibly empty).
400 Bad Request q is missing.
404 Not Found Repository missing or not readable.

Example

curl -H "Authorization: Bearer <token>" \
  "https://api.gitvetrix.com/api/v1/repos/{owner}/{repo}/issues/search?q=login&limit=10"

GET /api/v1/repos/{owner}/{repo}/issues/{number}/comments

List an issue's comments in creation order. Returns a bare JSON array.

Response

[
  {
    "id": "<uuid>",
    "issue_id": "<uuid>",
    "author_id": "<uuid>",
    "author": { "id": "<uuid>", "username": "alice", "...": "..." },
    "body": "Comment text.",
    "created_at": "2026-01-02T15:04:05Z",
    "updated_at": "2026-01-02T15:04:05Z"
  }
]

Status codes

Status When
200 OK Comments returned.
404 Not Found Issue or repository missing or not readable.

POST /api/v1/repos/{owner}/{repo}/issues/{number}/comments

Add a comment.

Request body

{ "body": "Comment text." }

body is required.

Response201 Created with the comment object shown above.

Status codes

Status When
201 Created Comment added.
400 Bad Request Missing or empty body.
404 Not Found Issue or repository missing or not readable.

Example

curl -X POST -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{"body":"Reproduced on the latest build."}' \
  https://api.gitvetrix.com/api/v1/repos/{owner}/{repo}/issues/70/comments

PATCH /api/v1/repos/{owner}/{repo}/issues/{number}/comments/{cid}

Edit a comment. Only the comment author may edit it.

Path parameters

Name Type Description
cid uuid Comment identifier.

Request body

{ "body": "Edited text." }

Status codes

Status When
200 OK Comment updated.
400 Bad Request Invalid comment id or empty body.
403 Forbidden Caller is not the comment author.
404 Not Found Comment or repository missing.

DELETE /api/v1/repos/{owner}/{repo}/issues/{number}/comments/{cid}

Delete a comment. The comment author or an instance admin may delete it.

Status codes

Status When
204 No Content Comment deleted.
400 Bad Request Invalid comment id.
403 Forbidden Caller is neither the author nor an admin.
404 Not Found Comment or repository missing.

GET /api/v1/repos/{owner}/{repo}/issues/{number}/description-history

List the recorded edits to an issue's description, newest first. Returns a bare JSON array.

Response

[
  {
    "id": "<uuid>",
    "issue_id": "<uuid>",
    "body_before": "Old body.",
    "body_after": "New body.",
    "edited_by": "<uuid>",
    "edited_at": "2026-01-02T15:04:05Z",
    "editor_username": "alice",
    "editor_display_name": "Alice"
  }
]

Status codes

Status When
200 OK History returned.
404 Not Found Issue or repository missing or not readable.

DELETE /api/v1/repos/{owner}/{repo}/issues/{number}/description-history/{id}

Delete a single description-history entry. Restricted to repository admins and instance admins; every deletion is recorded in the audit log.

Path parameters

Name Type Description
id uuid History entry identifier.

Status codes

Status When
204 No Content Entry deleted.
400 Bad Request Invalid entry id.
403 Forbidden Caller lacks history-delete permission.
404 Not Found Entry or repository missing.

GET /api/v1/repos/{owner}/{repo}/issues/{number}/children

List the direct child issues of an issue. Returns a bare JSON array of issue objects.

Status codes

Status When
200 OK Children returned (possibly empty).
404 Not Found Issue or repository missing or not readable.

PUT /api/v1/repos/{owner}/{repo}/issues/{number}/parent

Re-parent an existing issue. (At create time, set the parent inline with the parent_id UUID on POST .../issues instead.) The author, the repository owner, or an instance admin may set it.

Request body

{ "parent_number": 12 }

parent_number is the issue number of the parent within the same repository. An issue cannot be its own parent. The parent must not be a sub-task type, and a support issue cannot be the parent of an epic or story.

Status codes

Status When
204 No Content Parent set.
400 Bad Request Missing/non-positive parent_number, or it equals the issue itself.
403 Forbidden Caller may not modify the issue.
404 Not Found Issue, parent, or repository missing or not readable.
422 Unprocessable Entity Parent is a sub-task, or a support issue would parent an epic or story.

Example

curl -X PUT -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{"parent_number":12}' \
  https://api.gitvetrix.com/api/v1/repos/{owner}/{repo}/issues/70/parent

DELETE /api/v1/repos/{owner}/{repo}/issues/{number}/parent

Clear an issue's parent link. Same authorization as setting the parent.

Status codes

Status When
204 No Content Parent cleared.
403 Forbidden Caller may not modify the issue.
404 Not Found Issue or repository missing or not readable.

GET /api/v1/repos/{owner}/{repo}/labels

List a repository's labels. Returns a bare JSON array.

Response

[
  {
    "id": "<uuid>",
    "repo_id": "<uuid>",
    "name": "bug",
    "color": "e11d48",
    "description": null
  }
]

color is a 6-character hex value without a leading #.

Status codes

Status When
200 OK Labels returned.
404 Not Found Repository missing or not readable.

POST /api/v1/repos/{owner}/{repo}/labels

Create a label.

Request body

{ "name": "bug", "color": "e11d48", "description": "Something is broken" }
Field Required Notes
name yes 1–64 characters; unique within the repository.
color yes 6-character hex without #.
description no Up to 255 characters.

Status codes

Status When
201 Created Label created.
400 Bad Request Missing name, over-length name/description, or malformed color.
403 Forbidden Caller lacks label-create permission.
404 Not Found Repository missing.
409 Conflict A label with that name already exists.

GET /api/v1/repos/{owner}/{repo}/labels/{id}

Fetch one label by UUID. Returns the label object shown above.

Status codes

Status When
200 OK Label returned.
404 Not Found Label or repository missing or not readable.

PATCH /api/v1/repos/{owner}/{repo}/labels/{id}

Update a label. Only the fields present change.

Request body — any subset of name, color, description. The same validation as create applies.

Status codes

Status When
200 OK Label updated.
400 Bad Request Empty/over-length name, over-length description, or malformed color.
403 Forbidden Caller lacks label-update permission.
404 Not Found Label or repository missing.
409 Conflict The new name collides with an existing label.

DELETE /api/v1/repos/{owner}/{repo}/labels/{id}

Delete a label. The path segment is normally a label UUID. A non-UUID segment is treated as a label name (deprecated); a name-based deletion adds a Deprecation: true header and a Link header pointing at the UUID-based route.

Status codes

Status When
204 No Content Label deleted.
403 Forbidden Caller lacks label-delete permission.
404 Not Found Label or repository missing.

GET /api/v1/repos/{owner}/{repo}/milestones

List milestones with their open/closed issue counts. Returns a bare JSON array.

Query parameters

Name Type Default Description
state string all Filter by open or closed.

Response

[
  {
    "id": "<uuid>",
    "repo_id": "<uuid>",
    "title": "v1.0",
    "description": "First stable release.",
    "due_date": "2026-03-01",
    "state": "open",
    "created_at": "2026-01-02T15:04:05Z",
    "closed_at": null,
    "open_issues": 4,
    "closed_issues": 11
  }
]

Status codes

Status When
200 OK Milestones returned.
404 Not Found Repository missing or not readable.

POST /api/v1/repos/{owner}/{repo}/milestones

Create a milestone.

Request body

{ "title": "v1.0", "description": "First stable release.", "due_date": "2026-03-01" }
Field Required Notes
title yes Non-empty.
description no Plain text.
due_date no YYYY-MM-DD.

Status codes

Status When
201 Created Milestone created.
400 Bad Request Missing title or malformed due_date.
403 Forbidden Caller lacks repository-write permission.
404 Not Found Repository missing.

GET /api/v1/repos/{owner}/{repo}/milestones/{id}

Fetch one milestone by UUID, with its issue counts.

Status codes

Status When
200 OK Milestone returned.
400 Bad Request Malformed milestone id.
404 Not Found Milestone or repository missing or not readable.

PATCH /api/v1/repos/{owner}/{repo}/milestones/{id}

Update a milestone. Only the fields present change. Send due_date: "" to clear the due date. state accepts open or closed.

Status codes

Status When
200 OK Milestone updated.
400 Bad Request Malformed id, empty title, bad due_date, or invalid state.
403 Forbidden Caller lacks repository-write permission.
404 Not Found Milestone or repository missing.

DELETE /api/v1/repos/{owner}/{repo}/milestones/{id}

Delete a milestone.

Status codes

Status When
204 No Content Milestone deleted.
400 Bad Request Malformed milestone id.
403 Forbidden Caller lacks repository-write permission.
404 Not Found Repository missing.

GET /api/v1/issue-types

List the instance-wide issue types, ordered by position. Any authenticated caller may read them. Returns a bare JSON array of issue-type objects:

[
  {
    "id": "00000000-0000-0000-0000-000000000005",
    "name": "bug",
    "display_name": "Bug",
    "description": "A defect or unexpected behaviour",
    "color": "ef4444",
    "icon": "bug",
    "is_subtask": false,
    "position": 6
  }
]

The built-in types use stable UUIDs paired with these canonical name values: ...0001 epic, ...0002 story, ...0003 task, ...0004 analysis, ...0005 bug, ...0006 feature, and ...0007 support. The name is immutable, but an instance's display_name for a type may be customized — for example, feature ships with the display name Deficiency. Use the id value as issue_type_id when creating an issue.

Status codes

Status When
200 OK Types returned.

GET /api/v1/issue-types/{id}

Fetch one issue type by UUID.

Status codes

Status When
200 OK Type returned.
400 Bad Request Malformed id.
404 Not Found Type missing.

POST /api/v1/admin/issue-types

Create an issue type. Instance admins only.

Request body

{
  "name": "incident",
  "display_name": "Incident",
  "description": "A production incident",
  "color": "ef4444",
  "icon_name": "alert",
  "is_subtask": false,
  "position": 8
}
Field Required Notes
name yes Lower-cased and trimmed; the canonical identifier.
display_name yes Human-readable label.
color yes 6-character hex without #.
description / icon_name / is_subtask / position no

Status codes

Status When
201 Created Type created.
400 Bad Request Missing name/display_name or malformed color.
403 Forbidden Caller is not an instance admin.

PATCH /api/v1/admin/issue-types/{id}

Update an issue type. Instance admins only. The canonical name is immutable; display_name, description, color, icon_name, and position may change.

Status codes

Status When
200 OK Type updated.
400 Bad Request Malformed id, empty display_name, or malformed color.
403 Forbidden Caller is not an instance admin.
404 Not Found Type missing.

DELETE /api/v1/admin/issue-types/{id}

Delete an issue type. Instance admins only. A type that is still referenced by any issue cannot be deleted.

Status codes

Status When
204 No Content Type deleted.
400 Bad Request Malformed id.
403 Forbidden Caller is not an instance admin.
404 Not Found Type missing.
409 Conflict The type is still in use.

GET /api/v1/repos/{owner}/{repo}/issue-type-scheme

Read the ordered set of issue types enabled for a repository. Returns a bare JSON array of scheme items:

[
  { "issue_type": { "id": "<uuid>", "name": "epic", "...": "..." }, "position": 0 }
]

Status codes

Status When
200 OK Scheme returned.
404 Not Found Repository missing or not readable.

PUT /api/v1/repos/{owner}/{repo}/issue-type-scheme

Replace the repository's active set of issue types. Requires a repository admin, the organization owner, or an instance admin.

Request body

{ "type_ids": ["<uuid>", "<uuid>"] }

type_ids is the ordered list of issue-type UUIDs to enable. An empty array clears the scheme.

Status codes

Status When
200 OK Scheme replaced.
400 Bad Request Malformed body or a non-UUID entry.
403 Forbidden Caller may not manage the scheme.
404 Not Found Repository missing.

Errors

These endpoints use the shared error envelope and status-code conventions in errors.md. Resource-specific behavior worth noting:

  • A private repository the caller cannot read returns 404, not 403, on every read here — see errors.md.
  • Creating or updating an issue strictly decodes the body: an unknown field, a bare-string or nested issue_type, or parent_id on update returns 400 with a hint in detail. See issues-type-write-read-asymmetry.md.
  • Duplicate label names and in-use issue types return 409 Conflict.
  • Disallowed parent relationships return 422 Unprocessable Entity.

Rate limits

These endpoints are metered under the standard scopes described in rate-limits.md: reads under api.read and mutations under api.write. The ranked search endpoint, GET /api/v1/repos/{owner}/{repo}/issues/search, is metered under api.expensive.