API

REST API reference

What the web app can do, the REST API can do too: issues, projects, releases, time, documentation, webhooks and a workspace’s settings. For AI agents, the MCP server is usually the better way. AI & MCP: the better way for AI agents →

Basics

Address
Every workspace has its own: https://<workspace>.it4s.at/api/v1/…
Authentication
A personal access token in the header Authorization: Bearer it4s_pat_… (My Profile › API Tokens). The token has your account’s permissions, read-only if you like.
Errors
Problem JSON (RFC 9457) with status, code, detail and, for input errors, errors per field.
Lists
limit (up to 200) and cursor; the answer has items, total and nextCursor.
Specification
OpenAPI 3.1 at /api/v1/openapi.json, to click through at /api/docs – also in the demo workspace.

Try it without an account

The public demo workspace answers without signing in, read-only:

curl -s "https://demo.it4s.at/api/v1/issues?project=WEB&status=open"

Interactive API docs in the demo workspace →

All 251 endpoints

By area. The short descriptions come from the OpenAPI spec. Endpoints marked “no token” work without signing in.

Issues 17

MethodPathDescription
GET/api/v1/issuesSearch issues
POST/api/v1/issuesCreate an issue (any type)
POST/api/v1/issues/bulk-deleteSoft delete up to 50 issues; per-key results
POST/api/v1/issues/bulk-updateUpdate up to 50 issues; per-key results
GET/api/v1/issues/quick-searchQuick search
GET/api/v1/issues/tree/projectsProjects above the issue tree
GET/api/v1/issues/{key}
PATCH/api/v1/issues/{key}Update fields (partial). Send If-Match with the ETag to avoid overwriting someone else’s change.
DELETE/api/v1/issues/{key}Soft delete (restore with POST /issues/{key}/restore)
GET/api/v1/issues/{key}/activityHistory, newest first
POST/api/v1/issues/{key}/moveRank (and status) change: after = the issue above, before = the issue below
POST/api/v1/issues/{key}/restoreUndo a delete
POST/api/v1/issues/{key}/transition
GET/api/v1/issues/{key}/watchersWatchers, and whether you watch the issue
PUT/api/v1/issues/{key}/watchers/meWatch the issue (emails on new comments)
DELETE/api/v1/issues/{key}/watchers/meStop watching the issue
PUT/api/v1/issues/{key}/watchers/{userId}Add someone to the watch list (members, admins, customers)

Comments 8

MethodPathDescription
PATCH/api/v1/comments/{id}
DELETE/api/v1/comments/{id}Soft delete
PUT/api/v1/comments/{id}/answeredMark a question answered, or open it again
PUT/api/v1/comments/{id}/categorySet the category of a comment, or null for none (IT4S-463; project members and admins, and the author)
PUT/api/v1/comments/{id}/decisionMark a comment as a decision, or remove the mark (IT4S-429; project members and admins)
POST/api/v1/comments/{id}/restore
GET/api/v1/issues/{key}/comments
POST/api/v1/issues/{key}/commentsMarkdown body; @name mentions

Projects 16

MethodPathDescription
GET/api/v1/projects
POST/api/v1/projects
GET/api/v1/projects/{key}
PATCH/api/v1/projects/{key}
POST/api/v1/projects/{key}/archiveArchive an inactive project (project admins): read-only, out of the lists and the project limit
GET/api/v1/projects/{key}/avatarThe project avatar as WebP, 128 px or `size=small` 32 px; cache it, the URL carries the version
PUT/api/v1/projects/{key}/avatarUpload the project avatar (project admins; multipart/form-data, field "file"; PNG, JPEG, SVG or WebP, max 1 MB)
DELETE/api/v1/projects/{key}/avatar
POST/api/v1/projects/{key}/deleteSchedule an inactive project for removal with all its content (project admins, browser session only)
POST/api/v1/projects/{key}/keepTake back the deletion of a project; it stays inactive
GET/api/v1/projects/{key}/members
POST/api/v1/projects/{key}/membersAdd a member or change the role
DELETE/api/v1/projects/{key}/members/{userId}
POST/api/v1/projects/{key}/sample-issuesFill an empty project with sample issues (project admins)
DELETE/api/v1/projects/{key}/sample-issuesMove the sample issues to the trash and remove the sample release (project admins)
POST/api/v1/projects/{key}/unarchiveTake a project out of the archive; it stays inactive and counts towards the project limit

