notifyUsers=false in Jira Cloud: four ways your test bed fakes a pass
Gabriela Perdum
Author
14 min readAugust 24, 2026
Key takeaways
Before you trust any notification test, run POST /rest/api/3/issue/{key}/notify. A 403 means your tenant sends nothing and every suppression test you run will pass.
A company-managed project created over POST /rest/api/3/project has NO notification scheme unless you pass notificationScheme explicitly. I reproduced this across three templates and two project types.
user.notify.own.changes defaults to false, so a solo admin testing on their own issue gets no mail whichever route they use.
All four comment routes — including PUT /issue?notifyUsers=false — raise the comment event, never jira:issue_updated. Measured with a webhook on eight issues across two runs.
POST /issue/{key}/comment?notifyUsers=false returns 201 and silently drops the parameter. The comment endpoint has exactly two parameters and that is not one of them.
If you have ever had to backfill a comment onto a few thousand Jira work items, you already know the shape of the problem: the comment is the easy part, and the email storm is the part that gets you a meeting. I wrote up why sendNotifications: false does nothing when you paste it into an automation rule's exported JSON a few weeks ago. The short version is that it is not a parameter of that action, so nothing reads it.
That piece ended on a workaround I had not run. Atlassian publishes it themselves, on JRACLOUD-97682, and it is the thing everybody reaches for next: skip the comment endpoint, ride the comment in on the edit issue endpoint, which does accept notifyUsers=false.
So I built a test bed on a live Jira Cloud tenant and ran it. This tutorial is that bed, end to end — because the useful finding turned out not to be the workaround at all. It was that the bed lied to me four separate times, and every one of those lies looks exactly like success.
What Atlassian actually documents
Start from the primary source, not from a forum answer. I pulled the Jira Cloud platform OpenAPI document (developer.atlassian.com/cloud/jira/platform/swagger-v3.json, 3,618,606 bytes, fetched 24 August 2026) and read the three relevant operations out of it directly.
The add-comment endpoint takes exactly two parameters:issueIdOrKey and expand. That is the whole list. There is no notifyUsers, no sendNotifications, nothing. This is the machine-readable confirmation of the earlier article's conclusion.
The edit-issue endpoint's notifyUsers reads, verbatim:
Whether a notification email about the issue update is sent to all watchers. To disable the notification, administer Jira or administer project permissions are required. If the user doesn't have the necessary permission the request is ignored.
Read that carefully, because two clauses in it matter later. It promises to suppress mail "about the issue update" — it says nothing about the comment event. And a missing permission gets you ignored, never refused, so the call succeeds and the mail goes out anyway.
JRACLOUD-97682's own h3. Workaround gives the literal call:
I re-read the three tracker items over the JAC REST API on 24 August 2026, because vote counts and statuses rot and the numbers in my own notes were already stale:
Ticket
Status
Votes
Watchers
Created
AUTO-602 — suppress in-product notifications from Automation
Gathering Interest
1,073
512
2020-04-29
JRACLOUD-97682 — add notifyUsers=false to the comments API
Gathering Interest
1
2
2026-03-04
JRACLOUD-78140 — implement notifyUsers on a number of API calls
Closed / Won't Do
9
6
2022-01-06
4 rows × 5 columnsHeader row enabled
Two notes on citing these. AUTO-602 opens with the sentence you want — "Currently, we can only suppress Email notifications for the Edit Issue action performed by automation or Jira" — but its title and its request are about in-product and in-app notifications, so cite it for the limitation it states and not for the thing it asks for. And do not reach for JRACLOUD-78140 at all: it is Closed / Won't Do, and its description asks for notifyUsers on exactly four operations — "create issue, bulk create issue, assign issue, transition issue". Adding a comment is not one of them.
Building the bed
Everything below ran against a sanctioned test tenant over Basic auth with an API token, as a site admin. None of it belongs on a production site until you have read the whole article.
1
Create a throwaway company-managed project
POST /rest/api/3/project with a projectTemplateKey, a leadAccountId, and — this is the part that matters — an explicit notificationScheme.
2
Confirm the project actually has a notification scheme
GET /rest/api/3/project/{key}/notificationscheme. If this 404s, stop; nothing you measure afterwards means anything.
3
Put a recipient on the Issue Commented event whose mail you can actually read, using a recipient type Jira Cloud still supports.
4
Register a webhook on comment_created and jira:issue_updated, filtered to the project, so you can see which event each route raises.
5
Prove the tenant can send mail at all
POST /rest/api/3/issue/{key}/notify. This is the control, and it is the step everyone skips.
6
Run each route on its own fresh work item, with a plain summary edit as the control route, then read the webhook capture and the mailbox.
Steps two, three and five each turned up a way to get a confident, wrong answer, and the tenant's own plan turned up a fourth. Here they are in the order they bit me.
False negative 1 — the project has no notification scheme
I created the project the obvious way, then asked it for its notification scheme:
text
1GET /rest/api/3/project/NTFY/notificationscheme
2404 {"errorMessages":["No notification scheme associated with this project."]}
A company-managed project, freshly created, with no notification scheme at all. Not an empty one — none. Nothing in that project will ever raise scheme-driven mail, so every suppression test I ran in it would have come back clean.
I did not want to guess at the cause, so I isolated it. Three different templates, across two project types:
That project came up with 10000 Default Notification Scheme attached. So it is not the template and not the project type — POST /rest/api/3/project simply does not attach a default notification scheme unless you name one. If you already have projects in this state, PUT /rest/api/3/project/{key} with {"notificationScheme": 10000} retro-fits it; that returned 200 and the project reported the scheme immediately.
This one has a life beyond test beds. If you provision projects over the API — and plenty of teams do, this is the same class of gap as automation rules not travelling with the projects they belong to — then the people in those projects are getting no notifications, and nobody files a ticket about email they never expected.
Warning
A 404 from GET /rest/api/3/project/{key}/notificationscheme is not a permissions problem and not an API version problem. It is the literal absence of a scheme. Check it on every project you provision over REST.
False negative 2 — you don't get mail for your own changes
The second trap is the cheapest to fall into, because the natural way to test this is to comment on an issue you are watching and see whether your own inbox lights up.
That is the default, and it is per-user. With it off, Jira will not mail you about actions you performed yourself — so a solo admin testing suppression on their own work item gets silence from the suppressed route and silence from the unsuppressed one, and concludes the suppression works.
You can flip it with a PUT to the same endpoint, but I would rather not test a notification path using the one account whose notifications are specially suppressed. I put a separate recipient on the scheme instead, which is what step three of the bed is for.
False negative 3 — the whole tenant has outgoing mail switched off
This is the one that would have taken the article out at the knees, and I only caught it because I ran a positive control before believing a negative.
My routes had all returned success. No mail had arrived. That is exactly the result "the workaround works" would produce. So before writing a word of it, I asked the tenant to send me an email it had no reason to refuse:
Reproduced on three different work items. Atlassian's own OpenAPI document gives that status code exactly one meaning for this operation:
403 — Returned if: outgoing emails are disabled. no SMTP server is configured.
Those are two causes on paper and one in practice, because Atlassian's outgoing-mail page states that "In Jira Cloud, Outgoing Mail can only be enabled or disabled — there is no SMTP server to configure." On Cloud there is no second explanation available: a 403 here means the switch is off.
So the tenant sends nothing, at all, by any route. Every "no email arrived" result I had collected was worth precisely zero — and had I skipped this call, I would have published a confident measurement of a mechanism I had never once exercised. This is the same discipline that catches a Jira Cloud field quietly defaulting to a value nobody set: the absence of a symptom is not evidence until you have proved the instrument can produce one.
The setting itself is a site-level toggle. Atlassian's page for it carries a Cloud Only platform notice, puts it at ⚙️ Settings → System → Outgoing mail, and requires the Administer Jira global permission. Two sentences from it are worth memorising:
Disabling Outgoing Mail stops all notifications from jira@<domain>.atlassian.net. Notifications are not queued.
The Automation Send email action — still sends even with Outgoing Mail disabled (see AUTO-112).
That second one deserves a moment. If your plan for a risky backfill is "I'll flick outgoing mail off for an hour", it does not cover you: an automation rule with a Send email action will keep mailing people throughout. And because nothing is queued, the notifications you did want during that hour are gone rather than delayed.
Caution
Searching for how to disable outgoing mail over REST will hand you an Atlassian KB describing PUT /rest/jira-mail-plugin/1.0/outgoingMail/config. That article carries a Data Center Only platform notice. Atlassian's docs run as two parallel trees and the Data Center one frequently outranks the Cloud one — check the platform notice at the top of every page before you copy a path out of it.
I did not enable outgoing mail on this tenant to finish the measurement. It is a shared test site and I could not enumerate what else would have started sending the moment I flipped it — and an unknown blast radius is a reason not to proceed, not a reason to proceed carefully.
False negative 4 — the Free plan cap
The fourth one I did not measure directly, and I am labelling it as documented rather than tested. This tenant reports FREE for all three products, which I found the hard way when Jira refused a project role edit:
text
1POST /rest/api/3/project/NTFY/role/10002
2400 {"errorMessages":["You can't update role actors for this project as it's on the Jira Software Free plan."]}
Atlassian's notification documentation states the cap plainly:
Jira can send a maximum of 100 emails per day on the Free plan. After 100 emails, notifications are paused until the following day.
And, for anyone who upgrades to fix it: "it may take up to 30 days for this limit to be lifted." So a test run on a busy Free tenant late in the day sends nothing, silently, for reasons that have nothing to do with the thing you are testing — and a test run the following morning behaves differently. If you are testing notification behaviour on a Free sandbox, check the plan before you check anything else.
What the routes actually do
With the bed honest about what it could and could not tell me, here is what I measured. Four comment routes, plus two plain-summary-edit routes as controls, each on its own fresh work item, with a webhook capturing comment_created and jira:issue_updated.
Route
HTTP
Comment created
Webhook event raised
Changelog entry
A · POST /issue/{k}/comment
201
yes
comment_created
none
B · PUT /issue/{k}?notifyUsers=false
204
yes
comment_created
none
C · PUT /issue/{k} (no flag)
204
yes
comment_created
none
D · POST /issue/{k}/comment?notifyUsers=false
201
yes
comment_created
none
E · PUT /issue/{k}?notifyUsers=false (summary edit)
204
n/a
jira:issue_updated
yes
F · PUT /issue/{k} (summary edit, no flag)
204
n/a
jira:issue_updated
yes
7 rows × 5 columnsHeader row enabled
Three things fall out of that table.
Riding a comment in on the edit endpoint does not turn it into an issue update. Routes B and C never raised jira:issue_updated — only comment_created. Routes E and F, which edit an actual field, raise jira:issue_updated and nothing else. I ran the comment routes twice, on eight separate work items, and got the same split both times; E and F are the control that proves the observer can tell the two apart.
That matters because notification schemes key on events, not on which endpoint you called. GET /rest/api/3/events returns the catalogue your schemes are built from; on this tenant it is id 1 Issue Created, 2 Issue Updated, 3 Issue Assigned, 4 Issue Resolved, 5 Issue Closed, 6 Issue Commented, 13 Generic Event and 14 Issue Comment Edited.
So the row governing all four comment routes is Issue Commented (6), not Issue Updated (2) — while notifyUsers is documented against "a notification email about the issue update". The workaround is asking a flag scoped to one event to suppress a different one.
POST /comment?notifyUsers=false returns 201 and throws the parameter away. No error, no warning, comment created. It is the same failure mode as sendNotifications: false in an automation export, one layer down: the parameter is accepted by the transport and never read by the operation. If you have this in a script and no email storm has happened yet, it is not because the flag is working.
None of the comment routes write a changelog entry. Convenient if you are backfilling and did not want to pollute issue history; inconvenient if you were relying on the history tab to audit what your script did.
Two limits worth knowing before you write the loop
You cannot batch. update.comment is a JSON array, which reads like an invitation to add several comments per call. Jira refuses:
text
1PUT /rest/api/3/issue/{k}?notifyUsers=false
2{"update":{"comment":[{"add":{…}},{"add":{…}}]}}
34400 {"errors":{"comment":"Too many operations (2) provided for field 'comment'.
5 We support at most 1 operation for this field."}}
One comment per call, so a four-hundred-comment backfill is four hundred calls whichever route you pick. On this tenant, over twenty sequential calls each, the edit route is about fifteen percent slower per call and about twenty percent slower over the run:
Route
Median
Range
20 calls
Extrapolated to 400
POST /issue/{k}/comment
352 ms
242–468 ms
7.1 s
≈ 2.4 min
PUT /issue/{k}?notifyUsers=false
403 ms
344–668 ms
8.6 s
≈ 2.9 min
3 rows × 5 columnsHeader row enabled
Neither run hit a rate limit at that pace, but that is a single-threaded sequential loop on a quiet tenant and it is not a licence to fan out.
And the comment you get is indistinguishable. Reading both back over the API, route A and route B produce the same field set — author, body, created, id, jsdPublic, self, updateAuthor, updated — with the same author, the same jsdPublic: true and the same visibility: null. Nothing but the id and the timestamp separates them. So if the flag does work for you, nothing downstream will know how the comment arrived. That cuts both ways, which is a familiar shape for anyone who has pushed data into a Jira surface the public docs do not describe.
The lever that is certain
If you need a guarantee rather than a workaround, do not reach for a flag whose behaviour you cannot verify on your own tenant. Empty the Issue Commented row of the project's notification scheme for the duration of the backfill, then restore it. It is unglamorous, fully reversible, and it does not depend on undocumented behaviour.
One trap while you are in there. The old advice — add a single email address to the notification scheme so you can watch what fires — does not work on Cloud any more:
text
1POST /rest/api/3/notificationscheme
2{"notificationSchemeEvents":[{"event":{"id":"6"},
3 "notifications":[{"notificationType":"EmailAddress","parameter":"me@example.com"}]}]}
45400 {"errorMessages":["Recipient type EmailAddress is not supported."]}
I enumerated the whole set against the live API rather than trusting a doc page. These are accepted: CurrentAssignee, Reporter, CurrentUser, ProjectLead, ComponentLead, User, ProjectRole, AllWatchers. These are not: EmailAddress ("not supported") and IssueRole ("not found").
Group is accepted, and it has a trap in it that caught me while I was fact-checking this article. It wants the group name, and it rejects the group id — which is the opposite of the direction Jira Cloud has been moving in everywhere else. I tested three real groups both ways: the name returned 201 every time, and the corresponding groupId returned 400 "…is not a valid parameter" every time. I had written the reverse into this article from inference alone, and only caught it because I went back and ran it.
So to watch notifications land, you need a recipient that is a real account. Create one whose mailbox you can read, put it on the event as a User, and confirm it can browse the project — GET /rest/api/3/user/permission/search?accountId=…&permissions=BROWSE_PROJECTS&projectKey=… will tell you, and a recipient who cannot see the work item will not be mailed about it.
Prove the negative, don't observe it
The thread running through all four of these is one rule: a negative that authorises action has to be proved, not observed. A count of zero, an empty list, a quiet inbox — none of those license a conclusion until you have shown that the instrument can produce a non-zero on the same object.
POST /rest/api/3/issue/{key}/notify is the Jira equivalent, and it costs one call:
bash
1curl-u you@example.com:$TOKEN-X POST \2-H'Content-Type: application/json'\3'https://your-site.atlassian.net/rest/api/3/issue/ABC-1/notify'\4-d'{"subject":"control","textBody":"control","to":{"reporter":true}}'
204 means the tenant will send. 403 means it will not, and everything you were about to measure is void. Run it first, and run it again at the end.
One wrinkle to expect, because it will otherwise read as a failure: this endpoint also returns 400 when "the recipient is the same as the calling user". If you happen to be the reporter of the work item you picked, {"to":{"reporter":true}} gets you a 400 that has nothing to do with outgoing mail. Point it at a colleague's accountId, or pick a work item somebody else raised.
What I could not settle
I set out to answer one question — does notifyUsers=false on the edit-issue endpoint actually suppress the Issue Commented email — and I cannot answer it. The tenant I have admin on cannot send mail, and I was not willing to switch site-wide outgoing mail on to find out.
So, keeping the three registers apart:
Documented.notifyUsers suppresses "a notification email about the issue update", requires Administer Jira or Administer Projects, and is ignored rather than refused without them. The add-comment endpoint has no equivalent parameter. Atlassian publishes the edit-issue route as the workaround on JRACLOUD-97682.
Measured, here, on 24 August 2026. Everything in the tables above: the routes, the events, the latencies, the one-operation limit, the identical comment representation, the missing notification schemes, the unsupported recipient types, the user.notify.own.changes default, and the 403.
Still a guess. Whether the flag reaches the Issue Commented event. The webhook evidence says that event is what gets raised, and the parameter is documented against a different one — which makes me sceptical rather than certain. If you have a tenant with outgoing mail on, the bed above will settle it in about ten minutes, and I would genuinely like to know.
Whatever you find, do not find it the way I nearly did. Run the control first.