API Reference

Public REST endpoints reachable with a personal access token.

Authentication

Issue a personal access token from Profile → Integrations → Access tokens with the scope an endpoint requires below, then send it as "Authorization: Bearer velocis_pat_...". A token only reaches what its scopes allow — it never bypasses your own project permissions.

Sign in to issue a token

Issues

GET/issues
List issues

Returns a page of issues the token owner can see, newest first. Every filter is optional; limit is clamped to 1000 server-side.

Required scope: issues:read
Parameters
NameInRequiredTypeDescription
allocatablequeryOptionalstring`true` or `1` to drop issues whose status cannot receive a resource allocation. Adds to any `excludeStatuses` you pass rather than replacing it.
assignedToMequeryOptionalstring`true` or `1` to narrow to issues assigned to the caller. Applied outside `q`, so an `OR` in `q` cannot widen past it.
assigneeIdqueryOptionalstringNarrow to one assignee, by user id — or the literal `unassigned` for issues with nobody assigned.
excludeStatusesqueryOptionalstringComma-separated statuses to exclude. Parsed exactly like `statuses`.
facetsqueryOptionalstringComma-separated dimensions to count over the same filters, returned as `meta.facets`: `status`, `priority`, `assignee`, `project`, `sprint`, `type`, `epic`, `milestone`. Each dimension is counted without its own filter.
filteredFacetsqueryOptionalstringLike `facets`, but each dimension is counted under the FULL query, its own filter included — how many of the matching issues carry each value. Returned as `meta.filteredFacets`. In both, a bucket is `{ groupId, groupValue, totalCount }`; an `epic` bucket other than `no-epic` also carries `epicStatus`, the status of the epic issue itself; a `milestone` bucket other than `none` also carries the milestone `status` (`open` / `closed`) and its `position` in the project order. A `filteredFacets` bucket also carries `storyPoints`, the points of the bucket under the estimate rule in force: the own points of its members; with `advanced.features.leafEstimateRollup` on, the points of the members that are estimate leaves among ALL the matching issues (a sub-issue outside the result hides nothing), so the buckets add up to the result and the buckets of a sprint to its summary. A `milestone` bucket is always the closure minus the descendants assigned to another milestone. It is seeded from the matching members, so it equals the milestone progress points only when the list is unfiltered.
groupByqueryOptionalstringField being grouped by, such as `status` or `assignee`. Takes effect only together with `groupValue`.
groupValuequeryOptionalstringWhich group within `groupBy` to return — one status, one assignee id (`unassigned` for none), one epic id (`no-epic`), or one milestone id (`none`).
includeArchivedqueryOptionalstring`true` or `1` to return archived issues alongside active ones.
limitqueryOptionalnumberPage size. Defaults to 50 and is clamped to 1000.
onlyArchivedqueryOptionalstring`true` or `1` to return only archived issues. Checked before `includeArchived`, so the two cannot contradict each other.
pagequeryOptionalnumber1-based page number. Defaults to 1.
projectIdqueryOptionalstringNarrow to one project, by id. Use `projectIds` for several.
projectIdsqueryOptionalstringComma-separated project ids, to query across several projects at once. Entries that are not ids are dropped.
qqueryOptionalstringSearch query in the advanced-search grammar (`status:todo assignee:me is:open sort:priority-desc login`), combined with every other filter; at most 2000 characters. Free text ranks by relevance unless `sortBy` or a `sort:` token is set. Tokens that did not apply are listed in `meta.query.ignoredTokens`; the ordering that ran is `meta.appliedSort`.
sortByqueryOptionalstringField to sort by. A field outside the allowed set leaves the default ordering in place. Wins over a `sort:` token in `q`.
sortOrderqueryOptionalstring`asc` or `desc`. Applies only with `sortBy`; any other value reads as `asc`.
sprintIdqueryOptionalstringNarrow to the issues in one sprint, by id. Applied outside `q`, so an `OR` in `q` cannot widen past it.
statusqueryOptionalstringNarrow to a single status. Use `statuses` to pass several.
statusesqueryOptionalstringComma-separated statuses to include. Unrecognised values are dropped; if none survive, the filter is not applied rather than matching nothing.
tagIdsqueryOptionalstringComma-separated tag ids. Entries that are not ids are dropped.
unallocatedqueryOptionalstring`true` or `1` to return only issues that have no resource allocations.
Responses
200

A page of issues. Each row carries `allocation: { capability: 'manage' | 'self' | 'none', reason?: 'no_permission' | 'issue_archived' | 'issue_container' | 'issue_cancelled' }` — what the caller's CURRENT credential may do. Allocation routes do not accept personal access tokens, so a token request always reads `none` / `no_permission`. `meta.stats` counts the matching issues per status; `meta.query` is the parsed `q` (its `ignoredTokens` did not apply); `meta.appliedSort` is the ordering that ran; `meta.facets` is present when `facets` was requested.

403

The token lacks `issues:read`.

POST/issues
Create an issue

Creates an issue in the given project. The token owner must have permission to create issues there — the issues:write scope narrows the token, it does not grant access.

Required scope: issues:write
Request body
Responses
201

The created issue.

403

The token lacks `issues:write`, or its owner may not create issues in this project.

GET/issues/{id}
Get one issue

Returns a single issue by its id. 403 when the token owner cannot see it — the scope is a ceiling over their own permissions, never a grant.

Required scope: issues:read
Parameters
NameInRequiredTypeDescription
idpathRequiredstringThe issue's id. Not the issue number — `VEL-101` is rejected here.
Responses
200

The issue.

404

No such issue.

Projects

GET/projects
List projects

Returns the projects the token owner is a member of. Pass minimal=true for id + name only, which is what a script addressing issues usually needs.

Required scope: projects:read
Parameters
NameInRequiredTypeDescription
includeArchivedqueryOptionalstring`true` or `1` to return archived projects alongside active ones.
minimalqueryOptionalstring`true` or `1` to return only id and name per project — enough to address issues, and much smaller.
Responses
200

The projects.

403

The token lacks `projects:read`.

GET/projects/{id}
Get one project

Returns a single project by its id, including its workflow metadata. 403 when the token owner is not a member.

Required scope: projects:read
Parameters
NameInRequiredTypeDescription
idpathRequiredstringThe project's id, as returned by `GET /projects`.
Responses
200

The project.

404

No such project.