VectorKan API
A REST API for putting VectorKan inside your own systems — create tickets from your app, sync status with your tools, and pull everything your customers have reported. JSON in, JSON out, over HTTPS.
http://www.vectorkan.com/api/v1
The API is available on the Business plan.Getting started
- Create a key. In VectorKan, go to API keys in the sidebar and create one. The secret is shown once — store it somewhere safe.
- Check it works. Call
GET /me— it returns the workspace the key opens. - Find your project.
GET /projectsreturns each project'sid, which you need to create tickets. - Create your first ticket.
POST /issueswith that project id and a title.
curl http://www.vectorkan.com/api/v1/me \
-H "X-Api-Key: vk_your_key_here"
Authentication
Every request needs your key in an X-Api-Key header. The key identifies your
workspace, so you never pass a workspace id — and a key can only ever see its own
company's data.
X-Api-Key: vk_1a2b3c4d5e6f...
Errors & status codes
Failures return a JSON body with a single error field explaining what went wrong.
{ "error": "Title is required." }
| Code | Meaning |
|---|---|
200 | Success. |
201 | Created — returned by POST endpoints. |
400 | Something in the request was wrong; the message says what. |
401 | Missing or invalid API key. |
402 | Your plan doesn't include API access — upgrade to Business. |
403 | The key isn't allowed to do that. |
404 | No such record in this workspace. |
429 | Too many requests — see rate limits below. |
Rate limits
Each API key gets 120 requests a minute, replenished continuously, and one
key's usage never affects another's. Go over it and you'll get a
429 with a Retry-After header
saying how many seconds to wait.
If you're backfilling or syncing a lot, spread the work out rather than retrying immediately — and if the limit is genuinely too low for what you're building, tell us.
Workspace
/api/v1/meConfirms your key works and shows which workspace and plan it opens.
{
"workspaceId": "7be742fe-...",
"workspaceName": "Acme Inc",
"plan": "Business",
"authenticatedAs": "api:Production key"
}
/api/v1/membersLists the people in your workspace. Use a userId here to assign tickets.
Projects
/api/v1/projectsAll projects in your workspace.
/api/v1/projects/{projectId}A single project.
/api/v1/projects/{projectId}/statusesThe project's workflow columns. You need these names (or ids) to move a ticket.
[
{ "id": "bf0eb0af-...", "name": "Backlog", "category": "ToDo", "order": 0 },
{ "id": "016585fc-...", "name": "In Progress", "category": "InProgress", "order": 2 },
{ "id": "fc8b8161-...", "name": "Done", "category": "Done", "order": 4 }
]
Tickets
/api/v1/issuesLists tickets. Every filter is optional and they combine.
| Query parameter | Description |
|---|---|
projectId | Only tickets in this project. |
status | Status name, e.g. In Progress. |
assigneeId | Only tickets assigned to this user. |
q | Search the title and ticket key. |
limit / offset | Paging. Default 50, max 200. |
curl "http://www.vectorkan.com/api/v1/issues?status=In%20Progress&limit=10" \
-H "X-Api-Key: $VECTOR_KEY"
Responses are paged:
{
"total": 36, "limit": 10, "offset": 0,
"items": [ { "id": "...", "key": "ENG-36", "title": "Add dark mode", "status": "Backlog", ... } ]
}
/api/v1/issues/{issueId}A single ticket in full.
/api/v1/issuesCreates a ticket. This is the one most integrations start with.
projectId and title are required; everything else is optional.
curl -X POST http://www.vectorkan.com/api/v1/issues \
-H "X-Api-Key: $VECTOR_KEY" \
-H "Content-Type: application/json" \
-d '{
"projectId": "0854e185-...",
"title": "Payment webhook is failing",
"description": "Started after the 4.2 release.",
"type": "Bug",
"priority": "High",
"assigneeId": null
}'
type: Bug, Task, Story or Epic. priority: Low, Medium, High or Urgent.
Unknown values fall back to Task and Medium rather than failing.
/api/v1/issues/{issueId}Updates a ticket. Only the fields you send are changed.
curl -X PATCH http://www.vectorkan.com/api/v1/issues/ISSUE_ID \
-H "X-Api-Key: $VECTOR_KEY" \
-H "Content-Type: application/json" \
-d '{ "priority": "Urgent", "dueDate": "2026-08-30", "storyPoints": 5 }'
Send "dueDate": "" to clear a due date.
/api/v1/issues/{issueId}/transitionsMoves a ticket to another status — the endpoint for syncing state from your system.
curl -X POST http://www.vectorkan.com/api/v1/issues/ISSUE_ID/transitions \
-H "X-Api-Key: $VECTOR_KEY" \
-H "Content-Type: application/json" \
-d '{ "status": "In Progress" }'
Use the status name as above, or statusId if you prefer ids. Send an
unknown status and the error lists the valid ones for that project.
/api/v1/issues/{issueId}/assignAssigns a ticket. Send an empty assigneeId to unassign.
-d '{ "assigneeId": "16fb32e3-..." }'
Comments
/api/v1/issues/{issueId}/commentsEvery comment on a ticket, oldest first.
/api/v1/issues/{issueId}/commentsAdds a comment.
-d '{ "body": "Deployed the fix — @jordan can you confirm?" }'
@username mentions email the person you tagged.
Customer requests
Requests are what your own customers file through your public portal (see below). Pull them into your systems, then convert the real ones into tracked tickets.
/api/v1/projects/{projectId}/requestsRequests for a project. Optional ?status=New|Triaged|Closed.
/api/v1/requests/{requestId}/convertTurns a customer request into a ticket and links the two.
curl -X POST http://www.vectorkan.com/api/v1/requests/REQUEST_ID/convert \
-H "X-Api-Key: $VECTOR_KEY" \
-H "Content-Type: application/json" \
-d '{ "priority": "High" }'
Let your clients raise tickets
Every project can publish a public request form. Your customers open the link, describe their problem, and it lands in your triage queue — no VectorKan account needed, and they never see anything else in your workspace.
- Open the project in VectorKan and go to Requests.
- Switch Public request form on. (Pro and Business plans.)
- Copy the link that appears and share it — email it, or link it from your website, help centre or app.
The link looks like this:
http://www.vectorkan.com/request/YOUR_PROJECT_ID
You can also fetch it programmatically, which is handy if you generate support pages per client:
/api/v1/projects/{projectId}/portalReturns the shareable portal link and whether it's currently open.
{
"projectId": "0854e185-...",
"enabled": true,
"url": "http://www.vectorkan.com/request/0854e185-...",
"hint": "Share this link with your customers — no account needed to file a request."
}
POST /issues from your backend instead. The portal is the no-code option;
the API is the flexible one.
Common recipes
Raise a ticket when something breaks
Call the API from your error handler or alerting webhook so incidents land in your board automatically.
await fetch("http://www.vectorkan.com/api/v1/issues", {
method: "POST",
headers: {
"X-Api-Key": process.env.VECTOR_KEY,
"Content-Type": "application/json"
},
body: JSON.stringify({
projectId: process.env.VECTOR_PROJECT_ID,
title: `Checkout failed: ${error.code}`,
description: error.stack,
type: "Bug",
priority: "Urgent"
})
});
Close the VectorKan ticket when your system closes the job
curl -X POST http://www.vectorkan.com/api/v1/issues/$ID/transitions \
-H "X-Api-Key: $VECTOR_KEY" -H "Content-Type: application/json" \
-d '{ "status": "Done" }'
Poll for new customer requests every few minutes
curl "http://www.vectorkan.com/api/v1/projects/$PROJECT/requests?status=New" \
-H "X-Api-Key: $VECTOR_KEY"