API v2 Β· REST Β· JSON

NoackHub API

Build integrations, CLI tools, and your own clients. The whole feature surface is exposed as JSON with code samples in 6 languages.

πŸš€ Getting started

All requests go to https://dev.noackhub.noackhosting.net/api/v2. Authenticate with the header Authorization: token <din-token>.

Get tokens via POST /auth/login below.

πŸ“‹ Roles

RoleCan
userCreate repos, issues, PRs. Own settings.
customer_admin+ invite & administer their own invited users.
site_admin+ audit log + all users.
POST /auth/login

Logga in och fΓ₯ API-token. Anonyma anrop.

Request body (JSON):
{
  "password": "PASS",
  "username": "USER"
}
curl -X POST \
  -H 'Content-Type: application/json' \
  -d '{
  "password": "PASS",
  "username": "USER"
}' \
  https://dev.noackhub.noackhosting.net/api/v2/auth/login
πŸ“¦ Expected response (200)
{
  "token": "abc123def456...",
  "user": {"login": "anna", "email": "anna@ex.se", "is_admin": false}
}
GET /me πŸ”’ auth

HΓ€mta din egna user-info.

curl -X GET \
  -H "Authorization: token $TOKEN" \
  https://dev.noackhub.noackhosting.net/api/v2/me
πŸ“¦ Expected response (200)
{
  "id": 4,
  "login": "anna",
  "full_name": "Anna Andersson",
  "email": "anna@ex.se",
  "avatar_url": "https://noackhub.noackhosting.net/avatars/...",
  "is_admin": false
}
GET /me/state πŸ”’ auth

Onboarding-status (2FA, SSH-key, roll).

curl -X GET \
  -H "Authorization: token $TOKEN" \
  https://dev.noackhub.noackhosting.net/api/v2/me/state
πŸ“¦ Expected response (200)
{
  "role": "user",
  "twofa_enabled": true,
  "ssh_key_added": true,
  "invited_by": "mikael",
  "activated_at": "2026-05-12T10:14:21Z"
}
PATCH /me/profile πŸ”’ auth

Uppdatera profilfΓ€lt.

Request body (JSON):
{
  "email": "anna@ex.se",
  "full_name": "Anna Andersson",
  "location": "Stockholm"
}
curl -X PATCH \
  -H "Authorization: token $TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{
  "email": "anna@ex.se",
  "full_name": "Anna Andersson",
  "location": "Stockholm"
}' \
  https://dev.noackhub.noackhosting.net/api/v2/me/profile
πŸ“¦ Expected response (200)
{"ok": true}
POST /me/password πŸ”’ auth

Byt eget lΓΆsenord.

Request body (JSON):
{
  "new_password": "newPass12chars",
  "old_password": "oldPass"
}
curl -X POST \
  -H "Authorization: token $TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{
  "new_password": "newPass12chars",
  "old_password": "oldPass"
}' \
  https://dev.noackhub.noackhosting.net/api/v2/me/password
πŸ“¦ Expected response (200)
{"ok": true}
POST /me/2fa/setup πŸ”’ auth

Generera TOTP-secret + QR-kod (base64 PNG).

curl -X POST \
  -H "Authorization: token $TOKEN" \
  https://dev.noackhub.noackhosting.net/api/v2/me/2fa/setup
πŸ“¦ Expected response (200)
{"secret": "JBSWY3DPEHPK3PXP", "qr_png_base64": "iVBORw0KGgo...", "otpauth_url": "otpauth://totp/..."}
POST /me/2fa/confirm πŸ”’ auth

BekrΓ€fta enrollment med TOTP-kod.

Request body (JSON):
{
  "code": "123456"
}
curl -X POST \
  -H "Authorization: token $TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{
  "code": "123456"
}' \
  https://dev.noackhub.noackhosting.net/api/v2/me/2fa/confirm
πŸ“¦ Expected response (200)
{"ok": true}
POST /me/2fa/verify πŸ”’ auth

Verifiera TOTP-kod vid login.

Request body (JSON):
{
  "code": "123456"
}
curl -X POST \
  -H "Authorization: token $TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{
  "code": "123456"
}' \
  https://dev.noackhub.noackhosting.net/api/v2/me/2fa/verify
