REST API
Issues
Search, create, edit, comment on, attach to, move, link and import issues.
GET /issues(tracker:read): search. Query:project,status(keys of the project's workflow),category(todo,in_progress,done),severity,priority,type,nature(problem,improvement,task: the type's nature, which works in any project) (comma-separated lists),label,assignee(me,noneor id),open_only(true),blocked_only(true: only those with the blocked flag),mine(true: only those with the token's person as assignee or QA, like "My tasks" on screen),watching(true: only those they watch),q(free text: code, title, description and comments),query(advanced query, written in Portuguese, e.g.projeto = MOB e status = Aberto e responsavel = eu),saved_filter(the name of a saved filter),created_fromandcreated_to(YYYY-MM-DD),limit(up to 50),offset,sort(code,title,status,severity,assigneeorupdated),order(ascordesc) anddone_last(true: completed ones, groupdone, at the end, before the requested order). Withoutsort, most recent first. The API hides nothing by default: without a status filter, completed ones come too. The task list on screen hides completed ones until the person asks to "Show completed" (and then shows them at the end); to reproduce that, useopen_only=trueordone_last=true. In the MCP, the sameopen_onlyanddone_lastofsearch_issues. Each issue comes withclose_reason(in Closed),blockedandblocked_reason(the blocked flag),retest_failed(failed the last retest and not approved yet),assignee,qa_owner,sprint,release,releases(every delivery as"GOP 1.4.8-ota002", the main one first),module,parentandepic(codes),labels,start_date,due_date,external_idandedit_version(forPATCHand the batch, without opening each issue);include=description,custom_fieldsadds the description and custom fields.GET /search?q=<text>(tracker:read): "has this happened before?". Hybrid search, by meaning and by words, in issues (with their comments) and, withkinds=issue,ticket, in Help desk tickets (only for agents).issue=<code>instead ofqlooks for issues similar to that one, without it.project,open_only(true) andlimit(up to 30, default 8). Each result haskind,code,title,status_label,open,project,score(0 to 1),similarity(from the vector, when found by meaning),matched_by(text,meaning),likely_duplicateandurl;modeishybridortext(words only);semanticsays whether search by meaning is on for the company:on,indexed(how many items are already in the index; it grows every minute while the index is being built) and, when off,reason(no_vector: search by meaning isn't available on this server;no_key: aqua off, the company's own key or no AI credits). Withontrue andmodetext, search by meaning didn't answer in time or the person went over the limit of searches by meaning. Withissue, the search starts from the context card aqua writes for each issue (aqua_contextinGET /issues/{ref}).explain(default true;falsereturns only the search list, faster) makes aqua check each hit against the reference: it drops the ones that only share words and fills inrelation(same: the same problem;related: related) andreason(the link in one sentence);explainedsays whether it checked (without aqua turned on,falseand the search list). Before creating an issue, search here to avoid duplicates (see "Has this happened before?" above). In the MCP:search_similar.GET /issues/{code or id}(tracker:read): the issue withstatus(key,label,category,close_reasonin Closed withkeyandlabel, andretest_failed_atwhen it failed the last retest),blocked(sinceandreason, ornull),releases(every delivery, the main one first withprimary: true), parent andepic(the parent, or the parent's parent for a subtask), children, sprint, points, estimate, dates, custom fields, labels, links, watchers, comments, history (from/towith the stored values andtext, as on screen: names of releases, people and sprints;from_label/to_labelwhen the screen shows from/to),aqua_summary(the last conversation summary aqua made on screen:happened,pending,ballwith whose court the ball is in andoutdatedwhen there were comments or changes after it;nullwithout a summary),aqua_context(the context card aqua writes on its own, in the background, for "Has this happened before?":summarywith the problem in neutral words,area,terms,generated_atandoutdatedwhen the issue changed and the card is yet to be redone;nullwith aqua off or before the first card) andedit_version(forPATCH).?fields=status,releasesreturns only those parts (id,code,urlandedit_versionalways): good for checking many issues without fetching comments and history.GET /issues/{code or id}/comments(tracker:read): every comment, each withid,author,text,at,edited_at,deleted(who deleted it and when; the text comes empty),mentionsand the replies (replies).POST /issues/{code or id}/comments(tracker:write): comments,{"text": "...", "parent_id": "<id of the comment being replied to>"}.@Nomementions someone in the project."attachments": [{"file_name": "report.md", "content_base64": "..."}, {"url": "https://..."}]attaches up to 5 files to the comment (14 MB combined), with the attachment rules below; one bad attachment refuses the whole comment. 201 with theidand theattachments. In theGET, each comment carries itsattachments(id,name,type,size_bytes,download_url).GET /issues/{code or id}/evidences(tracker:read): the issue's attachments (evidence), oldest to newest, each withid,name,type,size_bytes,description,comment_id(when it came in a comment) anddownload_url.GET /evidences/{id}(tracker:read) downloads the file, with the same token (acceptsRange). Over the MCP, whose token doesn't work here,get_attachmentreads the content: text (md, csv, txt, log, json) and images (png, jpg, webp, gif up to 5 MB); chat attachments too.POST /issues/{code or id}/evidences(tracker:write): attaches a file, three ways:multipart/form-datawith the file in thefilefield (anddescriptionandcomment_idoptional, as text); JSON{"file_name": "review.md", "content_base64": "...", "description": "..."}(accepts thedata:...;base64,prefix); or JSON{"url": "https://example.com/screenshot.png"}, which tracker downloads (https and public addresses only, up to 3 redirects and 20 s; the URL isn't stored; the optionalfile_namechanges the name). Formats by the name's extension: png, jpg, jpeg, webp, gif, mp4, mov, pdf, json, txt, log, md, csv, zip; up to 15 MB per file and 60 files per hour per person.comment_idputs the file under one of your comments on the issue. PO/PM, QA, dev or admin (403 for others). 201 withattachment(as in theGET). There's no pre-signed URL: the bucket is private and every file goes through tracker, which checks the format and size.DELETE /issues/{code or id}/evidences/{id}removes it (the uploader or a project admin; the file of an approval version stays). In the MCP:attach_file,remove_attachmentandattachmentsinadd_comment; attachments show up inget_issue(evidences).PATCH /issues/{code or id}/comments/{id}(tracker:write): fixes the text,{"text": "..."}. Only the author (403 for others); the previous text is kept for the admin.DELETEon the same address deletes it: the comment stays in place, without the text (the author or a company admin).GET /issues/{code or id}/history(tracker:read): the full history, most recent first (limitup to 200,offset), withtotaland each event withat,by,action,field,textand, when present,fromandtoalready with names.POST /issues/{code or id}/move(tracker:write): takes the issue to another project in the same organization,{"project": "CHG", "confirm": true}. Withoutconfirm, it only returns the preview (moved: false, warnings about what has no equivalent in the target, subtasks that go along); withconfirm: true, it moves and returns the new code (code) and the old one (previous_code), which still finds the issue. 409 if the issue changed in the meantime: read it again and repeat. Requires editing the issue and creating issues in the target.POST /issues/{code or id}/links(tracker:write): links to another issue,{"target": "MOB-0007", "type": "blocks"}(blocks,relates_to, the default, orduplicates). Requires editing the issue. 201 with the issue's links (links, each withid).DELETE /issues/{ref}/links/{id}removes a link.GET /issues/{code or id}/proofs(tracker:read): proof approval (Design). The versions sent, newest to oldest, withstatus(pending,approved,changes_requested,superseded), note, decision with comment and the file (download_url).pendingis the id of the version awaiting a decision.POST /issues/{code or id}/proofs(tracker:write): sends the next version, as multipart/form-data withfileand an optionalnote(same formats and size as evidence). The one awaiting a decision is superseded. PO/PM, QA, dev or admin. 201 withversionand the versions.POST /issues/{code or id}/proofs/{id}/decision(tracker:write):{"decision": "approve"}or{"decision": "changes", "feedback": "what to change"}. PO/PM, QA, admin or the project's client (stakeholder). With the Design workflow, sending moves the issue to In approval, approving to Approved and requesting changes to Revisions. 422 when the version was already decided or superseded.GET /issues/{code or id}/watchers(tracker:read): who watches the issue (gets status and new comment notifications), withwatchingfor the token's person.POSTadds andDELETEremoves (tracker:write): with nothing, the person themselves;{"person": "[email protected]"}in the POST or?person=...in the DELETE for another person in the project, which requires editing the issue. The response hasperson(who was added or removed),watchingandwatchers.GET /issues/{ref}also returnswatchers.POST /issues/{code or id}/status(tracker:write): moves the issue to another status,{"status": "<key>"}. The project's workflow and the person's role in it apply (422 when the transition isn't allowed). Forclosed(Closed, QA template), also sendclose_reason:duplicated,cancelled,not_reproducedorwont_fix; with the issue already inclosed, the same request changes only the reason.POST /issues/{code or id}/block(tracker:write): flags the issue as blocked,{"reason": "what's in the way"}(optional; sending it again changes the reason). The flag works in any status and goes away on its own when the issue is completed.DELETEon the same address removes it. Every project role except stakeholder; a completed issue can't be blocked (422). Returnsblocked(since,reason) ornull. In the MCP:block_issue.DELETE /issues/{code or id}(tracker:write): deletes the issue (admin or the project's PO/PM; 403 for other roles). It disappears from lists, search and the API and can be restored for 30 days (on screen, in Issues → Deleted, or withPOST /issues/{ref}/restore). An issue with issues inside it (epic, subtasks) isn't deleted (422).POST /issues/{code or id}/restore(tracker:write): restores an issue deleted in the last 30 days, with comments, evidence and history. Admin or the project's PO/PM.GET /issues/deleted(tracker:read, optionalproject) lists the ones the person can restore (the 200 most recent), withrestore_until. After 30 days restoring returns 422.POST /issues/{code or id}/duplicate(tracker:write): creates a copy in the same project, like Duplicate on screen (content, classification, parent, points, fields and labels; no comments, evidence, links, people, sprint, release or technical notes). 201 with the copy'scode. Requires creating issues in the project.POST /issues(tracker:write): creates an issue. 201 when it creates; 200 when one with the sameexternal_idalready existed in the project.assigneeandqa_owner(me, id, e-mail or name of someone in the project) assign at creation: PO/PM and admins assign anyone, devs take it as assignee and QA as QA owner (403 otherwise; 422 when the person isn't in the project, without creating the issue). Devs create only subtask-level types, with the parent. With?similar=true, the created issue's response also hassimilar: the similar ones aqua confirmed (code,title,status_label,open,relation,reason,likely_duplicate,url), to link.PATCH /issues/{code or id}(tracker:write): edits the issue. Only the fields sent change;nullclears the value. Accepts the text fields,title,type,severity,priority,module,custom_fields(only the keys sent change; a key that doesn't exist in the project is refused),assigneeandqa_owner(me, id, e-mail or name of someone in the project), the technical notes (root_cause,fix_notes,fixed_version,fixed_build),parent,story_points,sprint(name or id of an open sprint;nullgoes back to the backlog),release(the main one: version or id; from another project in the company,"PLT backend-1a2b3c", when the fix ships only there),add_releases/remove_releases(other deliveries of the same fix, including in another project: id, version in the issue's project,"GOP 1.4.8-ota002"or{"project": "GOP", "version": "1.4.8-ota002"}, as a list or a comma-separated text; requires linking releases in both projects) andadd_labels/remove_labels. Each group requires the right role in the project (403 when it can't). The groups are saved in sequence: if one fails, the response hasappliedwith the ones already saved. To avoid overwriting someone else's edit, sendedit_version(the value read inGET /issues/{ref}): if someone changed the issue after that (fields, people, technical notes, parent, points, sprint, release, labels, estimate or dates; status, comments and hours don't count), nothing is saved and the response is 409 (conflict); read it again and reapply. The success response has the newedit_version.GET /issues/{code or id}/time(tracker:read): estimate, start, due date, recurrence (recurrenceandnext_occurrence), total logged, remaining and the time entries.POST /issues/{code or id}/time(tracker:write): logs hours worked,{"duration": "1h30", "work_date": "YYYY-MM-DD", "comment": "..."}(orminutesinstead ofduration; withoutwork_date, today). PO/PM, QA, dev and admin roles.PATCH /issues/{code or id}/plan(tracker:write):{"estimate": "8h", "start_date": "YYYY-MM-DD", "due_date": "YYYY-MM-DD", "recurrence": "monthly"}. An omitted field stays as it is;nullclears the value.recurrence(weekly,monthly,quarterly,yearly) makes the issue repeat: when it's completed, the next occurrence is born with start and due date moved forward, the same assignees and labels;time.next_occurrencepoints to it. Also works inPOST /issuesand in each item ofPOST /issues/import;null,""or"none"removes the recurrence.GET /issues/{code or id}/code(tracker:read): PRs (GitHub), MRs (GitLab) and commits linked to the issue, withid, repository, state (open,draft,merged,closed), branch, author and link.POST /issues/{code or id}/code(tracker:write): links a PR or commit by its link,{"url": "https://github.com/owner/repo/pull/12", "title": "..."}(GitLab MRs or commits too, including self-hosted). Doesn't change the status. 409 when it's already linked (commits by short or full sha). In a connected repository, the webhook later updates the title and state. PO/PM, QA, dev and admin roles.DELETE /issues/{code or id}/code?link_id=<id>(or?url=<link>, or the same in the JSON body) (tracker:write): unlinks. 404 when it wasn't linked.GET /time(tracker:read): time report. Query:fromandto(YYYY-MM-DD; default, the current month),project(prefix, slug or id) andperson(meor id); a filter that doesn't match is an error. Totals per person, per project and per issue, and the entries.POST /issues/bulk(tracker:write): the same action on up to 100 issues,{"issues": ["MOB-0012", "MOB-0013"], "action": "status", "value": "done"}.action:status,assignee(PO/PM or admin only;me, id, e-mail or name;noneclears),priority,severity,label,unlabel,release(version or id;noneclears),watch,unwatchanddelete(the last three withoutvalue). Each issue follows the rule of the individual action; the response hasrequested(distinct issues requested),updatedandfailed(codeanderrorfor each one that didn't change). Withoutvalueon an action that needs one: 422.POST /issues/batch(tracker:write): a per-issue batch, up to 50, to close out a delivery in one call:{"items": [{"issue": "MOB-0045", "fixed_version": "backend 4e8998ac", "fix_notes": "...", "code_links": ["https://github.com/org/repo/pull/251"], "status": "ready_for_qa"}]}. Each item accepts the fields ofPATCH /issues/{ref}(includingedit_version),code_links(links, or{url, title}; an already-linked link isn't an error) andstatus, applied in that order with the rules of the individual calls. An item that fails doesn't stop the others; the response hasrequested,succeeded,failedandresults(per item:ok,code,updated,linked,statusand, if it failed,failed_atwithissue(not found, or changed after theedit_version),fields,code_linksorstatus, anderror; earlier steps stay saved). Without other fields,edit_versionprotects the links and the status.POST /issues/import(tracker:write): up to 100 issues per request,{"project": "MOB", "issues": [...]}(each item can carry its ownproject). Item by item: a refused one doesn't undo the others. The response hascreated,existing,failedandresults(index,ok,code,urlorerror).
Issue fields: project (prefix, slug or id), title (required), type (the type key), severity (S1 to S4, default S3), priority (urgent, high, medium, low; PO/PM and admins only, others get medium), module (name), description, environment, app_version, build, device, operating_system, preconditions, steps_to_reproduce, actual_result, expected_result, impact, suggested_solution, parent (code or id of the parent issue: the epic of a regular issue, or the issue of a subtask; the level comes from the type), story_points (a number from 0 to 1000), start_date and due_date (start and due date, YYYY-MM-DD; the start doesn't come after the due date), custom_fields (an object keyed by the field key), labels (up to 10 names; one that doesn't exist is created) and external_id (the id at the source, up to 200 characters).
Templates per type: description, preconditions, steps_to_reproduce, actual_result, expected_result, impact and suggested_solution when omitted come filled with the type's template (the template in GET /projects). Send "" to leave one of those fields empty.
Use external_id in CI: with the name of the failed test, for example, running the pipeline again doesn't duplicate the issue.