Policies
Policies organize two owner-scoped email controls: DNE records for exact email addresses and domain rules for exact domains. Create a policy group first, then include its group_id or group_name on every child-route request.
Authentication
Every route requires a bearer token for a user, admin, or root principal. The API injects the caller's owner ID; do not send owner.
Policy groups
| Route | Required fields | Optional fields and behavior |
|---|---|---|
POST /v1/members/policy/get |
id or name |
group_id is an alias for id; group_name is an alias for name. |
POST /v1/members/policy/list |
None | Exact filters: id, name; supports shared pagination. |
POST /v1/members/policy/save |
name |
id updates an owned group; description and metadata are optional. |
POST /v1/members/policy/delete |
id or name |
Deletes the owned group record. |
Save a policy group
| Field | Required | Type | Description |
|---|---|---|---|
id |
No | UUID | Existing owned group to update. |
name |
Yes | String | Stable owner-scoped group name. |
description |
No | String or null |
Optional description. |
metadata |
No | Object or null |
Application-defined data. |
Save writes the complete editable record, so an omitted description or metadata clears that field on update.
curl -sS https://api.post.m7.org/v1/members/policy/save \
-H 'Authorization: Bearer ACCESS_TOKEN' \
-H 'Content-Type: application/json' \
-d '{
"name": "transactional-email",
"description": "Rules for transactional recipients"
}'
{
"status": 1,
"comment": "OK",
"data": {
"saved": true,
"item": {
"id": "POLICY_GROUP_UUID",
"name": "transactional-email",
"description": "Rules for transactional recipients"
}
}
}
Child policy scope
Every DNE and domain route requires one policy-group reference:
| Field | Required | Type | Behavior |
|---|---|---|---|
group_id |
Conditional | UUID | Uses an owned policy-group ID. |
group_name |
Conditional | String | Resolves an owned policy-group name to its ID. |
Send either field. If both are supplied, they must resolve to the same group or the request fails with a conflict. The API applies the resolved group and the caller's ownership to every child lookup, including lookups by record ID.
DNE records
A DNE record suppresses one exact email address in a policy group.
| Route | Required fields | Optional fields and behavior |
|---|---|---|
POST /v1/members/policy/dne/get |
Group scope; id or email |
Returns data.item, which is null when no scoped record matches. |
POST /v1/members/policy/dne/check |
Group scope; id or email |
Returns data.match and data.item. |
POST /v1/members/policy/dne/list |
Group scope | Exact filters: id, email, domain, type, source, reason_code; supports shared pagination. |
POST /v1/members/policy/dne/save |
Group scope, email |
Creates or updates the record scoped to that group and email. |
POST /v1/members/policy/dne/delete |
Group scope; id or email |
Deletes the scoped record. |
DNE save fields
| Field | Required | Type | Description |
|---|---|---|---|
email |
Yes | String | Email address. The API lowercases it and derives domain. |
type |
No | String | soft (default) or hard. |
source |
No | String | manual (default), bounce, deferred, complaint, import, or system. |
reason_code |
No | String or null |
Machine-readable reason. |
reason |
No | String or null |
Human-readable reason. |
metadata |
No | Object or null |
Application-defined data. |
Save writes the complete editable DNE record. Omitted type and source use their defaults; omitted reason_code, reason, and metadata become null on update.
curl -sS https://api.post.m7.org/v1/members/policy/dne/save \
-H 'Authorization: Bearer ACCESS_TOKEN' \
-H 'Content-Type: application/json' \
-d '{
"group_name": "transactional-email",
"email": "recipient@example.test",
"type": "soft",
"source": "manual",
"reason_code": "user_request"
}'
The response contains data.saved: true and data.item, including id, email, derived domain, group, type, and source.
Domain policies
A domain policy stores an allow or block decision for one exact domain in a policy group.
| Route | Required fields | Optional fields and behavior |
|---|---|---|
POST /v1/members/policy/domain/get |
Group scope; id or domain |
Returns data.item, which is null when no scoped record matches. |
POST /v1/members/policy/domain/check |
Group scope; id or domain |
Returns data.match and data.item. |
POST /v1/members/policy/domain/list |
Group scope | Exact filters: id, domain, policy, include_subdomains, source, reason_code; supports shared pagination. |
POST /v1/members/policy/domain/save |
Group scope, domain, policy |
Creates or updates the record scoped to that group and domain. |
POST /v1/members/policy/domain/delete |
Group scope; id or domain |
Deletes the scoped record. |
Domain-policy save fields
| Field | Required | Type | Description |
|---|---|---|---|
domain |
Yes | String | Domain name without an @ or spaces. The API lowercases it. |
policy |
Yes | String | allow or block. |
include_subdomains |
No | Boolean | Defaults to true; stored with the record. |
source |
No | String | manual (default), import, or system. |
reason_code |
No | String or null |
Machine-readable reason. |
reason |
No | String or null |
Human-readable reason. |
metadata |
No | Object or null |
Application-defined data. |
Save writes the complete editable domain-policy record. Omitted include_subdomains defaults to true, source defaults to manual, and omitted reason_code, reason, and metadata become null on update.
curl -sS https://api.post.m7.org/v1/members/policy/domain/save \
-H 'Authorization: Bearer ACCESS_TOKEN' \
-H 'Content-Type: application/json' \
-d '{
"group_id": "POLICY_GROUP_UUID",
"domain": "example.test",
"policy": "block",
"include_subdomains": true,
"source": "manual"
}'
The response contains data.saved: true and data.item, including id, group, domain, policy, and include_subdomains.
get and check match the exact requested domain. They do not expand a lookup to subdomains; use include_subdomains as the stored policy attribute.
Errors and scope
- A missing, unowned, or mismatched group reference fails before the child operation.
- A child record ID from another group is treated as not found.
getandcheckreturn a successful response with anullitem ormatch: falsewhen no scoped record exists;deletereturns a not-found error in that case.