Set member.moderation_action via REST API as part of message approval?

We're using Mailman 3.3.9.
My team and I have written a simple UI for displaying and approving/rejecting held messages from non list members. When an email receives an "always accept" flag from the UI we call the API to pass in the requested information:
Form form = new Form();
form.param("action", "accept");
Entity<Form> data = Entity.entity(form, MediaType.APPLICATION_FORM_URLENCODED_TYPE);
String safePath = UriBuilder.fromPath("lists/{listId}/held/{messageId}").build(listId, messageId).toString();
response = getTarget().path(safePath).request().post(data);
If that request is successful we update the accept_these_nonmembers
property of the mailing list with the user's email.
Form form = new Form();
if (fieldValue.getClass().isArray()) {
for (String val : (String[])fieldValue) {
form.param(property, String.valueOf(val));
}
} else {
form.param(property, String.valueOf(fieldValue));
}
Entity<Form> data = Entity.entity(form, MediaType.APPLICATION_FORM_URLENCODED_TYPE);
response = getTarget().path("lists/" + listId + "/config").request().method("PATCH", data);
The result of these two API calls is that both the subscribers and nonmembers properties of the mailing list are updated to include the new email (let's call it abc@123.com). The user can immediately send another email which is not held for moderation. The issue comes when a different nonmember sends an email and is approved (let's call it xyz@789.com). For some reason this blows out the "always accept" status of user abc@123.com and requires their email to be approved again.
After some research I believe this is because the accept_these_nonmembers
property has been deprecated (which seems valid because that property remains an empty array). Additional reading seems to indicate that we can now set moderation_action
on each individual user which supercedes the mailing list's default_nonmember_action
property (in our case it is Action.hold
).
The docs indicate that I should be able to submit a patch request to update the moderation action for any user: https://docs.mailman3.org/projects/mailman/en/latest/src/mailman/rest/docs/m...
But it requires the user ID. And when trying to get the user_id for a nonmember it appears that it is not returned by the API. The following call:
/3.0/addresses/abc@123.com
returns
{
"email": "abc@123.com",
"original_email": "abc@123.com",
"registered_on": "2025-03-03T19:18:35.169703",
"self_link": "https://0.0.0.0:8001/3.0/addresses/abc@123.com",
"http_etag": "\"92c44d0b3b323450f3576e6352acb59b4cc5d6f0a\""
}
So I'm not sure how I would be able to update this particular record without a member or user id.
So, all that said, I'm looking for information on how to do one of the following.
- When submitting a user's email to the
accept_these_nonmembers
, is there a way to indicate that themember.moderation_action
should be a specific value? - Retrieve a nonmember record and have it include a member or user id that I can use to explicitly update the
member.moderation_action
value?
There may of course be additional approaches that I'm not considering, but that's about the gist of it. Thoughts?

To be clear, everything seems to be working as intended, with the exception of the second always accept user appearing to blow out the previous always accept user.