Releases 13

MethodPathDescription
GET/api/v1/projects/{key}/releases
POST/api/v1/projects/{key}/releases
GET/api/v1/releases
GET/api/v1/releases/{id}
PATCH/api/v1/releases/{id}Update a release. Releasing with open issues answers 409 unless moveOpenIssuesTo is given (a release id, or null to keep them).
DELETE/api/v1/releases/{id}
GET/api/v1/releases/{id}/blockersOpen issues of the release that wait for another open issue of the project (blocks links), with their blockers
GET/api/v1/releases/{id}/candidatesOpen stories, tasks and bugs that could go into the release (without release by default; `source=backlog` or `other` unreleased releases), with the issue list filters
GET/api/v1/releases/{id}/issuesThe issues of the release (sub-tasks follow their parent), by rank, with summed estimates
PATCH/api/v1/releases/{id}/issuesMove issues into or out of an unreleased release (project admins). Epics move their open children, issues their open sub-tasks; all keys are checked first, a bad one changes nothing
POST/api/v1/releases/{id}/notes-aiRelease notes written by the workspace AI, streamed as text
GET/api/v1/releases/{id}/notes-draftA first version of the release notes from the done issues, grouped by type
POST/api/v1/releases/{id}/suggestAI proposal for the scope of an unreleased release (project admins, AI active): candidates best first with a one-line reason; assigns nothing

Board 1

MethodPathDescription
GET/api/v1/boardBoard columns with ranked issues

Worklogs 6

MethodPathDescription
GET/api/v1/issues/{key}/worklogsNewest first
POST/api/v1/issues/{key}/worklogsLog work for yourself
GET/api/v1/worklogsWorklogs across your projects
GET/api/v1/worklogs/{id}
PATCH/api/v1/worklogs/{id}Own worklogs; project admins change all
DELETE/api/v1/worklogs/{id}Puts the time back on the remaining estimate

Reports 2

MethodPathDescription
GET/api/v1/reports/estimatesEstimates of a scope (Estimate Report)
GET/api/v1/reports/timeLogged time per issue and user

Documentation 15

MethodPathDescription
PATCH/api/v1/doc-comments/{id}
DELETE/api/v1/doc-comments/{id}
GET/api/v1/docsFull-text search over titles and content (every word as a prefix)
GET/api/v1/docs/{ref}
PATCH/api/v1/docs/{ref}Change title or content, move (parent, position) or set the release of a top page; If-Match: W/"version" optional
DELETE/api/v1/docs/{ref}Move the page and its subpages to the trash
GET/api/v1/docs/{ref}/activityHistory, newest first
GET/api/v1/docs/{ref}/attachmentsThe files of the page
POST/api/v1/docs/{ref}/attachmentsUpload a file for the page (members; multipart/form-data, field "file")
GET/api/v1/docs/{ref}/comments
POST/api/v1/docs/{ref}/comments
POST/api/v1/docs/{ref}/restore
GET/api/v1/issues/{key}/docsDocumentation pages that mention the issue by key (none for customers)
GET/api/v1/projects/{key}/docsPages of a project (tree data: parent and position); `release` = name, id, or `none` for pages without a release
POST/api/v1/projects/{key}/docs

Attachments 10

MethodPathDescription
GET/api/v1/attachments/{id}Metadata with a signed download URL (15 minutes)
DELETE/api/v1/attachments/{id}Soft delete
GET/api/v1/attachments/{id}/contentFile bytes. Works with your session/token or with the signed URL from the metadata.
POST/api/v1/attachments/{id}/restore
GET/api/v1/issues/{key}/attachments
POST/api/v1/issues/{key}/attachmentsUpload a file (multipart/form-data, field "file"; optional field "commentId")
POST/api/v1/projects/{key}/attachmentsUpload a file for the project description, or with field "internal"=true for its internal note (project admins; multipart/form-data, field "file")
POST/api/v1/projects/{key}/draft-attachmentsUpload a file for an issue that is being created (IT4S-274; multipart/form-data, field "file"). Pass its id in "attachments" when creating the issue; only you see it until then, unused files are removed after 24 hours.
POST/api/v1/releases/{id}/attachmentsUpload a file for the release notes (project admins; multipart/form-data, field "file")
PUT/api/v1/uploads/{token}Upload a file to a one-time link (MCP create_upload_link): the raw file as the body, e.g. curl --data-binary @file