πŸ“¦ Expected response (200)
{"ok": true}
POST /me/2fa/disable πŸ”’ auth

StΓ€ng av 2FA.

Request body (JSON):
{
  "code": "123456"
}
curl -X POST \
  -H "Authorization: token $TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{
  "code": "123456"
}' \
  https://dev.noackhub.noackhosting.net/api/v2/me/2fa/disable
πŸ“¦ Expected response (200)
{"ok": true}
GET /me/keys πŸ”’ auth

Lista SSH-nycklar.

curl -X GET \
  -H "Authorization: token $TOKEN" \
  https://dev.noackhub.noackhosting.net/api/v2/me/keys
πŸ“¦ Expected response (200)
[
  {"id": 7, "title": "laptop", "fingerprint": "SHA256:abc...", "key": "ssh-ed25519 AAAAC3..."}
]
POST /me/keys πŸ”’ auth

LΓ€gg till SSH-nyckel.

Request body (JSON):
{
  "key": "ssh-ed25519 AAAA...",
  "title": "laptop"
}
curl -X POST \
  -H "Authorization: token $TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{
  "key": "ssh-ed25519 AAAA...",
  "title": "laptop"
}' \
  https://dev.noackhub.noackhosting.net/api/v2/me/keys
πŸ“¦ Expected response (201)
{"id": 8, "title": "laptop", "fingerprint": "SHA256:abc...", "key": "ssh-ed25519 AAAA..."}
DELETE /me/keys/{id} πŸ”’ auth

Ta bort SSH-nyckel.

curl -X DELETE \
  -H "Authorization: token $TOKEN" \
  https://dev.noackhub.noackhosting.net/api/v2/me/keys/{id}
πŸ“¦ Expected response (200)
{"ok": true}
GET /repos πŸ”’ auth

Lista mina repos.

curl -X GET \
  -H "Authorization: token $TOKEN" \
  https://dev.noackhub.noackhosting.net/api/v2/repos
πŸ“¦ Expected response (200)
[
  {
    "id": 12,
    "name": "mitt-repo",
    "full_name": "anna/mitt-repo",
    "private": false,
    "html_url": "https://noackhub.noackhosting.net/anna/mitt-repo",
    "ssh_url": "ssh://git@noackhub.noackhosting.net:2222/anna/mitt-repo.git",
    "clone_url": "https://noackhub.noackhosting.net/anna/mitt-repo.git",
    "default_branch": "main",
    "updated_at": "2026-05-13T08:42:01Z"
  }
]
POST /repos πŸ”’ auth

Skapa nytt repo.

Request body (JSON):
{
  "auto_init": true,
  "description": "Hello",
  "name": "mitt-repo",
  "private": false
}
curl -X POST \
  -H "Authorization: token $TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{
  "auto_init": true,
  "description": "Hello",
  "name": "mitt-repo",
  "private": false
}' \
  https://dev.noackhub.noackhosting.net/api/v2/repos
πŸ“¦ Expected response (201)
{
  "id": 13,
  "name": "mitt-repo",
  "full_name": "anna/mitt-repo",
  "private": false,
  "html_url": "https://noackhub.noackhosting.net/anna/mitt-repo",
  "ssh_url": "ssh://git@noackhub.noackhosting.net:2222/anna/mitt-repo.git",
  "default_branch": "main"
}
GET /repos/{owner}/{repo} πŸ”’ auth

HΓ€mta repo-detalj.

curl -X GET \
  -H "Authorization: token $TOKEN" \
  https://dev.noackhub.noackhosting.net/api/v2/repos/{owner}/{repo}
πŸ“¦ Expected response (200)
{
  "id": 13,
  "name": "mitt-repo",
  "full_name": "anna/mitt-repo",
  "private": false,
  "html_url": "https://noackhub.noackhosting.net/anna/mitt-repo",
  "ssh_url": "ssh://git@noackhub.noackhosting.net:2222/anna/mitt-repo.git",
  "default_branch": "main"
}
PATCH /repos/{owner}/{repo} πŸ”’ auth

