Issue Tracker
Vetrix includes a built-in issue tracker. Each repository has its own issues with sequential numbers, comments, labels, milestones, and assignees.
Issues
List issues
GET /api/v1/repos/{owner}/{repo}/issues
Query parameters:
| Parameter | Type | Description |
|---|---|---|
state |
string | Filter by state: open or closed. Default: all |
label |
string | Filter by label name |
page |
int | Page number (1-indexed). Default: 1 |
per_page |
int | Results per page. Default: 25, max: 100 |
Response 200 OK
[
{
"id": "uuid",
"repo_id": "uuid",
"number": 1,
"author_id": "uuid",
"title": "Login flow broken on mobile",
"body": "Reproduced on iOS 17...",
"state": "open",
"milestone_id": "uuid",
"locked": false,
"created_at": "2026-04-10T12:00:00Z",
"updated_at": "2026-04-10T12:00:00Z"
}
]
Create issue
POST /api/v1/repos/{owner}/{repo}/issues
Body
{
"title": "Login flow broken on mobile",
"body": "Reproduced on iOS 17...",
"milestone_id": "uuid"
}
title is required. milestone_id is optional.
Response 201 Created — the created issue object.
Get issue
GET /api/v1/repos/{owner}/{repo}/issues/{number}
Response 200 OK — the issue object.
Update issue
PATCH /api/v1/repos/{owner}/{repo}/issues/{number}
Only the issue author, repository owner, or an admin may update an issue.
Body — all fields optional:
{
"title": "Updated title",
"body": "Updated description",
"milestone_id": "uuid",
"locked": true
}
Response 200 OK — the updated issue object.
Close / reopen
POST /api/v1/repos/{owner}/{repo}/issues/{number}/close
POST /api/v1/repos/{owner}/{repo}/issues/{number}/reopen
Only the issue author, repository owner, or an admin may close or reopen an issue.
Response 204 No Content
Issue comments
List comments
GET /api/v1/repos/{owner}/{repo}/issues/{number}/comments
Response 200 OK
[
{
"id": "uuid",
"issue_id": "uuid",
"author_id": "uuid",
"body": "I can reproduce this.",
"created_at": "2026-04-10T12:05:00Z",
"updated_at": "2026-04-10T12:05:00Z"
}
]
Create comment
POST /api/v1/repos/{owner}/{repo}/issues/{number}/comments
Body
{
"body": "I can reproduce this."
}
Response 201 Created — the created comment object.
Full-text search
GET /api/v1/repos/{owner}/{repo}/issues/search?q={query}
Searches issue titles and bodies using PostgreSQL full-text search (websearch_to_tsquery). Title matches are ranked higher than body matches.
Query parameters:
| Parameter | Type | Description |
|---|---|---|
q |
string | Search query (required) |
limit |
int | Maximum results. Default: 25, max: 100 |
Response 200 OK
[
{
"id": "uuid",
"number": 5,
"title": "Login bug",
"rank": 0.0759615
}
]
The rank field is the ts_rank score; higher means more relevant.
Supported query syntax (PostgreSQL websearch_to_tsquery):
| Example | Meaning |
|---|---|
login bug |
Both words anywhere |
"login bug" |
Exact phrase |
login -timeout |
Exclude timeout |
login OR crash |
Either word |
Labels
Labels are per-repository tags that can be attached to issues.
List labels
GET /api/v1/repos/{owner}/{repo}/labels
Response 200 OK
[
{ "id": "uuid", "repo_id": "uuid", "name": "bug", "color": "e11d48" }
]
Create label
POST /api/v1/repos/{owner}/{repo}/labels
Requires repository owner or admin.
Body
{
"name": "bug",
"color": "e11d48"
}
color must be a 6-character lowercase or uppercase hex string without the leading # (e.g. e11d48, not #e11d48).
Response 201 Created — the created label object.
Delete label
DELETE /api/v1/repos/{owner}/{repo}/labels/{name}
Requires repository owner or admin. Deleting a label also removes it from all issues it was attached to.
Response 204 No Content
Milestones
Milestones group issues for a release or sprint.
List milestones
GET /api/v1/repos/{owner}/{repo}/milestones
Query parameters:
| Parameter | Type | Description |
|---|---|---|
state |
string | Filter by state: open or closed. Default: all |
Response 200 OK
[
{
"id": "uuid",
"repo_id": "uuid",
"title": "v1.0",
"description": "First stable release",
"due_date": "2026-05-01T00:00:00Z",
"state": "open",
"created_at": "2026-04-10T12:00:00Z"
}
]
Create milestone
POST /api/v1/repos/{owner}/{repo}/milestones
Requires repository owner or admin.
Body
{
"title": "v1.0",
"description": "First stable release",
"due_date": "2026-05-01T00:00:00Z"
}
title is required. due_date is optional.
Response 201 Created — the created milestone object.
Get milestone
GET /api/v1/repos/{owner}/{repo}/milestones/{id}
Response 200 OK — the milestone object.
Update milestone
PATCH /api/v1/repos/{owner}/{repo}/milestones/{id}
Requires repository owner or admin.
Body — all fields optional:
{
"title": "v1.1",
"description": "Patch release",
"due_date": "2026-06-01T00:00:00Z",
"state": "closed"
}
state must be open or closed.
Response 200 OK — the updated milestone object.
Delete milestone
DELETE /api/v1/repos/{owner}/{repo}/milestones/{id}
Requires repository owner or admin. Issues associated with the deleted milestone have their milestone_id set to null.
Response 204 No Content
Auto-close mentions
Commits and merge request descriptions are scanned for auto-close keywords. When a merge request that contains such a mention is merged, the referenced issue is automatically closed.
Supported keywords (case-insensitive)
| Keyword variants | Canonical form |
|---|---|
close, closes, closed |
closes |
fix, fixes, fixed |
fixes |
resolve, resolves, resolved |
resolves |
Formats
closes #5 → same-repository issue 5
fixes owner/repo#12 → cross-repository issue 12
resolves alice/myrepo#3 → cross-repository issue 3
Multiple mentions in the same message are all processed. Duplicate mentions of the same issue are deduplicated.
Example commit message
fix: handle nil pointer in auth middleware
closes #42
fixes alice/shared#7
Both issues will be closed when the commit lands on the default branch via a merged merge request.