Links 4

MethodPathDescription
GET/api/v1/issues/{key}/links
POST/api/v1/issues/{key}/links
DELETE/api/v1/issues/{key}/linksRemove the link of this type to `target`, in either direction
DELETE/api/v1/links/{id}

Tags 4

MethodPathDescription
GET/api/v1/tags
POST/api/v1/tags
PATCH/api/v1/tags/{id}
DELETE/api/v1/tags/{id}

Components 5

MethodPathDescription
GET/api/v1/components/{id}
PATCH/api/v1/components/{id}Change or archive a component (project admins); archived components stay on their issues and releases
GET/api/v1/projects/{key}/componentsThe components of a project in their order; archived ones with archived=true
POST/api/v1/projects/{key}/componentsAdd a component (project admins)
PUT/api/v1/projects/{key}/components/orderOrder the components (project admins): their ids, first to last

Users 14

MethodPathDescription
GET/api/v1/admin/usersAll users with details (admins); people by default, `kind=agent` for the agent personas, `kind=all` for both
GET/api/v1/invitationsOpen invitations (pending and expired) and the users against the plan (admins)
POST/api/v1/invitationsInvite people by email: a link valid 7 days each; members are skipped (admins)
DELETE/api/v1/invitations/{id}Revoke an invitation (admins)
POST/api/v1/invitations/{id}/resendSend a new link, valid 7 days; the old one stops working (admins)
GET/api/v1/usersLook up active users (assignee pickers, mentions); `agents=true` adds the agent personas of those people after them
POST/api/v1/users
GET/api/v1/users/{id}
PATCH/api/v1/users/{id}
DELETE/api/v1/users/{id}Delete an inactive user for good; their issues keep them as "Deleted user …" (admins)
GET/api/v1/users/{id}/avatarA user's picture as WebP, 128 px or `size=small` 32 px; cache it, the URL carries the version
GET/api/v1/users/{id}/invitationThe latest invitation: pending, expired or accepted (admins)
POST/api/v1/users/{id}/invitationInvite a user: emails a one-time link to set the password (also returned, for when no email is set up)
POST/api/v1/users/{id}/reset-2faTurn off two-factor sign-in for a user (lost phone)

Me 19

MethodPathDescription
GET/api/v1/meCurrent user, scopes and projects
PATCH/api/v1/meChange your name and email notification choices
PUT/api/v1/me/avatarUpload your picture (multipart/form-data, field "file"; PNG, JPEG, WebP or GIF, max 5 MB)
DELETE/api/v1/me/avatarRemove your picture; the Google picture or initials show again
POST/api/v1/me/deleteDelete your account (not while you own a workspace or are its last admin)
GET/api/v1/me/draftsYour unsaved drafts, newest first; optionally of one target
PUT/api/v1/me/drafts/{targetType}/{targetId}/{field}Keep a draft (the newer of the stored and the sent one wins)
DELETE/api/v1/me/drafts/{targetType}/{targetId}/{field}Remove a draft (after Save or Discard)
GET/api/v1/me/exportYour account data as JSON: profile, workspaces, sessions, tokens, connected apps, accepted terms
GET/api/v1/me/get-startedThe first steps of a workspace and which are done (admins)
POST/api/v1/me/password
PATCH/api/v1/me/prefsMerge UI preferences
POST/api/v1/me/totp/disable
POST/api/v1/me/totp/enable
POST/api/v1/me/totp/setup
POST/api/v1/me/whats-new/seenYou have seen the notes up to this version (hides the notice on all devices)
GET/api/v1/me/workspacesYour workspaces, for the switcher
POST/api/v1/me/workspaces/{id}/openA one-time link that signs you in on another of your workspaces (TEN-18)
GET/api/v1/whats-newRelease notes of the running version and the versions before it, newest first; `unseen` since the version you saw last