On 3/3/25 14:27, Andy Matthews wrote:
We're using Mailman 3.3.9.
Entity<Form> data = Entity.entity(form, MediaType.APPLICATION_FORM_URLENCODED_TYPE); response = getTarget().path("lists/" + listId + "/config").request().method("PATCH", data);
You are patching the list's config and with that patch you are replacing
the old value of accept_these_nonmembers
with the new, not appending
the new value. You would need to retrieve the existing value, update it
and PATCH that.
However, as you know, that setting is deprecated and exists only to
support the regexp and @list type of entries. For explicit email
addresses, the intent is to create a nonmember and set the nonmember's
moderation_action to defer
- you normally don't want accept
because
that bypasses all the subsequent checks such as administrivia,
implicit-dest, max_recipients, max_size, , no_subject, etc.
The result of these two API calls is that both the subscribers and nonmembers properties of the mailing list are updated to include the new email (let's call it abc@123.com). The user can immediately send another email which is not held for moderation. The issue comes when a different nonmember sends an email and is approved (let's call it xyz@789.com). For some reason this blows out the "always accept" status of user abc@123.com and requires their email to be approved again.
After some research I believe this is because the
accept_these_nonmembers
property has been deprecated (which seems valid because that property remains an empty array). Additional reading seems to indicate that we can now setmoderation_action
on each individual user which supercedes the mailing list'sdefault_nonmember_action
property (in our case it isAction.hold
).
That is correct, and that is the intended way to deal with nonmember moderation.
The docs indicate that I should be able to submit a patch request to update the moderation action for any user: https://docs.mailman3.org/projects/mailman/en/latest/src/mailman/rest/docs/m...
But it requires the user ID. And when trying to get the user_id for a nonmember it appears that it is not returned by the API. The following call:
/3.0/addresses/abc@123.com
returns
{ "email": "abc@123.com", "original_email": "abc@123.com", "registered_on": "2025-03-03T19:18:35.169703", "self_link": "https://0.0.0.0:8001/3.0/addresses/abc@123.com", "http_etag": "\"92c44d0b3b323450f3576e6352acb59b4cc5d6f0a\"" }
So I'm not sure how I would be able to update this particular record without a member or user id.
So, all that said, I'm looking for information on how to do one of the following.
- When submitting a user's email to the
accept_these_nonmembers
, is there a way to indicate that themember.moderation_action
should be a specific value?
No. You can put the email in the appropriate *_these_nonmembers, but that does only that. It doesn't affect the nonmember's moderation_action, nor does it create a nonmember if there isn't one already, but if there is a nonmember with non-None moderation_action, that action takes precedence over *_these_nonmembers.
- Retrieve a nonmember record and have it include a member or user id that I can use to explicitly update the
member.moderation_action
value?
You must be able to set a nonmember's moderation_action via REST. (The docs may need updating.) Postorius does it, so it can be done, but I don't offhand know the endpoint and I'm leaving the country for vacation tomorrow and don't have time to research it.
-- Mark Sapiro <mark@msapiro.net> The highway is for gamblers, San Francisco Bay Area, California better use your sense - B. Dylan

I'll keep researching, or perhaps another user will offer their insight. Have fun on your vacation Mark.

After reading Mark's comments it seems like a good approach, knowing that a moderator has explicitly chosen to "always accept" a post from a user, would be to first create that user record (including setting the moderation_action
property to defer
—as Mark indicates) , before approving their email. That way when the message itself is approved the user record is already included. And then we don't have any need to explicitly update the list's accept_these_nonmembers
property because we've already set the moderation_action
on the user.
Does that sound like an acceptable approach?
And a follow up question: at the moment we don't explicitly create users, we simply subscribe them to a list, and allow the implicit processes to do their magic. However if I wanted to manually create a nonmember, would I "create a user" or would I "subscribe a user to a list" with a role of nonmember
?
Which brings up an additional question. Is the moderation_action
list-specific or does it apply to all lists from the same domain? To be clear, if abc@123.com's moderation_action
is set to "defer" for **open-list@foo.bar** would that setting also apply to **another-open-list@foo.bar**?

Adding some additional clarification for myself, and anyone else who might read this thread. Users and members are separate, but related. From the docs: https://docs.mailman3.org/projects/mailman/en/latest/src/mailman/model/docs/...
Users represent people in Mailman, members represent subscriptions. Users control email addresses, and rosters are collections of members. A member ties a subscribed email address to a role, such as member, administrator, or moderator. Even non-members are represented by a roster.
Which tells me that the moderation_action
property is applied to a member and not a user. So for my use case it appears that I would need to take the following steps. Thus a single **user** record can be associated with multiple **member** records.
- Create a **user** record, if no user already exists
- Create a membership for that email, with the role set to
nonmember
and themoderation_action
property set todefer
as indicated by Mark earlier in this thread.

Okay, I've identified what I think is a working approach.
- I sent an email to my mailing list from a brand new, never before used, email: *foo@bar.com*
- I queried the
/3.0/addresses
endpoint and determined that just sending an email to a list automatically adds that email as a "known address". - I ran a
/members/find
API call, passing in thelist_id
and thesubscriber
, which returned a length 1 JSON array containing the member_id. - I ran a PATCH request against
/members/<member_uid>
, to update themoderation_action
- I reran step #3 and the response now included the
moderation_action
property with a value of *defer*
To confirm this all worked I sent, "always approved", and received emails from 2 different nonmember addresses and was able to receive them as expected.
participants (2)
-
Andy Matthews
-
Mark Sapiro