Creating & editing issues¶
Four write verbs: create files a new issue, edit changes an existing one,
clone copies one, delete removes one. JSON examples below show the data
block only — the envelope wrapper and exit codes live on
Output, and each command links to its reference page for the
complete flag and output-field tables. --dry-run is a local preview that
validates the payload's shape and never contacts Jira — it has no screen
schema, so unknown field names pass through. Add --validate-remote to a
create or edit dry-run for a read-only pre-flight that fetches the live
screen (createmeta / editmeta) and runs the same field-schema and custom-field
checks a real submit gets; the envelope confirms with
data.validated_remotely: true. A priority name is additionally checked
against the cached site priorities whenever that cache is present, on dry-run
and live alike.
create¶
File a new issue. Common fields go on convenience flags — --project,
--type, --summary, --assignee, --priority, --label, --parent — and
anything heavier (an ADF description, custom fields) goes in --json-input.
Flags layer on top of the JSON file, so an explicit flag overrides the same key
in the payload. Under --no-input the project, type, and summary must all be
resolvable from flags, JSON, or profile defaults before the command will submit.
jira issue create --project PROJ --type Task --summary "Fix the build"
jira issue create --project PROJ --type Bug --summary "Crash on startup" --assignee me --label regression
jira issue create --json-input new-issue.json --dry-run
jira issue create --json-input new-issue.json --output=json
The --json-input file accepts flat CLI-alias keys or the Jira-native
{"fields": {...}} object interchangeably (description is an ADF
document; description_markdown takes Markdown instead — a lossy shortcut
that can't carry mentions, dates, panels, or status lozenges):
{
"project_key": "PROJ",
"issue_type": "Task",
"summary": "Fix the build",
"description": {
"type": "doc",
"version": 1,
"content": [
{ "type": "paragraph", "content": [{ "type": "text", "text": "body" }] }
]
}
}
A live create returns data.issue with the new id, key, and self. A
--dry-run returns data.preview — the resolved fields the create would
submit (project_key, issue_type, summary, description_adf, and any
custom fields) with dry_run: true.
create and edit accept the same payload shapes
Both commands take either form: the Jira-native shape — a top-level
fields object holding bare field names with wire nesting
({"project": {"key": …}}, {"issuetype": {"name": …}}) — or flat
convenience keys at the top level (project_key, issue_type,
summary, plus any bare Jira field name). The CLI normalises either
into the same submit, so a payload written for one command works on
the other.
edit¶
Change one or more fields on an existing issue. Use --summary, --assignee,
or --markdown for single-field tweaks; pass --json-input for
everything else (an ADF description, custom fields, several fields at once). The
JSON payload follows
Atlassian's editIssue
shape — a top-level fields object of bare field names. edit accepts issue-key
lists and ranges with -p / --parallelism for bulk field changes.
Bare jira issue edit PROJ-123 (no field flags) opens $EDITOR on the
description. That works for a human at a terminal; under --no-input the CLI
refuses it rather than hang on a TTY prompt, and asks for --summary,
--assignee, --markdown, or --json-input instead.
jira issue edit PROJ-123 --summary "new title"
jira issue edit PROJ-123 --assignee me
jira issue edit PROJ-123 --markdown "## Steps\n\n1. Repro\n2. Fix"
jira issue edit PROJ-1..PROJ-10 -p 4 --summary "bulk title"
jira issue edit PROJ-123 --json-input fields.json --dry-run --output=json
--markdown is the headless way to replace the description without
the editor. It converts Markdown to ADF with the same lossy converter
create uses, so GFM features beyond the supported set degrade — in
the default strict mode a lossy conversion aborts before submission; add
--adf-best-effort to keep the converted document and surface a warning. The
same effect is available inside a --json-input payload through the
description_markdown key. For mentions, dates, panels, status, or tables —
constructs Markdown can't express — pass native ADF under fields.description
instead; that round-trips losslessly.
The --json-input file wraps the fields:
The payload may also be the exact PUT /rest/api/3/issue/{key} body, including
a top-level update block of add/set/remove operations as a sibling of
fields. The block is forwarded verbatim — Jira validates the operation verbs —
and appears in the envelope as data.update:
A live edit returns data.fields (the validated submission), data.result
(Jira's response, usually empty on a 204), and dry_run: false. A --dry-run
returns the same data.fields with dry_run: true and no result — the call
never reaches Jira.
clone¶
Copy an issue into a new one. The clone keeps the source's editable fields
(summary, ADF description, type, priority, labels, components, custom fields)
and drops lifecycle and identity (key, status, created date, comments,
worklogs, links). Override any carried field through --json-input — including
project.key to land the clone in a different project. The source survives
untouched; reach for jira issue move when you want to relocate the original
instead.
A live clone is destructive: it needs --force in headless, agent, or
--no-input mode, and prompts an interactive terminal otherwise. --dry-run
needs no --force.
jira issue clone PROJ-123 --dry-run
jira issue clone PROJ-123 --force
jira issue clone PROJ-123 --json-input overrides.json --force
jira issue clone PROJ-1..PROJ-10 -p 4 --force
The data.issue field is the source key; data.result is the new
clone — that pairing is easy to misread:
{
"dry_run": false,
"issue": "PROJ-123",
"result": {
"id": "10407",
"key": "PROJ-145",
"self": "https://example.atlassian.net/rest/api/3/issue/10407"
}
}
A --dry-run drops result, sets dry_run: true, and adds
data.payload.fields echoing the would-be create body.
delete¶
Permanently remove the issue. The key is freed for the project's next issue. If
you want the record preserved, transition it to a terminal status (Done,
Cancelled) instead. Like clone, a live delete needs --force in
headless, agent, or --no-input mode; multi-key delete requires --force even
in an interactive terminal, to avoid a long confirmation loop.
jira issue delete PROJ-123 --dry-run
jira issue delete PROJ-123 --force
jira issue delete PROJ-123 --force --delete-subtasks
jira issue delete PROJ-1..PROJ-10 -p 4 --force
A live delete returns data.issue (the key) and data.result: null — Jira
answers a successful delete with 204 No Content. A --dry-run returns
dry_run: true and data.payload.fields (empty, since delete carries no field
payload).
Delete is irreversible
There is no undo and no recycle bin. The validation pipeline catches shape
errors, but once the call lands the issue is gone. Confirm the key with
view first, or run --dry-run.
Subtasks block delete unless --delete-subtasks is set
Jira refuses to delete an issue that has subtasks unless the caller asks
for the cascade. --delete-subtasks is a delete-only flag.
See also¶
- Reading issues — find the key before you change it
- Custom fields — the field IDs you put in a payload
- ADF — the description document format
- Output — the JSON envelope and exit codes