Redigera repo.

Request body (JSON):
{
  "description": "Updated",
  "private": true
}
curl -X PATCH \
  -H "Authorization: token $TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{
  "description": "Updated",
  "private": true
}' \
  https://dev.noackhub.noackhosting.net/api/v2/repos/{owner}/{repo}
πŸ“¦ Expected response (200)
{
  "id": 13,
  "name": "mitt-repo",
  "full_name": "anna/mitt-repo",
  "private": false,
  "html_url": "https://noackhub.noackhosting.net/anna/mitt-repo",
  "ssh_url": "ssh://git@noackhub.noackhosting.net:2222/anna/mitt-repo.git",
  "default_branch": "main"
}
DELETE /repos/{owner}/{repo} πŸ”’ auth

Radera repo.

curl -X DELETE \
  -H "Authorization: token $TOKEN" \
  https://dev.noackhub.noackhosting.net/api/v2/repos/{owner}/{repo}
πŸ“¦ Expected response (200)
{"ok": true}
GET /repos/{owner}/{repo}/contents/{path} πŸ”’ auth

Lista filer eller hΓ€mta fil-innehΓ₯ll.

curl -X GET \
  -H "Authorization: token $TOKEN" \
  https://dev.noackhub.noackhosting.net/api/v2/repos/{owner}/{repo}/contents/{path}
πŸ“¦ Expected response (200)
[{"name": "README.md", "type": "file", "path": "README.md", "size": 142}]
GET /repos/{owner}/{repo}/commits πŸ”’ auth

Senaste commits.

curl -X GET \
  -H "Authorization: token $TOKEN" \
  https://dev.noackhub.noackhosting.net/api/v2/repos/{owner}/{repo}/commits
πŸ“¦ Expected response (200)
[
  {
    "sha": "f0a1b2c3d4e5",
    "commit": {"message": "Initial commit", "author": {"name": "anna", "email": "anna@ex.se", "date": "2026-05-13T08:00:00Z"}},
    "html_url": "https://noackhub.noackhosting.net/anna/mitt-repo/commit/f0a1b2c3d4e5"
  }
]
GET /repos/{owner}/{repo}/collaborators πŸ”’ auth

Lista collaborators.

curl -X GET \
  -H "Authorization: token $TOKEN" \
  https://dev.noackhub.noackhosting.net/api/v2/repos/{owner}/{repo}/collaborators
πŸ“¦ Expected response (200)
[{"login": "kund2", "permission": "write"}]
POST /repos/{owner}/{repo}/collaborators πŸ”’ auth

LΓ€gg till collaborator.

Request body (JSON):
{
  "permission": "write",
  "username": "kund2"
}
curl -X POST \
  -H "Authorization: token $TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{
  "permission": "write",
  "username": "kund2"
}' \
  https://dev.noackhub.noackhosting.net/api/v2/repos/{owner}/{repo}/collaborators
πŸ“¦ Expected response (201)
{"ok": true}
GET /repos/{owner}/{repo}/issues πŸ”’ auth

Lista issues (?state=open|closed|all).

curl -X GET \
  -H "Authorization: token $TOKEN" \
  https://dev.noackhub.noackhosting.net/api/v2/repos/{owner}/{repo}/issues
πŸ“¦ Expected response (200)
[
  {
    "id": 101,
    "number": 1,
    "title": "Bug",
    "state": "open",
    "user": {"login": "anna"},
    "body": "Steps to reproduce...",
    "created_at": "2026-05-13T08:30:00Z",
    "comments": 0
  }
]
POST /repos/{owner}/{repo}/issues πŸ”’ auth

Skapa issue.

Request body (JSON):
{
  "body": "Steps to reproduce...",
  "title": "Bug"
}
curl -X POST \
  -H "Authorization: token $TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{
  "body": "Steps to reproduce...",
  "title": "Bug"
}' \
  https://dev.noackhub.noackhosting.net/api/v2/repos/{owner}/{repo}/issues
