Authentication
The REST API uses HTTP Basic authentication. Pass your username and password with every request using the Authorization header.
curl -u admin:admin123 http://localhost:8080/api/projects
Using curl's -u user:pass flag is the simplest approach. For scripts, prefer storing credentials in environment variables:
export OTH_USER=admin export OTH_PASS=admin123 curl -u "$OTH_USER:$OTH_PASS" http://localhost:8080/api/projects
Security: Always use HTTPS in production. Never hard-code credentials in scripts committed to version control.
Base URL
All API endpoints are prefixed with /api. Replace localhost:8080 with your server hostname and port.
http://localhost:8080/api
All request and response bodies are application/json. Always include -H 'Content-Type: application/json' for write requests.
Error responses
On error, the API returns a standard HTTP status code and a JSON body:
{
"status": 404,
"error": "Not Found",
"message": "Project 'UNKNOWN' not found",
"timestamp": "2026-06-06T10:00:00Z"
}
| Status | Meaning |
|---|---|
200 | Success (GET, POST operations) |
201 | Resource created |
400 | Bad request — invalid JSON or missing required field |
401 | Unauthorised — missing or wrong credentials |
403 | Forbidden — authenticated but lacks permission |
404 | Resource not found |
409 | Conflict — e.g. duplicate project key |
500 | Internal server error |
Projects
List projects
GET
/api/projects
Returns all projects visible to the authenticated user.
Example request
curl -u admin:admin123 \ http://localhost:8080/api/projects
Example response
[
{
"id": 1,
"key": "ALPHA",
"name": "Project Alpha",
"description": "Main product backlog",
"visibility": "PRIVATE",
"owner": "admin",
"createdAt": "2026-06-01T09:00:00Z"
}
]
Create a project
POST
/api/projects
Creates a new project. Requires authentication.
Request body
| Field | Type | Required | Description |
|---|---|---|---|
key | string | Yes | Short unique identifier (e.g. ALPHA). Uppercase letters and digits only. |
name | string | Yes | Human-readable project name. |
description | string | No | Optional longer description. |
visibility | string | No | PUBLIC or PRIVATE (default: PRIVATE). |
Example request
curl -u admin:admin123 -X POST \ http://localhost:8080/api/projects \ -H 'Content-Type: application/json' \ -d '{ "key": "ALPHA", "name": "Project Alpha", "description": "Main product backlog", "visibility": "PRIVATE" }'
Example response (HTTP 201)
{
"id": 1,
"key": "ALPHA",
"name": "Project Alpha",
"description": "Main product backlog",
"visibility": "PRIVATE",
"owner": "admin",
"createdAt": "2026-06-06T09:00:00Z"
}
Issues
List issues
GET
/api/projects/{key}/issues
Returns all issues for the specified project.
Path parameters
| Parameter | Description |
|---|---|
key | The project key (e.g. ALPHA). |
Example request
curl -u admin:admin123 \ http://localhost:8080/api/projects/ALPHA/issues
Example response
[
{
"id": 1,
"number": 1,
"projectKey": "ALPHA",
"title": "Set up CI pipeline",
"description": "Configure GitHub Actions for build and test.",
"type": "TASK",
"status": "OPEN",
"priority": "NORMAL",
"reportedBy": "admin",
"assignee": null,
"createdAt": "2026-06-06T09:14:02Z",
"updatedAt": "2026-06-06T09:14:02Z"
}
]
Create an issue
POST
/api/projects/{key}/issues
Creates a new issue in the specified project.
Request body
| Field | Type | Required | Description |
|---|---|---|---|
title | string | Yes | Short summary of the issue. |
description | string | No | Detailed description. |
type | string | No | TASK, BUG, STORY, or EPIC. Default: TASK. |
priority | string | No | LOW, NORMAL, HIGH, or CRITICAL. Default: NORMAL. |
assignee | string | No | Username of the assignee. |
Example request
curl -u admin:admin123 -X POST \ http://localhost:8080/api/projects/ALPHA/issues \ -H 'Content-Type: application/json' \ -d '{ "title": "Login page crashes on empty password", "description": "Repro: submit login form with empty password field.", "type": "BUG", "priority": "CRITICAL" }'
Example response (HTTP 201)
{
"id": 2,
"number": 2,
"projectKey": "ALPHA",
"title": "Login page crashes on empty password",
"description": "Repro: submit login form with empty password field.",
"type": "BUG",
"status": "OPEN",
"priority": "CRITICAL",
"reportedBy": "admin",
"assignee": null,
"createdAt": "2026-06-06T10:00:00Z",
"updatedAt": "2026-06-06T10:00:00Z"
}
Get issue detail
GET
/api/projects/{key}/issues/{n}
Returns a single issue by its sequential number.
Path parameters
| Parameter | Description |
|---|---|
key | The project key. |
n | The issue number within the project (e.g. 2 for ALPHA-2). |
Example request
curl -u admin:admin123 \ http://localhost:8080/api/projects/ALPHA/issues/2
Example response
{
"id": 2,
"number": 2,
"projectKey": "ALPHA",
"title": "Login page crashes on empty password",
"type": "BUG",
"status": "IN_PROGRESS",
"priority": "CRITICAL",
"reportedBy": "admin",
"assignee": "bob",
"labels": ["bug", "frontend"],
"sprintId": 1,
"createdAt": "2026-06-06T10:00:00Z",
"updatedAt": "2026-06-06T11:30:00Z"
}
Sprints
List sprints
GET
/api/projects/{key}/sprints
Returns all sprints for the specified project.
Example request
curl -u admin:admin123 \ http://localhost:8080/api/projects/ALPHA/sprints
Example response
[
{
"id": 1,
"projectKey": "ALPHA",
"name": "Sprint 1",
"goal": "Deliver MVP authentication flow",
"status": "ACTIVE",
"startDate": "2026-06-01",
"endDate": "2026-06-14",
"createdAt": "2026-05-30T14:00:00Z"
}
]
Create a sprint
POST
/api/projects/{key}/sprints
Creates a new sprint in PLANNING status.
Request body
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Sprint name (e.g. "Sprint 1"). |
goal | string | No | Sprint goal description. |
startDate | string | No | ISO date: YYYY-MM-DD. |
endDate | string | No | ISO date: YYYY-MM-DD. |
Example request
curl -u admin:admin123 -X POST \ http://localhost:8080/api/projects/ALPHA/sprints \ -H 'Content-Type: application/json' \ -d '{ "name": "Sprint 1", "goal": "Deliver MVP authentication flow", "startDate": "2026-06-01", "endDate": "2026-06-14" }'
Example response (HTTP 201)
{
"id": 1,
"projectKey": "ALPHA",
"name": "Sprint 1",
"goal": "Deliver MVP authentication flow",
"status": "PLANNING",
"startDate": "2026-06-01",
"endDate": "2026-06-14",
"createdAt": "2026-05-30T14:00:00Z"
}
Start a sprint
POST
/api/projects/{key}/sprints/{id}/start
Transitions a sprint from PLANNING to ACTIVE.
Path parameters
| Parameter | Description |
|---|---|
key | The project key. |
id | The sprint ID. |
Example request
curl -u admin:admin123 -X POST \ http://localhost:8080/api/projects/ALPHA/sprints/1/start
Example response
{
"id": 1,
"name": "Sprint 1",
"status": "ACTIVE",
"startDate": "2026-06-01",
"endDate": "2026-06-14"
}
Complete a sprint
POST
/api/projects/{key}/sprints/{id}/complete
Transitions a sprint from ACTIVE to COMPLETED.
Example request
curl -u admin:admin123 -X POST \ http://localhost:8080/api/projects/ALPHA/sprints/1/complete
Example response
{
"id": 1,
"name": "Sprint 1",
"status": "COMPLETED",
"startDate": "2026-06-01",
"endDate": "2026-06-14"
}
Sprint Issue Assignment
Add issue to sprint
POST
/api/projects/{key}/sprints/{id}/issues/{n}
Assigns an issue to a sprint.
Path parameters
| Parameter | Description |
|---|---|
key | The project key. |
id | The sprint ID. |
n | The issue number within the project. |
Example request
curl -u admin:admin123 -X POST \ http://localhost:8080/api/projects/ALPHA/sprints/1/issues/2
Example response (HTTP 200)
{
"message": "Issue ALPHA-2 added to Sprint 1"
}
Remove issue from sprint
DELETE
/api/projects/{key}/sprints/{id}/issues/{n}
Removes an issue from a sprint (issue returns to backlog).
Example request
curl -u admin:admin123 -X DELETE \ http://localhost:8080/api/projects/ALPHA/sprints/1/issues/2
Example response (HTTP 200)
{
"message": "Issue ALPHA-2 removed from Sprint 1"
}