API: REST endpoint to move project cards between columns (PAT-compatible) #3
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Problem
Gitea has no REST endpoint to move a project board card between columns. The only existing route is the web handler
POST /{owner}/-/projects/{id}/move, which gates on browser session + CSRF token — calling it with a PAT returns HTTP 303 redirecting to/user/login, which is easy to mistake for a successful 3xx.What works today (read + link)
PATCH /api/v1/repos/{owner}/{repo}/issues/{n}with{"projects":[<id>, ...]}— links an issue to a project (defaults the card to the project's default column).GET /api/v1/users/{u}/projects/{id}/columnsand.../columns/{col_id}/issues— landed in #1 / #2 for user and org scopes (parity with repo scope).What's missing (write — column placement)
POST /api/v1/projects/columns/{column_id}/move-issue(or equivalent) to place a card into a specific column./moveroute can't be called with a PAT.Proposal
Add REST write endpoints for project board column operations, symmetric to the read endpoints already merged. Candidate surface:
POST /api/v1/projects/columns/{column_id}/issues— body:{issue_id, sorting?}— place card into column at position.PATCH /api/v1/projects/columns/{column_id}/issues/{issue_id}— body:{target_column_id?, sorting?}— move card to another column or reorder.Auth: same PAT scopes as the existing project read endpoints.
Related
move_issuewrite method is exposed but has no working underlying API to callTrap
An HTTP 303 from a Gitea web route called with a PAT is an auth-bounce to login, not success. Any new endpoint must return a real API response (200/204 with JSON), not a redirect.
Already shipped in #2 (merged). Both list-per-column and move-card-between-columns are PAT-compatible REST endpoints today:
List issues in a column
Move card between columns
Note:
issue_idis the issue's internalid(top-level field on the issue object), not the per-repoindex.Smoke test against project 7 (2026-05-15)
Before: col 27 (High Priority) had 0 issues. After: 1 issue. Reverse move with
{"column_id":25}→ 204, state restored. List endpoint returned correct counts at every step.Note on the proposed shape
The issue proposed a global, owner-less endpoint (
POST /api/v1/projects/columns/{column_id}/issues). The shipped surface is owner-scoped (/users/{u}/...or/orgs/{org}/...) which mirrors the existing repo-scope conventions. If you want the global variant as a more ergonomic alternative, file a follow-up — but the missing functionality is no longer missing.Closing as resolved.