πŸ“¦ Expected response (201)
{
  "id": 102,
  "number": 2,
  "title": "Bug",
  "state": "open",
  "user": {"login": "anna"},
  "body": "Steps to reproduce...",
  "html_url": "https://noackhub.noackhosting.net/anna/mitt-repo/issues/2"
}
GET /repos/{owner}/{repo}/issues/{number} πŸ”’ auth

HΓ€mta issue + kommentarer.

curl -X GET \
  -H "Authorization: token $TOKEN" \
  https://dev.noackhub.noackhosting.net/api/v2/repos/{owner}/{repo}/issues/{number}
πŸ“¦ Expected response (200)
{
  "id": 101,
  "number": 1,
  "title": "Bug",
  "state": "open",
  "body": "Steps to reproduce...",
  "user": {"login": "anna"},
  "comments_list": [
    {"id": 222, "body": "I can confirm this.", "user": {"login": "bob"}, "created_at": "2026-05-13T09:00:00Z"}
  ]
}
POST /repos/{owner}/{repo}/issues/{number}/comments πŸ”’ auth

Kommentera issue.

Request body (JSON):
{
  "body": "Min kommentar"
}
curl -X POST \
  -H "Authorization: token $TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{
  "body": "Min kommentar"
}' \
  https://dev.noackhub.noackhosting.net/api/v2/repos/{owner}/{repo}/issues/{number}/comments
πŸ“¦ Expected response (201)
{"id": 223, "body": "Min kommentar", "user": {"login": "anna"}, "created_at": "2026-05-13T10:30:00Z"}
POST /repos/{owner}/{repo}/issues/{number}/state πŸ”’ auth

StΓ€ng eller ΓΆppna issue.

Request body (JSON):
{
  "state": "closed"
}
curl -X POST \
  -H "Authorization: token $TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{
  "state": "closed"
}' \
  https://dev.noackhub.noackhosting.net/api/v2/repos/{owner}/{repo}/issues/{number}/state
πŸ“¦ Expected response (200)
{"ok": true}
GET /repos/{owner}/{repo}/pulls πŸ”’ auth

Lista pull requests.

curl -X GET \
  -H "Authorization: token $TOKEN" \
  https://dev.noackhub.noackhosting.net/api/v2/repos/{owner}/{repo}/pulls
πŸ“¦ Expected response (200)
[{"id": 50, "number": 1, "title": "Add feature X", "state": "open", "user": {"login": "anna"}, "head": "feature-x", "base": "main"}]
GET /repos/{owner}/{repo}/pulls/{number} πŸ”’ auth

PR-detalj + kommentarer.

curl -X GET \
  -H "Authorization: token $TOKEN" \
  https://dev.noackhub.noackhosting.net/api/v2/repos/{owner}/{repo}/pulls/{number}
πŸ“¦ Expected response (200)
{"id": 50, "number": 1, "title": "Add feature X", "state": "open", "body": "...", "comments_list": []}
GET /repos/{owner}/{repo}/releases πŸ”’ auth

Lista releases.

curl -X GET \
  -H "Authorization: token $TOKEN" \
  https://dev.noackhub.noackhosting.net/api/v2/repos/{owner}/{repo}/releases
πŸ“¦ Expected response (200)
[
  {"id": 5, "tag_name": "v1.0.0", "name": "First stable", "draft": false, "prerelease": false, "published_at": "2026-05-10T12:00:00Z"}
]
GET /repos/{owner}/{repo}/releases/{tag} πŸ”’ auth

Release-detalj.

curl -X GET \
  -H "Authorization: token $TOKEN" \
  https://dev.noackhub.noackhosting.net/api/v2/repos/{owner}/{repo}/releases/{tag}
πŸ“¦ Expected response (200)
{"id": 5, "tag_name": "v1.0.0", "name": "First stable", "body": "Changelog...", "draft": false}
GET /repos/{owner}/{repo}/actions/runs πŸ”’ auth

Lista workflow-runs.

curl -X GET \
  -H "Authorization: token $TOKEN" \
  https://dev.noackhub.noackhosting.net/api/v2/repos/{owner}/{repo}/actions/runs