Settings 34

MethodPathDescription
GET/api/v1/admin/overviewThe Administration hub: a short status per admin page and the items that need an admin
GET/api/v1/admin/usageThe plan and what the workspace uses of its limits
GET/api/v1/legal/workspaceThe current terms and DPA, and what the owner has accepted
POST/api/v1/legal/workspace/acceptThe owner accepts the current terms and DPA for the company
GET/api/v1/settings
PATCH/api/v1/settings
GET/api/v1/settings/aiAI for the workspace (admins); without the API key
PUT/api/v1/settings/aiSet AI; leave out `apiKey` to keep it, null removes it. A new key or model needs a new test.
POST/api/v1/settings/ai/testTest key and model with Anthropic (no tokens used). Without a body: the saved ones, stored (AI features run only after a successful test); with `model`/`apiKey` not saved yet: only answered
GET/api/v1/settings/confluenceConfluence connection for the documentation import (admins); without the API token
PUT/api/v1/settings/confluenceSet the Confluence connection (classic API token); leave out `apiToken` to keep it, null removes it
POST/api/v1/settings/confluence/testTest the Confluence connection: the values in the body (only answered, a token left out is the stored one) or the saved connection (stored)
POST/api/v1/settings/delete-workspaceLock this workspace and schedule its removal after 30 days (admins, browser session only)
GET/api/v1/settings/emailEmail server (admins); without the password
PUT/api/v1/settings/emailSet the email server; leave out `password` to keep it, null removes it
POST/api/v1/settings/email/testSend a test email to yourself: with the values in the body (not saved yet; a password left out is the stored one), or the saved settings
GET/api/v1/settings/google-domain/proofThe DNS record that proves the saved Google domain, and its state (admins); null without a domain
POST/api/v1/settings/google-domain/verifyLook up the DNS record now (admins)
GET/api/v1/settings/jiraJira connection for the import (admins); without the API token
PUT/api/v1/settings/jiraSet the Jira connection; leave out `apiToken` to keep it, null removes it
POST/api/v1/settings/jira/testTest the Jira connection: the values in the body (only answered, a token left out is the stored one) or the saved connection (stored)
GET/api/v1/settings/support-accessWho may come in, and the visits so far
PATCH/api/v1/settings/support-accessChange who may come in (browser session only)
POST/api/v1/settings/support-access/{id}/approveApprove a request; the time starts now (browser session only)
POST/api/v1/settings/support-access/{id}/declineDecline a request (browser session only)
POST/api/v1/settings/support-access/{id}/endEnd a visit now (browser session only)
GET/api/v1/settings/workspaceName, address, language, time zone and logo of this workspace (admins)
PATCH/api/v1/settings/workspaceChange name, language or time zone
POST/api/v1/settings/workspace/addressChange the address (admins, browser session only); the old one redirects for 90 days
GET/api/v1/settings/workspace/address-checkWhether this workspace can move to an address
PUT/api/v1/settings/workspace/logoUpload the logo (multipart/form-data, field "file"; PNG, JPEG, SVG or WebP, at most 1 MB, at least 128 px)
DELETE/api/v1/settings/workspace/logoRemove the logo: the initials show again
GET/api/v1/workspace/keepStart the inactivity period of this workspace again; the signed link from the warning email
GET/api/v1/workspace/logoThe logo as WebP, 128 px or `size=small` 32 px; no sign-in, the URL carries the version

Backup 9

MethodPathDescription
GET/api/v1/admin/backupsThe latest 30 backups and restores
POST/api/v1/admin/backupsStart a backup of all data and files in the background; poll it, then download the zip
GET/api/v1/admin/backups/automaticThe nightly backups and the snapshots before a restore, and how long the plan keeps them
GET/api/v1/admin/backups/{id}
DELETE/api/v1/admin/backups/{id}Delete a backup or restore run with its zip
GET/api/v1/admin/backups/{id}/downloadThe zip of a finished backup
POST/api/v1/admin/backups/{id}/restoreRestore a stored backup in the background. `new`: any admin, with `address`. `overwrite`: the owner, with the workspace address in `confirm`; a snapshot is taken first.
POST/api/v1/admin/restoresUpload a backup zip to restore (multipart, field "file"); the worker checks it, then POST …/restore
POST/api/v1/admin/restores/{id}/restoreReplace ALL data with a checked backup in the background, after a snapshot. Body: { confirm: the workspace address }.