πŸ“¦ Expected response (200)
[{"id": 17, "status": "success", "head_branch": "main", "head_sha": "f0a1b2c", "run_number": 4, "created_at": "2026-05-13T09:00:00Z"}]
GET /repos/{owner}/{repo}/actions/runs/{id} πŸ”’ auth

Run-detalj.

curl -X GET \
  -H "Authorization: token $TOKEN" \
  https://dev.noackhub.noackhosting.net/api/v2/repos/{owner}/{repo}/actions/runs/{id}
πŸ“¦ Expected response (200)
{"id": 17, "status": "success", "head_branch": "main", "head_sha": "f0a1b2c", "jobs": []}
GET /repos/{owner}/{repo}/actions/runs/{id}/jobs πŸ”’ auth

Jobs i en run.

curl -X GET \
  -H "Authorization: token $TOKEN" \
  https://dev.noackhub.noackhosting.net/api/v2/repos/{owner}/{repo}/actions/runs/{id}/jobs
πŸ“¦ Expected response (200)
[{"id": 88, "name": "build", "status": "success", "started_at": "2026-05-13T09:00:10Z", "completed_at": "2026-05-13T09:01:42Z"}]
GET /repos/{owner}/{repo}/actions/jobs/{id}/logs πŸ”’ auth

Plain text-loggar (Content-Type: text/plain).

curl -X GET \
  -H "Authorization: token $TOKEN" \
  https://dev.noackhub.noackhosting.net/api/v2/repos/{owner}/{repo}/actions/jobs/{id}/logs
πŸ“¦ Expected response (200)
Set up job
Run actions/checkout@v4
...
GET /admin/invites πŸ”’ auth

Lista invites. customer_admin ser bara egna.

curl -X GET \
  -H "Authorization: token $TOKEN" \
  https://dev.noackhub.noackhosting.net/api/v2/admin/invites
πŸ“¦ Expected response (200)
[
  {"id": 3, "username": "kund1", "email": "kund@ex.se", "role": "user", "invited_by": "mikael", "status": "pending", "created_at": "2026-05-13T07:00:00Z"}
]
POST /admin/invites πŸ”’ auth

Skapa invite + skicka aktiveringsmail.

Request body (JSON):
{
  "email": "kund@ex.se",
  "fullName": "Kund Namn",
  "role": "user",
  "username": "kund1"
}
curl -X POST \
  -H "Authorization: token $TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{
  "email": "kund@ex.se",
  "fullName": "Kund Namn",
  "role": "user",
  "username": "kund1"
}' \
  https://dev.noackhub.noackhosting.net/api/v2/admin/invites
πŸ“¦ Expected response (201)
{"id": 4, "username": "kund1", "email": "kund@ex.se", "role": "user", "token": "...", "status": "pending"}
GET /admin/users πŸ”’ auth

Lista alla anvΓ€ndare.

curl -X GET \
  -H "Authorization: token $TOKEN" \
  https://dev.noackhub.noackhosting.net/api/v2/admin/users
πŸ“¦ Expected response (200)
[
  {"id": 1, "login": "mikael", "email": "mikael@noackinfra.se", "is_admin": true, "active": true, "role": "site_admin"},
  {"id": 4, "login": "anna", "email": "anna@ex.se", "is_admin": false, "active": true, "role": "user"}
]
POST /admin/users/{user}/disable πŸ”’ auth

Inaktivera user.

curl -X POST \
  -H "Authorization: token $TOKEN" \
  https://dev.noackhub.noackhosting.net/api/v2/admin/users/{user}/disable
πŸ“¦ Expected response (200)
{"ok": true}
POST /admin/users/{user}/enable πŸ”’ auth

Aktivera user.

curl -X POST \
  -H "Authorization: token $TOKEN" \
  https://dev.noackhub.noackhosting.net/api/v2/admin/users/{user}/enable
πŸ“¦ Expected response (200)
{"ok": true}
DELETE /admin/users/{user} πŸ”’ auth

Radera user (purge).

curl -X DELETE \
  -H "Authorization: token $TOKEN" \
  https://dev.noackhub.noackhosting.net/api/v2/admin/users/{user}
πŸ“¦ Expected response (200)
{"ok": true}

Questions? Email support@noackhosting.se