Webhooks 9

MethodPathDescription
POST/api/v1/webhook-deliveries/{id}/redeliverSend a delivery again (same id and body)
GET/api/v1/webhooksAll webhooks
POST/api/v1/webhooksAdd a webhook; the answer contains the signing secret, shown only once
GET/api/v1/webhooks/{id}
PATCH/api/v1/webhooks/{id}
DELETE/api/v1/webhooks/{id}
GET/api/v1/webhooks/{id}/deliveriesDelivery log, newest first (kept 30 days)
POST/api/v1/webhooks/{id}/rotate-secretNew signing secret (generated, or `secret` = the receiver's own, IT4S-373); the old one stops working right away
POST/api/v1/webhooks/{id}/testSend a ping delivery

Agents 8

MethodPathDescription
GET/api/v1/agentsAll agent personas of the workspace (workspace admins; others get their own)
GET/api/v1/me/agentsYour agent personas, active first
POST/api/v1/me/agentsCreate a persona for your app connections (a removed one of the same name comes back)
PATCH/api/v1/me/agents/{id}Rename a persona, describe it, or choose its connections
DELETE/api/v1/me/agents/{id}Remove a persona: it stays in the history, its connections act as you again
PUT/api/v1/me/agents/{id}/avatarThe persona's picture (multipart/form-data, field "file"; PNG, JPEG, WebP or GIF, max 5 MB)
DELETE/api/v1/me/agents/{id}/avatarRemove the persona's picture (initials again)
GET/api/v1/me/connectionsYour app connections (OAuth), with the persona each acts as

Confluence import 6

MethodPathDescription
GET/api/v1/admin/confluence-runsThe latest 20 Confluence import runs
POST/api/v1/admin/confluence-runsAnalyze a Confluence space in the background: export its pages and files and preview the import. Poll the run.
GET/api/v1/admin/confluence-runs/{id}
PATCH/api/v1/admin/confluence-runs/{id}Pages (a root page with its subpages, null: the whole space) and target of an analyzed run; returns the new preview
POST/api/v1/admin/confluence-runs/{id}/importImport an analyzed run in the background, with the files from Confluence. Poll the run.
GET/api/v1/admin/confluence/spacesThe Confluence spaces the connection can read

Jira import 6

MethodPathDescription
GET/api/v1/admin/jira-runsThe latest 20 import runs
POST/api/v1/admin/jira-runsAnalyze a Jira project in the background: export it from Jira and plan the import (dry run). Poll the run.
GET/api/v1/admin/jira-runs/{id}
PATCH/api/v1/admin/jira-runs/{id}User and status mapping and project name of an analyzed run; returns the new report
POST/api/v1/admin/jira-runs/{id}/importImport an analyzed run in the background, with the attachment files from Jira. Poll the run.
GET/api/v1/admin/jira/projectsThe Jira projects the connection can see

Billing 5

MethodPathDescription
POST/api/v1/billing/stripe-webhookStripe webhook: checkout.session.completed, customer.subscription.updated and .deleted, invoice.payment_failed; signed
GET/api/v1/settings/billingBilling details, the subscription, prices and invoices (admins)
POST/api/v1/settings/billing/checkoutStart the upgrade to Team: a Stripe Checkout page for the active users (admins, browser session only)
PUT/api/v1/settings/billing/detailsCompany, VAT ID, address and invoice email; kept at Stripe too (admins)
POST/api/v1/settings/billing/portalStripe's page for the payment method, invoices and cancelling (admins, browser session only)

AI 4

MethodPathDescription
GET/api/v1/issues/{key}/summaryThe AI summary for you (customers get one from public content only); null when none was generated yet. 409 when AI is off.
POST/api/v1/issues/{key}/summaryGenerate or regenerate the AI summary with the workspace model
GET/api/v1/projects/{key}/briefingThe stored AI briefing of the project for you; null when none was written yet. 409 when AI is off.
POST/api/v1/projects/{key}/briefingWrite or rewrite the AI briefing with the workspace model

Dashboard 4

MethodPathDescription
GET/api/v1/me/dashboardCounts, what's new since your last visit, your open issues by urgency, opened vs. closed in the last 7 days
POST/api/v1/me/dashboard/seenMark all seen: What's new starts from now
GET/api/v1/me/dashboard/summaryToday's AI summary and next steps, written on the first call of the day; null when AI is off
POST/api/v1/me/dashboard/summaryWrite the AI summary again (Refresh); null when AI is off

GitHub 4

MethodPathDescription
POST/api/v1/github/webhookGitHub repository webhook (content type application/json, events Pull requests, Pushes, Check suites, Check runs, Statuses); signed with the secret
GET/api/v1/settings/githubPayload URL, whether a secret is set, the last delivery
POST/api/v1/settings/github/secretGenerate a new webhook secret (shown once); changes are then made as you, via GitHub
DELETE/api/v1/settings/github/secretRemove the secret: deliveries are refused

Project groups 4

MethodPathDescription
GET/api/v1/project-groupsProject groups with the member projects you can read (all groups for workspace admins)
POST/api/v1/project-groupsAdd a project group (workspace admins); `projects` are moved into it
PATCH/api/v1/project-groups/{id}Change a project group (workspace admins); `projects` replaces its member projects
DELETE/api/v1/project-groups/{id}Delete a project group (workspace admins); its projects stay

API tokens 3

MethodPathDescription
GET/api/v1/me/tokens
POST/api/v1/me/tokensCreate a personal access token. The secret is returned only once.
DELETE/api/v1/me/tokens/{id}

Code 3

MethodPathDescription
DELETE/api/v1/code-links/{id}
GET/api/v1/issues/{key}/codeLinked pull requests, branches and commits (empty for customers)
POST/api/v1/issues/{key}/codeLink code; the same URL again updates title and state

Connected Apps 3

MethodPathDescription
GET/api/v1/admin/oauth-grantsAll app connections (OAuth grants), newest first
DELETE/api/v1/admin/oauth-grants/{id}Delete an app connection (revokes it, removes the record)
POST/api/v1/admin/oauth-grants/{id}/revokeDisconnect an app: its tokens stop working right away

Designs 3

MethodPathDescription
DELETE/api/v1/designs/{id}
GET/api/v1/issues/{key}/designsDesign references: patterns, mockups, artifacts, links (empty for customers)
POST/api/v1/issues/{key}/designsAdd a design reference; a mockup file is uploaded to the issue first

Events 3

MethodPathDescription
GET/api/v1/eventsLive updates (server-sent events)
GET/api/v1/presenceWho has issues or pages open now (not for customers)
PUT/api/v1/presenceHeartbeat of a browser tab: the issue or page it shows and whether it has unsaved changes

System 3

MethodPathDescription
GET/api/v1/issue-typesIssue types with their colours and icons (SVG, PNG) no token
GET/api/v1/issue-types/{file}The icon of an issue type: `story.svg`, or `story.png?size=32` (16 to 128 px) no token
GET/api/v1/versionThe running version: tag, commit and environment no token

Admin 2

MethodPathDescription
POST/api/v1/admin/jira-importImport a Jira export (dry run by default)
POST/api/v1/admin/jira-import/attachmentsUpload one attachment file of a Jira import (multipart: fields jiraId, issueKey, createdAt?, then file)

Overview 2

MethodPathDescription
GET/api/v1/issues/{key}/overviewThe read-only Overview of an issue for you
POST/api/v1/issues/{key}/visitRecord that you have the issue open; returns your visit before this one

Permissions 2

MethodPathDescription
GET/api/v1/permissionsWhat the project roles Customer and Member may do (any signed-in user, so clients can hide what is not allowed)
PUT/api/v1/permissionsSet the Customer and Member permissions (workspace admins); valid in all projects